From 9ffcdc60c5afa199d760d74e1b127ab69878c703 Mon Sep 17 00:00:00 2001 From: Anna Pak Date: Sun, 4 Oct 2020 15:26:12 +0300 Subject: [PATCH 001/156] refactoring of AdminCreateInvoiceTest --- .../Test/Mftf/Test/AdminCreateInvoiceTest.xml | 93 +++++++------------ 1 file changed, 31 insertions(+), 62 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index 73c126bb7794f..e6a0a8b3661dd 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -18,77 +18,46 @@ - + + - + + + + + + + + + + + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - + - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - From 0c14e5ffd0778b5d7d203b3b74deea361a3d3f80 Mon Sep 17 00:00:00 2001 From: Anna Pak Date: Sun, 4 Oct 2020 15:38:27 +0300 Subject: [PATCH 002/156] refactored --- .../Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index e6a0a8b3661dd..f91c8d9993044 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -55,7 +55,7 @@ - + From ea995471fc9a9c0f75ad3dae3cbfbaba215327f0 Mon Sep 17 00:00:00 2001 From: Anna Pak Date: Mon, 5 Oct 2020 13:16:32 +0300 Subject: [PATCH 003/156] wrap openOrder action with ActionGroup Please enter the commit message for your changes. Lines starting --- .../Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index f91c8d9993044..f79154398eaff 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -45,7 +45,9 @@ - + + + From 3e467313566cb38f7af8bb6c5d9b991b35d0dcbe Mon Sep 17 00:00:00 2001 From: Anna Pak Date: Mon, 5 Oct 2020 14:14:04 +0300 Subject: [PATCH 004/156] deprecating old test Please enter the commit message for your changes. Lines starting --- .../Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index f79154398eaff..49ae1844a1cf1 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -8,7 +8,7 @@ - + From ff1a003de96805fda207c5f9c6cef95d08ba20c8 Mon Sep 17 00:00:00 2001 From: govindasharma974 Date: Sat, 10 Oct 2020 14:11:32 +0530 Subject: [PATCH 005/156] Fixed issue related with wrong invoice id ,creditmemo id and shipmen id in url of view page. --- .../Adminhtml/Order/Creditmemo/View.php | 9 +-- .../Adminhtml/Order/CreditmemoLoader.php | 6 +- .../Adminhtml/Order/Invoice/View.php | 7 +- .../AdminGoToCreditmemoViewActionGroup.xml | 22 +++++++ ...pmentViewPageWithWrongCreditmemoIdTest.xml | 39 +++++++++++ .../Adminhtml/Order/Creditmemo/ViewTest.php | 50 +++++++++++--- .../Adminhtml/Order/Shipment/View.php | 9 +-- .../Adminhtml/Order/ShipmentLoader.php | 7 +- .../AdminGoToShipmentViewActionGroup.xml | 22 +++++++ .../Test/Mftf/Page/AdminShipmentViewPage.xml | 13 ++++ ...hipmentViewPageWithWrongShipmentIdTest.xml | 39 +++++++++++ .../Adminhtml/Order/Shipment/ViewTest.php | 65 +++++++++++++++---- 12 files changed, 254 insertions(+), 34 deletions(-) create mode 100644 app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml create mode 100644 app/code/Magento/Sales/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongCreditmemoIdTest.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminGoToShipmentViewActionGroup.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/Page/AdminShipmentViewPage.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/View.php index be0afdb4a043b..c5832f64547c1 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/View.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/View.php @@ -6,8 +6,9 @@ namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo; use Magento\Backend\App\Action; +use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface; -class View extends \Magento\Backend\App\Action +class View extends \Magento\Backend\App\Action implements HttpGetActionInterface { /** * Authorization level of a basic admin session @@ -75,9 +76,9 @@ public function execute() } return $resultPage; } else { - $resultForward = $this->resultForwardFactory->create(); - $resultForward->forward('noroute'); - return $resultForward; + $resultRedirect = $this->resultRedirectFactory->create(); + $resultRedirect->setPath('sales/creditmemo'); + return $resultRedirect; } } } diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php index 0c5864e954a4f..dbcf22bc7bcf9 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php @@ -181,7 +181,11 @@ public function load() $creditmemoId = $this->getCreditmemoId(); $orderId = $this->getOrderId(); if ($creditmemoId) { - $creditmemo = $this->creditmemoRepository->get($creditmemoId); + try { + $creditmemo = $this->creditmemoRepository->get($creditmemoId); + } catch (\Exception $e) { + $this->messageManager->addErrorMessage(__('This creditmemo no longer exists.')); + return false; } elseif ($orderId) { $data = $this->getCreditmemo(); $order = $this->orderFactory->create()->load($orderId); diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/View.php index da700aae2f78a..b0e860d7f2e2d 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/View.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/View.php @@ -44,9 +44,10 @@ public function execute() { $invoice = $this->getInvoice(); if (!$invoice) { - /** @var \Magento\Framework\Controller\Result\Forward $resultForward */ - $resultForward = $this->resultForwardFactory->create(); - return $resultForward->forward('noroute'); + /** @var \Magento\Framework\Controller\Result\RedirectFactory $resultRedirect */ + $resultRedirect = $this->resultRedirectFactory->create(); + $resultRedirect->setPath('sales/invoice'); + return $resultRedirect; } /** @var \Magento\Backend\Model\View\Result\Page $resultPage */ diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml new file mode 100644 index 0000000000000..b55a7e8d6e5ed --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml @@ -0,0 +1,22 @@ + + + + + + + Goes to the Order Creditmemo View Page. + + + + + + + + + \ No newline at end of file diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongCreditmemoIdTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongCreditmemoIdTest.xml new file mode 100644 index 0000000000000..f04629708e0cd --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongCreditmemoIdTest.xml @@ -0,0 +1,39 @@ + + + + + + + + + <description value="Open Creditmemo View Page with Wrong Creditmemo Id."/> + <severity value="MAJOR"/> + <group value="sales"/> + </annotations> + + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin"/> + </before> + + <after> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + + <actionGroup ref="AdminGoToCreditmemoViewActionGroup" stepKey="navigateOpenCreditmemoViewPage"> + <argument name="identifier" value="test"/> + </actionGroup> + + <waitForPageLoad stepKey="waitForPageLoad"/> + + <seeInCurrentUrl url="{{AdminCreditmemosGridPage.url}}" stepKey="redirectToCreditmemosGridPage"/> + + <see selector="{{AdminMessagesSection.error}}" userInput='This creditmemo no longer exists.' + stepKey="seeErrorMessage"/> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php index 46c3113c8edc2..e7556fe309ecf 100644 --- a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php +++ b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php @@ -13,6 +13,8 @@ use Magento\Backend\Model\View\Result\Forward; use Magento\Backend\Model\View\Result\ForwardFactory; use Magento\Backend\Model\View\Result\Page; +use Magento\Backend\Model\View\Result\Redirect; +use Magento\Backend\Model\View\Result\RedirectFactory; use Magento\Framework\App\ActionFlag; use Magento\Framework\App\Request\Http; use Magento\Framework\Message\Manager; @@ -105,6 +107,17 @@ class ViewTest extends TestCase */ protected $pageTitleMock; + /** + * @var \Magento\Shipping\Controller\Adminhtml\Order\Creditmemo\View + * @var RedirectFactory|MockObject + */ + protected $resultRedirectFactoryMock; + + /** + * @var Redirect|MockObject + */ + protected $resultRedirectMock; + /** * @var PageFactory|MockObject */ @@ -239,7 +252,8 @@ protected function setUp(): void 'context' => $this->contextMock, 'creditmemoLoader' => $this->loaderMock, 'resultPageFactory' => $this->resultPageFactoryMock, - 'resultForwardFactory' => $this->resultForwardFactoryMock + 'resultForwardFactory' => $this->resultForwardFactoryMock, + 'resultRedirectFactory' => $this->resultRedirectFactoryMock ] ); } @@ -252,16 +266,11 @@ public function testExecuteNoCreditMemo() $this->loaderMock->expects($this->once()) ->method('load') ->willReturn(false); - $this->resultForwardFactoryMock->expects($this->once()) - ->method('create') - ->willReturn($this->resultForwardMock); - $this->resultForwardMock->expects($this->once()) - ->method('forward') - ->with('noroute') - ->willReturnSelf(); - + + $this->prepareRedirect(); + $this->setPath('sales/creditmemo'); $this->assertInstanceOf( - Forward::class, + Redirect::class, $this->controller->execute() ); } @@ -322,4 +331,25 @@ public function executeDataProvider() [$this->invoiceMock] ]; } + + /** + * prepareRedirect + */ + protected function prepareRedirect() + { + $this->resultRedirectFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->resultRedirectMock); + } + + /** + * @param string $path + * @param array $params + */ + protected function setPath($path, $params = []) + { + $this->resultRedirectMock->expects($this->once()) + ->method('setPath') + ->with($path, $params); + } } diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/View.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/View.php index d8fda0bfe781b..d903a1a7d5889 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/View.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/View.php @@ -7,8 +7,9 @@ namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment; use Magento\Backend\App\Action; +use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface; -class View extends \Magento\Backend\App\Action +class View extends \Magento\Backend\App\Action implements HttpGetActionInterface { /** * Authorization level of a basic admin session @@ -71,9 +72,9 @@ public function execute() $resultPage->getConfig()->getTitle()->prepend("#" . $shipment->getIncrementId()); return $resultPage; } else { - $resultForward = $this->resultForwardFactory->create(); - $resultForward->forward('noroute'); - return $resultForward; + $resultRedirect = $this->resultRedirectFactory->create(); + $resultRedirect->setPath('sales/shipment'); + return $resultRedirect; } } } diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php index c4094a63ec527..4f44bfb6458b1 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php @@ -110,7 +110,12 @@ public function load() $orderId = $this->getOrderId(); $shipmentId = $this->getShipmentId(); if ($shipmentId) { - $shipment = $this->shipmentRepository->get($shipmentId); + try { + $shipment = $this->shipmentRepository->get($shipmentId); + } catch (\Exception $e) { + $this->messageManager->addErrorMessage(__('This shipment no longer exists.')); + return false; + } } elseif ($orderId) { $order = $this->orderRepository->get($orderId); diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminGoToShipmentViewActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminGoToShipmentViewActionGroup.xml new file mode 100644 index 0000000000000..09f74839b3a30 --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminGoToShipmentViewActionGroup.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="AdminGoToShipmentViewActionGroup"> + <annotations> + <description>Goes to the Order Shipment View Page.</description> + </annotations> + <arguments> + <argument name="identifier" type="string"/> + </arguments> + + <amOnPage url="{{AdminShipmentViewPage.url}}/{{identifier}}" stepKey="amOnShipmentViewPage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + </actionGroup> +</actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Shipping/Test/Mftf/Page/AdminShipmentViewPage.xml b/app/code/Magento/Shipping/Test/Mftf/Page/AdminShipmentViewPage.xml new file mode 100644 index 0000000000000..5a965db2b4efe --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Page/AdminShipmentViewPage.xml @@ -0,0 +1,13 @@ +<?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="AdminShipmentViewPage" url="sales/shipment/view/shipment_id" area="admin" module="Shipping"> + </page> +</pages> \ No newline at end of file diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml new file mode 100644 index 0000000000000..0311ebc320b59 --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml @@ -0,0 +1,39 @@ +<?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="AdminOpenShipmentViewPageWithWrongShipmentIdTest"> + <annotations> + <stories value="Shipment Page With Wrong Shipment Id"/> + <title value="Open Shipment View Page with Wrong Shipment Id"/> + <description value="Open Shipment View Page with Wrong Shipment Id."/> + <severity value="MAJOR"/> + <group value="shipping"/> + </annotations> + + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin"/> + </before> + + <after> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + + <actionGroup ref="AdminGoToShipmentViewActionGroup" stepKey="navigateOpenShipmentViewPage"> + <argument name="identifier" value="test"/> + </actionGroup> + + <waitForPageLoad stepKey="waitForPageLoad"/> + + <seeInCurrentUrl url="{{AdminShipmentsGridPage.url}}" stepKey="redirectToShipmentsGridPage"/> + + <see selector="{{AdminMessagesSection.error}}" userInput='This shipment no longer exists.' + stepKey="seeErrorMessage"/> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/ViewTest.php b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/ViewTest.php index 04b357eeaefca..d99ce83d91de2 100644 --- a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/ViewTest.php +++ b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/ViewTest.php @@ -11,6 +11,8 @@ use Magento\Backend\Model\View\Result\Forward; use Magento\Backend\Model\View\Result\ForwardFactory; use Magento\Backend\Model\View\Result\Page; +use Magento\Backend\Model\View\Result\Redirect; +use Magento\Backend\Model\View\Result\RedirectFactory; use Magento\Framework\App\RequestInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; @@ -21,6 +23,7 @@ use Magento\Sales\Model\Order\Shipment; use Magento\Shipping\Block\Adminhtml\View; use Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader; +use Magento\Shipping\Controller\Adminhtml\Order\Shipment\View as OrderShipmentView; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -84,11 +87,24 @@ class ViewTest extends TestCase */ protected $pageTitleMock; + /** * @var \Magento\Shipping\Controller\Adminhtml\Order\Shipment\View + * @var RedirectFactory|MockObject + */ + protected $resultRedirectFactoryMock; + + /** + * @var Redirect|MockObject + */ + protected $resultRedirectMock; + + /** + * @var OrderShipmentView */ protected $controller; + protected function setUp(): void { $this->requestMock = $this->getMockBuilder(RequestInterface::class) @@ -130,16 +146,25 @@ protected function setUp(): void ['updateBackButtonUrl'] ); + $this->resultRedirectFactoryMock = $this->getMockBuilder(RedirectFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->resultRedirectMock = $this->getMockBuilder(Redirect::class) + ->disableOriginalConstructor() + ->getMock(); + $objectManager = new ObjectManager($this); $context = $objectManager->getObject( Context::class, [ 'request' => $this->requestMock, - 'objectManager' => $this->objectManagerMock + 'objectManager' => $this->objectManagerMock, + 'resultRedirectFactory' => $this->resultRedirectFactoryMock ] ); $this->controller = $objectManager->getObject( - \Magento\Shipping\Controller\Adminhtml\Order\Shipment\View::class, + OrderShipmentView::class, [ 'context' => $context, 'shipmentLoader' => $this->shipmentLoaderMock, @@ -216,15 +241,12 @@ public function testExecuteNoShipment() $tracking = []; $this->loadShipment($orderId, $shipmentId, $shipment, $tracking, null, false); - $this->resultForwardFactoryMock->expects($this->once()) - ->method('create') - ->willReturn($this->resultForwardMock); - $this->resultForwardMock->expects($this->once()) - ->method('forward') - ->with('noroute') - ->willReturnSelf(); - - $this->assertEquals($this->resultForwardMock, $this->controller->execute()); + $this->prepareRedirect(); + $this->setPath('sales/shipment'); + $this->assertInstanceOf( + Redirect::class, + $this->controller->execute() + ); } /** @@ -255,4 +277,25 @@ protected function loadShipment($orderId, $shipmentId, $shipment, $tracking, $co ->method('load') ->willReturn($returnShipment); } + + /** + * prepareRedirect + */ + protected function prepareRedirect() + { + $this->resultRedirectFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->resultRedirectMock); + } + + /** + * @param string $path + * @param array $params + */ + protected function setPath($path, $params = []) + { + $this->resultRedirectMock->expects($this->once()) + ->method('setPath') + ->with($path, $params); + } } From 0e78fe405442b1eb8955c1e53bc2c65f539b6f63 Mon Sep 17 00:00:00 2001 From: govindasharma974 <govindpokhrelsharma@cedcommerce.com> Date: Sat, 10 Oct 2020 14:18:21 +0530 Subject: [PATCH 006/156] Fixed issue related with wrong invoice id ,creditmemo id and shipmen id in url of view page. --- ...l => AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/code/Magento/Sales/Test/Mftf/Test/{AdminOpenShipmentViewPageWithWrongCreditmemoIdTest.xml => AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml} (100%) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongCreditmemoIdTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml similarity index 100% rename from app/code/Magento/Sales/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongCreditmemoIdTest.xml rename to app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml From ff5de32bd53e7a7b7b357bf3e3606092dd777681 Mon Sep 17 00:00:00 2001 From: Govind Sharma <govindpokhrelsharma@cedcoss.com> Date: Sat, 10 Oct 2020 16:27:48 +0530 Subject: [PATCH 007/156] Update ViewTest.php --- .../Controller/Adminhtml/Order/Creditmemo/ViewTest.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php index e7556fe309ecf..b6935269e3da7 100644 --- a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php +++ b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php @@ -216,7 +216,13 @@ protected function setUp(): void $this->resultForwardMock = $this->getMockBuilder(Forward::class) ->disableOriginalConstructor() ->getMock(); - + $this->resultRedirectFactoryMock = $this->getMockBuilder(RedirectFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->resultRedirectMock = $this->getMockBuilder(Redirect::class) + ->disableOriginalConstructor() + ->getMock(); $this->contextMock->expects($this->any()) ->method('getSession') ->willReturn($this->sessionMock); From 6b1837b2db974a986f9e16264e89bf3c01fed5ea Mon Sep 17 00:00:00 2001 From: govindasharma974 <govindpokhrelsharma@cedcommerce.com> Date: Mon, 12 Oct 2020 10:47:39 +0530 Subject: [PATCH 008/156] Added new line to to mftf files, added words to csv and fixed compilation issue --- .../Adminhtml/Order/CreditmemoLoader.php | 3 +- .../AdminGoToCreditmemoViewActionGroup.xml | 2 +- ...tmemoViewPageWithWrongCreditmemoIdTest.xml | 2 +- app/code/Magento/Sales/i18n/en_US.csv | 1293 +++++++++-------- .../AdminGoToShipmentViewActionGroup.xml | 2 +- .../Test/Mftf/Page/AdminShipmentViewPage.xml | 2 +- ...hipmentViewPageWithWrongShipmentIdTest.xml | 2 +- app/code/Magento/Shipping/i18n/en_US.csv | 261 ++-- 8 files changed, 785 insertions(+), 782 deletions(-) diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php index dbcf22bc7bcf9..7bb0b38a8d5ff 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php @@ -183,9 +183,10 @@ public function load() if ($creditmemoId) { try { $creditmemo = $this->creditmemoRepository->get($creditmemoId); - } catch (\Exception $e) { + } catch (\Exception $e) { $this->messageManager->addErrorMessage(__('This creditmemo no longer exists.')); return false; + } } elseif ($orderId) { $data = $this->getCreditmemo(); $order = $this->orderFactory->create()->load($orderId); diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml index b55a7e8d6e5ed..041ebc7baa84d 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml @@ -19,4 +19,4 @@ <amOnPage url="{{AdminCreditmemoViewPage.url}}/{{identifier}}" stepKey="amOnCreditmemoViewPage"/> <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml index f04629708e0cd..c6522cb22cdf3 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml @@ -36,4 +36,4 @@ <see selector="{{AdminMessagesSection.error}}" userInput='This creditmemo no longer exists.' stepKey="seeErrorMessage"/> </test> -</tests> \ No newline at end of file +</tests> diff --git a/app/code/Magento/Sales/i18n/en_US.csv b/app/code/Magento/Sales/i18n/en_US.csv index 97c1706f975da..059569775e419 100644 --- a/app/code/Magento/Sales/i18n/en_US.csv +++ b/app/code/Magento/Sales/i18n/en_US.csv @@ -1,344 +1,344 @@ -"Credit Memos","Credit Memos" +Credit Memos,Credit Memos Orders,Orders Invoices,Invoices -"We can't get the order instance right now.","We can't get the order instance right now." -"Create New Order","Create New Order" -"Save Order Address","Save Order Address" +We can't get the order instance right now.,We can't get the order instance right now. +Create New Order,Create New Order +Save Order Address,Save Order Address Shipping,Shipping Billing,Billing -"Edit Order %1 %2 Address","Edit Order %1 %2 Address" -"Order Address Information","Order Address Information" -"Please correct the parent block for this block.","Please correct the parent block for this block." -"Submit Comment","Submit Comment" -"Submit Order","Submit Order" -"Are you sure you want to cancel this order?","Are you sure you want to cancel this order?" +Edit Order %1 %2 Address,Edit Order %1 %2 Address +Order Address Information,Order Address Information +Please correct the parent block for this block.,Please correct the parent block for this block. +Submit Comment,Submit Comment +Submit Order,Submit Order +Are you sure you want to cancel this order?,Are you sure you want to cancel this order? Cancel,Cancel -"Billing Address","Billing Address" -"Payment Method","Payment Method" -"Order Comment","Order Comment" +Billing Address,Billing Address +Payment Method,Payment Method +Order Comment,Order Comment Coupons,Coupons -"Please select a customer","Please select a customer" -"Create New Customer","Create New Customer" -"Account Information","Account Information" +Please select a customer,Please select a customer +Create New Customer,Create New Customer +Account Information,Account Information From,From To,To Message,Message -"Edit Order #%1","Edit Order #%1" -"Create New Order for %1 in %2","Create New Order for %1 in %2" -"Create New Order in %1","Create New Order in %1" -"Create New Order for %1","Create New Order for %1" -"Create New Order for New Customer","Create New Order for New Customer" -"Items Ordered","Items Ordered" -"This product is disabled.","This product is disabled." -"Buy %1 for price %2","Buy %1 for price %2" -"Item ordered qty","Item ordered qty" -"%1 with %2 discount each","%1 with %2 discount each" -"%1 for %2","%1 for %2" -"* - Enter custom price including tax","* - Enter custom price including tax" -"* - Enter custom price excluding tax","* - Enter custom price excluding tax" +Edit Order #%1,Edit Order #%1 +Create New Order for %1 in %2,Create New Order for %1 in %2 +Create New Order in %1,Create New Order in %1 +Create New Order for %1,Create New Order for %1 +Create New Order for New Customer,Create New Order for New Customer +Items Ordered,Items Ordered +This product is disabled.,This product is disabled. +Buy %1 for price %2,Buy %1 for price %2 +Item ordered qty,Item ordered qty +%1 with %2 discount each,%1 with %2 discount each +%1 for %2,%1 for %2 +* - Enter custom price including tax,* - Enter custom price including tax +* - Enter custom price excluding tax,* - Enter custom price excluding tax Configure,Configure -"This product does not have any configurable options","This product does not have any configurable options" -"Newsletter Subscription","Newsletter Subscription" -"Please select products","Please select products" -"Add Selected Product(s) to Order","Add Selected Product(s) to Order" +This product does not have any configurable options,This product does not have any configurable options +Newsletter Subscription,Newsletter Subscription +Please select products,Please select products +Add Selected Product(s) to Order,Add Selected Product(s) to Order ID,ID Product,Product SKU,SKU Price,Price Select,Select Quantity,Quantity -"Shipping Address","Shipping Address" -"Shipping Method","Shipping Method" -"Update Changes","Update Changes" -"Shopping Cart","Shopping Cart" -"Are you sure you want to delete all items from shopping cart?","Are you sure you want to delete all items from shopping cart?" -"Clear Shopping Cart","Clear Shopping Cart" -"Products in Comparison List","Products in Comparison List" -"Recently Compared Products","Recently Compared Products" -"Recently Viewed Products","Recently Viewed Products" -"Last Ordered Items","Last Ordered Items" -"Recently Viewed","Recently Viewed" -"Wish List","Wish List" -"Please select a store","Please select a store" -"Order Totals","Order Totals" -"Shipping Incl. Tax (%1)","Shipping Incl. Tax (%1)" -"Shipping Excl. Tax (%1)","Shipping Excl. Tax (%1)" -"New Credit Memo for Invoice #%1","New Credit Memo for Invoice #%1" -"New Credit Memo for Order #%1","New Credit Memo for Order #%1" -"Refund Shipping (Incl. Tax)","Refund Shipping (Incl. Tax)" -"Refund Shipping (Excl. Tax)","Refund Shipping (Excl. Tax)" -"Refund Shipping","Refund Shipping" -"Update Qty's","Update Qty's" +Shipping Address,Shipping Address +Shipping Method,Shipping Method +Update Changes,Update Changes +Shopping Cart,Shopping Cart +Are you sure you want to delete all items from shopping cart?,Are you sure you want to delete all items from shopping cart? +Clear Shopping Cart,Clear Shopping Cart +Products in Comparison List,Products in Comparison List +Recently Compared Products,Recently Compared Products +Recently Viewed Products,Recently Viewed Products +Last Ordered Items,Last Ordered Items +Recently Viewed,Recently Viewed +Wish List,Wish List +Please select a store,Please select a store +Order Totals,Order Totals +Shipping Incl. Tax (%1),Shipping Incl. Tax (%1) +Shipping Excl. Tax (%1),Shipping Excl. Tax (%1) +New Credit Memo for Invoice #%1,New Credit Memo for Invoice #%1 +New Credit Memo for Order #%1,New Credit Memo for Order #%1 +Refund Shipping (Incl. Tax),Refund Shipping (Incl. Tax) +Refund Shipping (Excl. Tax),Refund Shipping (Excl. Tax) +Refund Shipping,Refund Shipping +Update Qty's,Update Qty's Refund,Refund -"Refund Offline","Refund Offline" -"Paid Amount","Paid Amount" -"Refund Amount","Refund Amount" -"Shipping Amount","Shipping Amount" -"Shipping Refund","Shipping Refund" -"Order Grand Total","Order Grand Total" -"Adjustment Refund","Adjustment Refund" -"Adjustment Fee","Adjustment Fee" -"Send Email","Send Email" -"Are you sure you want to send a credit memo email to customer?","Are you sure you want to send a credit memo email to customer?" +Refund Offline,Refund Offline +Paid Amount,Paid Amount +Refund Amount,Refund Amount +Shipping Amount,Shipping Amount +Shipping Refund,Shipping Refund +Order Grand Total,Order Grand Total +Adjustment Refund,Adjustment Refund +Adjustment Fee,Adjustment Fee +Send Email,Send Email +Are you sure you want to send a credit memo email to customer?,Are you sure you want to send a credit memo email to customer? Void,Void Print,Print -"The credit memo email was sent.","The credit memo email was sent." -"The credit memo email wasn't sent.","The credit memo email wasn't sent." -"Credit Memo #%1 | %3 | %2 (%4)","Credit Memo #%1 | %3 | %2 (%4)" -"Total Refund","Total Refund" -"New Invoice and Shipment for Order #%1","New Invoice and Shipment for Order #%1" -"New Invoice for Order #%1","New Invoice for Order #%1" -"Submit Invoice and Shipment","Submit Invoice and Shipment" -"Submit Invoice","Submit Invoice" -"Are you sure you want to send an invoice email to customer?","Are you sure you want to send an invoice email to customer?" -"Credit Memo","Credit Memo" +The credit memo email was sent.,The credit memo email was sent. +The credit memo email wasn't sent.,The credit memo email wasn't sent. +Credit Memo #%1 | %3 | %2 (%4),Credit Memo #%1 | %3 | %2 (%4) +Total Refund,Total Refund +New Invoice and Shipment for Order #%1,New Invoice and Shipment for Order #%1 +New Invoice for Order #%1,New Invoice for Order #%1 +Submit Invoice and Shipment,Submit Invoice and Shipment +Submit Invoice,Submit Invoice +Are you sure you want to send an invoice email to customer?,Are you sure you want to send an invoice email to customer? +Credit Memo,Credit Memo Capture,Capture -"The invoice email was sent.","The invoice email was sent." -"The invoice email wasn't sent.","The invoice email wasn't sent." -"Invoice #%1 | %2 | %4 (%3)","Invoice #%1 | %2 | %4 (%3)" -"Invalid parent block for this block","Invalid parent block for this block" -"Order Statuses","Order Statuses" -"Create New Status","Create New Status" -"Assign Status to State","Assign Status to State" -"Save Status Assignment","Save Status Assignment" -"Assign Order Status to State","Assign Order Status to State" -"Assignment Information","Assignment Information" -"Order Status","Order Status" -"Order State","Order State" -"Use Order Status As Default","Use Order Status As Default" -"Visible On Storefront","Visible On Storefront" -"Edit Order Status","Edit Order Status" -"Save Status","Save Status" -"New Order Status","New Order Status" -"Order Status Information","Order Status Information" -"Status Code","Status Code" -"Status Label","Status Label" -"Store View Specific Labels","Store View Specific Labels" -"Total Paid","Total Paid" -"Total Refunded","Total Refunded" -"Total Due","Total Due" -"Total Canceled","Total Canceled" +The invoice email was sent.,The invoice email was sent. +The invoice email wasn't sent.,The invoice email wasn't sent. +Invoice #%1 | %2 | %4 (%3),Invoice #%1 | %2 | %4 (%3) +Invalid parent block for this block,Invalid parent block for this block +Order Statuses,Order Statuses +Create New Status,Create New Status +Assign Status to State,Assign Status to State +Save Status Assignment,Save Status Assignment +Assign Order Status to State,Assign Order Status to State +Assignment Information,Assignment Information +Order Status,Order Status +Order State,Order State +Use Order Status As Default,Use Order Status As Default +Visible On Storefront,Visible On Storefront +Edit Order Status,Edit Order Status +Save Status,Save Status +New Order Status,New Order Status +Order Status Information,Order Status Information +Status Code,Status Code +Status Label,Status Label +Store View Specific Labels,Store View Specific Labels +Total Paid,Total Paid +Total Refunded,Total Refunded +Total Due,Total Due +Total Canceled,Total Canceled Edit,Edit -"Are you sure you want to send an order email to customer?","Are you sure you want to send an order email to customer?" +Are you sure you want to send an order email to customer?,Are you sure you want to send an order email to customer? "This will create an offline refund. To create an online refund, open an invoice and create credit memo for it. Do you want to continue?","This will create an offline refund. To create an online refund, open an invoice and create credit memo for it. Do you want to continue?" -"Are you sure you want to void the payment?","Are you sure you want to void the payment?" +Are you sure you want to void the payment?,Are you sure you want to void the payment? Hold,Hold hold,hold Unhold,Unhold unhold,unhold -"Are you sure you want to accept this payment?","Are you sure you want to accept this payment?" -"Accept Payment","Accept Payment" -"Are you sure you want to deny this payment?","Are you sure you want to deny this payment?" -"Deny Payment","Deny Payment" -"Get Payment Update","Get Payment Update" -"Invoice and Ship","Invoice and Ship" +Are you sure you want to accept this payment?,Are you sure you want to accept this payment? +Accept Payment,Accept Payment +Are you sure you want to deny this payment?,Are you sure you want to deny this payment? +Deny Payment,Deny Payment +Get Payment Update,Get Payment Update +Invoice and Ship,Invoice and Ship Invoice,Invoice Ship,Ship Reorder,Reorder -"Order # %1 %2 | %3","Order # %1 %2 | %3" +Order # %1 %2 | %3,Order # %1 %2 | %3 "This order contains (%1) items and therefore cannot be edited through the admin interface. If you wish to continue editing, the (%2) items will be removed, the order will be canceled and a new order will be placed.","This order contains (%1) items and therefore cannot be edited through the admin interface. If you wish to continue editing, the (%2) items will be removed, the order will be canceled and a new order will be placed." -"Are you sure? This order will be canceled and a new one will be created instead.","Are you sure? This order will be canceled and a new one will be created instead." -"Save Gift Message","Save Gift Message" -" [deleted]"," [deleted]" -"Order Credit Memos","Order Credit Memos" -"Credit memo #%1 created","Credit memo #%1 created" -"Credit memo #%1 comment added","Credit memo #%1 comment added" -"Shipment #%1 created","Shipment #%1 created" -"Shipment #%1 comment added","Shipment #%1 comment added" -"Invoice #%1 created","Invoice #%1 created" -"Invoice #%1 comment added","Invoice #%1 comment added" -"Tracking number %1 for %2 assigned","Tracking number %1 for %2 assigned" -"Comments History","Comments History" -"Order History","Order History" +Are you sure? This order will be canceled and a new one will be created instead.,Are you sure? This order will be canceled and a new one will be created instead. +Save Gift Message,Save Gift Message + [deleted], [deleted] +Order Credit Memos,Order Credit Memos +Credit memo #%1 created,Credit memo #%1 created +Credit memo #%1 comment added,Credit memo #%1 comment added +Shipment #%1 created,Shipment #%1 created +Shipment #%1 comment added,Shipment #%1 comment added +Invoice #%1 created,Invoice #%1 created +Invoice #%1 comment added,Invoice #%1 comment added +Tracking number %1 for %2 assigned,Tracking number %1 for %2 assigned +Comments History,Comments History +Order History,Order History Information,Information -"Order Information","Order Information" -"Order Invoices","Order Invoices" +Order Information,Order Information +Order Invoices,Order Invoices Shipments,Shipments -"Order Shipments","Order Shipments" +Order Shipments,Order Shipments Transactions,Transactions -"Order View","Order View" +Order View,Order View Any,Any Specified,Specified -"Applies to Any of the Specified Order Statuses except canceled orders","Applies to Any of the Specified Order Statuses except canceled orders" -"Cart Price Rule","Cart Price Rule" +Applies to Any of the Specified Order Statuses except canceled orders,Applies to Any of the Specified Order Statuses except canceled orders +Cart Price Rule,Cart Price Rule Yes,Yes No,No -"Show Actual Values","Show Actual Values" -"New Order RSS","New Order RSS" +Show Actual Values,Show Actual Values +New Order RSS,New Order RSS Subtotal,Subtotal -"Shipping & Handling","Shipping & Handling" -"Discount (%1)","Discount (%1)" +Shipping & Handling,Shipping & Handling +Discount (%1),Discount (%1) Discount,Discount -"Grand Total","Grand Total" +Grand Total,Grand Total Back,Back Fetch,Fetch -"Transaction # %1 | %2","Transaction # %1 | %2" +Transaction # %1 | %2,Transaction # %1 | %2 N/A,N/A Key,Key Value,Value -"We found an invalid entity model.","We found an invalid entity model." -"Order # %1","Order # %1" -"Back to My Orders","Back to My Orders" -"View Another Order","View Another Order" -"About Your Refund","About Your Refund" -"My Orders","My Orders" -"Subscribe to Order Status","Subscribe to Order Status" -"About Your Invoice","About Your Invoice" -"Print Order # %1","Print Order # %1" -"Grand Total to be Charged","Grand Total to be Charged" +We found an invalid entity model.,We found an invalid entity model. +Order # %1,Order # %1 +Back to My Orders,Back to My Orders +View Another Order,View Another Order +About Your Refund,About Your Refund +My Orders,My Orders +Subscribe to Order Status,Subscribe to Order Status +About Your Invoice,About Your Invoice +Print Order # %1,Print Order # %1 +Grand Total to be Charged,Grand Total to be Charged Unassign,Unassign -"We can't add this item to your shopping cart right now.","We can't add this item to your shopping cart right now." -"You sent the message.","You sent the message." +We can't add this item to your shopping cart right now.,We can't add this item to your shopping cart right now. +You sent the message.,You sent the message. Sales,Sales -"Invoice capturing error","Invoice capturing error" -"This order no longer exists.","This order no longer exists." -"Please enter a comment.","Please enter a comment." -"We cannot add order history.","We cannot add order history." -"You updated the order address.","You updated the order address." -"We can't update the order address right now.","We can't update the order address right now." -"You have not canceled the item.","You have not canceled the item." -"You canceled the order.","You canceled the order." +Invoice capturing error,Invoice capturing error +This order no longer exists.,This order no longer exists. +Please enter a comment.,Please enter a comment. +We cannot add order history.,We cannot add order history. +You updated the order address.,You updated the order address. +We can't update the order address right now.,We can't update the order address right now. +You have not canceled the item.,You have not canceled the item. +You canceled the order.,You canceled the order. """%1"" coupon code was not applied. Do not apply discount is selected for item(s)","""%1"" coupon code was not applied. Do not apply discount is selected for item(s)" """%1"" coupon code is not valid.","""%1"" coupon code is not valid." -"The coupon code has been accepted.","The coupon code has been accepted." -"Quote item id is not received.","Quote item id is not received." -"Quote item is not loaded.","Quote item is not loaded." -"New Order","New Order" -"You created the order.","You created the order." -"Order saving error: %1","Order saving error: %1" -"Cannot add new comment.","Cannot add new comment." -"The credit memo has been canceled.","The credit memo has been canceled." -"Credit memo has not been canceled.","Credit memo has not been canceled." -"New Memo for #%1","New Memo for #%1" -"New Memo","New Memo" -"The credit memo's total must be positive.","The credit memo's total must be positive." -"Cannot create online refund for Refund to Store Credit.","Cannot create online refund for Refund to Store Credit." -"You created the credit memo.","You created the credit memo." -"We can't save the credit memo right now.","We can't save the credit memo right now." -"We can't update the item's quantity right now.","We can't update the item's quantity right now." -"View Memo for #%1","View Memo for #%1" -"View Memo","View Memo" -"You voided the credit memo.","You voided the credit memo." -"We can't void the credit memo.","We can't void the credit memo." -"The order no longer exists.","The order no longer exists." -"We can't create credit memo for the order.","We can't create credit memo for the order." -"Edit Order","Edit Order" -"You sent the order email.","You sent the order email." -"We can't send the email order right now.","We can't send the email order right now." -"You have not put the order on hold.","You have not put the order on hold." -"You put the order on hold.","You put the order on hold." -"You canceled the invoice.","You canceled the invoice." -"Invoice canceling error","Invoice canceling error" -"The invoice has been captured.","The invoice has been captured." -"The order does not allow an invoice to be created.","The order does not allow an invoice to be created." -"You can't create an invoice without products.","You can't create an invoice without products." -"New Invoice","New Invoice" -"We can't save the invoice right now.","We can't save the invoice right now." -"You created the invoice and shipment.","You created the invoice and shipment." -"The invoice has been created.","The invoice has been created." -"We can't send the invoice email right now.","We can't send the invoice email right now." -"We can't send the shipment right now.","We can't send the shipment right now." -"Cannot update item quantity.","Cannot update item quantity." -"The invoice has been voided.","The invoice has been voided." -"Invoice voiding error","Invoice voiding error" -"%1 order(s) cannot be canceled.","%1 order(s) cannot be canceled." -"You cannot cancel the order(s).","You cannot cancel the order(s)." -"We canceled %1 order(s).","We canceled %1 order(s)." -"%1 order(s) were not put on hold.","%1 order(s) were not put on hold." -"No order(s) were put on hold.","No order(s) were put on hold." -"You have put %1 order(s) on hold.","You have put %1 order(s) on hold." -"%1 order(s) were not released from on hold status.","%1 order(s) were not released from on hold status." -"No order(s) were released from on hold status.","No order(s) were released from on hold status." -"%1 order(s) have been released from on hold status.","%1 order(s) have been released from on hold status." -"There are no printable documents related to selected orders.","There are no printable documents related to selected orders." -"The payment has been accepted.","The payment has been accepted." -"The payment has been denied.","The payment has been denied." -"Transaction has been approved.","Transaction has been approved." -"Transaction has been voided/declined.","Transaction has been voided/declined." -"There is no update for the transaction.","There is no update for the transaction." -"We can't update the payment right now.","We can't update the payment right now." -"You assigned the order status.","You assigned the order status." -"Something went wrong while assigning the order status.","Something went wrong while assigning the order status." -"We can't find this order status.","We can't find this order status." -"Create New Order Status","Create New Order Status" -"We found another order status with the same order status code.","We found another order status with the same order status code." -"You saved the order status.","You saved the order status." -"We can't add the order status right now.","We can't add the order status right now." -"You have unassigned the order status.","You have unassigned the order status." -"Something went wrong while unassigning the order.","Something went wrong while unassigning the order." -"Can't unhold order.","Can't unhold order." -"You released the order from holding status.","You released the order from holding status." -"The order was not on hold.","The order was not on hold." -"Exception occurred during order load","Exception occurred during order load" -"Something went wrong while saving the gift message.","Something went wrong while saving the gift message." -"You saved the gift card message.","You saved the gift card message." -"The payment has been voided.","The payment has been voided." -"We can't void the payment right now.","We can't void the payment right now." -"Please correct the transaction ID and try again.","Please correct the transaction ID and try again." -"The transaction details have been updated.","The transaction details have been updated." -"We can't update the transaction details.","We can't update the transaction details." -"Orders and Returns","Orders and Returns" -"You entered incorrect data. Please try again.","You entered incorrect data. Please try again." +The coupon code has been accepted.,The coupon code has been accepted. +Quote item id is not received.,Quote item id is not received. +Quote item is not loaded.,Quote item is not loaded. +New Order,New Order +You created the order.,You created the order. +Order saving error: %1,Order saving error: %1 +Cannot add new comment.,Cannot add new comment. +The credit memo has been canceled.,The credit memo has been canceled. +Credit memo has not been canceled.,Credit memo has not been canceled. +New Memo for #%1,New Memo for #%1 +New Memo,New Memo +The credit memo's total must be positive.,The credit memo's total must be positive. +Cannot create online refund for Refund to Store Credit.,Cannot create online refund for Refund to Store Credit. +You created the credit memo.,You created the credit memo. +We can't save the credit memo right now.,We can't save the credit memo right now. +We can't update the item's quantity right now.,We can't update the item's quantity right now. +View Memo for #%1,View Memo for #%1 +View Memo,View Memo +You voided the credit memo.,You voided the credit memo. +We can't void the credit memo.,We can't void the credit memo. +The order no longer exists.,The order no longer exists. +We can't create credit memo for the order.,We can't create credit memo for the order. +Edit Order,Edit Order +You sent the order email.,You sent the order email. +We can't send the email order right now.,We can't send the email order right now. +You have not put the order on hold.,You have not put the order on hold. +You put the order on hold.,You put the order on hold. +You canceled the invoice.,You canceled the invoice. +Invoice canceling error,Invoice canceling error +The invoice has been captured.,The invoice has been captured. +The order does not allow an invoice to be created.,The order does not allow an invoice to be created. +You can't create an invoice without products.,You can't create an invoice without products. +New Invoice,New Invoice +We can't save the invoice right now.,We can't save the invoice right now. +You created the invoice and shipment.,You created the invoice and shipment. +The invoice has been created.,The invoice has been created. +We can't send the invoice email right now.,We can't send the invoice email right now. +We can't send the shipment right now.,We can't send the shipment right now. +Cannot update item quantity.,Cannot update item quantity. +The invoice has been voided.,The invoice has been voided. +Invoice voiding error,Invoice voiding error +%1 order(s) cannot be canceled.,%1 order(s) cannot be canceled. +You cannot cancel the order(s).,You cannot cancel the order(s). +We canceled %1 order(s).,We canceled %1 order(s). +%1 order(s) were not put on hold.,%1 order(s) were not put on hold. +No order(s) were put on hold.,No order(s) were put on hold. +You have put %1 order(s) on hold.,You have put %1 order(s) on hold. +%1 order(s) were not released from on hold status.,%1 order(s) were not released from on hold status. +No order(s) were released from on hold status.,No order(s) were released from on hold status. +%1 order(s) have been released from on hold status.,%1 order(s) have been released from on hold status. +There are no printable documents related to selected orders.,There are no printable documents related to selected orders. +The payment has been accepted.,The payment has been accepted. +The payment has been denied.,The payment has been denied. +Transaction has been approved.,Transaction has been approved. +Transaction has been voided/declined.,Transaction has been voided/declined. +There is no update for the transaction.,There is no update for the transaction. +We can't update the payment right now.,We can't update the payment right now. +You assigned the order status.,You assigned the order status. +Something went wrong while assigning the order status.,Something went wrong while assigning the order status. +We can't find this order status.,We can't find this order status. +Create New Order Status,Create New Order Status +We found another order status with the same order status code.,We found another order status with the same order status code. +You saved the order status.,You saved the order status. +We can't add the order status right now.,We can't add the order status right now. +You have unassigned the order status.,You have unassigned the order status. +Something went wrong while unassigning the order.,Something went wrong while unassigning the order. +Can't unhold order.,Can't unhold order. +You released the order from holding status.,You released the order from holding status. +The order was not on hold.,The order was not on hold. +Exception occurred during order load,Exception occurred during order load +Something went wrong while saving the gift message.,Something went wrong while saving the gift message. +You saved the gift card message.,You saved the gift card message. +The payment has been voided.,The payment has been voided. +We can't void the payment right now.,We can't void the payment right now. +Please correct the transaction ID and try again.,Please correct the transaction ID and try again. +The transaction details have been updated.,The transaction details have been updated. +We can't update the transaction details.,We can't update the transaction details. +Orders and Returns,Orders and Returns +You entered incorrect data. Please try again.,You entered incorrect data. Please try again. Home,Home -"Go to Home Page","Go to Home Page" -"We can't find this wish list.","We can't find this wish list." +Go to Home Page,Go to Home Page +We can't find this wish list.,We can't find this wish list. "We could not add a product to cart by the ID ""%1"".","We could not add a product to cart by the ID ""%1""." -"There is an error in one of the option rows.","There is an error in one of the option rows." -"Shipping Address: ","Shipping Address: " -"Billing Address: ","Billing Address: " -"Please specify order items.","Please specify order items." -"Please specify a shipping method.","Please specify a shipping method." -"Please specify a payment method.","Please specify a payment method." -"This payment method is not available.","This payment method is not available." -"Validation is failed.","Validation is failed." -"You did not email your customer. Please check your email settings.","You did not email your customer. Please check your email settings." -"-- Please Select --","-- Please Select --" +There is an error in one of the option rows.,There is an error in one of the option rows. +Shipping Address: ,Shipping Address: +Billing Address: ,Billing Address: +Please specify order items.,Please specify order items. +Please specify a shipping method.,Please specify a shipping method. +Please specify a payment method.,Please specify a payment method. +This payment method is not available.,This payment method is not available. +Validation is failed.,Validation is failed. +You did not email your customer. Please check your email settings.,You did not email your customer. Please check your email settings. +-- Please Select --,-- Please Select -- "Path ""%1"" is not part of allowed directory ""%2""","Path ""%1"" is not part of allowed directory ""%2""" -"Identifying Fields required","Identifying Fields required" -"Id required","Id required" +Identifying Fields required,Identifying Fields required +Id required,Id required """Invoice Document Validation Error(s):\n"" .","""Invoice Document Validation Error(s):\n"" ." "Could not save an invoice, see error log for details","Could not save an invoice, see error log for details" -"A hold action is not available.","A hold action is not available." -"You cannot remove the hold.","You cannot remove the hold." -"We cannot cancel this order.","We cannot cancel this order." +A hold action is not available.,A hold action is not available. +You cannot remove the hold.,You cannot remove the hold. +We cannot cancel this order.,We cannot cancel this order. Guest,Guest -"Please enter the first name.","Please enter the first name." -"Please enter the last name.","Please enter the last name." -"Please enter the street.","Please enter the street." -"Please enter the city.","Please enter the city." -"Please enter the phone number.","Please enter the phone number." -"Please enter the company.","Please enter the company." -"Please enter the fax number.","Please enter the fax number." -"Please enter the zip/postal code.","Please enter the zip/postal code." -"Please enter the country.","Please enter the country." -"Please enter the state/province.","Please enter the state/province." -"Requested entity doesn't exist","Requested entity doesn't exist" -"Could not delete order address","Could not delete order address" -"Could not save order address","Could not save order address" +Please enter the first name.,Please enter the first name. +Please enter the last name.,Please enter the last name. +Please enter the street.,Please enter the street. +Please enter the city.,Please enter the city. +Please enter the phone number.,Please enter the phone number. +Please enter the company.,Please enter the company. +Please enter the fax number.,Please enter the fax number. +Please enter the zip/postal code.,Please enter the zip/postal code. +Please enter the country.,Please enter the country. +Please enter the state/province.,Please enter the state/province. +Requested entity doesn't exist,Requested entity doesn't exist +Could not delete order address,Could not delete order address +Could not save order address,Could not save order address Pending,Pending Refunded,Refunded Canceled,Canceled -"Unknown State","Unknown State" +Unknown State,Unknown State "We found an invalid quantity to refund item ""%1"".","We found an invalid quantity to refund item ""%1""." -"The creditmemo contains product item that is not part of the original order.","The creditmemo contains product item that is not part of the original order." -"The quantity to refund must not be greater than the unrefunded quantity.","The quantity to refund must not be greater than the unrefunded quantity." -"Maximum shipping amount allowed to refund is: %1","Maximum shipping amount allowed to refund is: %1" -"Order Id is required for creditmemo document","Order Id is required for creditmemo document" +The creditmemo contains product item that is not part of the original order.,The creditmemo contains product item that is not part of the original order. +The quantity to refund must not be greater than the unrefunded quantity.,The quantity to refund must not be greater than the unrefunded quantity. +Maximum shipping amount allowed to refund is: %1,Maximum shipping amount allowed to refund is: %1 +Order Id is required for creditmemo document,Order Id is required for creditmemo document "The creditmemo contains product SKU ""%1"" that is not part of the original order.","The creditmemo contains product SKU ""%1"" that is not part of the original order." "The quantity to creditmemo must not be greater than the unrefunded quantity for product SKU ""%1"".","The quantity to creditmemo must not be greater than the unrefunded quantity for product SKU ""%1""." -"You can't create a creditmemo without products.","You can't create a creditmemo without products." -"The most money available to refund is %1.","The most money available to refund is %1." -"Could not delete credit memo","Could not delete credit memo" -"Could not save credit memo","Could not save credit memo" -"This order already has associated customer account","This order already has associated customer account" +You can't create a creditmemo without products.,You can't create a creditmemo without products. +The most money available to refund is %1.,The most money available to refund is %1. +Could not delete credit memo,Could not delete credit memo +Could not save credit memo,Could not save credit memo +This order already has associated customer account,This order already has associated customer account Paid,Paid -"We cannot register an existing invoice","We cannot register an existing invoice" -"We can't create creditmemo for the invoice.","We can't create creditmemo for the invoice." -"Order Id is required for invoice document","Order Id is required for invoice document" +We cannot register an existing invoice,We cannot register an existing invoice +We can't create creditmemo for the invoice.,We can't create creditmemo for the invoice. +Order Id is required for invoice document,Order Id is required for invoice document "The quantity to invoice must not be greater than the uninvoiced quantity for product SKU ""%1"".","The quantity to invoice must not be greater than the uninvoiced quantity for product SKU ""%1""." -"The invoice contains one or more items that are not part of the original order.","The invoice contains one or more items that are not part of the original order." -"ID required","ID required" -"Unknown Status","Unknown Status" +The invoice contains one or more items that are not part of the original order.,The invoice contains one or more items that are not part of the original order. +ID required,ID required +Unknown Status,Unknown Status Ordered,Ordered Shipped,Shipped Invoiced,Invoiced @@ -346,460 +346,461 @@ Backordered,Backordered Returned,Returned Partial,Partial Mixed,Mixed -"Registered a Void notification.","Registered a Void notification." +Registered a Void notification.,Registered a Void notification. "If the invoice was created offline, try creating an offline credit memo.","If the invoice was created offline, try creating an offline credit memo." -"We refunded %1 online.","We refunded %1 online." -"We refunded %1 offline.","We refunded %1 offline." +We refunded %1 online.,We refunded %1 online. +We refunded %1 offline.,We refunded %1 offline. "IPN ""Refunded"". Refund issued by merchant. Registered notification about refunded amount of %1. Transaction ID: ""%2"". Credit Memo has not been created. Please create offline Credit Memo.","IPN ""Refunded"". Refund issued by merchant. Registered notification about refunded amount of %1. Transaction ID: ""%2"". Credit Memo has not been created. Please create offline Credit Memo." -"The credit memo has been created automatically.","The credit memo has been created automatically." -"Registered notification about refunded amount of %1.","Registered notification about refunded amount of %1." -"Canceled order online","Canceled order online" -"Canceled order offline","Canceled order offline" -"Approved the payment online.","Approved the payment online." -"There is no need to approve this payment.","There is no need to approve this payment." -"Denied the payment online","Denied the payment online" -"Registered update about approved payment.","Registered update about approved payment." -"Registered update about denied payment.","Registered update about denied payment." -"There is no update for the payment.","There is no update for the payment." -"Voided authorization.","Voided authorization." -"Amount: %1.","Amount: %1." +The credit memo has been created automatically.,The credit memo has been created automatically. +Registered notification about refunded amount of %1.,Registered notification about refunded amount of %1. +Canceled order online,Canceled order online +Canceled order offline,Canceled order offline +Approved the payment online.,Approved the payment online. +There is no need to approve this payment.,There is no need to approve this payment. +Denied the payment online,Denied the payment online +Registered update about approved payment.,Registered update about approved payment. +Registered update about denied payment.,Registered update about denied payment. +There is no update for the payment.,There is no update for the payment. +Voided authorization.,Voided authorization. +Amount: %1.,Amount: %1. "Transaction ID: ""%1""","Transaction ID: ""%1""" -"The payment method you requested is not available.","The payment method you requested is not available." -"The payment disallows storing objects.","The payment disallows storing objects." +The payment method you requested is not available.,The payment method you requested is not available. +The payment disallows storing objects.,The payment disallows storing objects. "The transaction ""%1"" cannot be captured yet.","The transaction ""%1"" cannot be captured yet." -"The order amount of %1 is pending approval on the payment gateway.","The order amount of %1 is pending approval on the payment gateway." -"Ordered amount of %1","Ordered amount of %1" -"An amount of %1 will be captured after being approved at the payment gateway.","An amount of %1 will be captured after being approved at the payment gateway." -"Registered notification about captured amount of %1.","Registered notification about captured amount of %1." -"Order is suspended as its capture amount %1 is suspected to be fraudulent.","Order is suspended as its capture amount %1 is suspected to be fraudulent." -"The parent transaction ID must have a transaction ID.","The parent transaction ID must have a transaction ID." -"Payment transactions disallow storing objects.","Payment transactions disallow storing objects." +The order amount of %1 is pending approval on the payment gateway.,The order amount of %1 is pending approval on the payment gateway. +Ordered amount of %1,Ordered amount of %1 +An amount of %1 will be captured after being approved at the payment gateway.,An amount of %1 will be captured after being approved at the payment gateway. +Registered notification about captured amount of %1.,Registered notification about captured amount of %1. +Order is suspended as its capture amount %1 is suspected to be fraudulent.,Order is suspended as its capture amount %1 is suspected to be fraudulent. +The parent transaction ID must have a transaction ID.,The parent transaction ID must have a transaction ID. +Payment transactions disallow storing objects.,Payment transactions disallow storing objects. "The transaction ""%1"" (%2) is already closed.","The transaction ""%1"" (%2) is already closed." -"Set order for existing transactions not allowed","Set order for existing transactions not allowed" +Set order for existing transactions not allowed,Set order for existing transactions not allowed "At minimum, you need to set a payment ID.","At minimum, you need to set a payment ID." Order,Order Authorization,Authorization "We found an unsupported transaction type ""%1"".","We found an unsupported transaction type ""%1""." -"Please set a proper payment and order id.","Please set a proper payment and order id." -"Please enter a Transaction ID.","Please enter a Transaction ID." -"You can't do this without a transaction object.","You can't do this without a transaction object." -"Order # ","Order # " -"Order Date: ","Order Date: " -"Sold to:","Sold to:" -"Ship to:","Ship to:" -"Payment Method:","Payment Method:" -"Shipping Method:","Shipping Method:" -"Total Shipping Charges","Total Shipping Charges" +Please set a proper payment and order id.,Please set a proper payment and order id. +Please enter a Transaction ID.,Please enter a Transaction ID. +You can't do this without a transaction object.,You can't do this without a transaction object. +Order # ,Order # +Order Date: ,Order Date: +Sold to:,Sold to: +Ship to:,Ship to: +Payment Method:,Payment Method: +Shipping Method:,Shipping Method: +Total Shipping Charges,Total Shipping Charges Title,Title Number,Number -"We found an invalid renderer model.","We found an invalid renderer model." -"Please define the PDF object before using.","Please define the PDF object before using." +We found an invalid renderer model.,We found an invalid renderer model. +Please define the PDF object before using.,Please define the PDF object before using. "We don't recognize the draw line data. Please define the ""lines"" array.","We don't recognize the draw line data. Please define the ""lines"" array." Products,Products -"Total (ex)","Total (ex)" +Total (ex),Total (ex) Qty,Qty Tax,Tax -"Total (inc)","Total (inc)" -"Credit Memo # ","Credit Memo # " -"Invoice # ","Invoice # " -"The order object is not specified.","The order object is not specified." -"The source object is not specified.","The source object is not specified." -"An item object is not specified.","An item object is not specified." -"A PDF object is not specified.","A PDF object is not specified." -"A PDF page object is not specified.","A PDF page object is not specified." -"Excl. Tax","Excl. Tax" -"Incl. Tax","Incl. Tax" -"Packing Slip # ","Packing Slip # " +Total (inc),Total (inc) +Credit Memo # ,Credit Memo # +Invoice # ,Invoice # +The order object is not specified.,The order object is not specified. +The source object is not specified.,The source object is not specified. +An item object is not specified.,An item object is not specified. +A PDF object is not specified.,A PDF object is not specified. +A PDF page object is not specified.,A PDF page object is not specified. +Excl. Tax,Excl. Tax +Incl. Tax,Incl. Tax +Packing Slip # ,Packing Slip # title,title -"The PDF total model %1 must be or extend \Magento\Sales\Model\Order\Pdf\Total\DefaultTotal.","The PDF total model %1 must be or extend \Magento\Sales\Model\Order\Pdf\Total\DefaultTotal." -"We cannot register an existing shipment","We cannot register an existing shipment" -"Parent shipment cannot be loaded for track object.","Parent shipment cannot be loaded for track object." -"Order Id is required for shipment document","Order Id is required for shipment document" -"You can't create a shipment without products.","You can't create a shipment without products." +The PDF total model %1 must be or extend \Magento\Sales\Model\Order\Pdf\Total\DefaultTotal.,The PDF total model %1 must be or extend \Magento\Sales\Model\Order\Pdf\Total\DefaultTotal. +We cannot register an existing shipment,We cannot register an existing shipment +Parent shipment cannot be loaded for track object.,Parent shipment cannot be loaded for track object. +Order Id is required for shipment document,Order Id is required for shipment document +You can't create a shipment without products.,You can't create a shipment without products. "The shipment contains product SKU ""%1"" that is not part of the original order.","The shipment contains product SKU ""%1"" that is not part of the original order." "The quantity to ship must not be greater than the unshipped quantity for product SKU ""%1"".","The quantity to ship must not be greater than the unshipped quantity for product SKU ""%1""." -"Please enter a tracking number.","Please enter a tracking number." -"Could not delete shipment","Could not delete shipment" -"Could not save shipment","Could not save shipment" -"The last status can't be unassigned from its current state.","The last status can't be unassigned from its current state." +Please enter a tracking number.,Please enter a tracking number. +Could not delete shipment,Could not delete shipment +Could not save shipment,Could not save shipment +The last status can't be unassigned from its current state.,The last status can't be unassigned from its current state. "Status can't be unassigned, because it is used by existing order(s).","Status can't be unassigned, because it is used by existing order(s)." -"The total model should be extended from \Magento\Sales\Model\Order\Total\AbstractTotal.","The total model should be extended from \Magento\Sales\Model\Order\Total\AbstractTotal." -"An invoice cannot be created when an order has a status of %1","An invoice cannot be created when an order has a status of %1" -"A creditmemo can not be created when an order has a status of %1","A creditmemo can not be created when an order has a status of %1" -"The order does not allow a creditmemo to be created.","The order does not allow a creditmemo to be created." -"A shipment cannot be created when an order has a status of %1","A shipment cannot be created when an order has a status of %1" -"The order does not allow a shipment to be created.","The order does not allow a shipment to be created." +The total model should be extended from \Magento\Sales\Model\Order\Total\AbstractTotal.,The total model should be extended from \Magento\Sales\Model\Order\Total\AbstractTotal. +An invoice cannot be created when an order has a status of %1,An invoice cannot be created when an order has a status of %1 +A creditmemo can not be created when an order has a status of %1,A creditmemo can not be created when an order has a status of %1 +The order does not allow a creditmemo to be created.,The order does not allow a creditmemo to be created. +A shipment cannot be created when an order has a status of %1,A shipment cannot be created when an order has a status of %1 +The order does not allow a shipment to be created.,The order does not allow a shipment to be created. """Creditmemo Document Validation Error(s):\n"" .","""Creditmemo Document Validation Error(s):\n"" ." "Could not save a Creditmemo, see error log for details","Could not save a Creditmemo, see error log for details" -"We cannot determine the field name.","We cannot determine the field name." +We cannot determine the field name.,We cannot determine the field name. City,City Company,Company Country,Country Email,Email -"First Name","First Name" -"Last Name","Last Name" +First Name,First Name +Last Name,Last Name State/Province,State/Province -"Street Address","Street Address" -"Phone Number","Phone Number" -"Zip/Postal Code","Zip/Postal Code" -"We can't save the address:\n%1","We can't save the address:\n%1" -"Cannot save comment:\n%1","Cannot save comment:\n%1" -"We don't have enough information to save the parent transaction ID.","We don't have enough information to save the parent transaction ID." -"We cannot create an empty shipment.","We cannot create an empty shipment." -"Cannot save track:\n%1","Cannot save track:\n%1" -"Cannot unassign status from state","Cannot unassign status from state" -"New Orders","New Orders" -"Order #%1 created at %2","Order #%1 created at %2" -"Details for %1 #%2","Details for %1 #%2" -"Notified Date: %1","Notified Date: %1" -"Comment: %1<br/>","Comment: %1<br/>" -"Current Status: %1<br/>","Current Status: %1<br/>" -"Total: %1<br/>","Total: %1<br/>" -"Order # %1 Notification(s)","Order # %1 Notification(s)" -"You can not cancel Credit Memo","You can not cancel Credit Memo" -"Could not cancel creditmemo","Could not cancel creditmemo" -"We cannot register an existing credit memo.","We cannot register an existing credit memo." +Street Address,Street Address +Phone Number,Phone Number +Zip/Postal Code,Zip/Postal Code +We can't save the address:\n%1,We can't save the address:\n%1 +Cannot save comment:\n%1,Cannot save comment:\n%1 +We don't have enough information to save the parent transaction ID.,We don't have enough information to save the parent transaction ID. +We cannot create an empty shipment.,We cannot create an empty shipment. +Cannot save track:\n%1,Cannot save track:\n%1 +Cannot unassign status from state,Cannot unassign status from state +New Orders,New Orders +Order #%1 created at %2,Order #%1 created at %2 +Details for %1 #%2,Details for %1 #%2 +Notified Date: %1,Notified Date: %1 +Comment: %1<br/>,Comment: %1<br/> +Current Status: %1<br/>,Current Status: %1<br/> +Total: %1<br/>,Total: %1<br/> +Order # %1 Notification(s),Order # %1 Notification(s) +You can not cancel Credit Memo,You can not cancel Credit Memo +Could not cancel creditmemo,Could not cancel creditmemo +We cannot register an existing credit memo.,We cannot register an existing credit memo. "We found an invalid quantity to invoice item ""%1"".","We found an invalid quantity to invoice item ""%1""." "The Order State ""%1"" must not be set manually.","The Order State ""%1"" must not be set manually." """Shipment Document Validation Error(s):\n"" .","""Shipment Document Validation Error(s):\n"" ." "Could not save a shipment, see error log for details","Could not save a shipment, see error log for details" -"VAT Request Identifier","VAT Request Identifier" -"VAT Request Date","VAT Request Date" -"Pending Payment","Pending Payment" +VAT Request Identifier,VAT Request Identifier +VAT Request Date,VAT Request Date +Pending Payment,Pending Payment Processing,Processing -"On Hold","On Hold" +On Hold,On Hold Complete,Complete Closed,Closed -"Suspected Fraud","Suspected Fraud" -"Payment Review","Payment Review" +Suspected Fraud,Suspected Fraud +Payment Review,Payment Review New,New -"test message","test message" -"Email has not been sent","Email has not been sent" -"Authorized amount of %1.","Authorized amount of %1." -"We will authorize %1 after the payment is approved at the payment gateway.","We will authorize %1 after the payment is approved at the payment gateway." -"Authorized amount of %1. Order is suspended as its authorizing amount %1 is suspected to be fraudulent.","Authorized amount of %1. Order is suspended as its authorizing amount %1 is suspected to be fraudulent." -"Captured amount of %1 online.","Captured amount of %1 online." -"Authorized amount of %1","Authorized amount of %1" +test message,test message +Email has not been sent,Email has not been sent +Authorized amount of %1.,Authorized amount of %1. +We will authorize %1 after the payment is approved at the payment gateway.,We will authorize %1 after the payment is approved at the payment gateway. +Authorized amount of %1. Order is suspended as its authorizing amount %1 is suspected to be fraudulent.,Authorized amount of %1. Order is suspended as its authorizing amount %1 is suspected to be fraudulent. +Captured amount of %1 online.,Captured amount of %1 online. +Authorized amount of %1,Authorized amount of %1 " Transaction ID: ""%1"""," Transaction ID: ""%1""" View,View -"Group was removed","Group was removed" +Group was removed,Group was removed "Changing address information will not recalculate shipping, tax or other order amount.","Changing address information will not recalculate shipping, tax or other order amount." -"Comment Text","Comment Text" -"Notify Customer by Email","Notify Customer by Email" -"Visible on Storefront","Visible on Storefront" +Comment Text,Comment Text +Notify Customer by Email,Notify Customer by Email +Visible on Storefront,Visible on Storefront Customer,Customer Notified,Notified -"Not Notified","Not Notified" -"No Payment Methods","No Payment Methods" -"Order Comments","Order Comments" -"Apply Coupon Code","Apply Coupon Code" +Not Notified,Not Notified +No Payment Methods,No Payment Methods +Order Comments,Order Comments +Apply Coupon Code,Apply Coupon Code Apply,Apply -"Remove Coupon Code","Remove Coupon Code" +Remove Coupon Code,Remove Coupon Code Remove,Remove -"Address Information","Address Information" -"Payment & Shipping Information","Payment & Shipping Information" -"Order Total","Order Total" -"Order Currency:","Order Currency:" -"Same As Billing Address","Same As Billing Address" -"Select from existing customer addresses:","Select from existing customer addresses:" -"Add New Address","Add New Address" -"Save in address book","Save in address book" -"You don't need to select a shipping address.","You don't need to select a shipping address." -"Gift Message for the Entire Order","Gift Message for the Entire Order" -"Leave this box blank if you don't want to leave a gift message for the entire order.","Leave this box blank if you don't want to leave a gift message for the entire order." -"Row Subtotal","Row Subtotal" +Address Information,Address Information +Payment & Shipping Information,Payment & Shipping Information +Order Total,Order Total +Order Currency:,Order Currency: +Same As Billing Address,Same As Billing Address +Select from existing customer addresses:,Select from existing customer addresses: +Add New Address,Add New Address +Save in address book,Save in address book +You don't need to select a shipping address.,You don't need to select a shipping address. +Gift Message for the Entire Order,Gift Message for the Entire Order +Leave this box blank if you don't want to leave a gift message for the entire order.,Leave this box blank if you don't want to leave a gift message for the entire order. +Row Subtotal,Row Subtotal Action,Action -"No ordered items","No ordered items" -"Update Items and Quantities","Update Items and Quantities" -"Total %1 product(s)","Total %1 product(s)" +No ordered items,No ordered items +Update Items and Quantities,Update Items and Quantities +Total %1 product(s),Total %1 product(s) Subtotal:,Subtotal: -"Tier Pricing","Tier Pricing" -"Custom Price","Custom Price" -"Please select","Please select" -"Move to Shopping Cart","Move to Shopping Cart" -"Move to Wish List","Move to Wish List" -"Subscribe to Newsletter","Subscribe to Newsletter" -"Click to change shipping method","Click to change shipping method" +Tier Pricing,Tier Pricing +Custom Price,Custom Price +Please select,Please select +Move to Shopping Cart,Move to Shopping Cart +Move to Wish List,Move to Wish List +Subscribe to Newsletter,Subscribe to Newsletter +Click to change shipping method,Click to change shipping method "Sorry, no quotes are available for this order.","Sorry, no quotes are available for this order." -"Get shipping methods and rates","Get shipping methods and rates" -"You don't need to select a shipping method.","You don't need to select a shipping method." -"Customer's Activities","Customer's Activities" +Get shipping methods and rates,Get shipping methods and rates +You don't need to select a shipping method.,You don't need to select a shipping method. +Customer's Activities,Customer's Activities Refresh,Refresh Item,Item -"Add To Order","Add To Order" -"Configure and Add to Order","Configure and Add to Order" -"No items","No items" -"Append Comments","Append Comments" -"Email Order Confirmation","Email Order Confirmation" -"Grand Total Excl. Tax","Grand Total Excl. Tax" -"Grand Total Incl. Tax","Grand Total Incl. Tax" -"Subtotal (Excl. Tax)","Subtotal (Excl. Tax)" -"Subtotal (Incl. Tax)","Subtotal (Incl. Tax)" -"Payment & Shipping Method","Payment & Shipping Method" -"Payment Information","Payment Information" -"The order was placed using %1.","The order was placed using %1." -"Shipping Information","Shipping Information" -"Items to Refund","Items to Refund" -"Return to Stock","Return to Stock" -"Qty to Refund","Qty to Refund" -"Tax Amount","Tax Amount" -"Discount Amount","Discount Amount" -"Row Total","Row Total" -"No Items To Refund","No Items To Refund" -"Credit Memo Comments","Credit Memo Comments" -"Refund Totals","Refund Totals" -"Email Copy of Credit Memo","Email Copy of Credit Memo" -"Please enter a positive number in this field.","Please enter a positive number in this field." -"Items Refunded","Items Refunded" -"No Items","No Items" -"Memo Total","Memo Total" -"Credit Memo History","Credit Memo History" -"Credit Memo Totals","Credit Memo Totals" -"Customer Name: %1","Customer Name: %1" -"Purchased From: %1","Purchased From: %1" -"Gift Message","Gift Message" +Add To Order,Add To Order +Configure and Add to Order,Configure and Add to Order +No items,No items +Append Comments,Append Comments +Email Order Confirmation,Email Order Confirmation +Grand Total Excl. Tax,Grand Total Excl. Tax +Grand Total Incl. Tax,Grand Total Incl. Tax +Subtotal (Excl. Tax),Subtotal (Excl. Tax) +Subtotal (Incl. Tax),Subtotal (Incl. Tax) +Payment & Shipping Method,Payment & Shipping Method +Payment Information,Payment Information +The order was placed using %1.,The order was placed using %1. +Shipping Information,Shipping Information +Items to Refund,Items to Refund +Return to Stock,Return to Stock +Qty to Refund,Qty to Refund +Tax Amount,Tax Amount +Discount Amount,Discount Amount +Row Total,Row Total +No Items To Refund,No Items To Refund +Credit Memo Comments,Credit Memo Comments +Refund Totals,Refund Totals +Email Copy of Credit Memo,Email Copy of Credit Memo +Please enter a positive number in this field.,Please enter a positive number in this field. +Items Refunded,Items Refunded +No Items,No Items +Memo Total,Memo Total +Credit Memo History,Credit Memo History +Credit Memo Totals,Credit Memo Totals +Customer Name: %1,Customer Name: %1 +Purchased From: %1,Purchased From: %1 +Gift Message,Gift Message From:,From: To:,To: Message:,Message: -"Shipping & Handling","Shipping & Handling" -"Gift Options","Gift Options" -"Create Shipment","Create Shipment" -"Invoice and shipment types do not match for some items on this order. You can create a shipment only after creating the invoice.","Invoice and shipment types do not match for some items on this order. You can create a shipment only after creating the invoice." +Shipping & Handling,Shipping & Handling +Gift Options,Gift Options +Create Shipment,Create Shipment +Invoice and shipment types do not match for some items on this order. You can create a shipment only after creating the invoice.,Invoice and shipment types do not match for some items on this order. You can create a shipment only after creating the invoice. %1,%1 -"Qty to Invoice","Qty to Invoice" -"Invoice History","Invoice History" -"Invoice Comments","Invoice Comments" -"Invoice Totals","Invoice Totals" +Qty to Invoice,Qty to Invoice +Invoice History,Invoice History +Invoice Comments,Invoice Comments +Invoice Totals,Invoice Totals Amount,Amount -"Capture Online","Capture Online" -"Capture Offline","Capture Offline" -"Not Capture","Not Capture" -"The invoice will be created offline without the payment gateway.","The invoice will be created offline without the payment gateway." -"Email Copy of Invoice","Email Copy of Invoice" -"Items Invoiced","Items Invoiced" -"Total Tax","Total Tax" -"From Name","From Name" -"To Name","To Name" +Capture Online,Capture Online +Capture Offline,Capture Offline +Not Capture,Not Capture +The invoice will be created offline without the payment gateway.,The invoice will be created offline without the payment gateway. +Email Copy of Invoice,Email Copy of Invoice +Items Invoiced,Items Invoiced +Total Tax,Total Tax +From Name,From Name +To Name,To Name Status,Status Comment,Comment -"Notification Not Applicable","Notification Not Applicable" -"Order & Account Information","Order & Account Information" -"The order confirmation email was sent","The order confirmation email was sent" -"The order confirmation email is not sent","The order confirmation email is not sent" -"Order Date","Order Date" -"Order Date (%1)","Order Date (%1)" -"Purchased From","Purchased From" -"Link to the New Order","Link to the New Order" -"Link to the Previous Order","Link to the Previous Order" -"Placed from IP","Placed from IP" -"%1 / %2 rate:","%1 / %2 rate:" -"Customer Name","Customer Name" -"Customer Group","Customer Group" -"Notes for this Order","Notes for this Order" -"Comment added","Comment added" -"Transaction Data","Transaction Data" -"Transaction ID","Transaction ID" -"Parent Transaction ID","Parent Transaction ID" -"Order ID","Order ID" -"Transaction Type","Transaction Type" -"Is Closed","Is Closed" -"Created At","Created At" -"Child Transactions","Child Transactions" -"Transaction Details","Transaction Details" +Notification Not Applicable,Notification Not Applicable +Order & Account Information,Order & Account Information +The order confirmation email was sent,The order confirmation email was sent +The order confirmation email is not sent,The order confirmation email is not sent +Order Date,Order Date +Order Date (%1),Order Date (%1) +Purchased From,Purchased From +Link to the New Order,Link to the New Order +Link to the Previous Order,Link to the Previous Order +Placed from IP,Placed from IP +%1 / %2 rate:,%1 / %2 rate: +Customer Name,Customer Name +Customer Group,Customer Group +Notes for this Order,Notes for this Order +Comment added,Comment added +Transaction Data,Transaction Data +Transaction ID,Transaction ID +Parent Transaction ID,Parent Transaction ID +Order ID,Order ID +Transaction Type,Transaction Type +Is Closed,Is Closed +Created At,Created At +Child Transactions,Child Transactions +Transaction Details,Transaction Details Items,Items -"Gift Message for this Order","Gift Message for this Order" -"Shipped By","Shipped By" -"Tracking Number","Tracking Number" -"Billing Last Name","Billing Last Name" -"Find Order By","Find Order By" -"ZIP Code","ZIP Code" -"Billing ZIP Code","Billing ZIP Code" +Gift Message for this Order,Gift Message for this Order +Shipped By,Shipped By +Tracking Number,Tracking Number +Billing Last Name,Billing Last Name +Find Order By,Find Order By +ZIP Code,ZIP Code +Billing ZIP Code,Billing ZIP Code Continue,Continue -"Print All Refunds","Print All Refunds" -"Refund #","Refund #" -"Print Refund","Print Refund" -"Product Name","Product Name" -"Order #","Order #" +Print All Refunds,Print All Refunds +Refund #,Refund # +Print Refund,Print Refund +Product Name,Product Name +Order #,Order # Date,Date -"Ship To","Ship To" +Ship To,Ship To Actions,Actions -"View Order","View Order" -"You have placed no orders.","You have placed no orders." -"No shipping information available","No shipping information available" -"Print Order","Print Order" -"Print All Invoices","Print All Invoices" -"Invoice #","Invoice #" -"Print Invoice","Print Invoice" -"Qty Invoiced","Qty Invoiced" +View Order,View Order +You have placed no orders.,You have placed no orders. +No shipping information available,No shipping information available +Print Order,Print Order +Print All Invoices,Print All Invoices +Invoice #,Invoice # +Print Invoice,Print Invoice +Qty Invoiced,Qty Invoiced Close,Close -"About Your Order","About Your Order" +About Your Order,About Your Order "<span class=""label"">Order Date:</span> %1","<span class=""label"">Order Date:</span> %1" -"Refund #%1","Refund #%1" -"Shipment #%1","Shipment #%1" -"Qty Shipped","Qty Shipped" -"Recent Orders","Recent Orders" -"View All","View All" -"Gift Message for This Order","Gift Message for This Order" -"Recently Ordered","Recently Ordered" -"Add to Cart","Add to Cart" +Refund #%1,Refund #%1 +Shipment #%1,Shipment #%1 +Qty Shipped,Qty Shipped +Recent Orders,Recent Orders +View All,View All +Gift Message for This Order,Gift Message for This Order +Recently Ordered,Recently Ordered +Add to Cart,Add to Cart Search,Search -"Credit memo for your %store_name order","Credit memo for your %store_name order" +Credit memo for your %store_name order,Credit memo for your %store_name order "%name,","%name," -"Thank you for your order from %store_name.","Thank you for your order from %store_name." +Thank you for your order from %store_name.,Thank you for your order from %store_name. "You can check the status of your order by <a href=""%account_url"">logging into your account</a>.","You can check the status of your order by <a href=""%account_url"">logging into your account</a>." "If you have questions about your order, you can email us at <a href=""mailto:%store_email"">%store_email</a>","If you have questions about your order, you can email us at <a href=""mailto:%store_email"">%store_email</a>" "or call us at <a href=""tel:%store_phone"">%store_phone</a>","or call us at <a href=""tel:%store_phone"">%store_phone</a>" "Our hours are <span class=""no-link"">%store_hours</span>.","Our hours are <span class=""no-link"">%store_hours</span>." -"Your Credit Memo #%creditmemo_id for Order #%order_id","Your Credit Memo #%creditmemo_id for Order #%order_id" -"Billing Info","Billing Info" -"Shipping Info","Shipping Info" -"Update to your %store_name credit memo","Update to your %store_name credit memo" -"Your order #%increment_id has been updated with a status of <strong>%order_status</strong>.","Your order #%increment_id has been updated with a status of <strong>%order_status</strong>." -"Invoice for your %store_name order","Invoice for your %store_name order" -"Your Invoice #%invoice_id for Order #%order_id","Your Invoice #%invoice_id for Order #%order_id" -"Update to your %store_name invoice","Update to your %store_name invoice" -"Your %store_name order confirmation","Your %store_name order confirmation" +Your Credit Memo #%creditmemo_id for Order #%order_id,Your Credit Memo #%creditmemo_id for Order #%order_id +Billing Info,Billing Info +Shipping Info,Shipping Info +Update to your %store_name credit memo,Update to your %store_name credit memo +Your order #%increment_id has been updated with a status of <strong>%order_status</strong>.,Your order #%increment_id has been updated with a status of <strong>%order_status</strong>. +Invoice for your %store_name order,Invoice for your %store_name order +Your Invoice #%invoice_id for Order #%order_id,Your Invoice #%invoice_id for Order #%order_id +Update to your %store_name invoice,Update to your %store_name invoice +Your %store_name order confirmation,Your %store_name order confirmation "%customer_name,","%customer_name," -"Once your package ships we will send you a tracking number.","Once your package ships we will send you a tracking number." +Once your package ships we will send you a tracking number.,Once your package ships we will send you a tracking number. "Your Order <span class=""no-link"">#%increment_id</span>","Your Order <span class=""no-link"">#%increment_id</span>" "Placed on <span class=""no-link"">%created_at</span>","Placed on <span class=""no-link"">%created_at</span>" -"Once your package ships we will send an email with a link to track your order.","Once your package ships we will send an email with a link to track your order." -"Update to your %store_name order","Update to your %store_name order" -"Your %store_name order has shipped","Your %store_name order has shipped" -"Your shipping confirmation is below. Thank you again for your business.","Your shipping confirmation is below. Thank you again for your business." -"Your Shipment #%shipment_id for Order #%order_id","Your Shipment #%shipment_id for Order #%order_id" -"Update to your %store_name shipment","Update to your %store_name shipment" -"Gift Options for ","Gift Options for " -"Add Products","Add Products" -"You have item changes","You have item changes" +Once your package ships we will send an email with a link to track your order.,Once your package ships we will send an email with a link to track your order. +Update to your %store_name order,Update to your %store_name order +Your %store_name order has shipped,Your %store_name order has shipped +Your shipping confirmation is below. Thank you again for your business.,Your shipping confirmation is below. Thank you again for your business. +Your Shipment #%shipment_id for Order #%order_id,Your Shipment #%shipment_id for Order #%order_id +Update to your %store_name shipment,Update to your %store_name shipment +Gift Options for ,Gift Options for +Add Products,Add Products +You have item changes,You have item changes Ok,Ok Operations,Operations Create,Create -"Send Order Email","Send Order Email" -"Accept or Deny Payment","Accept or Deny Payment" -"Send Sales Emails","Send Sales Emails" -"Sales Section","Sales Section" -"Sales Emails Section","Sales Emails Section" +Send Order Email,Send Order Email +Accept or Deny Payment,Accept or Deny Payment +Send Sales Emails,Send Sales Emails +Sales Section,Sales Section +Sales Emails Section,Sales Emails Section General,General -"Hide Customer IP","Hide Customer IP" +Hide Customer IP,Hide Customer IP "Choose whether a customer IP is shown in orders, invoices, shipments, and credit memos.","Choose whether a customer IP is shown in orders, invoices, shipments, and credit memos." -"Checkout Totals Sort Order","Checkout Totals Sort Order" -"Allow Reorder","Allow Reorder" -"Invoice and Packing Slip Design","Invoice and Packing Slip Design" -"Logo for PDF Print-outs (200x50)","Logo for PDF Print-outs (200x50)" +Checkout Totals Sort Order,Checkout Totals Sort Order +Allow Reorder,Allow Reorder +Invoice and Packing Slip Design,Invoice and Packing Slip Design +Logo for PDF Print-outs (200x50),Logo for PDF Print-outs (200x50) "Your default logo will be used in PDF and HTML documents.<br />(jpeg, tiff, png) If your pdf image is distorted, try to use larger file-size image.","Your default logo will be used in PDF and HTML documents.<br />(jpeg, tiff, png) If your pdf image is distorted, try to use larger file-size image." -"Logo for HTML Print View","Logo for HTML Print View" +Logo for HTML Print View,Logo for HTML Print View "Logo for HTML documents only. If empty, default will be used.<br />(jpeg, gif, png)","Logo for HTML documents only. If empty, default will be used.<br />(jpeg, gif, png)" Address,Address -"Minimum Order Amount","Minimum Order Amount" +Minimum Order Amount,Minimum Order Amount Enable,Enable -"Minimum Amount","Minimum Amount" -"Subtotal after discount","Subtotal after discount" -"Include Tax to Amount","Include Tax to Amount" -"Description Message","Description Message" -"This message will be shown in the shopping cart when the subtotal (after discount) is lower than the minimum allowed amount.","This message will be shown in the shopping cart when the subtotal (after discount) is lower than the minimum allowed amount." -"Error to Show in Shopping Cart","Error to Show in Shopping Cart" -"Validate Each Address Separately in Multi-address Checkout","Validate Each Address Separately in Multi-address Checkout" -"Multi-address Description Message","Multi-address Description Message" -"We'll use the default description above if you leave this empty.","We'll use the default description above if you leave this empty." -"Multi-address Error to Show in Shopping Cart","Multi-address Error to Show in Shopping Cart" -"We'll use the default error above if you leave this empty.","We'll use the default error above if you leave this empty." +Minimum Amount,Minimum Amount +Subtotal after discount,Subtotal after discount +Include Tax to Amount,Include Tax to Amount +Description Message,Description Message +This message will be shown in the shopping cart when the subtotal (after discount) is lower than the minimum allowed amount.,This message will be shown in the shopping cart when the subtotal (after discount) is lower than the minimum allowed amount. +Error to Show in Shopping Cart,Error to Show in Shopping Cart +Validate Each Address Separately in Multi-address Checkout,Validate Each Address Separately in Multi-address Checkout +Multi-address Description Message,Multi-address Description Message +We'll use the default description above if you leave this empty.,We'll use the default description above if you leave this empty. +Multi-address Error to Show in Shopping Cart,Multi-address Error to Show in Shopping Cart +We'll use the default error above if you leave this empty.,We'll use the default error above if you leave this empty. Dashboard,Dashboard -"Use Aggregated Data","Use Aggregated Data" -"Orders Cron Settings","Orders Cron Settings" -"Pending Payment Order Lifetime (minutes)","Pending Payment Order Lifetime (minutes)" -"Sales Emails","Sales Emails" -"Asynchronous sending","Asynchronous sending" +Use Aggregated Data,Use Aggregated Data +Orders Cron Settings,Orders Cron Settings +Pending Payment Order Lifetime (minutes),Pending Payment Order Lifetime (minutes) +Sales Emails,Sales Emails +Asynchronous sending,Asynchronous sending Enabled,Enabled -"New Order Confirmation Email Sender","New Order Confirmation Email Sender" -"New Order Confirmation Template","New Order Confirmation Template" +New Order Confirmation Email Sender,New Order Confirmation Email Sender +New Order Confirmation Template,New Order Confirmation Template "Email template chosen based on theme fallback when ""Default"" option is selected.","Email template chosen based on theme fallback when ""Default"" option is selected." -"New Order Confirmation Template for Guest","New Order Confirmation Template for Guest" -"Send Order Email Copy To","Send Order Email Copy To" +New Order Confirmation Template for Guest,New Order Confirmation Template for Guest +Send Order Email Copy To,Send Order Email Copy To Comma-separated,Comma-separated -"Send Order Email Copy Method","Send Order Email Copy Method" -"Order Comment Email Sender","Order Comment Email Sender" -"Order Comment Email Template","Order Comment Email Template" -"Order Comment Email Template for Guest","Order Comment Email Template for Guest" -"Send Order Comment Email Copy To","Send Order Comment Email Copy To" -"Send Order Comments Email Copy Method","Send Order Comments Email Copy Method" -"Invoice Email Sender","Invoice Email Sender" -"Invoice Email Template","Invoice Email Template" -"Invoice Email Template for Guest","Invoice Email Template for Guest" -"Send Invoice Email Copy To","Send Invoice Email Copy To" -"Send Invoice Email Copy Method","Send Invoice Email Copy Method" -"Invoice Comment Email Sender","Invoice Comment Email Sender" -"Invoice Comment Email Template","Invoice Comment Email Template" -"Invoice Comment Email Template for Guest","Invoice Comment Email Template for Guest" -"Send Invoice Comment Email Copy To","Send Invoice Comment Email Copy To" -"Send Invoice Comments Email Copy Method","Send Invoice Comments Email Copy Method" +Send Order Email Copy Method,Send Order Email Copy Method +Order Comment Email Sender,Order Comment Email Sender +Order Comment Email Template,Order Comment Email Template +Order Comment Email Template for Guest,Order Comment Email Template for Guest +Send Order Comment Email Copy To,Send Order Comment Email Copy To +Send Order Comments Email Copy Method,Send Order Comments Email Copy Method +Invoice Email Sender,Invoice Email Sender +Invoice Email Template,Invoice Email Template +Invoice Email Template for Guest,Invoice Email Template for Guest +Send Invoice Email Copy To,Send Invoice Email Copy To +Send Invoice Email Copy Method,Send Invoice Email Copy Method +Invoice Comment Email Sender,Invoice Comment Email Sender +Invoice Comment Email Template,Invoice Comment Email Template +Invoice Comment Email Template for Guest,Invoice Comment Email Template for Guest +Send Invoice Comment Email Copy To,Send Invoice Comment Email Copy To +Send Invoice Comments Email Copy Method,Send Invoice Comments Email Copy Method Shipment,Shipment -"Shipment Email Sender","Shipment Email Sender" -"Shipment Email Template","Shipment Email Template" -"Shipment Email Template for Guest","Shipment Email Template for Guest" -"Send Shipment Email Copy To","Send Shipment Email Copy To" -"Send Shipment Email Copy Method","Send Shipment Email Copy Method" -"Shipment Comments","Shipment Comments" -"Shipment Comment Email Sender","Shipment Comment Email Sender" -"Shipment Comment Email Template","Shipment Comment Email Template" -"Shipment Comment Email Template for Guest","Shipment Comment Email Template for Guest" -"Send Shipment Comment Email Copy To","Send Shipment Comment Email Copy To" -"Send Shipment Comments Email Copy Method","Send Shipment Comments Email Copy Method" -"Credit Memo Email Sender","Credit Memo Email Sender" -"Credit Memo Email Template","Credit Memo Email Template" -"Credit Memo Email Template for Guest","Credit Memo Email Template for Guest" -"Send Credit Memo Email Copy To","Send Credit Memo Email Copy To" -"Send Credit Memo Email Copy Method","Send Credit Memo Email Copy Method" -"Credit Memo Comment Email Sender","Credit Memo Comment Email Sender" -"Credit Memo Comment Email Template","Credit Memo Comment Email Template" -"Credit Memo Comment Email Template for Guest","Credit Memo Comment Email Template for Guest" -"Send Credit Memo Comment Email Copy To","Send Credit Memo Comment Email Copy To" -"Send Credit Memo Comments Email Copy Method","Send Credit Memo Comments Email Copy Method" -"PDF Print-outs","PDF Print-outs" -"Display Order ID in Header","Display Order ID in Header" -"Customer Order Status Notification","Customer Order Status Notification" -"Asynchronous indexing","Asynchronous indexing" -"Orders and Returns Search Form","Orders and Returns Search Form" -"Anchor Custom Title","Anchor Custom Title" +Shipment Email Sender,Shipment Email Sender +Shipment Email Template,Shipment Email Template +Shipment Email Template for Guest,Shipment Email Template for Guest +Send Shipment Email Copy To,Send Shipment Email Copy To +Send Shipment Email Copy Method,Send Shipment Email Copy Method +Shipment Comments,Shipment Comments +Shipment Comment Email Sender,Shipment Comment Email Sender +Shipment Comment Email Template,Shipment Comment Email Template +Shipment Comment Email Template for Guest,Shipment Comment Email Template for Guest +Send Shipment Comment Email Copy To,Send Shipment Comment Email Copy To +Send Shipment Comments Email Copy Method,Send Shipment Comments Email Copy Method +Credit Memo Email Sender,Credit Memo Email Sender +Credit Memo Email Template,Credit Memo Email Template +Credit Memo Email Template for Guest,Credit Memo Email Template for Guest +Send Credit Memo Email Copy To,Send Credit Memo Email Copy To +Send Credit Memo Email Copy Method,Send Credit Memo Email Copy Method +Credit Memo Comment Email Sender,Credit Memo Comment Email Sender +Credit Memo Comment Email Template,Credit Memo Comment Email Template +Credit Memo Comment Email Template for Guest,Credit Memo Comment Email Template for Guest +Send Credit Memo Comment Email Copy To,Send Credit Memo Comment Email Copy To +Send Credit Memo Comments Email Copy Method,Send Credit Memo Comments Email Copy Method +PDF Print-outs,PDF Print-outs +Display Order ID in Header,Display Order ID in Header +Customer Order Status Notification,Customer Order Status Notification +Asynchronous indexing,Asynchronous indexing +Orders and Returns Search Form,Orders and Returns Search Form +Anchor Custom Title,Anchor Custom Title Template,Template -"Default Template","Default Template" +Default Template,Default Template Name,Name Phone,Phone -"ZIP/Post Code","ZIP/Post Code" -"Signed-up Point","Signed-up Point" +ZIP/Post Code,ZIP/Post Code +Signed-up Point,Signed-up Point Website,Website -"Bill-to Name","Bill-to Name" +Bill-to Name,Bill-to Name Created,Created -"Invoice Date","Invoice Date" -"Ship-to Name","Ship-to Name" -"Ship Date","Ship Date" -"Total Quantity","Total Quantity" -"Default Status","Default Status" -"State Code and Title","State Code and Title" -"Item Status","Item Status" -"Original Price","Original Price" -"Tax Percent","Tax Percent" -"All Store Views","All Store Views" -"PDF Credit Memos","PDF Credit Memos" -"Purchase Point","Purchase Point" -"Print Invoices","Print Invoices" -"Print Packing Slips","Print Packing Slips" -"Print Credit Memos","Print Credit Memos" -"Print All","Print All" -"Print Shipping Labels","Print Shipping Labels" -"Purchase Date","Purchase Date" -"Grand Total (Base)","Grand Total (Base)" -"Grand Total (Purchased)","Grand Total (Purchased)" -"Customer Email","Customer Email" -"Shipping and Handling","Shipping and Handling" -"PDF Invoices","PDF Invoices" -"PDF Shipments","PDF Shipments" -"PDF Creditmemos","PDF Creditmemos" +Invoice Date,Invoice Date +Ship-to Name,Ship-to Name +Ship Date,Ship Date +Total Quantity,Total Quantity +Default Status,Default Status +State Code and Title,State Code and Title +Item Status,Item Status +Original Price,Original Price +Tax Percent,Tax Percent +All Store Views,All Store Views +PDF Credit Memos,PDF Credit Memos +Purchase Point,Purchase Point +Print Invoices,Print Invoices +Print Packing Slips,Print Packing Slips +Print Credit Memos,Print Credit Memos +Print All,Print All +Print Shipping Labels,Print Shipping Labels +Purchase Date,Purchase Date +Grand Total (Base),Grand Total (Base) +Grand Total (Purchased),Grand Total (Purchased) +Customer Email,Customer Email +Shipping and Handling,Shipping and Handling +PDF Invoices,PDF Invoices +PDF Shipments,PDF Shipments +PDF Creditmemos,PDF Creditmemos Refunds,Refunds -"Allow Zero GrandTotal for Creditmemo","Allow Zero GrandTotal for Creditmemo" -"Allow Zero GrandTotal","Allow Zero GrandTotal" +Allow Zero GrandTotal for Creditmemo,Allow Zero GrandTotal for Creditmemo +Allow Zero GrandTotal,Allow Zero GrandTotal Email is required field for Admin order creation,Email is required field for Admin order creation If set YES Email field will be required during Admin order creation for new Customer.,If set YES Email field will be required during Admin order creation for new Customer. -"Could not save the shipment tracking","Could not save the shipment tracking" -"Please enter a coupon code!","Please enter a coupon code!" -"Reorder is not available.","Reorder is not available." +Could not save the shipment tracking,Could not save the shipment tracking +Please enter a coupon code!,Please enter a coupon code! +Reorder is not available.,Reorder is not available. +This creditmemo no longer exists.,This creditmemo no longer exists. diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminGoToShipmentViewActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminGoToShipmentViewActionGroup.xml index 09f74839b3a30..14587e17f75ba 100644 --- a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminGoToShipmentViewActionGroup.xml +++ b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminGoToShipmentViewActionGroup.xml @@ -19,4 +19,4 @@ <amOnPage url="{{AdminShipmentViewPage.url}}/{{identifier}}" stepKey="amOnShipmentViewPage"/> <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Shipping/Test/Mftf/Page/AdminShipmentViewPage.xml b/app/code/Magento/Shipping/Test/Mftf/Page/AdminShipmentViewPage.xml index 5a965db2b4efe..e78a4d5b2701c 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Page/AdminShipmentViewPage.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Page/AdminShipmentViewPage.xml @@ -10,4 +10,4 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> <page name="AdminShipmentViewPage" url="sales/shipment/view/shipment_id" area="admin" module="Shipping"> </page> -</pages> \ No newline at end of file +</pages> diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml index 0311ebc320b59..13688afd0efe9 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml @@ -36,4 +36,4 @@ <see selector="{{AdminMessagesSection.error}}" userInput='This shipment no longer exists.' stepKey="seeErrorMessage"/> </test> -</tests> \ No newline at end of file +</tests> diff --git a/app/code/Magento/Shipping/i18n/en_US.csv b/app/code/Magento/Shipping/i18n/en_US.csv index f777e64ef98c9..831c361382490 100644 --- a/app/code/Magento/Shipping/i18n/en_US.csv +++ b/app/code/Magento/Shipping/i18n/en_US.csv @@ -1,179 +1,180 @@ -"New Shipment for Order #%1","New Shipment for Order #%1" -"Submit Shipment","Submit Shipment" -"You are trying to add a quantity for some products that doesn't match the quantity that was shipped.","You are trying to add a quantity for some products that doesn't match the quantity that was shipped." -"Products should be added to package(s)","Products should be added to package(s)" -"The value that you entered is not valid.","The value that you entered is not valid." -"Add Tracking Number","Add Tracking Number" -"Custom Value","Custom Value" +New Shipment for Order #%1,New Shipment for Order #%1 +Submit Shipment,Submit Shipment +You are trying to add a quantity for some products that doesn't match the quantity that was shipped.,You are trying to add a quantity for some products that doesn't match the quantity that was shipped. +Products should be added to package(s),Products should be added to package(s) +The value that you entered is not valid.,The value that you entered is not valid. +Add Tracking Number,Add Tracking Number +Custom Value,Custom Value Add,Add -"Send Tracking Information","Send Tracking Information" -"Are you sure you want to send a Shipment email to customer?","Are you sure you want to send a Shipment email to customer?" +Send Tracking Information,Send Tracking Information +Are you sure you want to send a Shipment email to customer?,Are you sure you want to send a Shipment email to customer? Print,Print -"the shipment email was sent","the shipment email was sent" -"the shipment email is not sent","the shipment email is not sent" -"Shipment #%1 | %3 (%2)","Shipment #%1 | %3 (%2)" -"Create Shipping Label...","Create Shipping Label..." -"Print Shipping Label","Print Shipping Label" -"Show Packages","Show Packages" -"About Your Shipment","About Your Shipment" -"Order # %1","Order # %1" -"Back to My Orders","Back to My Orders" -"View Another Order","View Another Order" -"Please enter a comment.","Please enter a comment." -"Cannot add new comment.","Cannot add new comment." -"Please specify a carrier.","Please specify a carrier." -"Please enter a tracking number.","Please enter a tracking number." +the shipment email was sent,the shipment email was sent +the shipment email is not sent,the shipment email is not sent +Shipment #%1 | %3 (%2),Shipment #%1 | %3 (%2) +Create Shipping Label...,Create Shipping Label... +Print Shipping Label,Print Shipping Label +Show Packages,Show Packages +About Your Shipment,About Your Shipment +Order # %1,Order # %1 +Back to My Orders,Back to My Orders +View Another Order,View Another Order +Please enter a comment.,Please enter a comment. +Cannot add new comment.,Cannot add new comment. +Please specify a carrier.,Please specify a carrier. +Please enter a tracking number.,Please enter a tracking number. Shipments,Shipments -"We can't initialize shipment for adding tracking number.","We can't initialize shipment for adding tracking number." -"Cannot add tracking number.","Cannot add tracking number." -"You created the shipping label.","You created the shipping label." -"An error occurred while creating shipping label.","An error occurred while creating shipping label." -"You sent the shipment.","You sent the shipment." -"Cannot send shipment information.","Cannot send shipment information." -"There are no shipping labels related to selected orders.","There are no shipping labels related to selected orders." -"New Shipment","New Shipment" -"We don't recognize or support the file extension in this shipment: %1.","We don't recognize or support the file extension in this shipment: %1." -"We can't initialize shipment for delete tracking number.","We can't initialize shipment for delete tracking number." -"We can't delete tracking number.","We can't delete tracking number." -"We can't load track with retrieving identifier right now.","We can't load track with retrieving identifier right now." -"We can't save the shipment right now.","We can't save the shipment right now." +We can't initialize shipment for adding tracking number.,We can't initialize shipment for adding tracking number. +Cannot add tracking number.,Cannot add tracking number. +You created the shipping label.,You created the shipping label. +An error occurred while creating shipping label.,An error occurred while creating shipping label. +You sent the shipment.,You sent the shipment. +Cannot send shipment information.,Cannot send shipment information. +There are no shipping labels related to selected orders.,There are no shipping labels related to selected orders. +New Shipment,New Shipment +We don't recognize or support the file extension in this shipment: %1.,We don't recognize or support the file extension in this shipment: %1. +We can't initialize shipment for delete tracking number.,We can't initialize shipment for delete tracking number. +We can't delete tracking number.,We can't delete tracking number. +We can't load track with retrieving identifier right now.,We can't load track with retrieving identifier right now. +We can't save the shipment right now.,We can't save the shipment right now. """Shipment Document Validation Error(s):\n"" .","""Shipment Document Validation Error(s):\n"" ." -"The shipment has been created.","The shipment has been created." -"Cannot save shipment.","Cannot save shipment." -"The order no longer exists.","The order no longer exists." -"Cannot do shipment for the order separately from invoice.","Cannot do shipment for the order separately from invoice." -"Cannot do shipment for the order.","Cannot do shipment for the order." -"There are no shipping labels related to selected shipments.","There are no shipping labels related to selected shipments." -"Page not found.","Page not found." -"Tracking Information","Tracking Information" +The shipment has been created.,The shipment has been created. +Cannot save shipment.,Cannot save shipment. +The order no longer exists.,The order no longer exists. +Cannot do shipment for the order separately from invoice.,Cannot do shipment for the order separately from invoice. +Cannot do shipment for the order.,Cannot do shipment for the order. +There are no shipping labels related to selected shipments.,There are no shipping labels related to selected shipments. +Page not found.,Page not found. +Tracking Information,Tracking Information "Sorry, but we can't deliver to the destination country with this shipping module.","Sorry, but we can't deliver to the destination country with this shipping module." -"The shipping module is not available.","The shipping module is not available." -"This shipping method is not available. Please specify the zip code.","This shipping method is not available. Please specify the zip code." -"No packages for request","No packages for request" -"Security validation of XML document has been failed.","Security validation of XML document has been failed." -"All Allowed Countries","All Allowed Countries" -"Specific Countries","Specific Countries" +The shipping module is not available.,The shipping module is not available. +This shipping method is not available. Please specify the zip code.,This shipping method is not available. Please specify the zip code. +No packages for request,No packages for request +Security validation of XML document has been failed.,Security validation of XML document has been failed. +All Allowed Countries,All Allowed Countries +Specific Countries,Specific Countries Development,Development Live,Live -"Divide to equal weight (one request)","Divide to equal weight (one request)" -"Use origin weight (few requests)","Use origin weight (few requests)" +Divide to equal weight (one request),Divide to equal weight (one request) +Use origin weight (few requests),Use origin weight (few requests) Packages,Packages Package,Package Type,Type Length,Length -"Signature Confirmation","Signature Confirmation" -"Customs Value","Customs Value" +Signature Confirmation,Signature Confirmation +Customs Value,Customs Value Width,Width Contents,Contents -"Total Weight","Total Weight" +Total Weight,Total Weight Height,Height Size,Size Girth,Girth -"Items in the Package","Items in the Package" +Items in the Package,Items in the Package Product,Product Weight,Weight -"Qty Ordered","Qty Ordered" +Qty Ordered,Qty Ordered Qty,Qty "No detail for number ""%1""","No detail for number ""%1""" -"Shipping labels is not available.","Shipping labels is not available." -"Response info is not exist.","Response info is not exist." -"Invalid carrier: %1","Invalid carrier: %1" -"We don't have enough information to create shipping labels. Please make sure your store information and settings are complete.","We don't have enough information to create shipping labels. Please make sure your store information and settings are complete." -"Per Order","Per Order" -"Per Package","Per Package" +Shipping labels is not available.,Shipping labels is not available. +Response info is not exist.,Response info is not exist. +Invalid carrier: %1,Invalid carrier: %1 +We don't have enough information to create shipping labels. Please make sure your store information and settings are complete.,We don't have enough information to create shipping labels. Please make sure your store information and settings are complete. +Per Order,Per Order +Per Package,Per Package Fixed,Fixed Percent,Percent -"Tracking information is unavailable.","Tracking information is unavailable." +Tracking information is unavailable.,Tracking information is unavailable. message,message -"Email has not been sent","Email has not been sent" -"Payment & Shipping Method","Payment & Shipping Method" -"Payment Information","Payment Information" -"The order was placed using %1.","The order was placed using %1." -"Shipping Information","Shipping Information" -"Total Shipping Charges","Total Shipping Charges" -"Incl. Tax","Incl. Tax" -"Items to Ship","Items to Ship" -"Qty to Ship","Qty to Ship" +Email has not been sent,Email has not been sent +Payment & Shipping Method,Payment & Shipping Method +Payment Information,Payment Information +The order was placed using %1.,The order was placed using %1. +Shipping Information,Shipping Information +Total Shipping Charges,Total Shipping Charges +Incl. Tax,Incl. Tax +Items to Ship,Items to Ship +Qty to Ship,Qty to Ship Ship,Ship -"Shipment Total","Shipment Total" -"Shipment Comments","Shipment Comments" -"Comment Text","Comment Text" -"Shipment Options","Shipment Options" -"Create Shipping Label","Create Shipping Label" -"Append Comments","Append Comments" -"Email Copy of Shipment","Email Copy of Shipment" -"Invalid value(s) for Qty to Ship","Invalid value(s) for Qty to Ship" -"Select All","Select All" -"Product Name","Product Name" +Shipment Total,Shipment Total +Shipment Comments,Shipment Comments +Comment Text,Comment Text +Shipment Options,Shipment Options +Create Shipping Label,Create Shipping Label +Append Comments,Append Comments +Email Copy of Shipment,Email Copy of Shipment +Invalid value(s) for Qty to Ship,Invalid value(s) for Qty to Ship +Select All,Select All +Product Name,Product Name Delete,Delete -"Create Packages","Create Packages" +Create Packages,Create Packages Cancel,Cancel Save,Save -"Add Package","Add Package" -"Add Selected Product(s) to Package","Add Selected Product(s) to Package" -"Add Products to Package","Add Products to Package" -"USPS domestic shipments don't use package types.","USPS domestic shipments don't use package types." +Add Package,Add Package +Add Selected Product(s) to Package,Add Selected Product(s) to Package +Add Products to Package,Add Products to Package +USPS domestic shipments don't use package types.,USPS domestic shipments don't use package types. in,in cm,cm lb,lb kg,kg -"Delete Package","Delete Package" +Delete Package,Delete Package Explanation,Explanation Carrier,Carrier Title,Title Number,Number Action,Action -"Are you sure?","Are you sure?" -"Shipping & Handling Information","Shipping & Handling Information" -"Track Order","Track Order" -"No shipping information available","No shipping information available" -"Shipping and Tracking Information","Shipping and Tracking Information" -"Track this shipment","Track this shipment" -"Items Shipped","Items Shipped" -"Order Total","Order Total" -"Shipment History","Shipment History" -"Qty Shipped","Qty Shipped" -"Print All Shipments","Print All Shipments" -"Shipment #","Shipment #" -"Print Shipment","Print Shipment" -"Tracking Number(s):","Tracking Number(s):" +Are you sure?,Are you sure? +Shipping & Handling Information,Shipping & Handling Information +Track Order,Track Order +No shipping information available,No shipping information available +Shipping and Tracking Information,Shipping and Tracking Information +Track this shipment,Track this shipment +Items Shipped,Items Shipped +Order Total,Order Total +Shipment History,Shipment History +Qty Shipped,Qty Shipped +Print All Shipments,Print All Shipments +Shipment #,Shipment # +Print Shipment,Print Shipment +Tracking Number(s):,Tracking Number(s): SKU,SKU -"Order tracking","Order tracking" -"Tracking Number:","Tracking Number:" +Order tracking,Order tracking +Tracking Number:,Tracking Number: Carrier:,Carrier: Error:,Error: -"Tracking information is currently not available. Please ","Tracking information is currently not available. Please " -"contact us","contact us" -" for more information or "," for more information or " -"email us at ","email us at " +Tracking information is currently not available. Please ,Tracking information is currently not available. Please +contact us,contact us + for more information or , for more information or +email us at ,email us at Info:,Info: Track:,Track: -". ':'",". ':'" -"Delivered on:","Delivered on:" +. ':',. ':' +Delivered on:,Delivered on: N/A,N/A -"There is no tracking available for this shipment.","There is no tracking available for this shipment." -"There is no tracking available.","There is no tracking available." -"Close Window","Close Window" -"Track history","Track history" +There is no tracking available for this shipment.,There is no tracking available for this shipment. +There is no tracking available.,There is no tracking available. +Close Window,Close Window +Track history,Track history Location,Location Date,Date -"Local Time","Local Time" +Local Time,Local Time Description,Description -"See our Shipping Policy","See our Shipping Policy" -"Shipping Settings Section","Shipping Settings Section" -"Shipping Policy Parameters Section","Shipping Policy Parameters Section" -"Shipping Methods Section","Shipping Methods Section" -"Shipping Settings","Shipping Settings" +See our Shipping Policy,See our Shipping Policy +Shipping Settings Section,Shipping Settings Section +Shipping Policy Parameters Section,Shipping Policy Parameters Section +Shipping Methods Section,Shipping Methods Section +Shipping Settings,Shipping Settings Origin,Origin Country,Country Region/State,Region/State -"ZIP/Postal Code","ZIP/Postal Code" +ZIP/Postal Code,ZIP/Postal Code City,City -"Street Address","Street Address" -"Street Address Line 2","Street Address Line 2" -"Shipping Policy Parameters","Shipping Policy Parameters" -"Apply custom Shipping Policy","Apply custom Shipping Policy" -"Shipping Policy","Shipping Policy" -"Shipping Methods","Shipping Methods" -"Track your order","Track your order" -"Track All Shipments","Track All Shipments" +Street Address,Street Address +Street Address Line 2,Street Address Line 2 +Shipping Policy Parameters,Shipping Policy Parameters +Apply custom Shipping Policy,Apply custom Shipping Policy +Shipping Policy,Shipping Policy +Shipping Methods,Shipping Methods +Track your order,Track your order +Track All Shipments,Track All Shipments +This shipment no longer exists.,This shipment no longer exists. From 4ba689a035c8aba55e6dc4d8c9cb48871db5d47f Mon Sep 17 00:00:00 2001 From: govindasharma974 <govindpokhrelsharma@cedcommerce.com> Date: Wed, 14 Oct 2020 11:04:51 +0530 Subject: [PATCH 009/156] Fixed some test case issues --- .../Sales/Controller/Adminhtml/Order/CreditmemoLoader.php | 2 +- .../AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml | 2 +- .../Test/Unit/Controller/Adminhtml/Order/Shipment/ViewTest.php | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php index 7bb0b38a8d5ff..2451b76a5de1a 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php @@ -183,7 +183,7 @@ public function load() if ($creditmemoId) { try { $creditmemo = $this->creditmemoRepository->get($creditmemoId); - } catch (\Exception $e) { + } catch (\Exception $e) { $this->messageManager->addErrorMessage(__('This creditmemo no longer exists.')); return false; } diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml index c6522cb22cdf3..696a9f0db2eb0 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml @@ -31,7 +31,7 @@ <waitForPageLoad stepKey="waitForPageLoad"/> - <seeInCurrentUrl url="{{AdminCreditmemosGridPage.url}}" stepKey="redirectToCreditmemosGridPage"/> + <seeInCurrentUrl url="{{AdminCreditMemosGridPage.url}}" stepKey="redirectToCreditMemosGridPage"/> <see selector="{{AdminMessagesSection.error}}" userInput='This creditmemo no longer exists.' stepKey="seeErrorMessage"/> diff --git a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/ViewTest.php b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/ViewTest.php index d99ce83d91de2..aa983aa5c86ce 100644 --- a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/ViewTest.php +++ b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/ViewTest.php @@ -87,7 +87,6 @@ class ViewTest extends TestCase */ protected $pageTitleMock; - /** * @var \Magento\Shipping\Controller\Adminhtml\Order\Shipment\View * @var RedirectFactory|MockObject @@ -104,7 +103,6 @@ class ViewTest extends TestCase */ protected $controller; - protected function setUp(): void { $this->requestMock = $this->getMockBuilder(RequestInterface::class) From 9e99f43aeca1692343abf7450b61c91b2428b95f Mon Sep 17 00:00:00 2001 From: govindasharma974 <govindpokhrelsharma@cedcommerce.com> Date: Wed, 14 Oct 2020 16:21:52 +0530 Subject: [PATCH 010/156] Fixed MFTF issue --- .../Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml index 041ebc7baa84d..d417a6c5ed314 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml @@ -16,7 +16,7 @@ <argument name="identifier" type="string"/> </arguments> - <amOnPage url="{{AdminCreditmemoViewPage.url}}/{{identifier}}" stepKey="amOnCreditmemoViewPage"/> + <amOnPage url="{{AdminCreditMemoViewPage.url}}/{{identifier}}" stepKey="amOnCreditmemoViewPage"/> <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> </actionGroups> From 6359ac54873ff9d106f830e5b27c251823617b71 Mon Sep 17 00:00:00 2001 From: govindasharma974 <govindpokhrelsharma@cedcommerce.com> Date: Wed, 28 Oct 2020 16:50:53 +0530 Subject: [PATCH 011/156] Fixed MFTF issue --- .../Magento/Sales/Test/Mftf/Page/AdminCreditMemoViewPage.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Page/AdminCreditMemoViewPage.xml b/app/code/Magento/Sales/Test/Mftf/Page/AdminCreditMemoViewPage.xml index 2e61424b29a56..2a3bc814364ae 100644 --- a/app/code/Magento/Sales/Test/Mftf/Page/AdminCreditMemoViewPage.xml +++ b/app/code/Magento/Sales/Test/Mftf/Page/AdminCreditMemoViewPage.xml @@ -8,7 +8,7 @@ <pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> - <page name="AdminCreditMemoViewPage" url="sales/order_creditmemo/view/creditmemo_id/{{memoId}}/" parameterized="true" area="admin" module="Magento_Sales"> + <page name="AdminCreditMemoViewPage" url="sales/creditmemo/view/creditmemo_id/" area="admin" module="Magento_Sales"> <section name="AdminCreditMemoViewItemsSection"/> <section name="AdminCreditMemoViewTotalSection"/> </page> From ade5168bb1a2228e5b18b65d4e295be4be74af4c Mon Sep 17 00:00:00 2001 From: govindasharma974 <govindpokhrelsharma@cedcommerce.com> Date: Thu, 29 Oct 2020 17:29:42 +0530 Subject: [PATCH 012/156] updated test files --- .../Adminhtml/Order/Creditmemo/ViewTest.php | 2 +- .../Adminhtml/Order/Invoice/ViewTest.php | 55 ++++++++++++++++--- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php index b6935269e3da7..6e04f4caadc8f 100644 --- a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php +++ b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php @@ -108,7 +108,7 @@ class ViewTest extends TestCase protected $pageTitleMock; /** - * @var \Magento\Shipping\Controller\Adminhtml\Order\Creditmemo\View + * @var \Magento\Sales\Controller\Adminhtml\Order\Creditmemo\View * @var RedirectFactory|MockObject */ protected $resultRedirectFactoryMock; diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Invoice/ViewTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Invoice/ViewTest.php index c8376ab379b6f..a29ab201e0bd9 100644 --- a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Invoice/ViewTest.php +++ b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Invoice/ViewTest.php @@ -13,6 +13,8 @@ use Magento\Backend\Model\View\Result\Forward; use Magento\Backend\Model\View\Result\ForwardFactory; use Magento\Backend\Model\View\Result\Page; +use Magento\Backend\Model\View\Result\Redirect; +use Magento\Backend\Model\View\Result\RedirectFactory; use Magento\Framework\App\ActionFlag; use Magento\Framework\App\Request\Http; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; @@ -82,6 +84,17 @@ class ViewTest extends TestCase */ protected $pageTitleMock; + /** + * @var \Magento\Sales\Controller\Adminhtml\Order\Invoice\View + * @var RedirectFactory|MockObject + */ + protected $resultRedirectFactoryMock; + + /** + * @var Redirect|MockObject + */ + protected $resultRedirectMock; + /** * @var View */ @@ -194,6 +207,13 @@ protected function setUp(): void )->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); + $this->resultRedirectFactoryMock = $this->getMockBuilder(RedirectFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->resultRedirectMock = $this->getMockBuilder(Redirect::class) + ->disableOriginalConstructor() + ->getMock(); $this->invoiceRepository = $this->getMockBuilder(InvoiceRepositoryInterface::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); @@ -203,7 +223,8 @@ protected function setUp(): void [ 'context' => $contextMock, 'resultPageFactory' => $this->resultPageFactoryMock, - 'resultForwardFactory' => $this->resultForwardFactoryMock + 'resultForwardFactory' => $this->resultForwardFactoryMock, + 'resultRedirectFactory' => $this->resultRedirectFactoryMock ] ); @@ -287,16 +308,32 @@ public function testExecuteNoInvoice() ->method('get') ->willReturn(null); - $resultForward = $this->getMockBuilder(Forward::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $resultForward->expects($this->once())->method('forward')->with(('noroute'))->willReturnSelf(); + $this->prepareRedirect(); + $this->setPath('sales/invoice'); + $this->assertInstanceOf( + Redirect::class, + $this->controller->execute() + ); + } - $this->resultForwardFactoryMock->expects($this->once()) + /** + * prepareRedirect + */ + protected function prepareRedirect() + { + $this->resultRedirectFactoryMock->expects($this->once()) ->method('create') - ->willReturn($resultForward); + ->willReturn($this->resultRedirectMock); + } - $this->assertSame($resultForward, $this->controller->execute()); + /** + * @param string $path + * @param array $params + */ + protected function setPath($path, $params = []) + { + $this->resultRedirectMock->expects($this->once()) + ->method('setPath') + ->with($path, $params); } } From 7806115a430973fec96cef5be76de5d30cf81a76 Mon Sep 17 00:00:00 2001 From: Oleh Usik <o.usik@atwix.com> Date: Wed, 4 Nov 2020 12:41:57 +0200 Subject: [PATCH 013/156] Assert discount --- ...ssertStorefrontCartDiscountActionGroup.xml | 21 +++++++++++++++++++ ...tCheckoutWithCouponAndZeroSubtotalTest.xml | 6 ++++-- ...efrontUKCustomerCheckoutWithCouponTest.xml | 6 ++++-- ...eConditionAndFreeShippingIsAppliedTest.xml | 4 +++- ...inCreateCartPriceRuleEmptyFromDateTest.xml | 6 ++++-- ...inCreateCartPriceRuleForCouponCodeTest.xml | 6 ++++-- ...ateCartPriceRuleForGeneratedCouponTest.xml | 6 ++++-- ...talAndVerifyRuleConditionIsAppliedTest.xml | 4 +++- ...oryAndVerifyRuleConditionIsAppliedTest.xml | 4 +++- ...ghtAndVerifyRuleConditionIsAppliedTest.xml | 4 +++- .../StorefrontCartPriceRuleCountryTest.xml | 6 ++++-- .../StorefrontCartPriceRulePostcodeTest.xml | 6 ++++-- .../StorefrontCartPriceRuleQuantityTest.xml | 6 ++++-- .../Test/StorefrontCartPriceRuleStateTest.xml | 6 ++++-- .../StorefrontCartPriceRuleSubtotalTest.xml | 6 ++++-- ...ValueWithFullDiscountUsingCartRuleTest.xml | 6 ++++-- 16 files changed, 77 insertions(+), 26 deletions(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontCartDiscountActionGroup.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontCartDiscountActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontCartDiscountActionGroup.xml new file mode 100644 index 0000000000000..ed34b460d6158 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontCartDiscountActionGroup.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"> + <actionGroup name="AssertStorefrontCartDiscountActionGroup"> + <annotations> + <description>Assert that the provided Discount is present in the Storefront Shopping Cart.</description> + </annotations> + <arguments> + <argument name="discount" type="string" defaultValue="0"/> + </arguments> + <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscount"/> + <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-${{discount}}" stepKey="assertDiscount"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutWithCouponAndZeroSubtotalTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutWithCouponAndZeroSubtotalTest.xml index f910a9d47244f..fbfd781505ab7 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutWithCouponAndZeroSubtotalTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutWithCouponAndZeroSubtotalTest.xml @@ -47,8 +47,10 @@ <actionGroup ref="CheckoutFillEstimateShippingAndTaxActionGroup" stepKey="fillEstimateShippingAndTaxFields"/> <!-- Assert Discount and proceed to checkout --> - <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> - <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$50.00" stepKey="seeDiscountTotal"/> + <comment userInput="Adding the comment to replace action for preserving Backward Compatibility" stepKey="waitForDiscountElement"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeDiscountTotal"> + <argument name="discount" value="50.00"/> + </actionGroup> <click selector="{{CheckoutCartSummarySection.proceedToCheckout}}" stepKey="goToCheckout"/> <waitForPageLoad stepKey="waitForPageToLoad"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml index d037718a1ec94..fd38120aab98b 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml @@ -75,8 +75,10 @@ </actionGroup> <!-- Assert Discount and proceed to checkout --> - <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> - <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$15.00" stepKey="seeDiscountTotal"/> + <comment userInput="Adding the comment to replace action for preserving Backward Compatibility" stepKey="waitForDiscountElement"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeDiscountTotal"> + <argument name="discount" value="15.00"/> + </actionGroup> <click selector="{{CheckoutCartSummarySection.proceedToCheckout}}" stepKey="goToCheckout"/> <waitForPageLoad stepKey="waitForPageToLoad1"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleAndVerifyRuleConditionAndFreeShippingIsAppliedTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleAndVerifyRuleConditionAndFreeShippingIsAppliedTest.xml index 88853b2c40d9a..96da616818ae1 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleAndVerifyRuleConditionAndFreeShippingIsAppliedTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleAndVerifyRuleConditionAndFreeShippingIsAppliedTest.xml @@ -107,6 +107,8 @@ <argument name="total" value="$280.00"/> </actionGroup> <see selector="{{CheckoutCartSummarySection.shipping}}" userInput="$0.00" stepKey="seeAssertFreeShippingConditionApplied"/> - <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$280.00" stepKey="seeAssertDiscountAmountAppliedForMatchingItemsConditionIsTrue"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeAssertDiscountAmountAppliedForMatchingItemsConditionIsTrue"> + <argument name="discount" value="280.00"/> + </actionGroup> </test> </tests> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml index e206633808057..65bb0b4cbfb99 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml @@ -87,8 +87,10 @@ <argument name="coupon" value="_defaultCoupon"/> </actionGroup> <waitForPageLoad stepKey="waitForProductPageLoad2"/> - <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> - <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$5.00" stepKey="seeDiscountTotal"/> + <comment userInput="Adding the comment to replace action for preserving Backward Compatibility" stepKey="waitForDiscountElement"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeDiscountTotal"> + <argument name="discount" value="5.00"/> + </actionGroup> <!--Reset timezone--> <actionGroup ref="AdminOpenGeneralConfigurationPageActionGroup" stepKey="goToGeneralConfigReset"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml index 16af210066997..198ba1cd64f35 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml @@ -80,7 +80,9 @@ <argument name="coupon" value="_defaultCoupon"/> </actionGroup> <waitForPageLoad stepKey="waitForProductPageLoad2"/> - <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> - <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$5.00" stepKey="seeDiscountTotal"/> + <comment userInput="Adding the comment to replace action for preserving Backward Compatibility" stepKey="waitForDiscountElement"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeDiscountTotal"> + <argument name="discount" value="5.00"/> + </actionGroup> </test> </tests> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml index 6577ff9440456..70624a4e2e339 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml @@ -84,7 +84,9 @@ <waitForElementVisible selector="{{StorefrontSalesRuleCartCouponSection.couponField}}" stepKey="waitForCouponField" /> <fillField selector="{{StorefrontSalesRuleCartCouponSection.couponField}}" userInput="{$grabCouponCode}" stepKey="fillCouponField"/> <click selector="{{StorefrontSalesRuleCartCouponSection.applyButton}}" stepKey="clickApplyButton"/> - <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> - <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$0.99" stepKey="seeDiscountTotal"/> + <comment userInput="Adding the comment to replace action for preserving Backward Compatibility" stepKey="waitForDiscountElement"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeDiscountTotal"> + <argument name="discount" value="0.99"/> + </actionGroup> </test> </tests> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForMatchingSubtotalAndVerifyRuleConditionIsAppliedTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForMatchingSubtotalAndVerifyRuleConditionIsAppliedTest.xml index da8c8e4bc1f9d..1fe97b1f45036 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForMatchingSubtotalAndVerifyRuleConditionIsAppliedTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForMatchingSubtotalAndVerifyRuleConditionIsAppliedTest.xml @@ -116,6 +116,8 @@ <argument name="shippingMethod" value="Flat Rate - Fixed"/> <argument name="total" value="$285.00"/> </actionGroup> - <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$280.00" stepKey="seeAssertDiscountAmountAppliedForSubtotalConditionIsTrue"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeAssertDiscountAmountAppliedForSubtotalConditionIsTrue"> + <argument name="discount" value="280.00"/> + </actionGroup> </test> </tests> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingCategoryAndVerifyRuleConditionIsAppliedTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingCategoryAndVerifyRuleConditionIsAppliedTest.xml index f6e736c73db74..c80f43385d166 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingCategoryAndVerifyRuleConditionIsAppliedTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingCategoryAndVerifyRuleConditionIsAppliedTest.xml @@ -118,6 +118,8 @@ <argument name="shippingMethod" value="Flat Rate - Fixed"/> <argument name="total" value="$66.50"/> </actionGroup> - <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$61.50" stepKey="seeAssertDiscountAmountAppliedForMatchingCategory"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeAssertDiscountAmountAppliedForMatchingCategory"> + <argument name="discount" value="61.50"/> + </actionGroup> </test> </tests> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingTotalWeightAndVerifyRuleConditionIsAppliedTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingTotalWeightAndVerifyRuleConditionIsAppliedTest.xml index 5f110f7074f6f..cd72ec8529816 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingTotalWeightAndVerifyRuleConditionIsAppliedTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingTotalWeightAndVerifyRuleConditionIsAppliedTest.xml @@ -106,6 +106,8 @@ <argument name="shippingMethod" value="Flat Rate - Fixed"/> <argument name="total" value="$285.00"/> </actionGroup> - <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$280.00" stepKey="seeAssertDiscountAmountAppliedForWeightConditionIsTrue"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeAssertDiscountAmountAppliedForWeightConditionIsTrue"> + <argument name="discount" value="280.00"/> + </actionGroup> </test> </tests> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountryTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountryTest.xml index ea96fa41e5cad..3b54df544210f 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountryTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountryTest.xml @@ -77,8 +77,10 @@ <!-- See discount if we use valid country --> <selectOption selector="{{CheckoutCartSummarySection.country}}" userInput="Brazil" stepKey="fillCountry"/> <waitForPageLoad stepKey="waitForCountry1"/> - <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> - <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$9.99" stepKey="seeDiscountTotal"/> + <comment userInput="Adding the comment to replace action for preserving Backward Compatibility" stepKey="waitForDiscountElement"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeDiscountTotal"> + <argument name="discount" value="9.99"/> + </actionGroup> <!-- Do not see discount with other country --> <selectOption selector="{{CheckoutCartSummarySection.country}}" userInput="United States" stepKey="fillCountry2"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcodeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcodeTest.xml index 62c494b988bbd..d0cba156f635e 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcodeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcodeTest.xml @@ -81,8 +81,10 @@ <!-- See discount if we use valid postcode --> <fillField selector="{{CheckoutCartSummarySection.postcode}}" userInput="78613" stepKey="fillPostcode"/> <waitForPageLoad stepKey="waitForPostcode1"/> - <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> - <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$9.99" stepKey="seeDiscountTotal"/> + <comment userInput="Adding the comment to replace action for preserving Backward Compatibility" stepKey="waitForDiscountElement"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeDiscountTotal"> + <argument name="discount" value="9.99"/> + </actionGroup> <!-- Do not see discount with other postcode --> <fillField selector="{{CheckoutCartSummarySection.postcode}}" userInput="90210" stepKey="fillPostcode2"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantityTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantityTest.xml index 70ed09df7a2cc..1a449017e0386 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantityTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantityTest.xml @@ -83,7 +83,9 @@ <!-- Now we should see the discount because we have more than 1 item --> <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"/> + <comment userInput="Adding the comment to replace action for preserving Backward Compatibility" stepKey="waitForDiscountElement"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeDiscountTotal"> + <argument name="discount" value="1.00"/> + </actionGroup> </test> </tests> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleStateTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleStateTest.xml index da9ca9055d31b..68f6fc93eab94 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleStateTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleStateTest.xml @@ -77,8 +77,10 @@ <!-- See discount if we use valid postcode --> <selectOption selector="{{CheckoutCartSummarySection.stateProvince}}" userInput="Indiana" stepKey="fillState"/> <waitForPageLoad stepKey="waitForPostcode1"/> - <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> - <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$9.99" stepKey="seeDiscountTotal"/> + <comment userInput="Adding the comment to replace action for preserving Backward Compatibility" stepKey="waitForDiscountElement"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeDiscountTotal"> + <argument name="discount" value="9.99"/> + </actionGroup> <!-- Do not see discount with other postcode --> <selectOption selector="{{CheckoutCartSummarySection.stateProvince}}" userInput="Texas" stepKey="fillState2"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotalTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotalTest.xml index ce0d814e50308..0ffe1516d0232 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotalTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotalTest.xml @@ -81,7 +81,9 @@ <!-- Now we should see the discount because we exceeded $200 --> <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"/> + <comment userInput="Adding the comment to replace action for preserving Backward Compatibility" stepKey="waitForDiscountElement"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeDiscountTotal"> + <argument name="discount" value="0.01"/> + </actionGroup> </test> </tests> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartTotalValueWithFullDiscountUsingCartRuleTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartTotalValueWithFullDiscountUsingCartRuleTest.xml index 1178ca2cfb328..8df45937bb542 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartTotalValueWithFullDiscountUsingCartRuleTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartTotalValueWithFullDiscountUsingCartRuleTest.xml @@ -117,8 +117,10 @@ <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"/> - <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$29.00" stepKey="seeDiscountAmount"/> + <comment userInput="Adding the comment to replace action for preserving Backward Compatibility" stepKey="waitForOrderTotalUpdate"/> + <actionGroup ref="AssertStorefrontCartDiscountActionGroup" stepKey="seeDiscountAmount"> + <argument name="discount" value="29.00"/> + </actionGroup> <see selector="{{CheckoutCartSummarySection.subTotal}}" userInput="$29.00" stepKey="seeSubTotal"/> <see selector="{{CheckoutCartSummarySection.orderTotal}}" userInput="0.00" stepKey="seeOrderTotal"/> </test> From 937f9e5b767fb9beac965b22c22c8866d9595d95 Mon Sep 17 00:00:00 2001 From: "vadim.malesh" <engcom-vendorworker-charlie@adobe.com> Date: Fri, 6 Nov 2020 17:11:47 +0200 Subject: [PATCH 014/156] fix mftf, static --- .../Adminhtml/Order/CreditmemoLoader.php | 14 +++++++++----- ...CreditmemoViewPageWithWrongCreditmemoIdTest.xml | 3 +-- .../Adminhtml/Order/Creditmemo/ViewTest.php | 8 +------- .../Adminhtml/Order/Invoice/ViewTest.php | 7 ------- .../Controller/Adminhtml/Order/ShipmentLoader.php | 3 +-- 5 files changed, 12 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php index 2451b76a5de1a..c1e79b95af038 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php @@ -8,12 +8,12 @@ use Magento\Framework\DataObject; use Magento\Sales\Api\CreditmemoRepositoryInterface; -use \Magento\Sales\Model\Order\CreditmemoFactory; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\CreditmemoFactory; /** - * Class CreditmemoLoader + * Loader for creditmemo * - * @package Magento\Sales\Controller\Adminhtml\Order * @method CreditmemoLoader setCreditmemoId($id) * @method CreditmemoLoader setCreditmemo($creditMemo) * @method CreditmemoLoader setInvoiceId($id) @@ -22,6 +22,7 @@ * @method string getCreditmemo() * @method int getInvoiceId() * @method int getOrderId() + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) */ class CreditmemoLoader extends DataObject { @@ -129,7 +130,8 @@ protected function _getItemData() /** * Check if creditmeno can be created for order - * @param \Magento\Sales\Model\Order $order + * + * @param Order $order * @return bool */ protected function _canCreditmemo($order) @@ -153,7 +155,9 @@ protected function _canCreditmemo($order) } /** - * @param \Magento\Sales\Model\Order $order + * Inits invoice + * + * @param Order $order * @return $this|bool */ protected function _initInvoice($order) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml index 696a9f0db2eb0..cf7f61aa12a20 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml @@ -33,7 +33,6 @@ <seeInCurrentUrl url="{{AdminCreditMemosGridPage.url}}" stepKey="redirectToCreditMemosGridPage"/> - <see selector="{{AdminMessagesSection.error}}" userInput='This creditmemo no longer exists.' - stepKey="seeErrorMessage"/> + <actionGroup ref="AssertAdminPageIs404ActionGroup" stepKey="see404PageOnAdmin"/> </test> </tests> diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php index 6e04f4caadc8f..b7249e2af295c 100644 --- a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php +++ b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/ViewTest.php @@ -143,9 +143,6 @@ class ViewTest extends TestCase */ protected function setUp(): void { - $titleMock = $this->getMockBuilder(\Magento\Framework\App\Action\Title::class) - ->disableOriginalConstructor() - ->getMock(); $this->invoiceMock = $this->getMockBuilder(Invoice::class) ->disableOriginalConstructor() ->getMock(); @@ -238,9 +235,6 @@ protected function setUp(): void $this->contextMock->expects($this->any()) ->method('getObjectManager') ->willReturn($this->objectManagerMock); - $this->contextMock->expects($this->any()) - ->method('getTitle') - ->willReturn($titleMock); $this->contextMock->expects($this->any()) ->method('getMessageManager') ->willReturn($this->messageManagerMock); @@ -272,7 +266,7 @@ public function testExecuteNoCreditMemo() $this->loaderMock->expects($this->once()) ->method('load') ->willReturn(false); - + $this->prepareRedirect(); $this->setPath('sales/creditmemo'); $this->assertInstanceOf( diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Invoice/ViewTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Invoice/ViewTest.php index a29ab201e0bd9..d9003b7b4f061 100644 --- a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Invoice/ViewTest.php +++ b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Invoice/ViewTest.php @@ -127,10 +127,6 @@ protected function setUp(): void ->disableOriginalConstructor() ->setMethods([]) ->getMock(); - $this->titleMock = $this->getMockBuilder(\Magento\Framework\App\Action\Title::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); $this->viewMock = $this->getMockBuilder(\Magento\Framework\App\View::class) ->disableOriginalConstructor() ->setMethods([]) @@ -176,9 +172,6 @@ protected function setUp(): void $contextMock->expects($this->any()) ->method('getResponse') ->willReturn($this->responseMock); - $contextMock->expects($this->any()) - ->method('getTitle') - ->willReturn($this->titleMock); $contextMock->expects($this->any()) ->method('getView') ->willReturn($this->viewMock); diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php index 4f44bfb6458b1..5f0a2fb24c96f 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php @@ -18,9 +18,8 @@ use Magento\Sales\Api\Data\ShipmentItemCreationInterface; /** - * Class ShipmentLoader + * Loader for shipment * - * @package Magento\Shipping\Controller\Adminhtml\Order * @method ShipmentLoader setOrderId($id) * @method ShipmentLoader setShipmentId($id) * @method ShipmentLoader setShipment($shipment) From 6bb81585f10eb347cd4f35c9a286eab0a2d82d39 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Fri, 6 Nov 2020 18:37:18 +0200 Subject: [PATCH 015/156] AddOutOfStockProductToCompareListTest refactored --- ...tHoverProductOnCategoryPageActionGroup.xml | 19 +++ .../AddOutOfStockProductToCompareListTest.xml | 120 ++++++++---------- 2 files changed, 72 insertions(+), 67 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontHoverProductOnCategoryPageActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontHoverProductOnCategoryPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontHoverProductOnCategoryPageActionGroup.xml new file mode 100644 index 0000000000000..661d40fd4f13a --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontHoverProductOnCategoryPageActionGroup.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="StorefrontHoverProductOnCategoryPageActionGroup"> + <annotations> + <description>Hover product on the Category page</description> + </annotations> + + <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverOverProduct"/> + + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml index 92be79fdfe720..b2fbf2ae3810a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml @@ -20,7 +20,6 @@ <group value="Catalog"/> </annotations> <before> - <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> <argument name="tags" value=""/> @@ -30,81 +29,68 @@ <requiredEntity createDataKey="category"/> </createData> </before> + <after> - <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/> + <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> <argument name="tags" value=""/> </actionGroup> - <deleteData createDataKey="product" stepKey="deleteProduct"/> - <deleteData createDataKey="category" stepKey="deleteCategory"/> - <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + <deleteData createDataKey="product" stepKey="deleteProduct"/> + <deleteData createDataKey="category" stepKey="deleteCategory"/> </after> - <!--Open product page--> - <comment userInput="Open product page" stepKey="openProdPage"/> - <amOnPage url="{{StorefrontProductPage.url($$product.custom_attributes[url_key]$$)}}" stepKey="goToSimpleProductPage"/> - <waitForPageLoad stepKey="waitForSimpleProductPage"/> - <!--'Add to compare' link is not available--> - <comment userInput="'Add to compare' link is not available" stepKey="addToCompareLinkAvailability"/> + + <actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="openProductStorefront"> + <argument name="productUrl" value="$$product.custom_attributes[url_key]$$"/> + </actionGroup> + <dontSeeElement selector="{{StorefrontProductInfoMainSection.productAddToCompare}}" stepKey="dontSeeAddToCompareLink"/> - <!--Turn on 'out on stock' config--> - <comment userInput="Turn on 'out of stock' config" stepKey="onOutOfStockConfig"/> + <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockEnable.path}} {{CatalogInventoryOptionsShowOutOfStockEnable.value}}" stepKey="setConfigShowOutOfStockTrue"/> - <!--Clear cache and reindex--> - <comment userInput="Clear cache and reindex" stepKey="cleanCache"/> + <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> -</actionGroup> + <argument name="indices" value=""/> + </actionGroup> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> - <argument name="tags" value=""/> -</actionGroup> - <!--Open product page--> - <comment userInput="Open product page" stepKey="openProductPage"/> - <amOnPage url="{{StorefrontProductPage.url($$product.custom_attributes[url_key]$$)}}" stepKey="goToSimpleProductPage2"/> - <waitForPageLoad stepKey="waitForSimpleProductPage2"/> - <!--Click on 'Add to Compare' link--> - <waitForElementVisible selector="{{StorefrontProductInfoMainSection.productAddToCompare}}" stepKey="seeAddToCompareLink"/> - <comment userInput="Click on 'Add to Compare' link" stepKey="clickOnAddToCompareLink"/> - <click selector="{{StorefrontProductInfoMainSection.productAddToCompare}}" stepKey="clickOnAddToCompare"/> - <waitForPageLoad stepKey="waitForProdAddToCmpList"/> - <!--Assert success message--> - <comment userInput="Assert success message" stepKey="assertSuccessMsg"/> - <grabTextFrom selector="{{StorefrontMessagesSection.success}}" stepKey="grabTextFromSuccessMessage"/> - <assertEquals stepKey="assertSuccessMessage"> - <actualResult type="const">($grabTextFromSuccessMessage)</actualResult> - <expectedResult type="string">You added product $$product.name$$ to the comparison list.</expectedResult> - </assertEquals> - <!--See product in the comparison list--> - <comment userInput="See product in the comparison list" stepKey="seeProductInComparisonList"/> - <amOnPage url="{{StorefrontProductComparePage.url}}" stepKey="navigateToComparePage"/> - <waitForPageLoad stepKey="waitForStorefrontProductComparePageLoad"/> - <seeElement selector="{{StorefrontProductCompareMainSection.ProductLinkByName($product.name$)}}" stepKey="seeProductInCompareList"/> - <!--Go to Category page and delete product from comparison list--> - <comment userInput="Go to Category page and delete product from comparison list" stepKey="deleteProdFromCmpList"/> - <amOnPage url="{{StorefrontCategoryPage.url($$category.name$$)}}" stepKey="onCategoryPage"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad1"/> - <click selector="{{StorefrontComparisonSidebarSection.ClearAll}}" stepKey="clickClearAll"/> - <waitForPageLoad time="30" stepKey="waitForConfirmPageLoad"/> - <click selector="{{AdminDeleteRoleSection.confirm}}" stepKey="confirmProdDelate"/> - <waitForPageLoad time="30" stepKey="waitForConfirmLoad"/> - <!--Add product to compare list from Category page--> - <comment userInput="Add product to compare list fom Category page" stepKey="addToCmpFromCategPage"/> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverOverProduct"/> - <click selector="{{StorefrontProductInfoMainSection.productAddToCompare}}" stepKey="clickAddToCompare"/> - <waitForPageLoad stepKey="waitProdAddingToCmpList"/> - <!--Assert success message--> - <comment userInput="Assert success message" stepKey="assertSuccessMsg2"/> - <grabTextFrom selector="{{StorefrontMessagesSection.success}}" stepKey="grabTextFromSuccessMessage2"/> - <assertEquals stepKey="assertSuccessMessage2"> - <actualResult type="const">($grabTextFromSuccessMessage)</actualResult> - <expectedResult type="string">You added product $$product.name$$ to the comparison list.</expectedResult> - </assertEquals> - <!--Check that product displays on add to compare widget--> - <comment userInput="Check that product displays on add to compare widget" stepKey="checkProdNameOnWidget"/> + <argument name="tags" value=""/> + </actionGroup> + + <actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="openProductStorefront1"> + <argument name="productUrl" value="$$product.custom_attributes[url_key]$$"/> + </actionGroup> + + <actionGroup ref="StorefrontAddProductToCompareActionGroup" stepKey="addProductToCompare1"> + <argument name="productVar" value="$$product$$"/> + </actionGroup> + + <actionGroup ref="StorefrontGoToCategoryPageActionGroup" stepKey="openCategoryPage"> + <argument name="categoryName" value="$$category.name$$"/> + </actionGroup> + + <actionGroup ref="StorefrontOpenAndCheckComparisionActionGroup" stepKey="compareOpenComparePage"/> + + <actionGroup ref="SeeProductInComparisonListActionGroup" stepKey="seeProductInComparisonList"> + <argument name="productVar" value="$$product$$"/> + </actionGroup> + + <actionGroup ref="StorefrontGoToCategoryPageActionGroup" stepKey="openCategoryPage1"> + <argument name="categoryName" value="$$category.name$$"/> + </actionGroup> + + <actionGroup ref="StorefrontClearCompareActionGroup" stepKey="clearList"/> + + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/> + + <actionGroup ref="StorefrontAddProductToCompareActionGroup" stepKey="addProductToCompare2"> + <argument name="productVar" value="$$product$$"/> + </actionGroup> + <seeElement selector="{{StorefrontComparisonSidebarSection.ProductTitleByName($$product.name$$)}}" stepKey="seeProdNameOnCmpWidget"/> - <!--See product in the compare page--> - <comment userInput="See product in the compare page" stepKey="seeProductInComparePage"/> - <amOnPage url="{{StorefrontProductComparePage.url}}" stepKey="navigateToComparePage2"/> - <waitForPageLoad stepKey="waitForStorefrontProductComparePageLoad2"/> - <seeElement selector="{{StorefrontProductCompareMainSection.ProductLinkByName($product.name$)}}" stepKey="seeProductInCompareList2"/> + + <actionGroup ref="StorefrontOpenAndCheckComparisionActionGroup" stepKey="compareOpenComparePage1"/> + + <actionGroup ref="SeeProductInComparisonListActionGroup" stepKey="seeProductInComparisonList1"> + <argument name="productVar" value="$$product$$"/> + </actionGroup> + </test> </tests> From 32ae2ffa2441992e13b45e5606b2a0c8fb5d76f0 Mon Sep 17 00:00:00 2001 From: "vadim.malesh" <engcom-vendorworker-charlie@adobe.com> Date: Mon, 16 Nov 2020 13:48:07 +0200 Subject: [PATCH 016/156] fix static --- .../Test/Unit/Controller/Adminhtml/Order/Invoice/ViewTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Invoice/ViewTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Invoice/ViewTest.php index d9003b7b4f061..3429b3df85b8a 100644 --- a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Invoice/ViewTest.php +++ b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Invoice/ViewTest.php @@ -31,6 +31,7 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.TooManyFields) */ class ViewTest extends TestCase { From e3276fcf458ccc8d35248d2d83a68c73908afd63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vinicius=20Bordinh=C3=A3o?= <vinicius.bordinhao@blueacornici.com> Date: Mon, 16 Nov 2020 16:07:45 -0300 Subject: [PATCH 017/156] ISSUE-29690: Fixing issue when the images's order was using ID instead of position. --- .../Block/Plugin/Product/Media/Gallery.php | 16 +++++++++++++++- .../Block/Plugin/Product/Media/GalleryTest.php | 10 +++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php b/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php index 1df68482eb6b8..21bfb3b873a7b 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php +++ b/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php @@ -59,7 +59,7 @@ public function afterGetOptionsMediaGalleryDataJson( private function getProductGallery($product) { $result = []; - $images = $product->getMediaGalleryImages(); + $images = $this->getImagesOrderedByPosition($product); foreach ($images as $image) { $result[] = [ 'mediaType' => $image->getMediaType(), @@ -69,4 +69,18 @@ private function getProductGallery($product) } return $result; } + + /** + * @param Product $product + * @return array + */ + private function getImagesOrderedByPosition($product) + { + $imagesCollection = $product->getMediaGalleryImages(); + $images = $imagesCollection->getItems(); + usort($images, function ($el1, $el2) { + return $el1['position'] <=> $el2['position']; + }); + return $images; + } } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php index 16f9697d8ceda..367b639176665 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php @@ -11,6 +11,7 @@ use Magento\ConfigurableProduct\Block\Plugin\Product\Media\Gallery; use Magento\ConfigurableProduct\Model\Product\Type\Configurable; use Magento\Framework\DataObject; +use Magento\Framework\Data\Collection as DataCollection; use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use PHPUnit\Framework\MockObject\MockObject; @@ -41,13 +42,20 @@ public function testAfterGetOptions() ['media_type' => 'type', 'video_url' => 'url', 'file' => 'image.jpg'] ); + $dataCollection = $this->getMockBuilder(DataCollection::class) + ->disableOriginalConstructor() + ->onlyMethods(['getItems']) + ->getMock(); + + $galleryMock->expects(($this->any()))->method('getProduct')->willReturn($productMock); $productMock->expects($this->once())->method('getTypeId')->willReturn('configurable'); $productMock->expects($this->once())->method('getTypeInstance')->willReturn($configurableTypeMock); $configurableTypeMock->expects($this->once())->method('getUsedProducts')->with($productMock) ->willReturn([$variationProductMock]); $variationProductMock->expects($this->once())->method('getId')->willReturn($variationProductId); - $variationProductMock->expects($this->once())->method('getMediaGalleryImages')->willReturn([$image]); + $variationProductMock->expects($this->once())->method('getMediaGalleryImages')->willReturn($dataCollection); + $dataCollection->expects($this->once())->method('getItems')->willReturn([$image]); $variationProductMock->expects($this->once())->method('getImage')->willReturn('image.jpg'); $jsonMock->expects($this->once())->method('serialize')->with($expectedGalleryJson) ->willReturn(json_encode($expectedGalleryJson)); From 0a27db2a4a75e53d6531130a1f1b601477dc6e2f Mon Sep 17 00:00:00 2001 From: Nikola Lardev <nikolalardev@gmail.com> Date: Wed, 18 Nov 2020 00:37:15 +0200 Subject: [PATCH 018/156] Add regions for Albania,Denmark,Greece,Iceland,Portugal and Sweden --- .../Setup/Patch/Data/AddDataForAlbania.php | 99 ++++++++++++++++ .../Setup/Patch/Data/AddDataForDenmark.php | 92 +++++++++++++++ .../Setup/Patch/Data/AddDataForGreece.php | 101 ++++++++++++++++ .../Setup/Patch/Data/AddDataForIceland.php | 95 +++++++++++++++ .../Setup/Patch/Data/AddDataForPortugal.php | 107 +++++++++++++++++ .../Setup/Patch/Data/AddDataForSweden.php | 108 ++++++++++++++++++ .../Magento/Directory/Model/RegionTest.php | 8 +- 7 files changed, 609 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Directory/Setup/Patch/Data/AddDataForAlbania.php create mode 100644 app/code/Magento/Directory/Setup/Patch/Data/AddDataForDenmark.php create mode 100644 app/code/Magento/Directory/Setup/Patch/Data/AddDataForGreece.php create mode 100644 app/code/Magento/Directory/Setup/Patch/Data/AddDataForIceland.php create mode 100644 app/code/Magento/Directory/Setup/Patch/Data/AddDataForPortugal.php create mode 100644 app/code/Magento/Directory/Setup/Patch/Data/AddDataForSweden.php diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAlbania.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAlbania.php new file mode 100644 index 0000000000000..14aaffa1857ef --- /dev/null +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAlbania.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Directory\Setup\Patch\Data; + +use Magento\Directory\Setup\DataInstaller; +use Magento\Directory\Setup\DataInstallerFactory; +use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Framework\Setup\Patch\DataPatchInterface; + +/** + * Add Albania States + */ +class AddDataForAlbania implements DataPatchInterface +{ + /** + * @var ModuleDataSetupInterface + */ + private $moduleDataSetup; + + /** + * @var DataInstallerFactory + */ + private $dataInstallerFactory; + + /** + * AddDataForAlbania constructor. + * + * @param ModuleDataSetupInterface $moduleDataSetup + * @param DataInstallerFactory $dataInstallerFactory + */ + public function __construct( + ModuleDataSetupInterface $moduleDataSetup, + DataInstallerFactory $dataInstallerFactory + ) { + $this->moduleDataSetup = $moduleDataSetup; + $this->dataInstallerFactory = $dataInstallerFactory; + } + + /** + * @inheritdoc + */ + public function apply() + { + /** @var DataInstaller $dataInstaller */ + $dataInstaller = $this->dataInstallerFactory->create(); + $dataInstaller->addCountryRegions( + $this->moduleDataSetup->getConnection(), + $this->getDataForAlbania() + ); + + return $this; + } + + /** + * Albania states data. + * + * @return array + */ + private function getDataForAlbania() + { + return [ + ['AL', 'AL-01', 'Berat'], + ['AL', 'AL-09', 'Dibër'], + ['AL', 'AL-02', 'Durrës'], + ['AL', 'AL-03', 'Elbasan'], + ['AL', 'AL-04', 'Fier'], + ['AL', 'AL-05', 'Gjirokastër'], + ['AL', 'AL-06', 'Korçë'], + ['AL', 'AL-07', 'Kukës'], + ['AL', 'AL-08', 'Lezhë'], + ['AL', 'AL-10', 'Shkodër'], + ['AL', 'AL-11', 'Tiranë'], + ['AL', 'AL-12', 'Vlorë'] + ]; + } + + /** + * @inheritdoc + */ + public static function getDependencies() + { + return [ + InitializeDirectoryData::class, + ]; + } + + /** + * @inheritdoc + */ + public function getAliases() + { + return []; + } +} diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForDenmark.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForDenmark.php new file mode 100644 index 0000000000000..1415227a932e6 --- /dev/null +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForDenmark.php @@ -0,0 +1,92 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Directory\Setup\Patch\Data; + +use Magento\Directory\Setup\DataInstaller; +use Magento\Directory\Setup\DataInstallerFactory; +use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Framework\Setup\Patch\DataPatchInterface; + +/** + * Add Denmark States + */ +class AddDataForDenmark implements DataPatchInterface +{ + /** + * @var ModuleDataSetupInterface + */ + private $moduleDataSetup; + + /** + * @var DataInstallerFactory + */ + private $dataInstallerFactory; + + /** + * AddDataForDenmark constructor. + * + * @param ModuleDataSetupInterface $moduleDataSetup + * @param DataInstallerFactory $dataInstallerFactory + */ + public function __construct( + ModuleDataSetupInterface $moduleDataSetup, + DataInstallerFactory $dataInstallerFactory + ) { + $this->moduleDataSetup = $moduleDataSetup; + $this->dataInstallerFactory = $dataInstallerFactory; + } + + /** + * @inheritdoc + */ + public function apply() + { + /** @var DataInstaller $dataInstaller */ + $dataInstaller = $this->dataInstallerFactory->create(); + $dataInstaller->addCountryRegions( + $this->moduleDataSetup->getConnection(), + $this->getDataForDenmark() + ); + + return $this; + } + + /** + * Denmark states data. + * + * @return array + */ + private function getDataForDenmark() + { + return [ + ['DK', 'DK-84', 'Hovedstaden'], + ['DK', 'DK-82', 'Midtjylland'], + ['DK', 'DK-81', 'Nordjylland'], + ['DK', 'DK-85', 'Sjælland'], + ['DK', 'DK-83', 'Syddanmark'], + ]; + } + + /** + * @inheritdoc + */ + public static function getDependencies() + { + return [ + InitializeDirectoryData::class, + ]; + } + + /** + * @inheritdoc + */ + public function getAliases() + { + return []; + } +} diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForGreece.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForGreece.php new file mode 100644 index 0000000000000..a756035f1af4e --- /dev/null +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForGreece.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reGRrved. + * GRe COPYING.txt for licenGR details. + */ +declare(strict_types=1); + +namespace Magento\Directory\GRtup\Patch\Data; + +use Magento\Directory\Setup\DataInstaller; +use Magento\Directory\Setup\DataInstallerFactory; +use Magento\Framework\Setup\ModuleDataGRtupInterface; +use Magento\Framework\Setup\Patch\DataPatchInterface; + +/** + * Add Greece States + */ +class AddDataForGreece implements DataPatchInterface +{ + /** + * @var ModuleDataSetupInterface + */ + private $moduleDataGRtup; + + /** + * @var DataInstallerFactory + */ + private $dataInstallerFactory; + + /** + * AddDataForGreece constructor. + * + * @param ModuleDataSetupInterface $moduleDataSetup + * @param DataInstallerFactory $dataInstallerFactory + */ + public function __construct( + ModuleDataSetupInterface $moduleDataSetup, + DataInstallerFactory $dataInstallerFactory + ) { + $this->moduleDataSetup = $moduleDataSetup; + $this->dataInstallerFactory = $dataInstallerFactory; + } + + /** + * @inheritdoc + */ + public function apply() + { + /** @var DataInstaller $dataInstaller */ + $dataInstaller = $this->dataInstallerFactory->create(); + $dataInstaller->addCountryRegions( + $this->moduleDataSetup->getConnection(), + $this->getDataForGreece() + ); + + return $this; + } + + /** + * Greece states data. + * + * @return array + */ + private function getDataForGreece() + { + return [ + ['GR', 'GR-A', 'Anatolikí Makedonía kai Thráki'], + ['GR', 'GR-I', 'Attikí'], + ['GR', 'GR-G', 'Dytikí Elláda'], + ['GR', 'GR-C', 'Dytikí Makedonía'], + ['GR', 'GR-F', 'Ionía Nísia'], + ['GR', 'GR-D', 'Ípeiros'], + ['GR', 'GR-B', 'Kentrikí Makedonía'], + ['GR', 'GR-M', 'Kríti'], + ['GR', 'GR-L', 'Nótio Aigaío'], + ['GR', 'GR-J', 'Pelopónnisos'], + ['GR', 'GR-H', 'Stereá Elláda'], + ['GR', 'GR-E', 'Thessalía'], + ['GR', 'GR-K', 'Vóreio Aigaío'], + + ]; + } + + /** + * @inheritdoc + */ + public static function getDependencies() + { + return [ + InitializeDirectoryData::class, + ]; + } + + /** + * @inheritdoc + */ + public function getAliases() + { + return []; + } +} diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForIceland.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForIceland.php new file mode 100644 index 0000000000000..6339b8bb71db4 --- /dev/null +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForIceland.php @@ -0,0 +1,95 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Directory\Setup\Patch\Data; + +use Magento\Directory\Setup\DataInstaller; +use Magento\Directory\Setup\DataInstallerFactory; +use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Framework\Setup\Patch\DataPatchInterface; + +/** + * Add Iceland States + */ +class AddDataForIceland implements DataPatchInterface +{ + /** + * @var ModuleDataSetupInterface + */ + private $moduleDataSetup; + + /** + * @var DataInstallerFactory + */ + private $dataInstallerFactory; + + /** + * AddDataForIceland constructor. + * + * @param ModuleDataSetupInterface $moduleDataSetup + * @param DataInstallerFactory $dataInstallerFactory + */ + public function __construct( + ModuleDataSetupInterface $moduleDataSetup, + DataInstallerFactory $dataInstallerFactory + ) { + $this->moduleDataSetup = $moduleDataSetup; + $this->dataInstallerFactory = $dataInstallerFactory; + } + + /** + * @inheritdoc + */ + public function apply() + { + /** @var DataInstaller $dataInstaller */ + $dataInstaller = $this->dataInstallerFactory->create(); + $dataInstaller->addCountryRegions( + $this->moduleDataSetup->getConnection(), + $this->getDataForIceland() + ); + + return $this; + } + + /** + * Iceland states data. + * + * @return array + */ + private function getDataForIceland() + { + return [ + ['IS', 'IS-01', 'Höfuðborgarsvæði'], + ['IS', 'IS-02', 'Suðurnes'], + ['IS', 'IS-03', 'Vesturland'], + ['IS', 'IS-04', 'Vestfirðir'], + ['IS', 'IS-05', 'Norðurland vestra'], + ['IS', 'IS-06', 'Norðurland eystra'], + ['IS', 'IS-07', 'Austurland'], + ['IS', 'IS-08', 'Suðurland'] + ]; + } + + /** + * @inheritdoc + */ + public static function getDependencies() + { + return [ + InitializeDirectoryData::class, + ]; + } + + /** + * @inheritdoc + */ + public function getAliases() + { + return []; + } +} diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForPortugal.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForPortugal.php new file mode 100644 index 0000000000000..9daeb1cf5bf1e --- /dev/null +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForPortugal.php @@ -0,0 +1,107 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Directory\Setup\Patch\Data; + +use Magento\Directory\Setup\DataInstaller; +use Magento\Directory\Setup\DataInstallerFactory; +use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Framework\Setup\Patch\DataPatchInterface; + +/** + * Add Portugal States + */ +class AddDataForPortugal implements DataPatchInterface +{ + /** + * @var ModuleDataSetupInterface + */ + private $moduleDataSetup; + + /** + * @var DataInstallerFactory + */ + private $dataInstallerFactory; + + /** + * AddDataForPortugal constructor. + * + * @param ModuleDataSetupInterface $moduleDataSetup + * @param DataInstallerFactory $dataInstallerFactory + */ + public function __construct( + ModuleDataSetupInterface $moduleDataSetup, + DataInstallerFactory $dataInstallerFactory + ) { + $this->moduleDataSetup = $moduleDataSetup; + $this->dataInstallerFactory = $dataInstallerFactory; + } + + /** + * @inheritdoc + */ + public function apply() + { + /** @var DataInstaller $dataInstaller */ + $dataInstaller = $this->dataInstallerFactory->create(); + $dataInstaller->addCountryRegions( + $this->moduleDataSetup->getConnection(), + $this->getDataForPortugal() + ); + + return $this; + } + + /** + * Portugal states data. + * + * @return array + */ + private function getDataForPortugal() + { + return [ + ['PT', 'PT-01', 'Aveiro'], + ['PT', 'PT-02', 'Beja'], + ['PT', 'PT-03', 'Braga'], + ['PT', 'PT-04', 'Bragança'], + ['PT', 'PT-05', 'Castelo Branco'], + ['PT', 'PT-06', 'Coimbra'], + ['PT', 'PT-07', 'Évora'], + ['PT', 'PT-08', 'Faro'], + ['PT', 'PT-09', 'Guarda'], + ['PT', 'PT-10', 'Leiria'], + ['PT', 'PT-11', 'Lisboa'], + ['PT', 'PT-12', 'Portalegre'], + ['PT', 'PT-13', 'Porto'], + ['PT', 'PT-14', 'Santarém'], + ['PT', 'PT-15', 'Setúbal'], + ['PT', 'PT-16', 'Viana do Castelo'], + ['PT', 'PT-17', 'Vila Real'], + ['PT', 'PT-18', 'Viseu'], + ['PT', 'PT-19', 'Região Autónoma dos Açores'], + ['PT', 'PT-20', 'Região Autónoma da Madeira'] + ]; + } + + /** + * @inheritdoc + */ + public static function getDependencies() + { + return [ + InitializeDirectoryData::class, + ]; + } + + /** + * @inheritdoc + */ + public function getAliases() + { + return []; + } +} diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForSweden.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForSweden.php new file mode 100644 index 0000000000000..b4bed72a726bd --- /dev/null +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForSweden.php @@ -0,0 +1,108 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Directory\Setup\Patch\Data; + +use Magento\Directory\Setup\DataInstaller; +use Magento\Directory\Setup\DataInstallerFactory; +use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Framework\Setup\Patch\DataPatchInterface; + +/** + * Add Sweden States + */ +class AddDataForSweden implements DataPatchInterface +{ + /** + * @var ModuleDataSetupInterface + */ + private $moduleDataSetup; + + /** + * @var DataInstallerFactory + */ + private $dataInstallerFactory; + + /** + * AddDataForSweden constructor. + * + * @param ModuleDataSetupInterface $moduleDataSetup + * @param DataInstallerFactory $dataInstallerFactory + */ + public function __construct( + ModuleDataSetupInterface $moduleDataSetup, + DataInstallerFactory $dataInstallerFactory + ) { + $this->moduleDataSetup = $moduleDataSetup; + $this->dataInstallerFactory = $dataInstallerFactory; + } + + /** + * @inheritdoc + */ + public function apply() + { + /** @var DataInstaller $dataInstaller */ + $dataInstaller = $this->dataInstallerFactory->create(); + $dataInstaller->addCountryRegions( + $this->moduleDataSetup->getConnection(), + $this->getDataForSweden() + ); + + return $this; + } + + /** + * Swedish states data. + * + * @return array + */ + private function getDataForSweden() + { + return [ + ['SE', 'SE-K', 'Blekinge län'], + ['SE', 'SE-W', 'Dalarnas län'], + ['SE', 'SE-I', 'Gotlands län'], + ['SE', 'SE-X', 'Gävleborgs län'], + ['SE', 'SE-N', 'Hallands län'], + ['SE', 'SE-Z', 'Jämtlands län'], + ['SE', 'SE-F', 'Jönköpings län'], + ['SE', 'SE-H', 'Kalmar län'], + ['SE', 'SE-G', 'Kronobergs län'], + ['SE', 'SE-BD', 'Norrbottens län'], + ['SE', 'SE-M', 'Skåne län'], + ['SE', 'SE-AB', 'Stockholms län'], + ['SE', 'SE-D', 'Södermanlands län'], + ['SE', 'SE-C', 'Uppsala län'], + ['SE', 'SE-S', 'Värmlands län'], + ['SE', 'SE-AC', 'Västerbottens län'], + ['SE', 'SE-Y', 'Västernorrlands län'], + ['SE', 'SE-U', 'Västmanlands län'], + ['SE', 'SE-O', 'Västra Götalands län'], + ['SE', 'SE-T', 'Örebro län'], + ['SE', 'SE-E', 'Östergötlands län'] + ]; + } + + /** + * @inheritdoc + */ + public static function getDependencies() + { + return [ + InitializeDirectoryData::class, + ]; + } + + /** + * @inheritdoc + */ + public function getAliases() + { + return []; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Directory/Model/RegionTest.php b/dev/tests/integration/testsuite/Magento/Directory/Model/RegionTest.php index 774690617d861..44c8377f1eaf7 100644 --- a/dev/tests/integration/testsuite/Magento/Directory/Model/RegionTest.php +++ b/dev/tests/integration/testsuite/Magento/Directory/Model/RegionTest.php @@ -57,7 +57,13 @@ public function getCountryIdDataProvider():array ['countryId' => 'MX'], ['countryId' => 'PL'], ['countryId' => 'IT'], - ['countryId' => 'BG'] + ['countryId' => 'BG'], + ['countryId' => 'PT'], + ['countryId' => 'IS'], + ['countryId' => 'SE'], + ['countryId' => 'GR'], + ['countryId' => 'DK'], + ['countryId' => 'AL'] ]; } } From e38122ae332af8b324a14d1f93de979023a126e8 Mon Sep 17 00:00:00 2001 From: "vadim.malesh" <engcom-vendorworker-charlie@adobe.com> Date: Wed, 18 Nov 2020 13:44:15 +0200 Subject: [PATCH 019/156] fix i18n --- app/code/Magento/Sales/i18n/en_US.csv | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Sales/i18n/en_US.csv b/app/code/Magento/Sales/i18n/en_US.csv index dea0b76437ca7..c429a10411af4 100644 --- a/app/code/Magento/Sales/i18n/en_US.csv +++ b/app/code/Magento/Sales/i18n/en_US.csv @@ -284,8 +284,8 @@ Go to Home Page,Go to Home Page We can't find this wish list.,We can't find this wish list. "We could not add a product to cart by the ID ""%1"".","We could not add a product to cart by the ID ""%1""." There is an error in one of the option rows.,There is an error in one of the option rows. -Shipping Address: ,Shipping Address: -Billing Address: ,Billing Address: +"Shipping Address: ","Shipping Address: " +"Billing Address: ","Billing Address: " Please specify order items.,Please specify order items. Please specify a shipping method.,Please specify a shipping method. Please specify a payment method.,Please specify a payment method. @@ -383,8 +383,8 @@ Authorization,Authorization Please set a proper payment and order id.,Please set a proper payment and order id. Please enter a Transaction ID.,Please enter a Transaction ID. You can't do this without a transaction object.,You can't do this without a transaction object. -Order # ,Order # -Order Date: ,Order Date: +"Order # ","Order # " +"Order Date: ","Order Date: " Sold to:,Sold to: Ship to:,Ship to: Payment Method:,Payment Method: @@ -400,8 +400,8 @@ Total (ex),Total (ex) Qty,Qty Tax,Tax Total (inc),Total (inc) -Credit Memo # ,Credit Memo # -Invoice # ,Invoice # +"Credit Memo # ","Credit Memo # " +"Invoice # ","Invoice # " The order object is not specified.,The order object is not specified. The source object is not specified.,The source object is not specified. An item object is not specified.,An item object is not specified. @@ -409,7 +409,7 @@ A PDF object is not specified.,A PDF object is not specified. A PDF page object is not specified.,A PDF page object is not specified. Excl. Tax,Excl. Tax Incl. Tax,Incl. Tax -Packing Slip # ,Packing Slip # +"Packing Slip # ","Packing Slip # " title,title The PDF total model %1 must be or extend \Magento\Sales\Model\Order\Pdf\Total\DefaultTotal.,The PDF total model %1 must be or extend \Magento\Sales\Model\Order\Pdf\Total\DefaultTotal. We cannot register an existing shipment,We cannot register an existing shipment @@ -669,7 +669,7 @@ Your %store_name order has shipped,Your %store_name order has shipped Your shipping confirmation is below. Thank you again for your business.,Your shipping confirmation is below. Thank you again for your business. Your Shipment #%shipment_id for Order #%order_id,Your Shipment #%shipment_id for Order #%order_id Update to your %store_name shipment,Update to your %store_name shipment -Gift Options for ,Gift Options for +"Gift Options for ","Gift Options for " Add Products,Add Products You have item changes,You have item changes Ok,Ok From 1089f15b276cbbe30c2279349a934716148321be Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Thu, 19 Nov 2020 19:08:10 +0200 Subject: [PATCH 020/156] restoring stepKeys --- .../AddOutOfStockProductToCompareListTest.xml | 60 ++++++++++++++----- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml index b2fbf2ae3810a..c28c5a040e553 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml @@ -38,15 +38,21 @@ <deleteData createDataKey="product" stepKey="deleteProduct"/> <deleteData createDataKey="category" stepKey="deleteCategory"/> </after> + <comment userInput="Open product page | Comment is kept to preserve the step key for backward compatibility" stepKey="openProdPage"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="goToSimpleProductPage"/> - <actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="openProductStorefront"> + <actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="waitForSimpleProductPage"> <argument name="productUrl" value="$$product.custom_attributes[url_key]$$"/> </actionGroup> - + + <comment userInput="'Add to compare' link is not available | Comment is kept to preserve the step key for backward compatibility" stepKey="addToCompareLinkAvailability"/> + <dontSeeElement selector="{{StorefrontProductInfoMainSection.productAddToCompare}}" stepKey="dontSeeAddToCompareLink"/> + <comment userInput="Turn on 'out of stock' config | Comment is kept to preserve the step key for backward compatibility" stepKey="onOutOfStockConfig"/> <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockEnable.path}} {{CatalogInventoryOptionsShowOutOfStockEnable.value}}" stepKey="setConfigShowOutOfStockTrue"/> + <comment userInput="Clear cache and reindex | Comment is kept to preserve the step key for backward compatibility" stepKey="cleanCache"/> <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> <argument name="indices" value=""/> </actionGroup> @@ -54,41 +60,67 @@ <argument name="tags" value=""/> </actionGroup> - <actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="openProductStorefront1"> + <comment userInput="Open product page | Comment is kept to preserve the step key for backward compatibility" stepKey="openProductPage"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="goToSimpleProductPage2"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForSimpleProductPage2"/> + <actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="seeAddToCompareLink"> <argument name="productUrl" value="$$product.custom_attributes[url_key]$$"/> </actionGroup> + + <comment userInput="Click on 'Add to Compare' link | Comment is kept to preserve the step key for backward compatibility" stepKey="clickOnAddToCompareLink"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickOnAddToCompare"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForProdAddToCmpList"/> + <comment userInput="Assert success message | Comment is kept to preserve the step key for backward compatibility" stepKey="assertSuccessMsg"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="grabTextFromSuccessMessage"/> - <actionGroup ref="StorefrontAddProductToCompareActionGroup" stepKey="addProductToCompare1"> + <actionGroup ref="StorefrontAddProductToCompareActionGroup" stepKey="assertSuccessMessage"> <argument name="productVar" value="$$product$$"/> </actionGroup> - <actionGroup ref="StorefrontGoToCategoryPageActionGroup" stepKey="openCategoryPage"> + <comment userInput="See product in the comparison list | Comment is kept to preserve the step key for backward compatibility" stepKey="seeProductInComparisonList"/> + + <actionGroup ref="StorefrontGoToCategoryPageActionGroup" stepKey="openCategoryPage"> <argument name="categoryName" value="$$category.name$$"/> </actionGroup> - <actionGroup ref="StorefrontOpenAndCheckComparisionActionGroup" stepKey="compareOpenComparePage"/> + <actionGroup ref="StorefrontOpenAndCheckComparisionActionGroup" stepKey="navigateToComparePage"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForStorefrontProductComparePageLoad"/> - <actionGroup ref="SeeProductInComparisonListActionGroup" stepKey="seeProductInComparisonList"> + <actionGroup ref="SeeProductInComparisonListActionGroup" stepKey="seeProductInCompareList"> <argument name="productVar" value="$$product$$"/> </actionGroup> - <actionGroup ref="StorefrontGoToCategoryPageActionGroup" stepKey="openCategoryPage1"> + + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="deleteProdFromCmpList"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="onCategoryPage"/> + <actionGroup ref="StorefrontGoToCategoryPageActionGroup" stepKey="waitForPageLoad1"> <argument name="categoryName" value="$$category.name$$"/> </actionGroup> - <actionGroup ref="StorefrontClearCompareActionGroup" stepKey="clearList"/> + <actionGroup ref="StorefrontClearCompareActionGroup" stepKey="clickClearAll"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForConfirmPageLoad"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="confirmProdDelate"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForConfirmLoad"/> + <comment userInput="Add product to compare list fom Category page | Comment is kept to preserve the step key for backward compatibility" stepKey="addToCmpFromCategPage"/> - <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverOverProduct"/> - <actionGroup ref="StorefrontAddProductToCompareActionGroup" stepKey="addProductToCompare2"> + <actionGroup ref="StorefrontAddProductToCompareActionGroup" stepKey="clickAddToCompare"> <argument name="productVar" value="$$product$$"/> </actionGroup> - + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitProdAddingToCmpList"/> + <comment userInput="Assert success message | Comment is kept to preserve the step key for backward compatibility" stepKey="assertSuccessMsg2"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="grabTextFromSuccessMessage2"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="assertSuccessMessage2"/> + + <comment userInput="Check that product displays on add to compare widget | Comment is kept to preserve the step key for backward compatibility" stepKey="checkProdNameOnWidget"/> <seeElement selector="{{StorefrontComparisonSidebarSection.ProductTitleByName($$product.name$$)}}" stepKey="seeProdNameOnCmpWidget"/> - <actionGroup ref="StorefrontOpenAndCheckComparisionActionGroup" stepKey="compareOpenComparePage1"/> + <comment userInput="See product in the compare page" stepKey="seeProductInComparePage"/> + <actionGroup ref="StorefrontOpenAndCheckComparisionActionGroup" stepKey="navigateToComparePage2"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForStorefrontProductComparePageLoad2"/> - <actionGroup ref="SeeProductInComparisonListActionGroup" stepKey="seeProductInComparisonList1"> + <actionGroup ref="SeeProductInComparisonListActionGroup" stepKey="seeProductInCompareList2"> <argument name="productVar" value="$$product$$"/> </actionGroup> From 6e5d886359a298de1f8ee43c067ac3be6b6e5c6d Mon Sep 17 00:00:00 2001 From: Andrii Kasian <akasian@magento.com> Date: Thu, 19 Nov 2020 13:13:27 -0600 Subject: [PATCH 021/156] Allow to generate big number of customer on galera cluster --- .../FixtureGenerator/CustomerGenerator.php | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/setup/src/Magento/Setup/Model/FixtureGenerator/CustomerGenerator.php b/setup/src/Magento/Setup/Model/FixtureGenerator/CustomerGenerator.php index e2b11c3dc7eb3..f20060e15c2b1 100644 --- a/setup/src/Magento/Setup/Model/FixtureGenerator/CustomerGenerator.php +++ b/setup/src/Magento/Setup/Model/FixtureGenerator/CustomerGenerator.php @@ -124,24 +124,31 @@ private function getCustomerAddressEntityHandler() */ private function addDefaultAddresses() { - $this->getConnection()->query( - sprintf( - ' - update `%s` customer - join ( - select - parent_id, min(entity_id) as min, max(entity_id) as max - from `%s` - group by parent_id - ) customer_address on customer_address.parent_id = customer.entity_id + $batchSize = 10000; + $customerTableName = $this->resourceConnection->getTableName('customer_entity'); + $customerAddressTableName = $this->resourceConnection->getTableName('customer_address_entity'); + $customerMaxId = $this->getConnection()->fetchOne("select max(entity_id) from `$customerTableName`"); + for ($i = 1; $i < $customerMaxId; $i += $batchSize) { + $this->getConnection()->query( + " + update `$customerTableName` customer + join ( + select + parent_id, min(entity_id) as min, max(entity_id) as max + from `$customerAddressTableName` + group by parent_id + ) customer_address on customer_address.parent_id = customer.entity_id set customer.default_billing = customer_address.min, customer.default_shipping = customer_address.max - ', - $this->resourceConnection->getTableName('customer_entity'), - $this->resourceConnection->getTableName('customer_address_entity') - ) - ); + where entity_id between :min and :max + ", + [ + 'min' => $i, + 'max' => $i + $batchSize + ] + ); + } } /** From 876e37b6c907e542ecab093b5f67ca02c201d5cc Mon Sep 17 00:00:00 2001 From: Nikola Lardev <nikolalardev@gmail.com> Date: Sat, 21 Nov 2020 22:05:38 +0200 Subject: [PATCH 022/156] #30959 Add one more region for Greece and fix two Portugal states numbers --- .../Magento/Directory/Setup/Patch/Data/AddDataForGreece.php | 1 + .../Magento/Directory/Setup/Patch/Data/AddDataForPortugal.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForGreece.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForGreece.php index a756035f1af4e..122a2b2bbc195 100644 --- a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForGreece.php +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForGreece.php @@ -77,6 +77,7 @@ private function getDataForGreece() ['GR', 'GR-H', 'Stereá Elláda'], ['GR', 'GR-E', 'Thessalía'], ['GR', 'GR-K', 'Vóreio Aigaío'], + ['GR', 'GR-69', 'Ágion Óros'] ]; } diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForPortugal.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForPortugal.php index 9daeb1cf5bf1e..2960d431f123a 100644 --- a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForPortugal.php +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForPortugal.php @@ -82,8 +82,8 @@ private function getDataForPortugal() ['PT', 'PT-16', 'Viana do Castelo'], ['PT', 'PT-17', 'Vila Real'], ['PT', 'PT-18', 'Viseu'], - ['PT', 'PT-19', 'Região Autónoma dos Açores'], - ['PT', 'PT-20', 'Região Autónoma da Madeira'] + ['PT', 'PT-20', 'Região Autónoma dos Açores'], + ['PT', 'PT-30', 'Região Autónoma da Madeira'] ]; } From d157d42ebef3a903b39c3a8e224ab0646b91061d Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Mon, 23 Nov 2020 10:41:42 +0200 Subject: [PATCH 023/156] AdminCreateInvoiceTest deprecated --- .../Test/Mftf/Test/AdminCreateInvoiceTest.xml | 96 ++++++++++++------- .../Test/Mftf/Test/AdminInvoiceOrderTest.xml | 65 +++++++++++++ 2 files changed, 127 insertions(+), 34 deletions(-) create mode 100644 app/code/Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index 49ae1844a1cf1..3e8fd1e42c12b 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -12,54 +12,82 @@ <annotations> <features value="Sales"/> <stories value="Create an Invoice via the Admin"/> - <title value="Admin should be able to create an invoice"/> + <title value="DEPRECATED. Admin should be able to create an invoice"/> <description value="Admin should be able to create an invoice"/> <severity value="MAJOR"/> <testCaseId value="MAGETWO-72096"/> <group value="sales"/> + <skip> + <issueID value="DEPRECATED">Use AdminInvoiceOrderTest instead</issueID> + </skip> </annotations> - - <before> + <before> <createData entity="_defaultCategory" stepKey="createCategory"/> - <createData entity="_defaultProduct" stepKey="createSimpleProductApi"> + <createData entity="_defaultProduct" stepKey="createProduct"> <requiredEntity createDataKey="createCategory"/> </createData> - <createData entity="GuestCart" stepKey="createGuestCart"/> - <createData entity="SimpleCartItem" stepKey="addCartItem"> - <requiredEntity createDataKey="createGuestCart"/> - <requiredEntity createDataKey="createSimpleProductApi"/> - </createData> - <createData entity="GuestAddressInformation" stepKey="addGuestOrderAddress"> - <requiredEntity createDataKey="createGuestCart"/> - </createData> - <updateData createDataKey="createGuestCart" entity="GuestOrderPaymentMethod" stepKey="sendGuestPaymentInformation"> - <requiredEntity createDataKey="createGuestCart"/> - </updateData> </before> - <after> - <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <deleteData createDataKey="createSimpleProductApi" stepKey="deleteSimpleProductApi"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="adminLogout"/> + <deleteData createDataKey="createCategory" stepKey="deleteProduct1"/> + <deleteData createDataKey="createProduct" stepKey="deleteCategory1"/> </after> - <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin1"/> - - <actionGroup ref="AdminOpenOrderByEntityIdActionGroup" stepKey="openOrder"> - <argument name="entity_id" value="$createGuestCart.return$"/> - </actionGroup> - - <actionGroup ref="AdminCreateInvoiceActionGroup" stepKey="createInvoice"/> + <!-- todo: Create an order via the api instead of driving the browser --> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> + <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addToCart"/> + <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickCart"/> + <click selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="goToCheckout"/> + <waitForPageLoad stepKey="waitForPageLoad2"/> + <fillField selector="{{CheckoutShippingGuestInfoSection.email}}" userInput="{{CustomerEntityOne.email}}" stepKey="enterEmail"/> + <fillField selector="{{CheckoutShippingGuestInfoSection.firstName}}" userInput="{{CustomerEntityOne.firstname}}" stepKey="enterFirstName"/> + <fillField selector="{{CheckoutShippingGuestInfoSection.lastName}}" userInput="{{CustomerEntityOne.lastname}}" stepKey="enterLastName"/> + <fillField selector="{{CheckoutShippingGuestInfoSection.street}}" userInput="{{CustomerAddressSimple.street[0]}}" stepKey="enterStreet"/> + <fillField selector="{{CheckoutShippingGuestInfoSection.city}}" userInput="{{CustomerAddressSimple.city}}" stepKey="enterCity"/> + <selectOption selector="{{CheckoutShippingGuestInfoSection.region}}" userInput="{{CustomerAddressSimple.state}}" stepKey="selectRegion"/> + <fillField selector="{{CheckoutShippingGuestInfoSection.postcode}}" userInput="{{CustomerAddressSimple.postcode}}" stepKey="enterPostcode"/> + <fillField selector="{{CheckoutShippingGuestInfoSection.telephone}}" userInput="{{CustomerAddressSimple.telephone}}" stepKey="enterTelephone"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <click selector="{{CheckoutShippingMethodsSection.firstShippingMethod}}" stepKey="selectFirstShippingMethod"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask2"/> + <actionGroup ref="StorefrontCheckoutClickNextButtonActionGroup" stepKey="clickNext"/> + <!-- Checkout select Check/Money Order payment --> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectCheckMoneyPayment"/> + <waitForElement selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton"/> + <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber}}" stepKey="grabOrderNumber"/> + <!-- end todo --> - <actionGroup ref="FilterInvoiceGridByOrderIdWithCleanFiltersActionGroup" stepKey="filterInvoiceGridByOrderId"> - <argument name="orderId" value="$createGuestCart.return$"/> - </actionGroup> - - <actionGroup ref="AdminSelectFirstGridRowActionGroup" stepKey="openInvoiceFromGrid"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin1"/> - <actionGroup ref="AdminOrderViewCheckStatusActionGroup" stepKey="checkIfOrderStatusIsProcessing"> - <argument name="status" value="Processing"/> - </actionGroup> + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask3"/> + <actionGroup ref="ClearFiltersAdminDataGridActionGroup" stepKey="clearGridFilter"/> + <fillField selector="{{AdminOrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="searchOrderNum"/> + <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearch"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> + <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> + <actionGroup ref="AdminClickInvoiceButtonOrderViewActionGroup" stepKey="clickInvoice"/> + <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeSuccessMessage"/> + <click selector="{{AdminOrderDetailsOrderViewSection.invoices}}" stepKey="clickInvoices"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask5" /> + <see selector="{{AdminOrderDetailsInvoicesSection.content}}" userInput="{$grabOrderNumber}" stepKey="seeInvoice1"/> + <see selector="{{AdminOrderDetailsInvoicesSection.content}}" userInput="John Doe" stepKey="seeInvoice2"/> + <click selector="{{AdminOrderDetailsOrderViewSection.information}}" stepKey="clickInformation"/> + <waitForLoadingMaskToDisappear stepKey="waitForOrderInformationTabLoadingMask"/> + <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Processing" stepKey="seeOrderStatus"/> + <amOnPage url="{{AdminInvoicesPage.url}}" stepKey="goToInvoices"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask6" /> + <actionGroup ref="ResetProductGridToDefaultViewActionGroup" stepKey="resetGridInitial"/> + <click selector="{{AdminInvoicesGridSection.filter}}" stepKey="clickFilters"/> + <fillField selector="{{AdminInvoicesFiltersSection.orderNum}}" userInput="{$grabOrderNumber}" stepKey="searchOrderNum2"/> + <click selector="{{AdminInvoicesFiltersSection.applyFilters}}" stepKey="clickApplyFilters"/> + <click selector="{{AdminInvoicesGridSection.firstRow}}" stepKey="clickInvoice2"/> + <see selector="{{AdminInvoiceDetailsInformationSection.orderStatus}}" userInput="Processing" stepKey="seeOrderStatus2"/> </test> -</tests> +</tests> \ No newline at end of file diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml new file mode 100644 index 0000000000000..14fe9c1ece95b --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml @@ -0,0 +1,65 @@ +<?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="AdminInvoiceOrderTest"> + <annotations> + <features value="Sales"/> + <stories value="Create an Invoice via the Admin"/> + <title value="Admin should be able to create an invoice"/> + <description value="Admin should be able to create an invoice"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-72096"/> + <group value="sales"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createSimpleProductApi"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="GuestCart" stepKey="createGuestCart"/> + <createData entity="SimpleCartItem" stepKey="addCartItem"> + <requiredEntity createDataKey="createGuestCart"/> + <requiredEntity createDataKey="createSimpleProductApi"/> + </createData> + <createData entity="GuestAddressInformation" stepKey="addGuestOrderAddress"> + <requiredEntity createDataKey="createGuestCart"/> + </createData> + <updateData createDataKey="createGuestCart" entity="GuestOrderPaymentMethod" stepKey="sendGuestPaymentInformation"> + <requiredEntity createDataKey="createGuestCart"/> + </updateData> + </before> + + <after> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createSimpleProductApi" stepKey="deleteSimpleProductApi"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="adminLogout"/> + </after> + + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin1"/> + + <actionGroup ref="AdminOpenOrderByEntityIdActionGroup" stepKey="openOrder"> + <argument name="entity_id" value="$createGuestCart.return$"/> + </actionGroup> + + <actionGroup ref="AdminCreateInvoiceActionGroup" stepKey="createInvoice"/> + + <actionGroup ref="FilterInvoiceGridByOrderIdWithCleanFiltersActionGroup" stepKey="filterInvoiceGridByOrderId"> + <argument name="orderId" value="$createGuestCart.return$"/> + </actionGroup> + + <actionGroup ref="AdminSelectFirstGridRowActionGroup" stepKey="openInvoiceFromGrid"/> + + <actionGroup ref="AdminOrderViewCheckStatusActionGroup" stepKey="checkIfOrderStatusIsProcessing"> + <argument name="status" value="Processing"/> + </actionGroup> + + </test> +</tests> From b23cad2a6a4741d85471c856d2aa8c07e44ba0f6 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Mon, 23 Nov 2020 10:48:15 +0200 Subject: [PATCH 024/156] refactored --- .../Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml | 2 +- app/code/Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index 3e8fd1e42c12b..1916fb9ebdbbb 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -18,7 +18,7 @@ <testCaseId value="MAGETWO-72096"/> <group value="sales"/> <skip> - <issueID value="DEPRECATED">Use AdminInvoiceOrderTest instead</issueID> + <issueId value="DEPRECATED">Use AdminInvoiceOrderTest instead</issueId> </skip> </annotations> <before> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml index 14fe9c1ece95b..3b28fd10d58b9 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml @@ -46,7 +46,7 @@ <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin1"/> <actionGroup ref="AdminOpenOrderByEntityIdActionGroup" stepKey="openOrder"> - <argument name="entity_id" value="$createGuestCart.return$"/> + <argument name="entityId" value="$createGuestCart.return$"/> </actionGroup> <actionGroup ref="AdminCreateInvoiceActionGroup" stepKey="createInvoice"/> From 2d8be9cd0387dc81d2086e9f5f766efc2cd1d813 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Mon, 23 Nov 2020 11:26:49 +0200 Subject: [PATCH 025/156] refactored --- .../Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml index 3b28fd10d58b9..922037fe4a3cd 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminInvoiceOrderTest.xml @@ -35,6 +35,9 @@ <updateData createDataKey="createGuestCart" entity="GuestOrderPaymentMethod" stepKey="sendGuestPaymentInformation"> <requiredEntity createDataKey="createGuestCart"/> </updateData> + + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + </before> <after> @@ -42,8 +45,6 @@ <deleteData createDataKey="createSimpleProductApi" stepKey="deleteSimpleProductApi"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="adminLogout"/> </after> - - <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin1"/> <actionGroup ref="AdminOpenOrderByEntityIdActionGroup" stepKey="openOrder"> <argument name="entityId" value="$createGuestCart.return$"/> From 97e34547ec7acfadffec4951d4dadd9cae3531f5 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Mon, 23 Nov 2020 21:14:35 +0200 Subject: [PATCH 026/156] Refactored AdminMassProductPriceUpdateTest --- ...inCheckProductOnProductGridActionGroup.xml | 22 +++++++++ .../AdminSetPriceForMassUpdateActionGroup.xml | 24 ++++++++++ .../Test/AdminMassProductPriceUpdateTest.xml | 48 ++++++++++++++----- 3 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSetPriceForMassUpdateActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml new file mode 100644 index 0000000000000..34c9c1edf50cb --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.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="AdminCheckProductOnProductGridActionGroup"> + <annotations> + <description>Check the product on the Product Grid</description> + </annotations> + <arguments> + <argument name="product" type="entity"/> + </arguments> + + <checkOption selector="{{AdminProductGridSection.productRowCheckboxBySku(product.sku)}}" stepKey="selectProduct"/> + + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSetPriceForMassUpdateActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSetPriceForMassUpdateActionGroup.xml new file mode 100644 index 0000000000000..b00f181c92360 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSetPriceForMassUpdateActionGroup.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="AdminSetPriceForMassUpdateActionGroup"> + <annotations> + <description>Click the "Change" checkbox for the "Price" field. Set new price.</description> + </annotations> + <arguments> + <argument name="price" type="string"/> + </arguments> + + <scrollTo stepKey="scrollToPriceCheckBox" selector="{{AdminEditProductAttributesSection.ChangeAttributePriceToggle}}" x="0" y="-160"/> + <click selector="{{AdminEditProductAttributesSection.ChangeAttributePriceToggle}}" stepKey="selectPriceCheckBox"/> + <fillField stepKey="fillPrice" selector="{{AdminEditProductAttributesSection.AttributePrice}}" userInput="{{price}}"/> + + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml index 070c07d9feb7d..b3cf6e357fd6a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml @@ -41,19 +41,27 @@ <actionGroup ref="SortProductsByIdDescendingActionGroup" stepKey="sortProductsByIdDescending"/> <!--Select products--> - <checkOption selector="{{AdminProductGridSection.productRowCheckboxBySku($$simpleProduct1.sku$$)}}" stepKey="selectFirstProduct"/> - <checkOption selector="{{AdminProductGridSection.productRowCheckboxBySku($$simpleProduct2.sku$$)}}" stepKey="selectSecondProduct"/> + <actionGroup ref="AdminCheckProductOnProductGridActionGroup" stepKey="selectFirstProduct"> + <argument name="product" value="$simpleProduct1$"/> + </actionGroup> + <actionGroup ref="AdminCheckProductOnProductGridActionGroup" stepKey="selectSecondProduct"> + <argument name="product" value="$simpleProduct2$"/> + </actionGroup> <!-- Update product price--> - <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickDropdown"/> - <click selector="{{AdminProductGridSection.bulkActionOption('Update attributes')}}" stepKey="clickChangeStatus"/> - <waitForPageLoad stepKey="waitForProductAttributePageToLoad"/> - <scrollTo stepKey="scrollToPriceCheckBox" selector="{{AdminEditProductAttributesSection.ChangeAttributePriceToggle}}" x="0" y="-160"/> - <click selector="{{AdminEditProductAttributesSection.ChangeAttributePriceToggle}}" stepKey="selectPriceCheckBox"/> - <fillField stepKey="fillPrice" selector="{{AdminEditProductAttributesSection.AttributePrice}}" userInput="90.99"/> - <click stepKey="clickOnSaveButton" selector="{{AdminEditProductAttributesSection.Save}}"/> - <waitForPageLoad stepKey="waitForUpdatedProductToSave" /> - <see selector="{{AdminProductMessagesSection.successMessage}}" userInput="Message is added to queue" stepKey="seeAttributeUpateSuccessMsg"/> + <actionGroup ref="AdminClickMassUpdateProductAttributesActionGroup" stepKey="clickDropdown"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickChangeStatus"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForProductAttributePageToLoad"/> + + <actionGroup ref="AdminSetPriceForMassUpdateActionGroup" stepKey="scrollToPriceCheckBox"> + <argument name="price" value="90.99"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectPriceCheckBox"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="fillPrice"/> + + <actionGroup ref="AdminSaveProductsMassAttributesUpdateActionGroup" stepKey="clickOnSaveButton"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForUpdatedProductToSave"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeAttributeUpateSuccessMsg"/> <!-- Start message queue --> <actionGroup ref="CliConsumerStartActionGroup" stepKey="startMessageQueueConsumer"> @@ -64,7 +72,21 @@ <magentoCLI command="cron:run --group=index" stepKey="runCron"/> <!--Verify product name, sku and updated price--> - <click stepKey="openFirstProduct" selector="{{AdminProductGridSection.productRowBySku($$simpleProduct1.sku$$)}}"/> + <!-- <actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="goToFirstProductEditPage"> + <argument name="productId" value="$$simpleProduct1.id$$"/> + </actionGroup> --> + <actionGroup ref="AssertProductInfoOnEditPageActionGroup" stepKey="waitForFirstProductToLoad"> + <argument name="product" value="$$simpleProduct1$$"/> + </actionGroup> + + <!-- <actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="goToSecondProductEditPage"> + <argument name="productId" value="$$simpleProduct2.id$$"/> + </actionGroup> --> + <actionGroup ref="AssertProductInfoOnEditPageActionGroup" stepKey="waitForSecondProductToLoad"> + <argument name="product" value="$$simpleProduct2$$"/> + </actionGroup> + + <!-- <click stepKey="openFirstProduct" selector="{{AdminProductGridSection.productRowBySku($$simpleProduct1.sku$$)}}"/> <waitForPageLoad stepKey="waitForFirstProductToLoad"/> <seeInField stepKey="seeFirstProductNameInField" selector="{{AdminProductFormSection.productName}}" userInput="$$simpleProduct1.name$$"/> <seeInField stepKey="seeFirstProductSkuInField" selector="{{AdminProductFormSection.productSku}}" userInput="$$simpleProduct1.sku$$"/> @@ -75,6 +97,6 @@ <waitForPageLoad stepKey="waitForSecondProductToLoad"/> <seeInField stepKey="seeSecondProductNameInField" selector="{{AdminProductFormSection.productName}}" userInput="$$simpleProduct2.name$$"/> <seeInField stepKey="seeSecondProductSkuInField" selector="{{AdminProductFormSection.productSku}}" userInput="$$simpleProduct2.sku$$"/> - <seeInField stepKey="seeSecondProductPriceInField" selector="{{AdminProductFormSection.productPrice}}" userInput="90.99"/> + <seeInField stepKey="seeSecondProductPriceInField" selector="{{AdminProductFormSection.productPrice}}" userInput="90.99"/> --> </test> </tests> From 131cd1aae2a397e81457c0daf3962db39d5c0072 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Wed, 25 Nov 2020 17:06:44 +0200 Subject: [PATCH 027/156] Refactored AdminMassProductPriceUpdateTest --- ...oductPriceUpdatedOnEditPageActionGroup.xml | 25 +++++++++ .../Test/AdminMassProductPriceUpdateTest.xml | 54 +++++++------------ 2 files changed, 45 insertions(+), 34 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminProductPriceUpdatedOnEditPageActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminProductPriceUpdatedOnEditPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminProductPriceUpdatedOnEditPageActionGroup.xml new file mode 100644 index 0000000000000..c7a665119b328 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminProductPriceUpdatedOnEditPageActionGroup.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"> + <actionGroup name="AssertAdminProductPriceUpdatedOnEditPageActionGroup" extends="OpenEditProductOnBackendActionGroup"> + <annotations> + <description>Validate if Product price is updated on the Product creation/edit page</description> + </annotations> + <arguments> + <argument name="product" type="entity"/> + <argument name="price" type="string"/> + </arguments> + + <waitForPageLoad stepKey="waitForProductToLoad"/> + <seeInField selector="{{AdminProductFormSection.productName}}" userInput="{{product.name}}" stepKey="seeProductName"/> + <seeInField selector="{{AdminProductFormSection.productSku}}" userInput="{{product.sku}}" stepKey="seeProductSku"/> + <seeInField selector="{{AdminProductFormSection.productPrice}}" userInput="{{price}}" stepKey="seeProductPrice"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml index b3cf6e357fd6a..42719e2d6aa12 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml @@ -25,22 +25,16 @@ </before> <after> <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> - <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> - <!--Open Product Index Page--> <actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="navigateToProductIndex"/> - <!--Search products using keyword --> - <actionGroup ref="SearchProductGridByKeyword2ActionGroup" stepKey="searchByKeyword"> - <argument name="keyword" value="Testp"/> - </actionGroup> + <actionGroup ref="ClearFiltersAdminProductGridActionGroup" stepKey="searchByKeyword"/> - <!--Sort Products by ID in descending order--> <actionGroup ref="SortProductsByIdDescendingActionGroup" stepKey="sortProductsByIdDescending"/> - <!--Select products--> <actionGroup ref="AdminCheckProductOnProductGridActionGroup" stepKey="selectFirstProduct"> <argument name="product" value="$simpleProduct1$"/> </actionGroup> @@ -48,7 +42,6 @@ <argument name="product" value="$simpleProduct2$"/> </actionGroup> - <!-- Update product price--> <actionGroup ref="AdminClickMassUpdateProductAttributesActionGroup" stepKey="clickDropdown"/> <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickChangeStatus"/> <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForProductAttributePageToLoad"/> @@ -63,40 +56,33 @@ <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForUpdatedProductToSave"/> <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeAttributeUpateSuccessMsg"/> - <!-- Start message queue --> <actionGroup ref="CliConsumerStartActionGroup" stepKey="startMessageQueueConsumer"> <argument name="consumerName" value="{{AdminProductAttributeUpdateConsumerData.consumerName}}"/> <argument name="maxMessages" value="{{AdminProductAttributeUpdateConsumerData.messageLimit}}"/> </actionGroup> - <!-- Run cron --> + <magentoCLI command="cron:run --group=index" stepKey="runCron"/> - <!--Verify product name, sku and updated price--> - <!-- <actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="goToFirstProductEditPage"> - <argument name="productId" value="$$simpleProduct1.id$$"/> - </actionGroup> --> - <actionGroup ref="AssertProductInfoOnEditPageActionGroup" stepKey="waitForFirstProductToLoad"> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="openFirstProduct"/> + <actionGroup ref="AssertAdminProductPriceUpdatedOnEditPageActionGroup" stepKey="waitForFirstProductToLoad"> <argument name="product" value="$$simpleProduct1$$"/> + <argument name="price" value="90.99"/> </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductNameInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductSkuInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductPriceInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickOnBackButton"/> - <!-- <actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="goToSecondProductEditPage"> - <argument name="productId" value="$$simpleProduct2.id$$"/> - </actionGroup> --> - <actionGroup ref="AssertProductInfoOnEditPageActionGroup" stepKey="waitForSecondProductToLoad"> + <actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="waitForProductsToLoad"/> + + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="openSecondProduct"/> + <actionGroup ref="AssertAdminProductPriceUpdatedOnEditPageActionGroup" stepKey="waitForSecondProductToLoad"> <argument name="product" value="$$simpleProduct2$$"/> - </actionGroup> - - <!-- <click stepKey="openFirstProduct" selector="{{AdminProductGridSection.productRowBySku($$simpleProduct1.sku$$)}}"/> - <waitForPageLoad stepKey="waitForFirstProductToLoad"/> - <seeInField stepKey="seeFirstProductNameInField" selector="{{AdminProductFormSection.productName}}" userInput="$$simpleProduct1.name$$"/> - <seeInField stepKey="seeFirstProductSkuInField" selector="{{AdminProductFormSection.productSku}}" userInput="$$simpleProduct1.sku$$"/> - <seeInField stepKey="seeFirstProductPriceInField" selector="{{AdminProductFormSection.productPrice}}" userInput="90.99"/> - <click stepKey="clickOnBackButton" selector="{{AdminGridMainControls.back}}"/> - <waitForPageLoad stepKey="waitForProductsToLoad"/> - <click stepKey="openSecondProduct" selector="{{AdminProductGridSection.productRowBySku($$simpleProduct2.sku$$)}}"/> - <waitForPageLoad stepKey="waitForSecondProductToLoad"/> - <seeInField stepKey="seeSecondProductNameInField" selector="{{AdminProductFormSection.productName}}" userInput="$$simpleProduct2.name$$"/> - <seeInField stepKey="seeSecondProductSkuInField" selector="{{AdminProductFormSection.productSku}}" userInput="$$simpleProduct2.sku$$"/> - <seeInField stepKey="seeSecondProductPriceInField" selector="{{AdminProductFormSection.productPrice}}" userInput="90.99"/> --> + <argument name="price" value="90.99"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductNameInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductSkuInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductPriceInField"/> + </test> </tests> From bdb653dc3ff44f1ce1486935e27873620ea3f3bd Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Wed, 25 Nov 2020 17:14:32 +0200 Subject: [PATCH 028/156] delete unneeded file Please enter the commit message for your changes. Lines starting --- ...inCheckProductOnProductGridActionGroup.xml | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml deleted file mode 100644 index 34c9c1edf50cb..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.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="AdminCheckProductOnProductGridActionGroup"> - <annotations> - <description>Check the product on the Product Grid</description> - </annotations> - <arguments> - <argument name="product" type="entity"/> - </arguments> - - <checkOption selector="{{AdminProductGridSection.productRowCheckboxBySku(product.sku)}}" stepKey="selectProduct"/> - - </actionGroup> -</actionGroups> From faf0c872ac4e03555a278009f12743c0ef0b8412 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Wed, 25 Nov 2020 17:22:58 +0200 Subject: [PATCH 029/156] revert deletion --- ...inCheckProductOnProductGridActionGroup.xml | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml new file mode 100644 index 0000000000000..3bd68e80810e6 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.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="AdminCheckProductOnProductGridActionGroup"> + <annotations> + <description>Check the product on the Product Grid</description> + </annotations> + <arguments> + <argument name="product" type="entity"/> + </arguments> + + <checkOption selector="{{AdminProductGridSection.productRowCheckboxBySku(product.sku)}}" stepKey="selectProduct"/> + + </actionGroup> +</actionGroups> \ No newline at end of file From dd4334df1a3c28e4ee1c84e782971d77c15622d6 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Wed, 25 Nov 2020 17:29:51 +0200 Subject: [PATCH 030/156] extended decription fo Action Group Please enter the commit message for your changes. Lines starting --- .../ActionGroup/AdminCheckProductOnProductGridActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml index 3bd68e80810e6..aebd595a919f8 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml @@ -10,7 +10,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminCheckProductOnProductGridActionGroup"> <annotations> - <description>Check the product on the Product Grid</description> + <description>Check the checkbox for the product on the Product Grid</description> </annotations> <arguments> <argument name="product" type="entity"/> From 3b0e854a0e9a7dd18c135259d14bfd50a5e7dd5f Mon Sep 17 00:00:00 2001 From: "vadim.malesh" <engcom-vendorworker-charlie@adobe.com> Date: Fri, 27 Nov 2020 13:33:34 +0200 Subject: [PATCH 031/156] fix action group, revert i18n changes --- .../AdminGoToCreditmemoViewActionGroup.xml | 2 +- ...tmemoViewPageWithWrongCreditmemoIdTest.xml | 6 +- app/code/Magento/Sales/i18n/en_US.csv | 1280 ++++++++--------- 3 files changed, 642 insertions(+), 646 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml index d417a6c5ed314..08d02fe2b7bb1 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminGoToCreditmemoViewActionGroup.xml @@ -16,7 +16,7 @@ <argument name="identifier" type="string"/> </arguments> - <amOnPage url="{{AdminCreditMemoViewPage.url}}/{{identifier}}" stepKey="amOnCreditmemoViewPage"/> + <amOnPage url="{{AdminCreditMemoViewPage.url}}{{identifier}}" stepKey="amOnCreditmemoViewPage"/> <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml index cf7f61aa12a20..4436aab59874a 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml @@ -16,11 +16,9 @@ <severity value="MAJOR"/> <group value="sales"/> </annotations> - <before> <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin"/> </before> - <after> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> @@ -30,9 +28,7 @@ </actionGroup> <waitForPageLoad stepKey="waitForPageLoad"/> - <seeInCurrentUrl url="{{AdminCreditMemosGridPage.url}}" stepKey="redirectToCreditMemosGridPage"/> - - <actionGroup ref="AssertAdminPageIs404ActionGroup" stepKey="see404PageOnAdmin"/> + <see selector="{{AdminMessagesSection.error}}" userInput='This creditmemo no longer exists.' stepKey="seeErrorMessage"/> </test> </tests> diff --git a/app/code/Magento/Sales/i18n/en_US.csv b/app/code/Magento/Sales/i18n/en_US.csv index c429a10411af4..03589afb1cd19 100644 --- a/app/code/Magento/Sales/i18n/en_US.csv +++ b/app/code/Magento/Sales/i18n/en_US.csv @@ -1,344 +1,344 @@ -Credit Memos,Credit Memos +"Credit Memos","Credit Memos" Orders,Orders Invoices,Invoices -We can't get the order instance right now.,We can't get the order instance right now. -Create New Order,Create New Order -Save Order Address,Save Order Address +"We can't get the order instance right now.","We can't get the order instance right now." +"Create New Order","Create New Order" +"Save Order Address","Save Order Address" Shipping,Shipping Billing,Billing -Edit Order %1 %2 Address,Edit Order %1 %2 Address -Order Address Information,Order Address Information -Please correct the parent block for this block.,Please correct the parent block for this block. -Submit Comment,Submit Comment -Submit Order,Submit Order -Are you sure you want to cancel this order?,Are you sure you want to cancel this order? +"Edit Order %1 %2 Address","Edit Order %1 %2 Address" +"Order Address Information","Order Address Information" +"Please correct the parent block for this block.","Please correct the parent block for this block." +"Submit Comment","Submit Comment" +"Submit Order","Submit Order" +"Are you sure you want to cancel this order?","Are you sure you want to cancel this order?" Cancel,Cancel -Billing Address,Billing Address -Payment Method,Payment Method -Order Comment,Order Comment +"Billing Address","Billing Address" +"Payment Method","Payment Method" +"Order Comment","Order Comment" Coupons,Coupons -Please select a customer,Please select a customer -Create New Customer,Create New Customer -Account Information,Account Information +"Please select a customer","Please select a customer" +"Create New Customer","Create New Customer" +"Account Information","Account Information" From,From To,To Message,Message -Edit Order #%1,Edit Order #%1 -Create New Order for %1 in %2,Create New Order for %1 in %2 -Create New Order in %1,Create New Order in %1 -Create New Order for %1,Create New Order for %1 -Create New Order for New Customer,Create New Order for New Customer -Items Ordered,Items Ordered -This product is disabled.,This product is disabled. -Buy %1 for price %2,Buy %1 for price %2 -Item ordered qty,Item ordered qty -%1 with %2 discount each,%1 with %2 discount each -%1 for %2,%1 for %2 -* - Enter custom price including tax,* - Enter custom price including tax -* - Enter custom price excluding tax,* - Enter custom price excluding tax +"Edit Order #%1","Edit Order #%1" +"Create New Order for %1 in %2","Create New Order for %1 in %2" +"Create New Order in %1","Create New Order in %1" +"Create New Order for %1","Create New Order for %1" +"Create New Order for New Customer","Create New Order for New Customer" +"Items Ordered","Items Ordered" +"This product is disabled.","This product is disabled." +"Buy %1 for price %2","Buy %1 for price %2" +"Item ordered qty","Item ordered qty" +"%1 with %2 discount each","%1 with %2 discount each" +"%1 for %2","%1 for %2" +"* - Enter custom price including tax","* - Enter custom price including tax" +"* - Enter custom price excluding tax","* - Enter custom price excluding tax" Configure,Configure -This product does not have any configurable options,This product does not have any configurable options -Newsletter Subscription,Newsletter Subscription -Please select products,Please select products -Add Selected Product(s) to Order,Add Selected Product(s) to Order +"This product does not have any configurable options","This product does not have any configurable options" +"Newsletter Subscription","Newsletter Subscription" +"Please select products","Please select products" +"Add Selected Product(s) to Order","Add Selected Product(s) to Order" ID,ID Product,Product SKU,SKU Price,Price Select,Select Quantity,Quantity -Shipping Address,Shipping Address -Shipping Method,Shipping Method -Update Changes,Update Changes -Shopping Cart,Shopping Cart -Are you sure you want to delete all items from shopping cart?,Are you sure you want to delete all items from shopping cart? -Clear Shopping Cart,Clear Shopping Cart -Products in Comparison List,Products in Comparison List -Recently Compared Products,Recently Compared Products -Recently Viewed Products,Recently Viewed Products -Last Ordered Items,Last Ordered Items -Recently Viewed,Recently Viewed -Wish List,Wish List -Please select a store,Please select a store -Order Totals,Order Totals -Shipping Incl. Tax (%1),Shipping Incl. Tax (%1) -Shipping Excl. Tax (%1),Shipping Excl. Tax (%1) -New Credit Memo for Invoice #%1,New Credit Memo for Invoice #%1 -New Credit Memo for Order #%1,New Credit Memo for Order #%1 -Refund Shipping (Incl. Tax),Refund Shipping (Incl. Tax) -Refund Shipping (Excl. Tax),Refund Shipping (Excl. Tax) -Refund Shipping,Refund Shipping -Update Qty's,Update Qty's +"Shipping Address","Shipping Address" +"Shipping Method","Shipping Method" +"Update Changes","Update Changes" +"Shopping Cart","Shopping Cart" +"Are you sure you want to delete all items from shopping cart?","Are you sure you want to delete all items from shopping cart?" +"Clear Shopping Cart","Clear Shopping Cart" +"Products in Comparison List","Products in Comparison List" +"Recently Compared Products","Recently Compared Products" +"Recently Viewed Products","Recently Viewed Products" +"Last Ordered Items","Last Ordered Items" +"Recently Viewed","Recently Viewed" +"Wish List","Wish List" +"Please select a store","Please select a store" +"Order Totals","Order Totals" +"Shipping Incl. Tax (%1)","Shipping Incl. Tax (%1)" +"Shipping Excl. Tax (%1)","Shipping Excl. Tax (%1)" +"New Credit Memo for Invoice #%1","New Credit Memo for Invoice #%1" +"New Credit Memo for Order #%1","New Credit Memo for Order #%1" +"Refund Shipping (Incl. Tax)","Refund Shipping (Incl. Tax)" +"Refund Shipping (Excl. Tax)","Refund Shipping (Excl. Tax)" +"Refund Shipping","Refund Shipping" +"Update Qty's","Update Qty's" Refund,Refund -Refund Offline,Refund Offline -Paid Amount,Paid Amount -Refund Amount,Refund Amount -Shipping Amount,Shipping Amount -Shipping Refund,Shipping Refund -Order Grand Total,Order Grand Total -Adjustment Refund,Adjustment Refund -Adjustment Fee,Adjustment Fee -Send Email,Send Email -Are you sure you want to send a credit memo email to customer?,Are you sure you want to send a credit memo email to customer? +"Refund Offline","Refund Offline" +"Paid Amount","Paid Amount" +"Refund Amount","Refund Amount" +"Shipping Amount","Shipping Amount" +"Shipping Refund","Shipping Refund" +"Order Grand Total","Order Grand Total" +"Adjustment Refund","Adjustment Refund" +"Adjustment Fee","Adjustment Fee" +"Send Email","Send Email" +"Are you sure you want to send a credit memo email to customer?","Are you sure you want to send a credit memo email to customer?" Void,Void Print,Print -The credit memo email was sent.,The credit memo email was sent. -The credit memo email wasn't sent.,The credit memo email wasn't sent. -Credit Memo #%1 | %3 | %2 (%4),Credit Memo #%1 | %3 | %2 (%4) -Total Refund,Total Refund -New Invoice and Shipment for Order #%1,New Invoice and Shipment for Order #%1 -New Invoice for Order #%1,New Invoice for Order #%1 -Submit Invoice and Shipment,Submit Invoice and Shipment -Submit Invoice,Submit Invoice -Are you sure you want to send an invoice email to customer?,Are you sure you want to send an invoice email to customer? -Credit Memo,Credit Memo +"The credit memo email was sent.","The credit memo email was sent." +"The credit memo email wasn't sent.","The credit memo email wasn't sent." +"Credit Memo #%1 | %3 | %2 (%4)","Credit Memo #%1 | %3 | %2 (%4)" +"Total Refund","Total Refund" +"New Invoice and Shipment for Order #%1","New Invoice and Shipment for Order #%1" +"New Invoice for Order #%1","New Invoice for Order #%1" +"Submit Invoice and Shipment","Submit Invoice and Shipment" +"Submit Invoice","Submit Invoice" +"Are you sure you want to send an invoice email to customer?","Are you sure you want to send an invoice email to customer?" +"Credit Memo","Credit Memo" Capture,Capture -The invoice email was sent.,The invoice email was sent. -The invoice email wasn't sent.,The invoice email wasn't sent. -Invoice #%1 | %2 | %4 (%3),Invoice #%1 | %2 | %4 (%3) -Invalid parent block for this block,Invalid parent block for this block -Order Statuses,Order Statuses -Create New Status,Create New Status -Assign Status to State,Assign Status to State -Save Status Assignment,Save Status Assignment -Assign Order Status to State,Assign Order Status to State -Assignment Information,Assignment Information -Order Status,Order Status -Order State,Order State -Use Order Status As Default,Use Order Status As Default -Visible On Storefront,Visible On Storefront -Edit Order Status,Edit Order Status -Save Status,Save Status -New Order Status,New Order Status -Order Status Information,Order Status Information -Status Code,Status Code -Status Label,Status Label -Store View Specific Labels,Store View Specific Labels -Total Paid,Total Paid -Total Refunded,Total Refunded -Total Due,Total Due -Total Canceled,Total Canceled +"The invoice email was sent.","The invoice email was sent." +"The invoice email wasn't sent.","The invoice email wasn't sent." +"Invoice #%1 | %2 | %4 (%3)","Invoice #%1 | %2 | %4 (%3)" +"Invalid parent block for this block","Invalid parent block for this block" +"Order Statuses","Order Statuses" +"Create New Status","Create New Status" +"Assign Status to State","Assign Status to State" +"Save Status Assignment","Save Status Assignment" +"Assign Order Status to State","Assign Order Status to State" +"Assignment Information","Assignment Information" +"Order Status","Order Status" +"Order State","Order State" +"Use Order Status As Default","Use Order Status As Default" +"Visible On Storefront","Visible On Storefront" +"Edit Order Status","Edit Order Status" +"Save Status","Save Status" +"New Order Status","New Order Status" +"Order Status Information","Order Status Information" +"Status Code","Status Code" +"Status Label","Status Label" +"Store View Specific Labels","Store View Specific Labels" +"Total Paid","Total Paid" +"Total Refunded","Total Refunded" +"Total Due","Total Due" +"Total Canceled","Total Canceled" Edit,Edit -Are you sure you want to send an order email to customer?,Are you sure you want to send an order email to customer? +"Are you sure you want to send an order email to customer?","Are you sure you want to send an order email to customer?" "This will create an offline refund. To create an online refund, open an invoice and create credit memo for it. Do you want to continue?","This will create an offline refund. To create an online refund, open an invoice and create credit memo for it. Do you want to continue?" -Are you sure you want to void the payment?,Are you sure you want to void the payment? +"Are you sure you want to void the payment?","Are you sure you want to void the payment?" Hold,Hold hold,hold Unhold,Unhold unhold,unhold -Are you sure you want to accept this payment?,Are you sure you want to accept this payment? -Accept Payment,Accept Payment -Are you sure you want to deny this payment?,Are you sure you want to deny this payment? -Deny Payment,Deny Payment -Get Payment Update,Get Payment Update -Invoice and Ship,Invoice and Ship +"Are you sure you want to accept this payment?","Are you sure you want to accept this payment?" +"Accept Payment","Accept Payment" +"Are you sure you want to deny this payment?","Are you sure you want to deny this payment?" +"Deny Payment","Deny Payment" +"Get Payment Update","Get Payment Update" +"Invoice and Ship","Invoice and Ship" Invoice,Invoice Ship,Ship Reorder,Reorder -Order # %1 %2 | %3,Order # %1 %2 | %3 +"Order # %1 %2 | %3","Order # %1 %2 | %3" "This order contains (%1) items and therefore cannot be edited through the admin interface. If you wish to continue editing, the (%2) items will be removed, the order will be canceled and a new order will be placed.","This order contains (%1) items and therefore cannot be edited through the admin interface. If you wish to continue editing, the (%2) items will be removed, the order will be canceled and a new order will be placed." -Are you sure? This order will be canceled and a new one will be created instead.,Are you sure? This order will be canceled and a new one will be created instead. -Save Gift Message,Save Gift Message - [deleted], [deleted] -Order Credit Memos,Order Credit Memos -Credit memo #%1 created,Credit memo #%1 created -Credit memo #%1 comment added,Credit memo #%1 comment added -Shipment #%1 created,Shipment #%1 created -Shipment #%1 comment added,Shipment #%1 comment added -Invoice #%1 created,Invoice #%1 created -Invoice #%1 comment added,Invoice #%1 comment added -Tracking number %1 for %2 assigned,Tracking number %1 for %2 assigned -Comments History,Comments History -Order History,Order History +"Are you sure? This order will be canceled and a new one will be created instead.","Are you sure? This order will be canceled and a new one will be created instead." +"Save Gift Message","Save Gift Message" +" [deleted]"," [deleted]" +"Order Credit Memos","Order Credit Memos" +"Credit memo #%1 created","Credit memo #%1 created" +"Credit memo #%1 comment added","Credit memo #%1 comment added" +"Shipment #%1 created","Shipment #%1 created" +"Shipment #%1 comment added","Shipment #%1 comment added" +"Invoice #%1 created","Invoice #%1 created" +"Invoice #%1 comment added","Invoice #%1 comment added" +"Tracking number %1 for %2 assigned","Tracking number %1 for %2 assigned" +"Comments History","Comments History" +"Order History","Order History" Information,Information -Order Information,Order Information -Order Invoices,Order Invoices +"Order Information","Order Information" +"Order Invoices","Order Invoices" Shipments,Shipments -Order Shipments,Order Shipments +"Order Shipments","Order Shipments" Transactions,Transactions -Order View,Order View +"Order View","Order View" Any,Any Specified,Specified -Applies to Any of the Specified Order Statuses except canceled orders,Applies to Any of the Specified Order Statuses except canceled orders -Cart Price Rule,Cart Price Rule +"Applies to Any of the Specified Order Statuses except canceled orders","Applies to Any of the Specified Order Statuses except canceled orders" +"Cart Price Rule","Cart Price Rule" Yes,Yes No,No -Show Actual Values,Show Actual Values -New Order RSS,New Order RSS +"Show Actual Values","Show Actual Values" +"New Order RSS","New Order RSS" Subtotal,Subtotal -Shipping & Handling,Shipping & Handling -Discount (%1),Discount (%1) +"Shipping & Handling","Shipping & Handling" +"Discount (%1)","Discount (%1)" Discount,Discount -Grand Total,Grand Total +"Grand Total","Grand Total" Back,Back Fetch,Fetch -Transaction # %1 | %2,Transaction # %1 | %2 +"Transaction # %1 | %2","Transaction # %1 | %2" N/A,N/A Key,Key Value,Value -We found an invalid entity model.,We found an invalid entity model. -Order # %1,Order # %1 -Back to My Orders,Back to My Orders -View Another Order,View Another Order -About Your Refund,About Your Refund -My Orders,My Orders -Subscribe to Order Status,Subscribe to Order Status -About Your Invoice,About Your Invoice -Print Order # %1,Print Order # %1 -Grand Total to be Charged,Grand Total to be Charged +"We found an invalid entity model.","We found an invalid entity model." +"Order # %1","Order # %1" +"Back to My Orders","Back to My Orders" +"View Another Order","View Another Order" +"About Your Refund","About Your Refund" +"My Orders","My Orders" +"Subscribe to Order Status","Subscribe to Order Status" +"About Your Invoice","About Your Invoice" +"Print Order # %1","Print Order # %1" +"Grand Total to be Charged","Grand Total to be Charged" Unassign,Unassign -We can't add this item to your shopping cart right now.,We can't add this item to your shopping cart right now. -You sent the message.,You sent the message. +"We can't add this item to your shopping cart right now.","We can't add this item to your shopping cart right now." +"You sent the message.","You sent the message." Sales,Sales -Invoice capturing error,Invoice capturing error -This order no longer exists.,This order no longer exists. -Please enter a comment.,Please enter a comment. -We cannot add order history.,We cannot add order history. -You updated the order address.,You updated the order address. -We can't update the order address right now.,We can't update the order address right now. -You have not canceled the item.,You have not canceled the item. -You canceled the order.,You canceled the order. +"Invoice capturing error","Invoice capturing error" +"This order no longer exists.","This order no longer exists." +"Please enter a comment.","Please enter a comment." +"We cannot add order history.","We cannot add order history." +"You updated the order address.","You updated the order address." +"We can't update the order address right now.","We can't update the order address right now." +"You have not canceled the item.","You have not canceled the item." +"You canceled the order.","You canceled the order." """%1"" coupon code was not applied. Do not apply discount is selected for item(s)","""%1"" coupon code was not applied. Do not apply discount is selected for item(s)" """%1"" coupon code is not valid.","""%1"" coupon code is not valid." -The coupon code has been accepted.,The coupon code has been accepted. -Quote item id is not received.,Quote item id is not received. -Quote item is not loaded.,Quote item is not loaded. -New Order,New Order -You created the order.,You created the order. -Order saving error: %1,Order saving error: %1 -Cannot add new comment.,Cannot add new comment. -The credit memo has been canceled.,The credit memo has been canceled. -Credit memo has not been canceled.,Credit memo has not been canceled. -New Memo for #%1,New Memo for #%1 -New Memo,New Memo -The credit memo's total must be positive.,The credit memo's total must be positive. -Cannot create online refund for Refund to Store Credit.,Cannot create online refund for Refund to Store Credit. -You created the credit memo.,You created the credit memo. -We can't save the credit memo right now.,We can't save the credit memo right now. -We can't update the item's quantity right now.,We can't update the item's quantity right now. -View Memo for #%1,View Memo for #%1 -View Memo,View Memo -You voided the credit memo.,You voided the credit memo. -We can't void the credit memo.,We can't void the credit memo. -The order no longer exists.,The order no longer exists. -We can't create credit memo for the order.,We can't create credit memo for the order. -Edit Order,Edit Order -You sent the order email.,You sent the order email. -We can't send the email order right now.,We can't send the email order right now. -You have not put the order on hold.,You have not put the order on hold. -You put the order on hold.,You put the order on hold. -You canceled the invoice.,You canceled the invoice. -Invoice canceling error,Invoice canceling error -The invoice has been captured.,The invoice has been captured. -The order does not allow an invoice to be created.,The order does not allow an invoice to be created. -You can't create an invoice without products.,You can't create an invoice without products. -New Invoice,New Invoice -We can't save the invoice right now.,We can't save the invoice right now. -You created the invoice and shipment.,You created the invoice and shipment. -The invoice has been created.,The invoice has been created. -We can't send the invoice email right now.,We can't send the invoice email right now. -We can't send the shipment right now.,We can't send the shipment right now. -Cannot update item quantity.,Cannot update item quantity. -The invoice has been voided.,The invoice has been voided. -Invoice voiding error,Invoice voiding error -%1 order(s) cannot be canceled.,%1 order(s) cannot be canceled. -You cannot cancel the order(s).,You cannot cancel the order(s). -We canceled %1 order(s).,We canceled %1 order(s). -%1 order(s) were not put on hold.,%1 order(s) were not put on hold. -No order(s) were put on hold.,No order(s) were put on hold. -You have put %1 order(s) on hold.,You have put %1 order(s) on hold. -%1 order(s) were not released from on hold status.,%1 order(s) were not released from on hold status. -No order(s) were released from on hold status.,No order(s) were released from on hold status. -%1 order(s) have been released from on hold status.,%1 order(s) have been released from on hold status. -There are no printable documents related to selected orders.,There are no printable documents related to selected orders. -The payment has been accepted.,The payment has been accepted. -The payment has been denied.,The payment has been denied. -Transaction has been approved.,Transaction has been approved. -Transaction has been voided/declined.,Transaction has been voided/declined. -There is no update for the transaction.,There is no update for the transaction. -We can't update the payment right now.,We can't update the payment right now. -You assigned the order status.,You assigned the order status. -Something went wrong while assigning the order status.,Something went wrong while assigning the order status. -We can't find this order status.,We can't find this order status. -Create New Order Status,Create New Order Status -We found another order status with the same order status code.,We found another order status with the same order status code. -You saved the order status.,You saved the order status. -We can't add the order status right now.,We can't add the order status right now. -You have unassigned the order status.,You have unassigned the order status. -Something went wrong while unassigning the order.,Something went wrong while unassigning the order. -Can't unhold order.,Can't unhold order. -You released the order from holding status.,You released the order from holding status. -The order was not on hold.,The order was not on hold. -Exception occurred during order load,Exception occurred during order load -Something went wrong while saving the gift message.,Something went wrong while saving the gift message. -You saved the gift card message.,You saved the gift card message. -The payment has been voided.,The payment has been voided. -We can't void the payment right now.,We can't void the payment right now. -Please correct the transaction ID and try again.,Please correct the transaction ID and try again. -The transaction details have been updated.,The transaction details have been updated. -We can't update the transaction details.,We can't update the transaction details. -Orders and Returns,Orders and Returns -You entered incorrect data. Please try again.,You entered incorrect data. Please try again. +"The coupon code has been accepted.","The coupon code has been accepted." +"Quote item id is not received.","Quote item id is not received." +"Quote item is not loaded.","Quote item is not loaded." +"New Order","New Order" +"You created the order.","You created the order." +"Order saving error: %1","Order saving error: %1" +"Cannot add new comment.","Cannot add new comment." +"The credit memo has been canceled.","The credit memo has been canceled." +"Credit memo has not been canceled.","Credit memo has not been canceled." +"New Memo for #%1","New Memo for #%1" +"New Memo","New Memo" +"The credit memo's total must be positive.","The credit memo's total must be positive." +"Cannot create online refund for Refund to Store Credit.","Cannot create online refund for Refund to Store Credit." +"You created the credit memo.","You created the credit memo." +"We can't save the credit memo right now.","We can't save the credit memo right now." +"We can't update the item's quantity right now.","We can't update the item's quantity right now." +"View Memo for #%1","View Memo for #%1" +"View Memo","View Memo" +"You voided the credit memo.","You voided the credit memo." +"We can't void the credit memo.","We can't void the credit memo." +"The order no longer exists.","The order no longer exists." +"We can't create credit memo for the order.","We can't create credit memo for the order." +"Edit Order","Edit Order" +"You sent the order email.","You sent the order email." +"We can't send the email order right now.","We can't send the email order right now." +"You have not put the order on hold.","You have not put the order on hold." +"You put the order on hold.","You put the order on hold." +"You canceled the invoice.","You canceled the invoice." +"Invoice canceling error","Invoice canceling error" +"The invoice has been captured.","The invoice has been captured." +"The order does not allow an invoice to be created.","The order does not allow an invoice to be created." +"You can't create an invoice without products.","You can't create an invoice without products." +"New Invoice","New Invoice" +"We can't save the invoice right now.","We can't save the invoice right now." +"You created the invoice and shipment.","You created the invoice and shipment." +"The invoice has been created.","The invoice has been created." +"We can't send the invoice email right now.","We can't send the invoice email right now." +"We can't send the shipment right now.","We can't send the shipment right now." +"Cannot update item quantity.","Cannot update item quantity." +"The invoice has been voided.","The invoice has been voided." +"Invoice voiding error","Invoice voiding error" +"%1 order(s) cannot be canceled.","%1 order(s) cannot be canceled." +"You cannot cancel the order(s).","You cannot cancel the order(s)." +"We canceled %1 order(s).","We canceled %1 order(s)." +"%1 order(s) were not put on hold.","%1 order(s) were not put on hold." +"No order(s) were put on hold.","No order(s) were put on hold." +"You have put %1 order(s) on hold.","You have put %1 order(s) on hold." +"%1 order(s) were not released from on hold status.","%1 order(s) were not released from on hold status." +"No order(s) were released from on hold status.","No order(s) were released from on hold status." +"%1 order(s) have been released from on hold status.","%1 order(s) have been released from on hold status." +"There are no printable documents related to selected orders.","There are no printable documents related to selected orders." +"The payment has been accepted.","The payment has been accepted." +"The payment has been denied.","The payment has been denied." +"Transaction has been approved.","Transaction has been approved." +"Transaction has been voided/declined.","Transaction has been voided/declined." +"There is no update for the transaction.","There is no update for the transaction." +"We can't update the payment right now.","We can't update the payment right now." +"You assigned the order status.","You assigned the order status." +"Something went wrong while assigning the order status.","Something went wrong while assigning the order status." +"We can't find this order status.","We can't find this order status." +"Create New Order Status","Create New Order Status" +"We found another order status with the same order status code.","We found another order status with the same order status code." +"You saved the order status.","You saved the order status." +"We can't add the order status right now.","We can't add the order status right now." +"You have unassigned the order status.","You have unassigned the order status." +"Something went wrong while unassigning the order.","Something went wrong while unassigning the order." +"Can't unhold order.","Can't unhold order." +"You released the order from holding status.","You released the order from holding status." +"The order was not on hold.","The order was not on hold." +"Exception occurred during order load","Exception occurred during order load" +"Something went wrong while saving the gift message.","Something went wrong while saving the gift message." +"You saved the gift card message.","You saved the gift card message." +"The payment has been voided.","The payment has been voided." +"We can't void the payment right now.","We can't void the payment right now." +"Please correct the transaction ID and try again.","Please correct the transaction ID and try again." +"The transaction details have been updated.","The transaction details have been updated." +"We can't update the transaction details.","We can't update the transaction details." +"Orders and Returns","Orders and Returns" +"You entered incorrect data. Please try again.","You entered incorrect data. Please try again." Home,Home -Go to Home Page,Go to Home Page -We can't find this wish list.,We can't find this wish list. +"Go to Home Page","Go to Home Page" +"We can't find this wish list.","We can't find this wish list." "We could not add a product to cart by the ID ""%1"".","We could not add a product to cart by the ID ""%1""." -There is an error in one of the option rows.,There is an error in one of the option rows. +"There is an error in one of the option rows.","There is an error in one of the option rows." "Shipping Address: ","Shipping Address: " "Billing Address: ","Billing Address: " -Please specify order items.,Please specify order items. -Please specify a shipping method.,Please specify a shipping method. -Please specify a payment method.,Please specify a payment method. -This payment method is not available.,This payment method is not available. -Validation is failed.,Validation is failed. -You did not email your customer. Please check your email settings.,You did not email your customer. Please check your email settings. --- Please Select --,-- Please Select -- +"Please specify order items.","Please specify order items." +"Please specify a shipping method.","Please specify a shipping method." +"Please specify a payment method.","Please specify a payment method." +"This payment method is not available.","This payment method is not available." +"Validation is failed.","Validation is failed." +"You did not email your customer. Please check your email settings.","You did not email your customer. Please check your email settings." +"-- Please Select --","-- Please Select --" "Path ""%1"" is not part of allowed directory ""%2""","Path ""%1"" is not part of allowed directory ""%2""" -Identifying Fields required,Identifying Fields required -Id required,Id required +"Identifying Fields required","Identifying Fields required" +"Id required","Id required" """Invoice Document Validation Error(s):\n"" .","""Invoice Document Validation Error(s):\n"" ." "Could not save an invoice, see error log for details","Could not save an invoice, see error log for details" -A hold action is not available.,A hold action is not available. -You cannot remove the hold.,You cannot remove the hold. -We cannot cancel this order.,We cannot cancel this order. +"A hold action is not available.","A hold action is not available." +"You cannot remove the hold.","You cannot remove the hold." +"We cannot cancel this order.","We cannot cancel this order." Guest,Guest -Please enter the first name.,Please enter the first name. -Please enter the last name.,Please enter the last name. -Please enter the street.,Please enter the street. -Please enter the city.,Please enter the city. -Please enter the phone number.,Please enter the phone number. -Please enter the company.,Please enter the company. -Please enter the fax number.,Please enter the fax number. -Please enter the zip/postal code.,Please enter the zip/postal code. -Please enter the country.,Please enter the country. -Please enter the state/province.,Please enter the state/province. -Requested entity doesn't exist,Requested entity doesn't exist -Could not delete order address,Could not delete order address -Could not save order address,Could not save order address +"Please enter the first name.","Please enter the first name." +"Please enter the last name.","Please enter the last name." +"Please enter the street.","Please enter the street." +"Please enter the city.","Please enter the city." +"Please enter the phone number.","Please enter the phone number." +"Please enter the company.","Please enter the company." +"Please enter the fax number.","Please enter the fax number." +"Please enter the zip/postal code.","Please enter the zip/postal code." +"Please enter the country.","Please enter the country." +"Please enter the state/province.","Please enter the state/province." +"Requested entity doesn't exist","Requested entity doesn't exist" +"Could not delete order address","Could not delete order address" +"Could not save order address","Could not save order address" Pending,Pending Refunded,Refunded Canceled,Canceled -Unknown State,Unknown State +"Unknown State","Unknown State" "We found an invalid quantity to refund item ""%1"".","We found an invalid quantity to refund item ""%1""." -The creditmemo contains product item that is not part of the original order.,The creditmemo contains product item that is not part of the original order. -The quantity to refund must not be greater than the unrefunded quantity.,The quantity to refund must not be greater than the unrefunded quantity. -Maximum shipping amount allowed to refund is: %1,Maximum shipping amount allowed to refund is: %1 -Order Id is required for creditmemo document,Order Id is required for creditmemo document +"The creditmemo contains product item that is not part of the original order.","The creditmemo contains product item that is not part of the original order." +"The quantity to refund must not be greater than the unrefunded quantity.","The quantity to refund must not be greater than the unrefunded quantity." +"Maximum shipping amount allowed to refund is: %1","Maximum shipping amount allowed to refund is: %1" +"Order Id is required for creditmemo document","Order Id is required for creditmemo document" "The creditmemo contains product SKU ""%1"" that is not part of the original order.","The creditmemo contains product SKU ""%1"" that is not part of the original order." "The quantity to creditmemo must not be greater than the unrefunded quantity for product SKU ""%1"".","The quantity to creditmemo must not be greater than the unrefunded quantity for product SKU ""%1""." -You can't create a creditmemo without products.,You can't create a creditmemo without products. -The most money available to refund is %1.,The most money available to refund is %1. -Could not delete credit memo,Could not delete credit memo -Could not save credit memo,Could not save credit memo -This order already has associated customer account,This order already has associated customer account +"You can't create a creditmemo without products.","You can't create a creditmemo without products." +"The most money available to refund is %1.","The most money available to refund is %1." +"Could not delete credit memo","Could not delete credit memo" +"Could not save credit memo","Could not save credit memo" +"This order already has associated customer account","This order already has associated customer account" Paid,Paid -We cannot register an existing invoice,We cannot register an existing invoice -We can't create creditmemo for the invoice.,We can't create creditmemo for the invoice. -Order Id is required for invoice document,Order Id is required for invoice document +"We cannot register an existing invoice","We cannot register an existing invoice" +"We can't create creditmemo for the invoice.","We can't create creditmemo for the invoice." +"Order Id is required for invoice document","Order Id is required for invoice document" "The quantity to invoice must not be greater than the uninvoiced quantity for product SKU ""%1"".","The quantity to invoice must not be greater than the uninvoiced quantity for product SKU ""%1""." -The invoice contains one or more items that are not part of the original order.,The invoice contains one or more items that are not part of the original order. -ID required,ID required -Unknown Status,Unknown Status +"The invoice contains one or more items that are not part of the original order.","The invoice contains one or more items that are not part of the original order." +"ID required","ID required" +"Unknown Status","Unknown Status" Ordered,Ordered Shipped,Shipped Invoiced,Invoiced @@ -346,462 +346,462 @@ Backordered,Backordered Returned,Returned Partial,Partial Mixed,Mixed -Registered a Void notification.,Registered a Void notification. +"Registered a Void notification.","Registered a Void notification." "If the invoice was created offline, try creating an offline credit memo.","If the invoice was created offline, try creating an offline credit memo." -We refunded %1 online.,We refunded %1 online. -We refunded %1 offline.,We refunded %1 offline. +"We refunded %1 online.","We refunded %1 online." +"We refunded %1 offline.","We refunded %1 offline." "IPN ""Refunded"". Refund issued by merchant. Registered notification about refunded amount of %1. Transaction ID: ""%2"". Credit Memo has not been created. Please create offline Credit Memo.","IPN ""Refunded"". Refund issued by merchant. Registered notification about refunded amount of %1. Transaction ID: ""%2"". Credit Memo has not been created. Please create offline Credit Memo." -The credit memo has been created automatically.,The credit memo has been created automatically. -Registered notification about refunded amount of %1.,Registered notification about refunded amount of %1. -Canceled order online,Canceled order online -Canceled order offline,Canceled order offline -Approved the payment online.,Approved the payment online. -There is no need to approve this payment.,There is no need to approve this payment. -Denied the payment online,Denied the payment online -Registered update about approved payment.,Registered update about approved payment. -Registered update about denied payment.,Registered update about denied payment. -There is no update for the payment.,There is no update for the payment. -Voided authorization.,Voided authorization. -Amount: %1.,Amount: %1. +"The credit memo has been created automatically.","The credit memo has been created automatically." +"Registered notification about refunded amount of %1.","Registered notification about refunded amount of %1." +"Canceled order online","Canceled order online" +"Canceled order offline","Canceled order offline" +"Approved the payment online.","Approved the payment online." +"There is no need to approve this payment.","There is no need to approve this payment." +"Denied the payment online","Denied the payment online" +"Registered update about approved payment.","Registered update about approved payment." +"Registered update about denied payment.","Registered update about denied payment." +"There is no update for the payment.","There is no update for the payment." +"Voided authorization.","Voided authorization." +"Amount: %1.","Amount: %1." "Transaction ID: ""%1""","Transaction ID: ""%1""" -The payment method you requested is not available.,The payment method you requested is not available. -The payment disallows storing objects.,The payment disallows storing objects. +"The payment method you requested is not available.","The payment method you requested is not available." +"The payment disallows storing objects.","The payment disallows storing objects." "The transaction ""%1"" cannot be captured yet.","The transaction ""%1"" cannot be captured yet." -The order amount of %1 is pending approval on the payment gateway.,The order amount of %1 is pending approval on the payment gateway. -Ordered amount of %1,Ordered amount of %1 -An amount of %1 will be captured after being approved at the payment gateway.,An amount of %1 will be captured after being approved at the payment gateway. -Registered notification about captured amount of %1.,Registered notification about captured amount of %1. -Order is suspended as its capture amount %1 is suspected to be fraudulent.,Order is suspended as its capture amount %1 is suspected to be fraudulent. -The parent transaction ID must have a transaction ID.,The parent transaction ID must have a transaction ID. -Payment transactions disallow storing objects.,Payment transactions disallow storing objects. +"The order amount of %1 is pending approval on the payment gateway.","The order amount of %1 is pending approval on the payment gateway." +"Ordered amount of %1","Ordered amount of %1" +"An amount of %1 will be captured after being approved at the payment gateway.","An amount of %1 will be captured after being approved at the payment gateway." +"Registered notification about captured amount of %1.","Registered notification about captured amount of %1." +"Order is suspended as its capture amount %1 is suspected to be fraudulent.","Order is suspended as its capture amount %1 is suspected to be fraudulent." +"The parent transaction ID must have a transaction ID.","The parent transaction ID must have a transaction ID." +"Payment transactions disallow storing objects.","Payment transactions disallow storing objects." "The transaction ""%1"" (%2) is already closed.","The transaction ""%1"" (%2) is already closed." -Set order for existing transactions not allowed,Set order for existing transactions not allowed +"Set order for existing transactions not allowed","Set order for existing transactions not allowed" "At minimum, you need to set a payment ID.","At minimum, you need to set a payment ID." Order,Order Authorization,Authorization "We found an unsupported transaction type ""%1"".","We found an unsupported transaction type ""%1""." -Please set a proper payment and order id.,Please set a proper payment and order id. -Please enter a Transaction ID.,Please enter a Transaction ID. -You can't do this without a transaction object.,You can't do this without a transaction object. +"Please set a proper payment and order id.","Please set a proper payment and order id." +"Please enter a Transaction ID.","Please enter a Transaction ID." +"You can't do this without a transaction object.","You can't do this without a transaction object." "Order # ","Order # " "Order Date: ","Order Date: " -Sold to:,Sold to: -Ship to:,Ship to: -Payment Method:,Payment Method: -Shipping Method:,Shipping Method: -Total Shipping Charges,Total Shipping Charges +"Sold to:","Sold to:" +"Ship to:","Ship to:" +"Payment Method:","Payment Method:" +"Shipping Method:","Shipping Method:" +"Total Shipping Charges","Total Shipping Charges" Title,Title Number,Number -We found an invalid renderer model.,We found an invalid renderer model. -Please define the PDF object before using.,Please define the PDF object before using. +"We found an invalid renderer model.","We found an invalid renderer model." +"Please define the PDF object before using.","Please define the PDF object before using." "We don't recognize the draw line data. Please define the ""lines"" array.","We don't recognize the draw line data. Please define the ""lines"" array." Products,Products -Total (ex),Total (ex) +"Total (ex)","Total (ex)" Qty,Qty Tax,Tax -Total (inc),Total (inc) +"Total (inc)","Total (inc)" "Credit Memo # ","Credit Memo # " "Invoice # ","Invoice # " -The order object is not specified.,The order object is not specified. -The source object is not specified.,The source object is not specified. -An item object is not specified.,An item object is not specified. -A PDF object is not specified.,A PDF object is not specified. -A PDF page object is not specified.,A PDF page object is not specified. -Excl. Tax,Excl. Tax -Incl. Tax,Incl. Tax +"The order object is not specified.","The order object is not specified." +"The source object is not specified.","The source object is not specified." +"An item object is not specified.","An item object is not specified." +"A PDF object is not specified.","A PDF object is not specified." +"A PDF page object is not specified.","A PDF page object is not specified." +"Excl. Tax","Excl. Tax" +"Incl. Tax","Incl. Tax" "Packing Slip # ","Packing Slip # " title,title -The PDF total model %1 must be or extend \Magento\Sales\Model\Order\Pdf\Total\DefaultTotal.,The PDF total model %1 must be or extend \Magento\Sales\Model\Order\Pdf\Total\DefaultTotal. -We cannot register an existing shipment,We cannot register an existing shipment -Parent shipment cannot be loaded for track object.,Parent shipment cannot be loaded for track object. -Order Id is required for shipment document,Order Id is required for shipment document -You can't create a shipment without products.,You can't create a shipment without products. +"The PDF total model %1 must be or extend \Magento\Sales\Model\Order\Pdf\Total\DefaultTotal.","The PDF total model %1 must be or extend \Magento\Sales\Model\Order\Pdf\Total\DefaultTotal." +"We cannot register an existing shipment","We cannot register an existing shipment" +"Parent shipment cannot be loaded for track object.","Parent shipment cannot be loaded for track object." +"Order Id is required for shipment document","Order Id is required for shipment document" +"You can't create a shipment without products.","You can't create a shipment without products." "The shipment contains product SKU ""%1"" that is not part of the original order.","The shipment contains product SKU ""%1"" that is not part of the original order." "The quantity to ship must not be greater than the unshipped quantity for product SKU ""%1"".","The quantity to ship must not be greater than the unshipped quantity for product SKU ""%1""." -Please enter a tracking number.,Please enter a tracking number. -Could not delete shipment,Could not delete shipment -Could not save shipment,Could not save shipment -The last status can't be unassigned from its current state.,The last status can't be unassigned from its current state. +"Please enter a tracking number.","Please enter a tracking number." +"Could not delete shipment","Could not delete shipment" +"Could not save shipment","Could not save shipment" +"The last status can't be unassigned from its current state.","The last status can't be unassigned from its current state." "Status can't be unassigned, because it is used by existing order(s).","Status can't be unassigned, because it is used by existing order(s)." -The total model should be extended from \Magento\Sales\Model\Order\Total\AbstractTotal.,The total model should be extended from \Magento\Sales\Model\Order\Total\AbstractTotal. -An invoice cannot be created when an order has a status of %1,An invoice cannot be created when an order has a status of %1 -A creditmemo can not be created when an order has a status of %1,A creditmemo can not be created when an order has a status of %1 -The order does not allow a creditmemo to be created.,The order does not allow a creditmemo to be created. -A shipment cannot be created when an order has a status of %1,A shipment cannot be created when an order has a status of %1 -The order does not allow a shipment to be created.,The order does not allow a shipment to be created. +"The total model should be extended from \Magento\Sales\Model\Order\Total\AbstractTotal.","The total model should be extended from \Magento\Sales\Model\Order\Total\AbstractTotal." +"An invoice cannot be created when an order has a status of %1","An invoice cannot be created when an order has a status of %1" +"A creditmemo can not be created when an order has a status of %1","A creditmemo can not be created when an order has a status of %1" +"The order does not allow a creditmemo to be created.","The order does not allow a creditmemo to be created." +"A shipment cannot be created when an order has a status of %1","A shipment cannot be created when an order has a status of %1" +"The order does not allow a shipment to be created.","The order does not allow a shipment to be created." """Creditmemo Document Validation Error(s):\n"" .","""Creditmemo Document Validation Error(s):\n"" ." "Could not save a Creditmemo, see error log for details","Could not save a Creditmemo, see error log for details" -We cannot determine the field name.,We cannot determine the field name. +"We cannot determine the field name.","We cannot determine the field name." City,City Company,Company Country,Country Email,Email -First Name,First Name -Last Name,Last Name +"First Name","First Name" +"Last Name","Last Name" State/Province,State/Province -Street Address,Street Address -Phone Number,Phone Number -Zip/Postal Code,Zip/Postal Code -We can't save the address:\n%1,We can't save the address:\n%1 -Cannot save comment:\n%1,Cannot save comment:\n%1 -We don't have enough information to save the parent transaction ID.,We don't have enough information to save the parent transaction ID. -We cannot create an empty shipment.,We cannot create an empty shipment. -Cannot save track:\n%1,Cannot save track:\n%1 -Cannot unassign status from state,Cannot unassign status from state -New Orders,New Orders -Order #%1 created at %2,Order #%1 created at %2 -Details for %1 #%2,Details for %1 #%2 -Notified Date: %1,Notified Date: %1 -Comment: %1<br/>,Comment: %1<br/> -Current Status: %1<br/>,Current Status: %1<br/> -Total: %1<br/>,Total: %1<br/> -Order # %1 Notification(s),Order # %1 Notification(s) -You can not cancel Credit Memo,You can not cancel Credit Memo -Could not cancel creditmemo,Could not cancel creditmemo -We cannot register an existing credit memo.,We cannot register an existing credit memo. +"Street Address","Street Address" +"Phone Number","Phone Number" +"Zip/Postal Code","Zip/Postal Code" +"We can't save the address:\n%1","We can't save the address:\n%1" +"Cannot save comment:\n%1","Cannot save comment:\n%1" +"We don't have enough information to save the parent transaction ID.","We don't have enough information to save the parent transaction ID." +"We cannot create an empty shipment.","We cannot create an empty shipment." +"Cannot save track:\n%1","Cannot save track:\n%1" +"Cannot unassign status from state","Cannot unassign status from state" +"New Orders","New Orders" +"Order #%1 created at %2","Order #%1 created at %2" +"Details for %1 #%2","Details for %1 #%2" +"Notified Date: %1","Notified Date: %1" +"Comment: %1<br/>","Comment: %1<br/>" +"Current Status: %1<br/>","Current Status: %1<br/>" +"Total: %1<br/>","Total: %1<br/>" +"Order # %1 Notification(s)","Order # %1 Notification(s)" +"You can not cancel Credit Memo","You can not cancel Credit Memo" +"Could not cancel creditmemo","Could not cancel creditmemo" +"We cannot register an existing credit memo.","We cannot register an existing credit memo." "We found an invalid quantity to invoice item ""%1"".","We found an invalid quantity to invoice item ""%1""." "The Order State ""%1"" must not be set manually.","The Order State ""%1"" must not be set manually." """Shipment Document Validation Error(s):\n"" .","""Shipment Document Validation Error(s):\n"" ." "Could not save a shipment, see error log for details","Could not save a shipment, see error log for details" -VAT Request Identifier,VAT Request Identifier -VAT Request Date,VAT Request Date -Pending Payment,Pending Payment +"VAT Request Identifier","VAT Request Identifier" +"VAT Request Date","VAT Request Date" +"Pending Payment","Pending Payment" Processing,Processing -On Hold,On Hold +"On Hold","On Hold" Complete,Complete Closed,Closed -Suspected Fraud,Suspected Fraud -Payment Review,Payment Review +"Suspected Fraud","Suspected Fraud" +"Payment Review","Payment Review" New,New -test message,test message -Email has not been sent,Email has not been sent -Authorized amount of %1.,Authorized amount of %1. -We will authorize %1 after the payment is approved at the payment gateway.,We will authorize %1 after the payment is approved at the payment gateway. -Authorized amount of %1. Order is suspended as its authorizing amount %1 is suspected to be fraudulent.,Authorized amount of %1. Order is suspended as its authorizing amount %1 is suspected to be fraudulent. -Captured amount of %1 online.,Captured amount of %1 online. -Authorized amount of %1,Authorized amount of %1 +"test message","test message" +"Email has not been sent","Email has not been sent" +"Authorized amount of %1.","Authorized amount of %1." +"We will authorize %1 after the payment is approved at the payment gateway.","We will authorize %1 after the payment is approved at the payment gateway." +"Authorized amount of %1. Order is suspended as its authorizing amount %1 is suspected to be fraudulent.","Authorized amount of %1. Order is suspended as its authorizing amount %1 is suspected to be fraudulent." +"Captured amount of %1 online.","Captured amount of %1 online." +"Authorized amount of %1","Authorized amount of %1" " Transaction ID: ""%1"""," Transaction ID: ""%1""" View,View -Group was removed,Group was removed +"Group was removed","Group was removed" "Changing address information will not recalculate shipping, tax or other order amount.","Changing address information will not recalculate shipping, tax or other order amount." -Comment Text,Comment Text -Notify Customer by Email,Notify Customer by Email -Visible on Storefront,Visible on Storefront +"Comment Text","Comment Text" +"Notify Customer by Email","Notify Customer by Email" +"Visible on Storefront","Visible on Storefront" Customer,Customer Notified,Notified -Not Notified,Not Notified -No Payment Methods,No Payment Methods -Order Comments,Order Comments -Apply Coupon Code,Apply Coupon Code +"Not Notified","Not Notified" +"No Payment Methods","No Payment Methods" +"Order Comments","Order Comments" +"Apply Coupon Code","Apply Coupon Code" Apply,Apply -Remove Coupon Code,Remove Coupon Code +"Remove Coupon Code","Remove Coupon Code" Remove,Remove -Address Information,Address Information -Payment & Shipping Information,Payment & Shipping Information -Order Total,Order Total -Order Currency:,Order Currency: -Same As Billing Address,Same As Billing Address -Select from existing customer addresses:,Select from existing customer addresses: -Add New Address,Add New Address -Save in address book,Save in address book -You don't need to select a shipping address.,You don't need to select a shipping address. -Gift Message for the Entire Order,Gift Message for the Entire Order -Leave this box blank if you don't want to leave a gift message for the entire order.,Leave this box blank if you don't want to leave a gift message for the entire order. -Row Subtotal,Row Subtotal +"Address Information","Address Information" +"Payment & Shipping Information","Payment & Shipping Information" +"Order Total","Order Total" +"Order Currency:","Order Currency:" +"Same As Billing Address","Same As Billing Address" +"Select from existing customer addresses:","Select from existing customer addresses:" +"Add New Address","Add New Address" +"Save in address book","Save in address book" +"You don't need to select a shipping address.","You don't need to select a shipping address." +"Gift Message for the Entire Order","Gift Message for the Entire Order" +"Leave this box blank if you don't want to leave a gift message for the entire order.","Leave this box blank if you don't want to leave a gift message for the entire order." +"Row Subtotal","Row Subtotal" Action,Action -No ordered items,No ordered items -Update Items and Quantities,Update Items and Quantities -Total %1 product(s),Total %1 product(s) +"No ordered items","No ordered items" +"Update Items and Quantities","Update Items and Quantities" +"Total %1 product(s)","Total %1 product(s)" Subtotal:,Subtotal: -Tier Pricing,Tier Pricing -Custom Price,Custom Price -Please select,Please select -Move to Shopping Cart,Move to Shopping Cart -Move to Wish List,Move to Wish List -Subscribe to Newsletter,Subscribe to Newsletter -Click to change shipping method,Click to change shipping method +"Tier Pricing","Tier Pricing" +"Custom Price","Custom Price" +"Please select","Please select" +"Move to Shopping Cart","Move to Shopping Cart" +"Move to Wish List","Move to Wish List" +"Subscribe to Newsletter","Subscribe to Newsletter" +"Click to change shipping method","Click to change shipping method" "Sorry, no quotes are available for this order.","Sorry, no quotes are available for this order." -Get shipping methods and rates,Get shipping methods and rates -You don't need to select a shipping method.,You don't need to select a shipping method. -Customer's Activities,Customer's Activities +"Get shipping methods and rates","Get shipping methods and rates" +"You don't need to select a shipping method.","You don't need to select a shipping method." +"Customer's Activities","Customer's Activities" Refresh,Refresh Item,Item -Add To Order,Add To Order -Configure and Add to Order,Configure and Add to Order -No items,No items -Append Comments,Append Comments -Email Order Confirmation,Email Order Confirmation -Grand Total Excl. Tax,Grand Total Excl. Tax -Grand Total Incl. Tax,Grand Total Incl. Tax -Subtotal (Excl. Tax),Subtotal (Excl. Tax) -Subtotal (Incl. Tax),Subtotal (Incl. Tax) -Payment & Shipping Method,Payment & Shipping Method -Payment Information,Payment Information -The order was placed using %1.,The order was placed using %1. -Shipping Information,Shipping Information -Items to Refund,Items to Refund -Return to Stock,Return to Stock -Qty to Refund,Qty to Refund -Tax Amount,Tax Amount -Discount Amount,Discount Amount -Row Total,Row Total -No Items To Refund,No Items To Refund -Credit Memo Comments,Credit Memo Comments -Refund Totals,Refund Totals -Email Copy of Credit Memo,Email Copy of Credit Memo -Please enter a positive number in this field.,Please enter a positive number in this field. -Items Refunded,Items Refunded -No Items,No Items -Memo Total,Memo Total -Credit Memo History,Credit Memo History -Credit Memo Totals,Credit Memo Totals -Customer Name: %1,Customer Name: %1 -Purchased From: %1,Purchased From: %1 -Gift Message,Gift Message +"Add To Order","Add To Order" +"Configure and Add to Order","Configure and Add to Order" +"No items","No items" +"Append Comments","Append Comments" +"Email Order Confirmation","Email Order Confirmation" +"Grand Total Excl. Tax","Grand Total Excl. Tax" +"Grand Total Incl. Tax","Grand Total Incl. Tax" +"Subtotal (Excl. Tax)","Subtotal (Excl. Tax)" +"Subtotal (Incl. Tax)","Subtotal (Incl. Tax)" +"Payment & Shipping Method","Payment & Shipping Method" +"Payment Information","Payment Information" +"The order was placed using %1.","The order was placed using %1." +"Shipping Information","Shipping Information" +"Items to Refund","Items to Refund" +"Return to Stock","Return to Stock" +"Qty to Refund","Qty to Refund" +"Tax Amount","Tax Amount" +"Discount Amount","Discount Amount" +"Row Total","Row Total" +"No Items To Refund","No Items To Refund" +"Credit Memo Comments","Credit Memo Comments" +"Refund Totals","Refund Totals" +"Email Copy of Credit Memo","Email Copy of Credit Memo" +"Please enter a positive number in this field.","Please enter a positive number in this field." +"Items Refunded","Items Refunded" +"No Items","No Items" +"Memo Total","Memo Total" +"Credit Memo History","Credit Memo History" +"Credit Memo Totals","Credit Memo Totals" +"Customer Name: %1","Customer Name: %1" +"Purchased From: %1","Purchased From: %1" +"Gift Message","Gift Message" From:,From: To:,To: Message:,Message: -Shipping & Handling,Shipping & Handling -Gift Options,Gift Options -Create Shipment,Create Shipment -Invoice and shipment types do not match for some items on this order. You can create a shipment only after creating the invoice.,Invoice and shipment types do not match for some items on this order. You can create a shipment only after creating the invoice. +"Shipping & Handling","Shipping & Handling" +"Gift Options","Gift Options" +"Create Shipment","Create Shipment" +"Invoice and shipment types do not match for some items on this order. You can create a shipment only after creating the invoice.","Invoice and shipment types do not match for some items on this order. You can create a shipment only after creating the invoice." %1,%1 -Qty to Invoice,Qty to Invoice -Invoice History,Invoice History -Invoice Comments,Invoice Comments -Invoice Totals,Invoice Totals +"Qty to Invoice","Qty to Invoice" +"Invoice History","Invoice History" +"Invoice Comments","Invoice Comments" +"Invoice Totals","Invoice Totals" Amount,Amount -Capture Online,Capture Online -Capture Offline,Capture Offline -Not Capture,Not Capture -The invoice will be created offline without the payment gateway.,The invoice will be created offline without the payment gateway. -Email Copy of Invoice,Email Copy of Invoice -Items Invoiced,Items Invoiced -Total Tax,Total Tax -From Name,From Name -To Name,To Name +"Capture Online","Capture Online" +"Capture Offline","Capture Offline" +"Not Capture","Not Capture" +"The invoice will be created offline without the payment gateway.","The invoice will be created offline without the payment gateway." +"Email Copy of Invoice","Email Copy of Invoice" +"Items Invoiced","Items Invoiced" +"Total Tax","Total Tax" +"From Name","From Name" +"To Name","To Name" Status,Status Comment,Comment -Notification Not Applicable,Notification Not Applicable -Order & Account Information,Order & Account Information -The order confirmation email was sent,The order confirmation email was sent -The order confirmation email is not sent,The order confirmation email is not sent -Order Date,Order Date -Order Date (%1),Order Date (%1) -Purchased From,Purchased From -Link to the New Order,Link to the New Order -Link to the Previous Order,Link to the Previous Order -Placed from IP,Placed from IP -%1 / %2 rate:,%1 / %2 rate: -Customer Name,Customer Name -Customer Group,Customer Group -Notes for this Order,Notes for this Order -Comment added,Comment added -Transaction Data,Transaction Data -Transaction ID,Transaction ID -Parent Transaction ID,Parent Transaction ID -Order ID,Order ID -Transaction Type,Transaction Type -Is Closed,Is Closed -Created At,Created At -Child Transactions,Child Transactions -Transaction Details,Transaction Details +"Notification Not Applicable","Notification Not Applicable" +"Order & Account Information","Order & Account Information" +"The order confirmation email was sent","The order confirmation email was sent" +"The order confirmation email is not sent","The order confirmation email is not sent" +"Order Date","Order Date" +"Order Date (%1)","Order Date (%1)" +"Purchased From","Purchased From" +"Link to the New Order","Link to the New Order" +"Link to the Previous Order","Link to the Previous Order" +"Placed from IP","Placed from IP" +"%1 / %2 rate:","%1 / %2 rate:" +"Customer Name","Customer Name" +"Customer Group","Customer Group" +"Notes for this Order","Notes for this Order" +"Comment added","Comment added" +"Transaction Data","Transaction Data" +"Transaction ID","Transaction ID" +"Parent Transaction ID","Parent Transaction ID" +"Order ID","Order ID" +"Transaction Type","Transaction Type" +"Is Closed","Is Closed" +"Created At","Created At" +"Child Transactions","Child Transactions" +"Transaction Details","Transaction Details" Items,Items -Gift Message for this Order,Gift Message for this Order -Shipped By,Shipped By -Tracking Number,Tracking Number -Billing Last Name,Billing Last Name -Find Order By,Find Order By -ZIP Code,ZIP Code -Billing ZIP Code,Billing ZIP Code +"Gift Message for this Order","Gift Message for this Order" +"Shipped By","Shipped By" +"Tracking Number","Tracking Number" +"Billing Last Name","Billing Last Name" +"Find Order By","Find Order By" +"ZIP Code","ZIP Code" +"Billing ZIP Code","Billing ZIP Code" Continue,Continue -Print All Refunds,Print All Refunds -Refund #,Refund # -Print Refund,Print Refund -Product Name,Product Name -Order #,Order # +"Print All Refunds","Print All Refunds" +"Refund #","Refund #" +"Print Refund","Print Refund" +"Product Name","Product Name" +"Order #","Order #" Date,Date -Ship To,Ship To +"Ship To","Ship To" Actions,Actions -View Order,View Order -You have placed no orders.,You have placed no orders. -No shipping information available,No shipping information available -Print Order,Print Order -Print All Invoices,Print All Invoices -Invoice #,Invoice # -Print Invoice,Print Invoice -Qty Invoiced,Qty Invoiced +"View Order","View Order" +"You have placed no orders.","You have placed no orders." +"No shipping information available","No shipping information available" +"Print Order","Print Order" +"Print All Invoices","Print All Invoices" +"Invoice #","Invoice #" +"Print Invoice","Print Invoice" +"Qty Invoiced","Qty Invoiced" Close,Close -About Your Order,About Your Order +"About Your Order","About Your Order" "<span class=""label"">Order Date:</span> %1","<span class=""label"">Order Date:</span> %1" -Refund #%1,Refund #%1 -Shipment #%1,Shipment #%1 -Qty Shipped,Qty Shipped -Recent Orders,Recent Orders -View All,View All -Gift Message for This Order,Gift Message for This Order -Recently Ordered,Recently Ordered -Add to Cart,Add to Cart +"Refund #%1","Refund #%1" +"Shipment #%1","Shipment #%1" +"Qty Shipped","Qty Shipped" +"Recent Orders","Recent Orders" +"View All","View All" +"Gift Message for This Order","Gift Message for This Order" +"Recently Ordered","Recently Ordered" +"Add to Cart","Add to Cart" Search,Search -Credit memo for your %store_name order,Credit memo for your %store_name order +"Credit memo for your %store_name order","Credit memo for your %store_name order" "%name,","%name," -Thank you for your order from %store_name.,Thank you for your order from %store_name. +"Thank you for your order from %store_name.","Thank you for your order from %store_name." "You can check the status of your order by <a href=""%account_url"">logging into your account</a>.","You can check the status of your order by <a href=""%account_url"">logging into your account</a>." "If you have questions about your order, you can email us at <a href=""mailto:%store_email"">%store_email</a>","If you have questions about your order, you can email us at <a href=""mailto:%store_email"">%store_email</a>" "or call us at <a href=""tel:%store_phone"">%store_phone</a>","or call us at <a href=""tel:%store_phone"">%store_phone</a>" "Our hours are <span class=""no-link"">%store_hours</span>.","Our hours are <span class=""no-link"">%store_hours</span>." -Your Credit Memo #%creditmemo_id for Order #%order_id,Your Credit Memo #%creditmemo_id for Order #%order_id -Billing Info,Billing Info -Shipping Info,Shipping Info -Update to your %store_name credit memo,Update to your %store_name credit memo -Your order #%increment_id has been updated with a status of <strong>%order_status</strong>.,Your order #%increment_id has been updated with a status of <strong>%order_status</strong>. -Invoice for your %store_name order,Invoice for your %store_name order -Your Invoice #%invoice_id for Order #%order_id,Your Invoice #%invoice_id for Order #%order_id -Update to your %store_name invoice,Update to your %store_name invoice -Your %store_name order confirmation,Your %store_name order confirmation +"Your Credit Memo #%creditmemo_id for Order #%order_id","Your Credit Memo #%creditmemo_id for Order #%order_id" +"Billing Info","Billing Info" +"Shipping Info","Shipping Info" +"Update to your %store_name credit memo","Update to your %store_name credit memo" +"Your order #%increment_id has been updated with a status of <strong>%order_status</strong>.","Your order #%increment_id has been updated with a status of <strong>%order_status</strong>." +"Invoice for your %store_name order","Invoice for your %store_name order" +"Your Invoice #%invoice_id for Order #%order_id","Your Invoice #%invoice_id for Order #%order_id" +"Update to your %store_name invoice","Update to your %store_name invoice" +"Your %store_name order confirmation","Your %store_name order confirmation" "%customer_name,","%customer_name," -Once your package ships we will send you a tracking number.,Once your package ships we will send you a tracking number. +"Once your package ships we will send you a tracking number.","Once your package ships we will send you a tracking number." "Your Order <span class=""no-link"">#%increment_id</span>","Your Order <span class=""no-link"">#%increment_id</span>" "Placed on <span class=""no-link"">%created_at</span>","Placed on <span class=""no-link"">%created_at</span>" -Once your package ships we will send an email with a link to track your order.,Once your package ships we will send an email with a link to track your order. -Update to your %store_name order,Update to your %store_name order -Your %store_name order has shipped,Your %store_name order has shipped -Your shipping confirmation is below. Thank you again for your business.,Your shipping confirmation is below. Thank you again for your business. -Your Shipment #%shipment_id for Order #%order_id,Your Shipment #%shipment_id for Order #%order_id -Update to your %store_name shipment,Update to your %store_name shipment +"Once your package ships we will send an email with a link to track your order.","Once your package ships we will send an email with a link to track your order." +"Update to your %store_name order","Update to your %store_name order" +"Your %store_name order has shipped","Your %store_name order has shipped" +"Your shipping confirmation is below. Thank you again for your business.","Your shipping confirmation is below. Thank you again for your business." +"Your Shipment #%shipment_id for Order #%order_id","Your Shipment #%shipment_id for Order #%order_id" +"Update to your %store_name shipment","Update to your %store_name shipment" "Gift Options for ","Gift Options for " -Add Products,Add Products -You have item changes,You have item changes +"Add Products","Add Products" +"You have item changes","You have item changes" Ok,Ok Operations,Operations Create,Create -Send Order Email,Send Order Email -Accept or Deny Payment,Accept or Deny Payment -Send Sales Emails,Send Sales Emails -Sales Section,Sales Section -Sales Emails Section,Sales Emails Section +"Send Order Email","Send Order Email" +"Accept or Deny Payment","Accept or Deny Payment" +"Send Sales Emails","Send Sales Emails" +"Sales Section","Sales Section" +"Sales Emails Section","Sales Emails Section" General,General -Hide Customer IP,Hide Customer IP +"Hide Customer IP","Hide Customer IP" "Choose whether a customer IP is shown in orders, invoices, shipments, and credit memos.","Choose whether a customer IP is shown in orders, invoices, shipments, and credit memos." -Checkout Totals Sort Order,Checkout Totals Sort Order -Allow Reorder,Allow Reorder -Invoice and Packing Slip Design,Invoice and Packing Slip Design -Logo for PDF Print-outs (200x50),Logo for PDF Print-outs (200x50) +"Checkout Totals Sort Order","Checkout Totals Sort Order" +"Allow Reorder","Allow Reorder" +"Invoice and Packing Slip Design","Invoice and Packing Slip Design" +"Logo for PDF Print-outs (200x50)","Logo for PDF Print-outs (200x50)" "Your default logo will be used in PDF and HTML documents.<br />(jpeg, tiff, png) If your pdf image is distorted, try to use larger file-size image.","Your default logo will be used in PDF and HTML documents.<br />(jpeg, tiff, png) If your pdf image is distorted, try to use larger file-size image." -Logo for HTML Print View,Logo for HTML Print View +"Logo for HTML Print View","Logo for HTML Print View" "Logo for HTML documents only. If empty, default will be used.<br />(jpeg, gif, png)","Logo for HTML documents only. If empty, default will be used.<br />(jpeg, gif, png)" Address,Address -Minimum Order Amount,Minimum Order Amount +"Minimum Order Amount","Minimum Order Amount" Enable,Enable -Minimum Amount,Minimum Amount -Subtotal after discount,Subtotal after discount -Include Tax to Amount,Include Tax to Amount -Description Message,Description Message -This message will be shown in the shopping cart when the subtotal (after discount) is lower than the minimum allowed amount.,This message will be shown in the shopping cart when the subtotal (after discount) is lower than the minimum allowed amount. -Error to Show in Shopping Cart,Error to Show in Shopping Cart -Validate Each Address Separately in Multi-address Checkout,Validate Each Address Separately in Multi-address Checkout -Multi-address Description Message,Multi-address Description Message -We'll use the default description above if you leave this empty.,We'll use the default description above if you leave this empty. -Multi-address Error to Show in Shopping Cart,Multi-address Error to Show in Shopping Cart -We'll use the default error above if you leave this empty.,We'll use the default error above if you leave this empty. +"Minimum Amount","Minimum Amount" +"Subtotal after discount","Subtotal after discount" +"Include Tax to Amount","Include Tax to Amount" +"Description Message","Description Message" +"This message will be shown in the shopping cart when the subtotal (after discount) is lower than the minimum allowed amount.","This message will be shown in the shopping cart when the subtotal (after discount) is lower than the minimum allowed amount." +"Error to Show in Shopping Cart","Error to Show in Shopping Cart" +"Validate Each Address Separately in Multi-address Checkout","Validate Each Address Separately in Multi-address Checkout" +"Multi-address Description Message","Multi-address Description Message" +"We'll use the default description above if you leave this empty.","We'll use the default description above if you leave this empty." +"Multi-address Error to Show in Shopping Cart","Multi-address Error to Show in Shopping Cart" +"We'll use the default error above if you leave this empty.","We'll use the default error above if you leave this empty." Dashboard,Dashboard -Use Aggregated Data,Use Aggregated Data -Orders Cron Settings,Orders Cron Settings -Pending Payment Order Lifetime (minutes),Pending Payment Order Lifetime (minutes) -Sales Emails,Sales Emails -Asynchronous sending,Asynchronous sending +"Use Aggregated Data","Use Aggregated Data" +"Orders Cron Settings","Orders Cron Settings" +"Pending Payment Order Lifetime (minutes)","Pending Payment Order Lifetime (minutes)" +"Sales Emails","Sales Emails" +"Asynchronous sending","Asynchronous sending" Enabled,Enabled -New Order Confirmation Email Sender,New Order Confirmation Email Sender -New Order Confirmation Template,New Order Confirmation Template +"New Order Confirmation Email Sender","New Order Confirmation Email Sender" +"New Order Confirmation Template","New Order Confirmation Template" "Email template chosen based on theme fallback when ""Default"" option is selected.","Email template chosen based on theme fallback when ""Default"" option is selected." -New Order Confirmation Template for Guest,New Order Confirmation Template for Guest -Send Order Email Copy To,Send Order Email Copy To +"New Order Confirmation Template for Guest","New Order Confirmation Template for Guest" +"Send Order Email Copy To","Send Order Email Copy To" Comma-separated,Comma-separated -Send Order Email Copy Method,Send Order Email Copy Method -Order Comment Email Sender,Order Comment Email Sender -Order Comment Email Template,Order Comment Email Template -Order Comment Email Template for Guest,Order Comment Email Template for Guest -Send Order Comment Email Copy To,Send Order Comment Email Copy To -Send Order Comments Email Copy Method,Send Order Comments Email Copy Method -Invoice Email Sender,Invoice Email Sender -Invoice Email Template,Invoice Email Template -Invoice Email Template for Guest,Invoice Email Template for Guest -Send Invoice Email Copy To,Send Invoice Email Copy To -Send Invoice Email Copy Method,Send Invoice Email Copy Method -Invoice Comment Email Sender,Invoice Comment Email Sender -Invoice Comment Email Template,Invoice Comment Email Template -Invoice Comment Email Template for Guest,Invoice Comment Email Template for Guest -Send Invoice Comment Email Copy To,Send Invoice Comment Email Copy To -Send Invoice Comments Email Copy Method,Send Invoice Comments Email Copy Method +"Send Order Email Copy Method","Send Order Email Copy Method" +"Order Comment Email Sender","Order Comment Email Sender" +"Order Comment Email Template","Order Comment Email Template" +"Order Comment Email Template for Guest","Order Comment Email Template for Guest" +"Send Order Comment Email Copy To","Send Order Comment Email Copy To" +"Send Order Comments Email Copy Method","Send Order Comments Email Copy Method" +"Invoice Email Sender","Invoice Email Sender" +"Invoice Email Template","Invoice Email Template" +"Invoice Email Template for Guest","Invoice Email Template for Guest" +"Send Invoice Email Copy To","Send Invoice Email Copy To" +"Send Invoice Email Copy Method","Send Invoice Email Copy Method" +"Invoice Comment Email Sender","Invoice Comment Email Sender" +"Invoice Comment Email Template","Invoice Comment Email Template" +"Invoice Comment Email Template for Guest","Invoice Comment Email Template for Guest" +"Send Invoice Comment Email Copy To","Send Invoice Comment Email Copy To" +"Send Invoice Comments Email Copy Method","Send Invoice Comments Email Copy Method" Shipment,Shipment -Shipment Email Sender,Shipment Email Sender -Shipment Email Template,Shipment Email Template -Shipment Email Template for Guest,Shipment Email Template for Guest -Send Shipment Email Copy To,Send Shipment Email Copy To -Send Shipment Email Copy Method,Send Shipment Email Copy Method -Shipment Comments,Shipment Comments -Shipment Comment Email Sender,Shipment Comment Email Sender -Shipment Comment Email Template,Shipment Comment Email Template -Shipment Comment Email Template for Guest,Shipment Comment Email Template for Guest -Send Shipment Comment Email Copy To,Send Shipment Comment Email Copy To -Send Shipment Comments Email Copy Method,Send Shipment Comments Email Copy Method -Credit Memo Email Sender,Credit Memo Email Sender -Credit Memo Email Template,Credit Memo Email Template -Credit Memo Email Template for Guest,Credit Memo Email Template for Guest -Send Credit Memo Email Copy To,Send Credit Memo Email Copy To -Send Credit Memo Email Copy Method,Send Credit Memo Email Copy Method -Credit Memo Comment Email Sender,Credit Memo Comment Email Sender -Credit Memo Comment Email Template,Credit Memo Comment Email Template -Credit Memo Comment Email Template for Guest,Credit Memo Comment Email Template for Guest -Send Credit Memo Comment Email Copy To,Send Credit Memo Comment Email Copy To -Send Credit Memo Comments Email Copy Method,Send Credit Memo Comments Email Copy Method -PDF Print-outs,PDF Print-outs -Display Order ID in Header,Display Order ID in Header -Customer Order Status Notification,Customer Order Status Notification -Asynchronous indexing,Asynchronous indexing -Orders and Returns Search Form,Orders and Returns Search Form -Anchor Custom Title,Anchor Custom Title +"Shipment Email Sender","Shipment Email Sender" +"Shipment Email Template","Shipment Email Template" +"Shipment Email Template for Guest","Shipment Email Template for Guest" +"Send Shipment Email Copy To","Send Shipment Email Copy To" +"Send Shipment Email Copy Method","Send Shipment Email Copy Method" +"Shipment Comments","Shipment Comments" +"Shipment Comment Email Sender","Shipment Comment Email Sender" +"Shipment Comment Email Template","Shipment Comment Email Template" +"Shipment Comment Email Template for Guest","Shipment Comment Email Template for Guest" +"Send Shipment Comment Email Copy To","Send Shipment Comment Email Copy To" +"Send Shipment Comments Email Copy Method","Send Shipment Comments Email Copy Method" +"Credit Memo Email Sender","Credit Memo Email Sender" +"Credit Memo Email Template","Credit Memo Email Template" +"Credit Memo Email Template for Guest","Credit Memo Email Template for Guest" +"Send Credit Memo Email Copy To","Send Credit Memo Email Copy To" +"Send Credit Memo Email Copy Method","Send Credit Memo Email Copy Method" +"Credit Memo Comment Email Sender","Credit Memo Comment Email Sender" +"Credit Memo Comment Email Template","Credit Memo Comment Email Template" +"Credit Memo Comment Email Template for Guest","Credit Memo Comment Email Template for Guest" +"Send Credit Memo Comment Email Copy To","Send Credit Memo Comment Email Copy To" +"Send Credit Memo Comments Email Copy Method","Send Credit Memo Comments Email Copy Method" +"PDF Print-outs","PDF Print-outs" +"Display Order ID in Header","Display Order ID in Header" +"Customer Order Status Notification","Customer Order Status Notification" +"Asynchronous indexing","Asynchronous indexing" +"Orders and Returns Search Form","Orders and Returns Search Form" +"Anchor Custom Title","Anchor Custom Title" Template,Template -Default Template,Default Template +"Default Template","Default Template" Name,Name Phone,Phone -ZIP/Post Code,ZIP/Post Code -Signed-up Point,Signed-up Point +"ZIP/Post Code","ZIP/Post Code" +"Signed-up Point","Signed-up Point" Website,Website -Bill-to Name,Bill-to Name +"Bill-to Name","Bill-to Name" Created,Created -Invoice Date,Invoice Date -Ship-to Name,Ship-to Name -Ship Date,Ship Date -Total Quantity,Total Quantity -Default Status,Default Status -State Code and Title,State Code and Title -Item Status,Item Status -Original Price,Original Price -Tax Percent,Tax Percent -All Store Views,All Store Views -PDF Credit Memos,PDF Credit Memos -Purchase Point,Purchase Point -Print Invoices,Print Invoices -Print Packing Slips,Print Packing Slips -Print Credit Memos,Print Credit Memos -Print All,Print All -Print Shipping Labels,Print Shipping Labels -Purchase Date,Purchase Date -Grand Total (Base),Grand Total (Base) -Grand Total (Purchased),Grand Total (Purchased) -Customer Email,Customer Email -Shipping and Handling,Shipping and Handling -PDF Invoices,PDF Invoices -PDF Shipments,PDF Shipments -PDF Creditmemos,PDF Creditmemos +"Invoice Date","Invoice Date" +"Ship-to Name","Ship-to Name" +"Ship Date","Ship Date" +"Total Quantity","Total Quantity" +"Default Status","Default Status" +"State Code and Title","State Code and Title" +"Item Status","Item Status" +"Original Price","Original Price" +"Tax Percent","Tax Percent" +"All Store Views","All Store Views" +"PDF Credit Memos","PDF Credit Memos" +"Purchase Point","Purchase Point" +"Print Invoices","Print Invoices" +"Print Packing Slips","Print Packing Slips" +"Print Credit Memos","Print Credit Memos" +"Print All","Print All" +"Print Shipping Labels","Print Shipping Labels" +"Purchase Date","Purchase Date" +"Grand Total (Base)","Grand Total (Base)" +"Grand Total (Purchased)","Grand Total (Purchased)" +"Customer Email","Customer Email" +"Shipping and Handling","Shipping and Handling" +"PDF Invoices","PDF Invoices" +"PDF Shipments","PDF Shipments" +"PDF Creditmemos","PDF Creditmemos" Refunds,Refunds -Allow Zero GrandTotal for Creditmemo,Allow Zero GrandTotal for Creditmemo -Allow Zero GrandTotal,Allow Zero GrandTotal +"Allow Zero GrandTotal for Creditmemo","Allow Zero GrandTotal for Creditmemo" +"Allow Zero GrandTotal","Allow Zero GrandTotal" Email is required field for Admin order creation,Email is required field for Admin order creation If set YES Email field will be required during Admin order creation for new Customer.,If set YES Email field will be required during Admin order creation for new Customer. -Could not save the shipment tracking,Could not save the shipment tracking -Please enter a coupon code!,Please enter a coupon code! -Reorder is not available.,Reorder is not available. -The coupon code has been removed.,The coupon code has been removed. -This creditmemo no longer exists.,This creditmemo no longer exists. +"Could not save the shipment tracking","Could not save the shipment tracking" +"Please enter a coupon code!","Please enter a coupon code!" +"Reorder is not available.","Reorder is not available." +"The coupon code has been removed.","The coupon code has been removed." +"This creditmemo no longer exists.","This creditmemo no longer exists." From 7006a96ab964cdce624ff95620fa93d83754683d Mon Sep 17 00:00:00 2001 From: "vadim.malesh" <engcom-vendorworker-charlie@adobe.com> Date: Fri, 27 Nov 2020 13:37:35 +0200 Subject: [PATCH 032/156] revert i18n shipping changes --- app/code/Magento/Shipping/i18n/en_US.csv | 262 +++++++++++------------ 1 file changed, 131 insertions(+), 131 deletions(-) diff --git a/app/code/Magento/Shipping/i18n/en_US.csv b/app/code/Magento/Shipping/i18n/en_US.csv index 831c361382490..0989f1bab4a3d 100644 --- a/app/code/Magento/Shipping/i18n/en_US.csv +++ b/app/code/Magento/Shipping/i18n/en_US.csv @@ -1,180 +1,180 @@ -New Shipment for Order #%1,New Shipment for Order #%1 -Submit Shipment,Submit Shipment -You are trying to add a quantity for some products that doesn't match the quantity that was shipped.,You are trying to add a quantity for some products that doesn't match the quantity that was shipped. -Products should be added to package(s),Products should be added to package(s) -The value that you entered is not valid.,The value that you entered is not valid. -Add Tracking Number,Add Tracking Number -Custom Value,Custom Value +"New Shipment for Order #%1","New Shipment for Order #%1" +"Submit Shipment","Submit Shipment" +"You are trying to add a quantity for some products that doesn't match the quantity that was shipped.","You are trying to add a quantity for some products that doesn't match the quantity that was shipped." +"Products should be added to package(s)","Products should be added to package(s)" +"The value that you entered is not valid.","The value that you entered is not valid." +"Add Tracking Number","Add Tracking Number" +"Custom Value","Custom Value" Add,Add -Send Tracking Information,Send Tracking Information -Are you sure you want to send a Shipment email to customer?,Are you sure you want to send a Shipment email to customer? +"Send Tracking Information","Send Tracking Information" +"Are you sure you want to send a Shipment email to customer?","Are you sure you want to send a Shipment email to customer?" Print,Print -the shipment email was sent,the shipment email was sent -the shipment email is not sent,the shipment email is not sent -Shipment #%1 | %3 (%2),Shipment #%1 | %3 (%2) -Create Shipping Label...,Create Shipping Label... -Print Shipping Label,Print Shipping Label -Show Packages,Show Packages -About Your Shipment,About Your Shipment -Order # %1,Order # %1 -Back to My Orders,Back to My Orders -View Another Order,View Another Order -Please enter a comment.,Please enter a comment. -Cannot add new comment.,Cannot add new comment. -Please specify a carrier.,Please specify a carrier. -Please enter a tracking number.,Please enter a tracking number. +"the shipment email was sent","the shipment email was sent" +"the shipment email is not sent","the shipment email is not sent" +"Shipment #%1 | %3 (%2)","Shipment #%1 | %3 (%2)" +"Create Shipping Label...","Create Shipping Label..." +"Print Shipping Label","Print Shipping Label" +"Show Packages","Show Packages" +"About Your Shipment","About Your Shipment" +"Order # %1","Order # %1" +"Back to My Orders","Back to My Orders" +"View Another Order","View Another Order" +"Please enter a comment.","Please enter a comment." +"Cannot add new comment.","Cannot add new comment." +"Please specify a carrier.","Please specify a carrier." +"Please enter a tracking number.","Please enter a tracking number." Shipments,Shipments -We can't initialize shipment for adding tracking number.,We can't initialize shipment for adding tracking number. -Cannot add tracking number.,Cannot add tracking number. -You created the shipping label.,You created the shipping label. -An error occurred while creating shipping label.,An error occurred while creating shipping label. -You sent the shipment.,You sent the shipment. -Cannot send shipment information.,Cannot send shipment information. -There are no shipping labels related to selected orders.,There are no shipping labels related to selected orders. -New Shipment,New Shipment -We don't recognize or support the file extension in this shipment: %1.,We don't recognize or support the file extension in this shipment: %1. -We can't initialize shipment for delete tracking number.,We can't initialize shipment for delete tracking number. -We can't delete tracking number.,We can't delete tracking number. -We can't load track with retrieving identifier right now.,We can't load track with retrieving identifier right now. -We can't save the shipment right now.,We can't save the shipment right now. +"We can't initialize shipment for adding tracking number.","We can't initialize shipment for adding tracking number." +"Cannot add tracking number.","Cannot add tracking number." +"You created the shipping label.","You created the shipping label." +"An error occurred while creating shipping label.","An error occurred while creating shipping label." +"You sent the shipment.","You sent the shipment." +"Cannot send shipment information.","Cannot send shipment information." +"There are no shipping labels related to selected orders.","There are no shipping labels related to selected orders." +"New Shipment","New Shipment" +"We don't recognize or support the file extension in this shipment: %1.","We don't recognize or support the file extension in this shipment: %1." +"We can't initialize shipment for delete tracking number.","We can't initialize shipment for delete tracking number." +"We can't delete tracking number.","We can't delete tracking number." +"We can't load track with retrieving identifier right now.","We can't load track with retrieving identifier right now." +"We can't save the shipment right now.","We can't save the shipment right now." """Shipment Document Validation Error(s):\n"" .","""Shipment Document Validation Error(s):\n"" ." -The shipment has been created.,The shipment has been created. -Cannot save shipment.,Cannot save shipment. -The order no longer exists.,The order no longer exists. -Cannot do shipment for the order separately from invoice.,Cannot do shipment for the order separately from invoice. -Cannot do shipment for the order.,Cannot do shipment for the order. -There are no shipping labels related to selected shipments.,There are no shipping labels related to selected shipments. -Page not found.,Page not found. -Tracking Information,Tracking Information +"The shipment has been created.","The shipment has been created." +"Cannot save shipment.","Cannot save shipment." +"The order no longer exists.","The order no longer exists." +"Cannot do shipment for the order separately from invoice.","Cannot do shipment for the order separately from invoice." +"Cannot do shipment for the order.","Cannot do shipment for the order." +"There are no shipping labels related to selected shipments.","There are no shipping labels related to selected shipments." +"Page not found.","Page not found." +"Tracking Information","Tracking Information" "Sorry, but we can't deliver to the destination country with this shipping module.","Sorry, but we can't deliver to the destination country with this shipping module." -The shipping module is not available.,The shipping module is not available. -This shipping method is not available. Please specify the zip code.,This shipping method is not available. Please specify the zip code. -No packages for request,No packages for request -Security validation of XML document has been failed.,Security validation of XML document has been failed. -All Allowed Countries,All Allowed Countries -Specific Countries,Specific Countries +"The shipping module is not available.","The shipping module is not available." +"This shipping method is not available. Please specify the zip code.","This shipping method is not available. Please specify the zip code." +"No packages for request","No packages for request" +"Security validation of XML document has been failed.","Security validation of XML document has been failed." +"All Allowed Countries","All Allowed Countries" +"Specific Countries","Specific Countries" Development,Development Live,Live -Divide to equal weight (one request),Divide to equal weight (one request) -Use origin weight (few requests),Use origin weight (few requests) +"Divide to equal weight (one request)","Divide to equal weight (one request)" +"Use origin weight (few requests)","Use origin weight (few requests)" Packages,Packages Package,Package Type,Type Length,Length -Signature Confirmation,Signature Confirmation -Customs Value,Customs Value +"Signature Confirmation","Signature Confirmation" +"Customs Value","Customs Value" Width,Width Contents,Contents -Total Weight,Total Weight +"Total Weight","Total Weight" Height,Height Size,Size Girth,Girth -Items in the Package,Items in the Package +"Items in the Package","Items in the Package" Product,Product Weight,Weight -Qty Ordered,Qty Ordered +"Qty Ordered","Qty Ordered" Qty,Qty "No detail for number ""%1""","No detail for number ""%1""" -Shipping labels is not available.,Shipping labels is not available. -Response info is not exist.,Response info is not exist. -Invalid carrier: %1,Invalid carrier: %1 -We don't have enough information to create shipping labels. Please make sure your store information and settings are complete.,We don't have enough information to create shipping labels. Please make sure your store information and settings are complete. -Per Order,Per Order -Per Package,Per Package +"Shipping labels is not available.","Shipping labels is not available." +"Response info is not exist.","Response info is not exist." +"Invalid carrier: %1","Invalid carrier: %1" +"We don't have enough information to create shipping labels. Please make sure your store information and settings are complete.","We don't have enough information to create shipping labels. Please make sure your store information and settings are complete." +"Per Order","Per Order" +"Per Package","Per Package" Fixed,Fixed Percent,Percent -Tracking information is unavailable.,Tracking information is unavailable. +"Tracking information is unavailable.","Tracking information is unavailable." message,message -Email has not been sent,Email has not been sent -Payment & Shipping Method,Payment & Shipping Method -Payment Information,Payment Information -The order was placed using %1.,The order was placed using %1. -Shipping Information,Shipping Information -Total Shipping Charges,Total Shipping Charges -Incl. Tax,Incl. Tax -Items to Ship,Items to Ship -Qty to Ship,Qty to Ship +"Email has not been sent","Email has not been sent" +"Payment & Shipping Method","Payment & Shipping Method" +"Payment Information","Payment Information" +"The order was placed using %1.","The order was placed using %1." +"Shipping Information","Shipping Information" +"Total Shipping Charges","Total Shipping Charges" +"Incl. Tax","Incl. Tax" +"Items to Ship","Items to Ship" +"Qty to Ship","Qty to Ship" Ship,Ship -Shipment Total,Shipment Total -Shipment Comments,Shipment Comments -Comment Text,Comment Text -Shipment Options,Shipment Options -Create Shipping Label,Create Shipping Label -Append Comments,Append Comments -Email Copy of Shipment,Email Copy of Shipment -Invalid value(s) for Qty to Ship,Invalid value(s) for Qty to Ship -Select All,Select All -Product Name,Product Name +"Shipment Total","Shipment Total" +"Shipment Comments","Shipment Comments" +"Comment Text","Comment Text" +"Shipment Options","Shipment Options" +"Create Shipping Label","Create Shipping Label" +"Append Comments","Append Comments" +"Email Copy of Shipment","Email Copy of Shipment" +"Invalid value(s) for Qty to Ship","Invalid value(s) for Qty to Ship" +"Select All","Select All" +"Product Name","Product Name" Delete,Delete -Create Packages,Create Packages +"Create Packages","Create Packages" Cancel,Cancel Save,Save -Add Package,Add Package -Add Selected Product(s) to Package,Add Selected Product(s) to Package -Add Products to Package,Add Products to Package -USPS domestic shipments don't use package types.,USPS domestic shipments don't use package types. +"Add Package","Add Package" +"Add Selected Product(s) to Package","Add Selected Product(s) to Package" +"Add Products to Package","Add Products to Package" +"USPS domestic shipments don't use package types.","USPS domestic shipments don't use package types." in,in cm,cm lb,lb kg,kg -Delete Package,Delete Package +"Delete Package","Delete Package" Explanation,Explanation Carrier,Carrier Title,Title Number,Number Action,Action -Are you sure?,Are you sure? -Shipping & Handling Information,Shipping & Handling Information -Track Order,Track Order -No shipping information available,No shipping information available -Shipping and Tracking Information,Shipping and Tracking Information -Track this shipment,Track this shipment -Items Shipped,Items Shipped -Order Total,Order Total -Shipment History,Shipment History -Qty Shipped,Qty Shipped -Print All Shipments,Print All Shipments -Shipment #,Shipment # -Print Shipment,Print Shipment -Tracking Number(s):,Tracking Number(s): +"Are you sure?","Are you sure?" +"Shipping & Handling Information","Shipping & Handling Information" +"Track Order","Track Order" +"No shipping information available","No shipping information available" +"Shipping and Tracking Information","Shipping and Tracking Information" +"Track this shipment","Track this shipment" +"Items Shipped","Items Shipped" +"Order Total","Order Total" +"Shipment History","Shipment History" +"Qty Shipped","Qty Shipped" +"Print All Shipments","Print All Shipments" +"Shipment #","Shipment #" +"Print Shipment","Print Shipment" +"Tracking Number(s):","Tracking Number(s):" SKU,SKU -Order tracking,Order tracking -Tracking Number:,Tracking Number: +"Order tracking","Order tracking" +"Tracking Number:","Tracking Number:" Carrier:,Carrier: Error:,Error: -Tracking information is currently not available. Please ,Tracking information is currently not available. Please -contact us,contact us - for more information or , for more information or -email us at ,email us at +"Tracking information is currently not available. Please ","Tracking information is currently not available. Please " +"contact us","contact us" +" for more information or "," for more information or " +"email us at ","email us at " Info:,Info: Track:,Track: -. ':',. ':' -Delivered on:,Delivered on: +". ':'",". ':'" +"Delivered on:","Delivered on:" N/A,N/A -There is no tracking available for this shipment.,There is no tracking available for this shipment. -There is no tracking available.,There is no tracking available. -Close Window,Close Window -Track history,Track history +"There is no tracking available for this shipment.","There is no tracking available for this shipment." +"There is no tracking available.","There is no tracking available." +"Close Window","Close Window" +"Track history","Track history" Location,Location Date,Date -Local Time,Local Time +"Local Time","Local Time" Description,Description -See our Shipping Policy,See our Shipping Policy -Shipping Settings Section,Shipping Settings Section -Shipping Policy Parameters Section,Shipping Policy Parameters Section -Shipping Methods Section,Shipping Methods Section -Shipping Settings,Shipping Settings +"See our Shipping Policy","See our Shipping Policy" +"Shipping Settings Section","Shipping Settings Section" +"Shipping Policy Parameters Section","Shipping Policy Parameters Section" +"Shipping Methods Section","Shipping Methods Section" +"Shipping Settings","Shipping Settings" Origin,Origin Country,Country Region/State,Region/State -ZIP/Postal Code,ZIP/Postal Code +"ZIP/Postal Code","ZIP/Postal Code" City,City -Street Address,Street Address -Street Address Line 2,Street Address Line 2 -Shipping Policy Parameters,Shipping Policy Parameters -Apply custom Shipping Policy,Apply custom Shipping Policy -Shipping Policy,Shipping Policy -Shipping Methods,Shipping Methods -Track your order,Track your order -Track All Shipments,Track All Shipments -This shipment no longer exists.,This shipment no longer exists. +"Street Address","Street Address" +"Street Address Line 2","Street Address Line 2" +"Shipping Policy Parameters","Shipping Policy Parameters" +"Apply custom Shipping Policy","Apply custom Shipping Policy" +"Shipping Policy","Shipping Policy" +"Shipping Methods","Shipping Methods" +"Track your order","Track your order" +"Track All Shipments","Track All Shipments" +"This shipment no longer exists.","This shipment no longer exists." From 758b0d64067f7e3091b0a4a550b0a2a79e79322e Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Mon, 30 Nov 2020 11:01:33 +0200 Subject: [PATCH 033/156] refactoring --- .../ActionGroup/AdminCheckProductOnProductGridActionGroup.xml | 2 +- .../Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml index aebd595a919f8..2faeea1cc299b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml @@ -19,4 +19,4 @@ <checkOption selector="{{AdminProductGridSection.productRowCheckboxBySku(product.sku)}}" stepKey="selectProduct"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml index 42719e2d6aa12..63277e2ed88fd 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml @@ -25,7 +25,7 @@ </before> <after> <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> - <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> From c172dc17940946721a1ff28df714c7e398c2165a Mon Sep 17 00:00:00 2001 From: Nikola Lardev <nikolalardev@gmail.com> Date: Mon, 30 Nov 2020 13:35:24 +0200 Subject: [PATCH 034/156] #30959 Fix typo --- .../Directory/Setup/Patch/Data/AddDataForGreece.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForGreece.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForGreece.php index 122a2b2bbc195..30b1021a3467d 100644 --- a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForGreece.php +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForGreece.php @@ -1,15 +1,15 @@ <?php /** - * Copyright © Magento, Inc. All rights reGRrved. - * GRe COPYING.txt for licenGR details. + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ declare(strict_types=1); -namespace Magento\Directory\GRtup\Patch\Data; +namespace Magento\Directory\Setup\Patch\Data; use Magento\Directory\Setup\DataInstaller; use Magento\Directory\Setup\DataInstallerFactory; -use Magento\Framework\Setup\ModuleDataGRtupInterface; +use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; /** @@ -20,7 +20,7 @@ class AddDataForGreece implements DataPatchInterface /** * @var ModuleDataSetupInterface */ - private $moduleDataGRtup; + private $moduleDataSetup; /** * @var DataInstallerFactory From beac203458390fc00814f96daa19d698b0221919 Mon Sep 17 00:00:00 2001 From: Vadim Malesh <51680850+engcom-Charlie@users.noreply.github.com> Date: Mon, 30 Nov 2020 14:08:24 +0200 Subject: [PATCH 035/156] remove redundant spaces --- .../Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml index 13688afd0efe9..ce8d6414e2882 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml @@ -16,11 +16,9 @@ <severity value="MAJOR"/> <group value="shipping"/> </annotations> - <before> <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin"/> </before> - <after> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> @@ -30,9 +28,7 @@ </actionGroup> <waitForPageLoad stepKey="waitForPageLoad"/> - <seeInCurrentUrl url="{{AdminShipmentsGridPage.url}}" stepKey="redirectToShipmentsGridPage"/> - <see selector="{{AdminMessagesSection.error}}" userInput='This shipment no longer exists.' stepKey="seeErrorMessage"/> </test> From ce7a3517b4d08ecd4b07eefcbf7e791e4f94db6b Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Mon, 30 Nov 2020 17:06:52 +0200 Subject: [PATCH 036/156] refactored --- .../Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index 1916fb9ebdbbb..c2070043e63de 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -90,4 +90,4 @@ <click selector="{{AdminInvoicesGridSection.firstRow}}" stepKey="clickInvoice2"/> <see selector="{{AdminInvoiceDetailsInformationSection.orderStatus}}" userInput="Processing" stepKey="seeOrderStatus2"/> </test> -</tests> \ No newline at end of file +</tests> From 7320189463af8d2a08f6138e524ed4838195d179 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Mon, 30 Nov 2020 17:15:08 +0200 Subject: [PATCH 037/156] refactored --- .../Mftf/Test/AddOutOfStockProductToCompareListTest.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml index c28c5a040e553..d8545c94010dc 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml @@ -87,13 +87,12 @@ <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForStorefrontProductComparePageLoad"/> <actionGroup ref="SeeProductInComparisonListActionGroup" stepKey="seeProductInCompareList"> - <argument name="productVar" value="$$product$$"/> + <argument name="productVar" value="$$product$$"/> </actionGroup> - - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="deleteProdFromCmpList"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="onCategoryPage"/> - <actionGroup ref="StorefrontGoToCategoryPageActionGroup" stepKey="waitForPageLoad1"> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="deleteProdFromCmpList"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="onCategoryPage"/> + <actionGroup ref="StorefrontGoToCategoryPageActionGroup" stepKey="waitForPageLoad1"> <argument name="categoryName" value="$$category.name$$"/> </actionGroup> From 8ba2695458f6c686a1caafb5cd629b0f67a85f10 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Tue, 1 Dec 2020 08:57:26 +0200 Subject: [PATCH 038/156] fixed indentation --- .../StorefrontHoverProductOnCategoryPageActionGroup.xml | 4 ++-- .../Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontHoverProductOnCategoryPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontHoverProductOnCategoryPageActionGroup.xml index 661d40fd4f13a..10d85a91a02c6 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontHoverProductOnCategoryPageActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontHoverProductOnCategoryPageActionGroup.xml @@ -10,10 +10,10 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="StorefrontHoverProductOnCategoryPageActionGroup"> <annotations> - <description>Hover product on the Category page</description> + <description>Hover product on the Category page</description> </annotations> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverOverProduct"/> + <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverOverProduct"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml index d8545c94010dc..8911e5d04fe4a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml @@ -31,7 +31,7 @@ </before> <after> - <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/> + <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> <argument name="tags" value=""/> </actionGroup> From d001c99173bbf407587b4ece8f8d51fec6e4f56c Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Tue, 1 Dec 2020 09:00:50 +0200 Subject: [PATCH 039/156] fixed indentation --- .../Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml index 8911e5d04fe4a..7f4228a21f3d5 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml @@ -120,7 +120,7 @@ <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForStorefrontProductComparePageLoad2"/> <actionGroup ref="SeeProductInComparisonListActionGroup" stepKey="seeProductInCompareList2"> - <argument name="productVar" value="$$product$$"/> + <argument name="productVar" value="$$product$$"/> </actionGroup> </test> From ffc0ab716c986735427125dd594449e8aac05f41 Mon Sep 17 00:00:00 2001 From: Vadim Malesh <51680850+engcom-Charlie@users.noreply.github.com> Date: Tue, 1 Dec 2020 10:17:20 +0200 Subject: [PATCH 040/156] update severity, testCaseId --- .../AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml index 4436aab59874a..38b85828c3421 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminOpenCreditmemoViewPageWithWrongCreditmemoIdTest.xml @@ -13,7 +13,8 @@ <stories value="Creditmemo Page With Wrong Creditmemo Id"/> <title value="Open Creditmemo View Page with Wrong Creditmemo Id"/> <description value="Open Creditmemo View Page with Wrong Creditmemo Id."/> - <severity value="MAJOR"/> + <severity value="BLOCKER"/> + <testCaseId value="MC-39500"/> <group value="sales"/> </annotations> <before> From 247817a04340e82b5246761888acfca82eee7736 Mon Sep 17 00:00:00 2001 From: Vadim Malesh <51680850+engcom-Charlie@users.noreply.github.com> Date: Tue, 1 Dec 2020 10:18:35 +0200 Subject: [PATCH 041/156] update severity, testCaseId --- .../Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml index ce8d6414e2882..d60dca08e6813 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminOpenShipmentViewPageWithWrongShipmentIdTest.xml @@ -13,7 +13,8 @@ <stories value="Shipment Page With Wrong Shipment Id"/> <title value="Open Shipment View Page with Wrong Shipment Id"/> <description value="Open Shipment View Page with Wrong Shipment Id."/> - <severity value="MAJOR"/> + <severity value="BLOCKER"/> + <testCaseId value="MC-39502"/> <group value="shipping"/> </annotations> <before> From 52e5d2cb33ddf9412e9fda9ef0694013f9796938 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Wed, 2 Dec 2020 17:19:59 +0200 Subject: [PATCH 042/156] autoformatted --- ...inCheckProductOnProductGridActionGroup.xml | 25 ++++---- .../AdminSetPriceForMassUpdateActionGroup.xml | 7 +-- ...oductPriceUpdatedOnEditPageActionGroup.xml | 5 +- .../Test/AdminMassProductPriceUpdateTest.xml | 57 +++++++++---------- 4 files changed, 45 insertions(+), 49 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml index 2faeea1cc299b..4216f4eedfda6 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <!-- /** * Copyright © Magento, Inc. All rights reserved. @@ -6,17 +6,16 @@ */ --> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminCheckProductOnProductGridActionGroup"> - <annotations> - <description>Check the checkbox for the product on the Product Grid</description> - </annotations> - <arguments> - <argument name="product" type="entity"/> - </arguments> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminCheckProductOnProductGridActionGroup"> + <annotations> + <description>Check the checkbox for the product on the Product Grid</description> + </annotations> + <arguments> + <argument name="product" type="entity"/> + </arguments> - <checkOption selector="{{AdminProductGridSection.productRowCheckboxBySku(product.sku)}}" stepKey="selectProduct"/> + <checkOption selector="{{AdminProductGridSection.productRowCheckboxBySku(product.sku)}}" stepKey="selectProduct"/> - </actionGroup> -</actionGroups> + </actionGroup> +</actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSetPriceForMassUpdateActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSetPriceForMassUpdateActionGroup.xml index b00f181c92360..0bae2a2f627a5 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSetPriceForMassUpdateActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSetPriceForMassUpdateActionGroup.xml @@ -6,8 +6,7 @@ */ --> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminSetPriceForMassUpdateActionGroup"> <annotations> <description>Click the "Change" checkbox for the "Price" field. Set new price.</description> @@ -16,9 +15,9 @@ <argument name="price" type="string"/> </arguments> - <scrollTo stepKey="scrollToPriceCheckBox" selector="{{AdminEditProductAttributesSection.ChangeAttributePriceToggle}}" x="0" y="-160"/> + <scrollTo stepKey="scrollToPriceCheckBox" selector="{{AdminEditProductAttributesSection.ChangeAttributePriceToggle}}" x="0" y="-160"/> <click selector="{{AdminEditProductAttributesSection.ChangeAttributePriceToggle}}" stepKey="selectPriceCheckBox"/> <fillField stepKey="fillPrice" selector="{{AdminEditProductAttributesSection.AttributePrice}}" userInput="{{price}}"/> </actionGroup> -</actionGroups> +</actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminProductPriceUpdatedOnEditPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminProductPriceUpdatedOnEditPageActionGroup.xml index c7a665119b328..42577f5e7735d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminProductPriceUpdatedOnEditPageActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminProductPriceUpdatedOnEditPageActionGroup.xml @@ -6,8 +6,7 @@ */ --> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AssertAdminProductPriceUpdatedOnEditPageActionGroup" extends="OpenEditProductOnBackendActionGroup"> <annotations> <description>Validate if Product price is updated on the Product creation/edit page</description> @@ -22,4 +21,4 @@ <seeInField selector="{{AdminProductFormSection.productSku}}" userInput="{{product.sku}}" stepKey="seeProductSku"/> <seeInField selector="{{AdminProductFormSection.productPrice}}" userInput="{{price}}" stepKey="seeProductPrice"/> </actionGroup> -</actionGroups> +</actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml index 63277e2ed88fd..f76ff23a3ec97 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml @@ -6,8 +6,7 @@ */ --> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="AdminMassProductPriceUpdateTest"> <annotations> <stories value="Mass product update"/> @@ -36,25 +35,25 @@ <actionGroup ref="SortProductsByIdDescendingActionGroup" stepKey="sortProductsByIdDescending"/> <actionGroup ref="AdminCheckProductOnProductGridActionGroup" stepKey="selectFirstProduct"> - <argument name="product" value="$simpleProduct1$"/> + <argument name="product" value="$simpleProduct1$"/> </actionGroup> - <actionGroup ref="AdminCheckProductOnProductGridActionGroup" stepKey="selectSecondProduct"> - <argument name="product" value="$simpleProduct2$"/> + <actionGroup ref="AdminCheckProductOnProductGridActionGroup" stepKey="selectSecondProduct"> + <argument name="product" value="$simpleProduct2$"/> </actionGroup> <actionGroup ref="AdminClickMassUpdateProductAttributesActionGroup" stepKey="clickDropdown"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickChangeStatus"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForProductAttributePageToLoad"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickChangeStatus"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForProductAttributePageToLoad"/> - <actionGroup ref="AdminSetPriceForMassUpdateActionGroup" stepKey="scrollToPriceCheckBox"> - <argument name="price" value="90.99"/> - </actionGroup> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectPriceCheckBox"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="fillPrice"/> + <actionGroup ref="AdminSetPriceForMassUpdateActionGroup" stepKey="scrollToPriceCheckBox"> + <argument name="price" value="90.99"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectPriceCheckBox"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="fillPrice"/> <actionGroup ref="AdminSaveProductsMassAttributesUpdateActionGroup" stepKey="clickOnSaveButton"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForUpdatedProductToSave"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeAttributeUpateSuccessMsg"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForUpdatedProductToSave"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeAttributeUpateSuccessMsg"/> <actionGroup ref="CliConsumerStartActionGroup" stepKey="startMessageQueueConsumer"> <argument name="consumerName" value="{{AdminProductAttributeUpdateConsumerData.consumerName}}"/> @@ -63,26 +62,26 @@ <magentoCLI command="cron:run --group=index" stepKey="runCron"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="openFirstProduct"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="openFirstProduct"/> <actionGroup ref="AssertAdminProductPriceUpdatedOnEditPageActionGroup" stepKey="waitForFirstProductToLoad"> - <argument name="product" value="$$simpleProduct1$$"/> - <argument name="price" value="90.99"/> + <argument name="product" value="$$simpleProduct1$$"/> + <argument name="price" value="90.99"/> </actionGroup> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductNameInField"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductSkuInField"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductPriceInField"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickOnBackButton"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductNameInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductSkuInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductPriceInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickOnBackButton"/> <actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="waitForProductsToLoad"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="openSecondProduct"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="openSecondProduct"/> <actionGroup ref="AssertAdminProductPriceUpdatedOnEditPageActionGroup" stepKey="waitForSecondProductToLoad"> - <argument name="product" value="$$simpleProduct2$$"/> - <argument name="price" value="90.99"/> - </actionGroup> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductNameInField"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductSkuInField"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductPriceInField"/> + <argument name="product" value="$$simpleProduct2$$"/> + <argument name="price" value="90.99"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductNameInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductSkuInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductPriceInField"/> </test> -</tests> +</tests> \ No newline at end of file From a048fb7c242556759d8d15081340906b48ed26ab Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Wed, 2 Dec 2020 17:30:29 +0200 Subject: [PATCH 043/156] corrected spacing --- .../AdminSetPriceForMassUpdateActionGroup.xml | 7 ++- ...oductPriceUpdatedOnEditPageActionGroup.xml | 5 +- .../Test/AdminMassProductPriceUpdateTest.xml | 57 ++++++++++--------- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSetPriceForMassUpdateActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSetPriceForMassUpdateActionGroup.xml index 0bae2a2f627a5..b00f181c92360 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSetPriceForMassUpdateActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSetPriceForMassUpdateActionGroup.xml @@ -6,7 +6,8 @@ */ --> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminSetPriceForMassUpdateActionGroup"> <annotations> <description>Click the "Change" checkbox for the "Price" field. Set new price.</description> @@ -15,9 +16,9 @@ <argument name="price" type="string"/> </arguments> - <scrollTo stepKey="scrollToPriceCheckBox" selector="{{AdminEditProductAttributesSection.ChangeAttributePriceToggle}}" x="0" y="-160"/> + <scrollTo stepKey="scrollToPriceCheckBox" selector="{{AdminEditProductAttributesSection.ChangeAttributePriceToggle}}" x="0" y="-160"/> <click selector="{{AdminEditProductAttributesSection.ChangeAttributePriceToggle}}" stepKey="selectPriceCheckBox"/> <fillField stepKey="fillPrice" selector="{{AdminEditProductAttributesSection.AttributePrice}}" userInput="{{price}}"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminProductPriceUpdatedOnEditPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminProductPriceUpdatedOnEditPageActionGroup.xml index 42577f5e7735d..c7a665119b328 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminProductPriceUpdatedOnEditPageActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminProductPriceUpdatedOnEditPageActionGroup.xml @@ -6,7 +6,8 @@ */ --> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AssertAdminProductPriceUpdatedOnEditPageActionGroup" extends="OpenEditProductOnBackendActionGroup"> <annotations> <description>Validate if Product price is updated on the Product creation/edit page</description> @@ -21,4 +22,4 @@ <seeInField selector="{{AdminProductFormSection.productSku}}" userInput="{{product.sku}}" stepKey="seeProductSku"/> <seeInField selector="{{AdminProductFormSection.productPrice}}" userInput="{{price}}" stepKey="seeProductPrice"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml index f76ff23a3ec97..63277e2ed88fd 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml @@ -6,7 +6,8 @@ */ --> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="AdminMassProductPriceUpdateTest"> <annotations> <stories value="Mass product update"/> @@ -35,25 +36,25 @@ <actionGroup ref="SortProductsByIdDescendingActionGroup" stepKey="sortProductsByIdDescending"/> <actionGroup ref="AdminCheckProductOnProductGridActionGroup" stepKey="selectFirstProduct"> - <argument name="product" value="$simpleProduct1$"/> + <argument name="product" value="$simpleProduct1$"/> </actionGroup> - <actionGroup ref="AdminCheckProductOnProductGridActionGroup" stepKey="selectSecondProduct"> - <argument name="product" value="$simpleProduct2$"/> + <actionGroup ref="AdminCheckProductOnProductGridActionGroup" stepKey="selectSecondProduct"> + <argument name="product" value="$simpleProduct2$"/> </actionGroup> <actionGroup ref="AdminClickMassUpdateProductAttributesActionGroup" stepKey="clickDropdown"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickChangeStatus"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForProductAttributePageToLoad"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickChangeStatus"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForProductAttributePageToLoad"/> - <actionGroup ref="AdminSetPriceForMassUpdateActionGroup" stepKey="scrollToPriceCheckBox"> - <argument name="price" value="90.99"/> - </actionGroup> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectPriceCheckBox"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="fillPrice"/> + <actionGroup ref="AdminSetPriceForMassUpdateActionGroup" stepKey="scrollToPriceCheckBox"> + <argument name="price" value="90.99"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectPriceCheckBox"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="fillPrice"/> <actionGroup ref="AdminSaveProductsMassAttributesUpdateActionGroup" stepKey="clickOnSaveButton"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForUpdatedProductToSave"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeAttributeUpateSuccessMsg"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForUpdatedProductToSave"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeAttributeUpateSuccessMsg"/> <actionGroup ref="CliConsumerStartActionGroup" stepKey="startMessageQueueConsumer"> <argument name="consumerName" value="{{AdminProductAttributeUpdateConsumerData.consumerName}}"/> @@ -62,26 +63,26 @@ <magentoCLI command="cron:run --group=index" stepKey="runCron"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="openFirstProduct"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="openFirstProduct"/> <actionGroup ref="AssertAdminProductPriceUpdatedOnEditPageActionGroup" stepKey="waitForFirstProductToLoad"> - <argument name="product" value="$$simpleProduct1$$"/> - <argument name="price" value="90.99"/> + <argument name="product" value="$$simpleProduct1$$"/> + <argument name="price" value="90.99"/> </actionGroup> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductNameInField"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductSkuInField"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductPriceInField"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickOnBackButton"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductNameInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductSkuInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeFirstProductPriceInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickOnBackButton"/> <actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="waitForProductsToLoad"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="openSecondProduct"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="openSecondProduct"/> <actionGroup ref="AssertAdminProductPriceUpdatedOnEditPageActionGroup" stepKey="waitForSecondProductToLoad"> - <argument name="product" value="$$simpleProduct2$$"/> - <argument name="price" value="90.99"/> - </actionGroup> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductNameInField"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductSkuInField"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductPriceInField"/> + <argument name="product" value="$$simpleProduct2$$"/> + <argument name="price" value="90.99"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductNameInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductSkuInField"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSecondProductPriceInField"/> </test> -</tests> \ No newline at end of file +</tests> From 92e94220d329065708e1e97fe038f5aa2fb022c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Szubert?= <bartlomiejszubert@gmail.com> Date: Thu, 3 Dec 2020 17:36:20 +0100 Subject: [PATCH 044/156] Fix #30724 - Customer Account Edit controller action enforces Page Title to "Account Information" --- app/code/Magento/Customer/Controller/Account/Edit.php | 9 ++++----- .../view/frontend/layout/customer_account_edit.xml | 3 +++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Account/Edit.php b/app/code/Magento/Customer/Controller/Account/Edit.php index 7c2b7215a05ef..d61bd4b1a0fcb 100644 --- a/app/code/Magento/Customer/Controller/Account/Edit.php +++ b/app/code/Magento/Customer/Controller/Account/Edit.php @@ -1,17 +1,16 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Customer\Controller\Account; -use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface; use Magento\Customer\Api\CustomerRepositoryInterface; -use Magento\Framework\Api\DataObjectHelper; use Magento\Customer\Model\Session; -use Magento\Framework\View\Result\PageFactory; +use Magento\Framework\Api\DataObjectHelper; use Magento\Framework\App\Action\Context; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\View\Result\PageFactory; class Edit extends \Magento\Customer\Controller\AbstractAccount implements HttpGetActionInterface { @@ -81,10 +80,10 @@ public function execute() \Magento\Customer\Api\Data\CustomerInterface::class ); } + $this->session->setCustomerData($customerDataObject); $this->session->setChangePassword($this->getRequest()->getParam('changepass') == 1); - $resultPage->getConfig()->getTitle()->set(__('Account Information')); return $resultPage; } } diff --git a/app/code/Magento/Customer/view/frontend/layout/customer_account_edit.xml b/app/code/Magento/Customer/view/frontend/layout/customer_account_edit.xml index f4dfaa6586b12..e89aa5ab624d9 100644 --- a/app/code/Magento/Customer/view/frontend/layout/customer_account_edit.xml +++ b/app/code/Magento/Customer/view/frontend/layout/customer_account_edit.xml @@ -7,6 +7,9 @@ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <update handle="customer_account"/> + <head> + <title>Account Information + From 6fc419105aa467bc909305775e8398d151969f0f Mon Sep 17 00:00:00 2001 From: Anna Pak <58164147+AnnaAPak@users.noreply.github.com> Date: Fri, 4 Dec 2020 09:33:05 +0200 Subject: [PATCH 045/156] Added line --- .../ActionGroup/AdminCheckProductOnProductGridActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml index 4216f4eedfda6..627659062b133 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml @@ -18,4 +18,4 @@ - \ No newline at end of file + From 64b617f95788ea499ced46dd620bf70a07868478 Mon Sep 17 00:00:00 2001 From: Anna Pak <58164147+AnnaAPak@users.noreply.github.com> Date: Fri, 4 Dec 2020 09:34:35 +0200 Subject: [PATCH 046/156] Added space --- .../Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml index 63277e2ed88fd..8a5da6d6e3640 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductPriceUpdateTest.xml @@ -38,7 +38,7 @@ - + From 9691ef605f9f46e4ee0d4b478dc0d1f736f1d125 Mon Sep 17 00:00:00 2001 From: Anna Pak <58164147+AnnaAPak@users.noreply.github.com> Date: Fri, 4 Dec 2020 09:43:49 +0200 Subject: [PATCH 047/156] corrected spacing --- .../ActionGroup/AdminCheckProductOnProductGridActionGroup.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml index 627659062b133..0e98db3e5d8a8 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCheckProductOnProductGridActionGroup.xml @@ -9,10 +9,10 @@ - Check the checkbox for the product on the Product Grid + Check the checkbox for the product on the Product Grid - + From 2f10855d003758de54fb23c83a972de25b6a26a7 Mon Sep 17 00:00:00 2001 From: Vova Yatsyuk Date: Fri, 4 Dec 2020 10:40:19 +0200 Subject: [PATCH 048/156] Allow to load base64 encoded images and fonts --- app/code/Magento/Csp/etc/config.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/code/Magento/Csp/etc/config.xml b/app/code/Magento/Csp/etc/config.xml index 6e2235479da93..07761995fdbca 100644 --- a/app/code/Magento/Csp/etc/config.xml +++ b/app/code/Magento/Csp/etc/config.xml @@ -92,6 +92,9 @@ 1 0 0 + + data + frame-src @@ -120,6 +123,9 @@ 1 0 0 + + data + @@ -197,6 +203,9 @@ 1 0 0 + + data + frame-src @@ -225,6 +234,9 @@ 1 0 0 + + data + From 59194579798bf462a46adbd8eefc8ba9804bdfe4 Mon Sep 17 00:00:00 2001 From: Dmitry Furs Date: Fri, 4 Dec 2020 14:27:48 +0300 Subject: [PATCH 049/156] Adjust .editorconfig to correct the automatic formatting of db_schema_whitelist.json files --- .editorconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.editorconfig b/.editorconfig index 1a9acd92fc0fc..40f57587d3497 100644 --- a/.editorconfig +++ b/.editorconfig @@ -16,3 +16,7 @@ indent_size = 2 [{composer, auth}.json] indent_size = 4 + +[db_schema_whitelist.json] +indent_size = 4 +trim_trailing_whitespace = false From db17e70f8ec0b2da5f7e9dfe6434d5b37cfcdf21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vinicius=20Bordinh=C3=A3o?= Date: Mon, 7 Dec 2020 01:08:16 -0300 Subject: [PATCH 050/156] ISSUE-29690: Developing MTFT tests covering the respective issue. --- ...ctOfConfigurableProductPageActionGroup.xml | 25 ++++ ...roductWithVideoAssociatedToVariantTest.xml | 134 ++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/StorefrontSelectSimpleProductOfConfigurableProductPageActionGroup.xml create mode 100644 app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithVideoAssociatedToVariantTest.xml diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/StorefrontSelectSimpleProductOfConfigurableProductPageActionGroup.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/StorefrontSelectSimpleProductOfConfigurableProductPageActionGroup.xml new file mode 100644 index 0000000000000..bfbef80f026da --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/StorefrontSelectSimpleProductOfConfigurableProductPageActionGroup.xml @@ -0,0 +1,25 @@ + + + + + + + Goes to the provided Storefront URL. Selects the provided Product Option under the Product Attribute. + + + + + + + + + + + + diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithVideoAssociatedToVariantTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithVideoAssociatedToVariantTest.xml new file mode 100644 index 0000000000000..7963eecbe5224 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithVideoAssociatedToVariantTest.xml @@ -0,0 +1,134 @@ + + + + + + + + + + <description value="Admin should be able to add videos for a Variant Product"/> + <severity value="MAJOR"/> + <testCaseId value="MC-37344"/> + <group value="ConfigurableProduct"/> + </annotations> + + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <createData entity="SimpleSubCategory" stepKey="categoryHandle"/> + + <createData entity="SimpleProduct" stepKey="simple1Handle"> + <requiredEntity createDataKey="categoryHandle"/> + </createData> + + <createData entity="SimpleProduct" stepKey="simple2Handle"> + <requiredEntity createDataKey="categoryHandle"/> + </createData> + + <createData entity="BaseConfigurableProduct" stepKey="baseConfigProductHandle"> + <requiredEntity createDataKey="categoryHandle"/> + </createData> + <createData entity="productDropDownAttribute" stepKey="productAttributeHandle"/> + + <createData entity="productAttributeOption1" stepKey="productAttributeOption1Handle"> + <requiredEntity createDataKey="productAttributeHandle"/> + </createData> + <createData entity="productAttributeOption2" stepKey="productAttributeOption2Handle"> + <requiredEntity createDataKey="productAttributeHandle"/> + </createData> + + <createData entity="AddToDefaultSet" stepKey="addToAttributeSetHandle"> + <requiredEntity createDataKey="productAttributeHandle"/> + </createData> + + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getAttributeOption1Handle"> + <requiredEntity createDataKey="productAttributeHandle"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getAttributeOption2Handle"> + <requiredEntity createDataKey="productAttributeHandle"/> + </getData> + + <createData entity="SimpleOne" stepKey="childProductHandle1"> + <requiredEntity createDataKey="productAttributeHandle"/> + <requiredEntity createDataKey="getAttributeOption1Handle"/> + </createData> + <createData entity="SimpleOne" stepKey="childProductHandle2"> + <requiredEntity createDataKey="productAttributeHandle"/> + <requiredEntity createDataKey="getAttributeOption2Handle"/> + </createData> + + <createData entity="ConfigurableProductTwoOptions" stepKey="configProductOptionHandle"> + <requiredEntity createDataKey="baseConfigProductHandle"/> + <requiredEntity createDataKey="productAttributeHandle"/> + <requiredEntity createDataKey="getAttributeOption1Handle"/> + <requiredEntity createDataKey="getAttributeOption2Handle"/> + </createData> + + <createData entity="ConfigurableProductAddChild" stepKey="configProductHandle1"> + <requiredEntity createDataKey="baseConfigProductHandle"/> + <requiredEntity createDataKey="childProductHandle1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="configProductHandle2"> + <requiredEntity createDataKey="baseConfigProductHandle"/> + <requiredEntity createDataKey="childProductHandle2"/> + </createData> + </before> + <after> + <actionGroup ref="AdminLogoutActionGroup" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="simple1Handle" stepKey="deleteSimple1"/> + <deleteData createDataKey="simple2Handle" stepKey="deleteSimple2"/> + <deleteData createDataKey="childProductHandle1" stepKey="deleteChild1"/> + <deleteData createDataKey="childProductHandle2" stepKey="deleteChild2"/> + <deleteData createDataKey="baseConfigProductHandle" stepKey="deleteConfig"/> + <deleteData createDataKey="categoryHandle" stepKey="deleteCategory"/> + <deleteData createDataKey="productAttributeHandle" stepKey="deleteProductAttribute"/> + + <!-- Reindex invalidated indices after product attribute has been created/deleted --> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> + </after> + + <actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="productIndexPage"/> + + <actionGroup ref="FilterProductGridBySkuActionGroup" stepKey="filterProductGrid"> + <argument name="product" value="$$childProductHandle1$$"/> + </actionGroup> + <actionGroup ref="OpenProductForEditByClickingRowXColumnYInProductGridActionGroup" stepKey="openProducForEditByClickingRow1Column2InProductGrid1"/> + + <actionGroup ref="AddProductVideoActionGroup" stepKey="addVideoForProduct" /> + + <!-- Add image to product --> + <actionGroup ref="AddProductImageActionGroup" stepKey="addImageForProduct"> + <argument name="image" value="MagentoLogo"/> + </actionGroup> + <actionGroup ref="SaveProductFormActionGroup" stepKey="saveProduct"/> + + <!-- Assert product image in admin product form --> + <actionGroup ref="AssertProductImageAdminProductPageActionGroup" stepKey="assertProductImageAdminProductPage"/> + + <!-- Assert product in storefront product page --> + <actionGroup ref="AssertProductNameAndSkuInStorefrontProductPageByCustomAttributeUrlKeyActionGroup" stepKey="AssertProductInStorefrontProductPage"> + <argument name="product" value="$$baseConfigProductHandle$$"/> + </actionGroup> + + <actionGroup ref="StorefrontSelectSimpleProductOfConfigurableProductPageActionGroup" stepKey="assertSimpleProductIsAccessibleInStorefrontProductPageActionGroup" > + <argument name="urlKey" value="$$baseConfigProductHandle.custom_attributes[url_key]$$" /> + <argument name="productAttribute" value="$$productAttributeHandle.default_value$$"/> + <argument name="productOption" value="$$getAttributeOption1Handle.value$$"/> + </actionGroup> + + <!-- Assert product image in storefront product page --> + <actionGroup ref="AssertProductImageStorefrontProductPage2ActionGroup" stepKey="assertProductImageStorefrontProductPageActionGroup"> + <argument name="product" value="$$baseConfigProductHandle$$"/> + <argument name="image" value="MagentoLogo"/> + </actionGroup> + + <!-- Assert product video in storefront product page --> + <actionGroup ref="AssertProductVideoStorefrontProductPageActionGroup" stepKey="assertProductVideoStorefrontProductPage"/> + </test> +</tests> From 41c3aa20144741faa1a5935c1764416872166474 Mon Sep 17 00:00:00 2001 From: Renon Stewart <srenon@users.noreply.github.com> Date: Tue, 8 Dec 2020 01:16:25 -0500 Subject: [PATCH 051/156] Issues 31197 - Loading wrong order tax info --- app/code/Magento/Sales/Block/Adminhtml/Order/Totals/Tax.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Totals/Tax.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Totals/Tax.php index e923b006a0ac6..1f8d0a0bc265d 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Totals/Tax.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Totals/Tax.php @@ -95,7 +95,7 @@ public function getFullTaxInfo() $taxClassAmount = $this->_taxHelper->getCalculatedTaxes($source); if (empty($taxClassAmount)) { - $rates = $this->_taxOrderFactory->create()->getCollection()->loadByOrder($source)->toArray(); + $rates = $this->_taxOrderFactory->create()->getCollection()->loadByOrder($this->getOrder())->toArray(); $taxClassAmount = $this->_taxCalculation->reproduceProcess($rates['items']); } From 9cae620c1648b48b01cce3dcc9fea06c9249a14a Mon Sep 17 00:00:00 2001 From: Elisei <brunoelisei@gmail.com> Date: Tue, 8 Dec 2020 13:19:04 -0300 Subject: [PATCH 052/156] Fixed #31211 --- app/code/Magento/Vault/i18n/en_US.csv | 1 + .../frontend/templates/customer_account/credit_card.phtml | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Vault/i18n/en_US.csv b/app/code/Magento/Vault/i18n/en_US.csv index f7ee19055563c..0c54d583198d1 100644 --- a/app/code/Magento/Vault/i18n/en_US.csv +++ b/app/code/Magento/Vault/i18n/en_US.csv @@ -13,3 +13,4 @@ Actions,Actions Delete,Delete "PayPal Account","PayPal Account" Cancel,Cancel +"Are you sure you want to delete this card: %1?","Are you sure you want to delete this card: %1?" \ No newline at end of file diff --git a/app/code/Magento/Vault/view/frontend/templates/customer_account/credit_card.phtml b/app/code/Magento/Vault/view/frontend/templates/customer_account/credit_card.phtml index 7be7946fff1bf..a2439898799cd 100644 --- a/app/code/Magento/Vault/view/frontend/templates/customer_account/credit_card.phtml +++ b/app/code/Magento/Vault/view/frontend/templates/customer_account/credit_card.phtml @@ -43,9 +43,7 @@ $ccNumberView = $block->escapeHtml($block->getNumberLast4Digits()); "modalClass": "my-credit-cards-popup", "toggleEvent": "click", "title": "<?= $block->escapeHtml(__('Delete')) ?>", - "content": "Are you sure you want to delete this card: <?= - /* @noEscape */ $ccNumberView - ?>?" + "content": "<?= $block->escapeHtml(__('Are you sure you want to delete this card: %1?', /* @noEscape */ $ccNumberView)) ?>" } }'> <span><?= $block->escapeHtml(__('Delete')) ?></span> From 8b5549cc4e92c64720b6e7b802eca7b9512229ba Mon Sep 17 00:00:00 2001 From: Arnob Saha <arnobsh@gmail.com> Date: Wed, 9 Dec 2020 00:53:21 -0600 Subject: [PATCH 053/156] MC-39353: Incorrect Quantity Shipped Displayed on order detail page on the front - MFTF test and the solution --- .../StorefrontCustomerOrderShipmentPage.xml | 14 +++ ...ontOrderShipmentsQtyShippedActionGroup.xml | 24 ++++ .../StorefrontSalesOrderShipmentSection.xml | 14 +++ ...ifyOrderShipmentForDecimalQuantityTest.xml | 104 ++++++++++++++++++ .../shipment/items/renderer/default.phtml | 2 +- 5 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerOrderShipmentPage.xml create mode 100644 app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertStorefrontOrderShipmentsQtyShippedActionGroup.xml create mode 100644 app/code/Magento/Sales/Test/Mftf/Section/StorefrontSalesOrderShipmentSection.xml create mode 100644 app/code/Magento/Sales/Test/Mftf/Test/StorefrontVerifyOrderShipmentForDecimalQuantityTest.xml diff --git a/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerOrderShipmentPage.xml b/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerOrderShipmentPage.xml new file mode 100644 index 0000000000000..da41e6ada79a0 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerOrderShipmentPage.xml @@ -0,0 +1,14 @@ +<?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="StorefrontCustomerOrderShipmentPage" url="sales/order/shipment/order_id/{{var1}}" area="storefront" module="Magento_Customer" parameterized="true"> + <section name="StorefrontCustomerOrderSection"/> + </page> +</pages> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertStorefrontOrderShipmentsQtyShippedActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertStorefrontOrderShipmentsQtyShippedActionGroup.xml new file mode 100644 index 0000000000000..0c3544f8944ed --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertStorefrontOrderShipmentsQtyShippedActionGroup.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="AssertStorefrontOrderShipmentsQtyShippedActionGroup"> + <annotations> + <description>Verify Customer Order Shipments Qty Shipped</description> + </annotations> + <arguments> + <argument name="expectedQtyShipped" type="string" defaultValue="0"/> + </arguments> + <grabTextFrom selector="{{StorefrontSalesOrderShipmentSection.salesOrderQtyShipped}}" stepKey="grabSalesOrderQtyShipped"/> + <assertEquals stepKey="assertOrderQtyShipped"> + <actualResult type="string">$grabSalesOrderQtyShipped</actualResult> + <expectedResult type="string">{{expectedQtyShipped}}</expectedResult> + </assertEquals> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/StorefrontSalesOrderShipmentSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/StorefrontSalesOrderShipmentSection.xml new file mode 100644 index 0000000000000..e2e814efb9f02 --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/Section/StorefrontSalesOrderShipmentSection.xml @@ -0,0 +1,14 @@ +<?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="StorefrontSalesOrderShipmentSection"> + <element name="salesOrderQtyShipped" type="text" selector="//td[@data-th='Qty Shipped']"/> + </section> +</sections> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontVerifyOrderShipmentForDecimalQuantityTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontVerifyOrderShipmentForDecimalQuantityTest.xml new file mode 100644 index 0000000000000..b086074132e85 --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontVerifyOrderShipmentForDecimalQuantityTest.xml @@ -0,0 +1,104 @@ +<?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="StorefrontVerifyOrderShipmentForDecimalQuantityTest"> + <annotations> + <title value="Incorrect Quantity Shipped Displayed on order detail page on the front"/> + <stories value="Verify shipment quantity for decimal quantity at frontend order shipment tab"/> + <description value="Verify shipment quantity for decimal quantity at frontend order shipment tab"/> + <features value="Sales"/> + <testCaseId value="MC-39777"/> + <useCaseId value="MC-39353"/> + <severity value="MAJOR"/> + <group value="Sales"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createSimpleCategory"/> + <createData entity="SimpleProduct" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="createSimpleCategory"/> + </createData> + <createData entity="Simple_US_Customer" stepKey="createSimpleUsCustomer"> + <field key="group_id">1</field> + </createData> + </before> + <after> + <!--Clear Filters--> + <actionGroup ref="AdminClearFiltersActionGroup" stepKey="ClearFiltersAfter"/> + <actionGroup ref="AdminOrdersGridClearFiltersActionGroup" stepKey="clearOrderListingFilters"/> + <deleteData createDataKey="createSimpleCategory" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="createSimpleProduct" stepKey="deletePreReqSimpleProduct"/> + <!--Logout from customer account--> + <amOnPage url="{{StorefrontCustomerLogoutPage.url}}" stepKey="logoutCustomerOne"/> + <waitForPageLoad stepKey="waitLogoutCustomerOne"/> + <deleteData createDataKey="createSimpleUsCustomer" stepKey="deleteCustomer"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + <!--Step1. Login as admin. Go to Catalog > Products page. Filtering *prod1*. Open *prod1* to edit--> + <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin" /> + <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="filterGroupedProductOptions"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + <!-- Step2. Update product Advanced Inventory Setting. + Set *Qty Uses Decimals* to *Yes* and *Enable Qty Increments* to *Yes* and *Qty Increments* to *2.14*. --> + <actionGroup ref="OpenProductForEditByClickingRowXColumnYInProductGridActionGroup" stepKey="openProduct"/> + <actionGroup ref="AdminClickOnAdvancedInventoryLinkActionGroup" stepKey="clickOnAdvancedInventoryLink"/> + <actionGroup ref="AdminSetQtyUsesDecimalsConfigActionGroup" stepKey="setQtyUsesDecimalsConfig"> + <argument name="value" value="Yes"/> + </actionGroup> + <actionGroup ref="AdminSetEnableQtyIncrementsActionGroup" stepKey="setEnableQtyIncrements"> + <argument name="value" value="Yes"/> + </actionGroup> + <actionGroup ref="AdminSetQtyIncrementsForProductActionGroup" stepKey="setQtyIncrementsValue"> + <argument name="qty" value="2.14"/> + </actionGroup> + <actionGroup ref="AdminSetMinAllowedQtyForProductActionGroup" stepKey="fillMiniAllowedQty"> + <argument name="qty" value="2.14"/> + </actionGroup> + <actionGroup ref="AdminSubmitAdvancedInventoryFormActionGroup" stepKey="clickOnDoneButton"/> + + <!--Step3. Save the product--> + <actionGroup ref="AdminProductFormSaveActionGroup" stepKey="clickOnSaveButton"/> + <!--Step4. Open *Customer view* (Go to *Store Front*). Open *prod1* page (Find via search and click on product name) --> + <!--Step5. Log in to Storefront as Customer--> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="signUpNewUser"> + <argument name="Customer" value="$$createSimpleUsCustomer$$"/> + </actionGroup> + <!--Step6. Go to product page--> + <amOnPage url="$$createSimpleProduct.custom_attributes[url_key]$$.html" stepKey="navigateToSimpleProductPage"/> + <waitForPageLoad stepKey="waitForCatalogPageLoad"/> + <!--Step7. Add Product to Shopping Cart--> + <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProductPage"> + <argument name="productName" value="$$createSimpleProduct.name$$"/> + </actionGroup> + + <!--Step8. Navigate to checkout--> + <actionGroup ref="StorefrontOpenCheckoutPageActionGroup" stepKey="openCheckoutPage"/> + <!--Step9. Click next button to open payment section--> + <actionGroup ref="StorefrontCheckoutClickNextButtonActionGroup" stepKey="clickNext"/> + <!--Step10. Click place order--> + <actionGroup ref="ClickPlaceOrderActionGroup" stepKey="placeOrder"/> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/> + <!--Step11. Go to admin Order page for newly created order--> + <actionGroup ref="OpenOrderByIdActionGroup" stepKey="filterOrdersGridById"> + <argument name="orderId" value="{$grabOrderNumber}"/> + </actionGroup> + + <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShipAction"/> + <click selector="{{AdminShipmentMainActionsSection.submitShipment}}" stepKey="clickSubmitShipment"/> + + <actionGroup ref="StorefrontNavigateToCustomerOrdersHistoryPageActionGroup" stepKey="goToOrderHistoryPage"/> + <!--Step12. Go to Customer Order Shipment Page and Checking the correctness of displayed Qty Shipped --> + <amOnPage url="{{StorefrontCustomerOrderShipmentPage.url({$grabOrderNumber})}}" stepKey="amOnOrderShipmentPage"/> + <waitForPageLoad time="30" stepKey="waitForOrderShipmentsPageLoad"/> + <actionGroup ref="AssertStorefrontOrderShipmentsQtyShippedActionGroup" stepKey="verifyAssertOrderShipments"> + <argument name="expectedQtyShipped" value="2.14"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/shipment/items/renderer/default.phtml b/app/code/Magento/Sales/view/frontend/templates/order/shipment/items/renderer/default.phtml index 6c7567a8cd14b..d2caa1a2ce935 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/shipment/items/renderer/default.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/shipment/items/renderer/default.phtml @@ -42,5 +42,5 @@ <td class="col sku" data-th="<?= $block->escapeHtml(__('SKU')) ?>"> <?= /* @noEscape */ $block->prepareSku($block->getSku()) ?> </td> - <td class="col qty" data-th="<?= $block->escapeHtml(__('Qty Shipped')) ?>"><?= (int) $_item->getQty() ?></td> + <td class="col qty" data-th="<?= $block->escapeHtml(__('Qty Shipped')) ?>"><?= (float) $_item->getQty() ?></td> </tr> From 24adb1448ef850ba2127acb80ac5abfbf94f5d1c Mon Sep 17 00:00:00 2001 From: "taras.gamanov" <engcom-vendorworker-hotel@adobe.com> Date: Wed, 9 Dec 2020 17:54:30 +0200 Subject: [PATCH 054/156] MFTF has been updated --- ...teConfigurableProductWithVideoAssociatedToVariantTest.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithVideoAssociatedToVariantTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithVideoAssociatedToVariantTest.xml index 7963eecbe5224..0eb730bf91afc 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithVideoAssociatedToVariantTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithVideoAssociatedToVariantTest.xml @@ -17,9 +17,13 @@ <severity value="MAJOR"/> <testCaseId value="MC-37344"/> <group value="ConfigurableProduct"/> + <skip> + <issueId value="MC-33903"/> + </skip> </annotations> <before> + <createData entity="ProductVideoYoutubeApiKeyConfig" stepKey="setYoutubeApiKeyConfig"/> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleSubCategory" stepKey="categoryHandle"/> @@ -81,6 +85,7 @@ </before> <after> <actionGroup ref="AdminLogoutActionGroup" stepKey="amOnLogoutPage"/> + <createData entity="DefaultProductVideoConfig" stepKey="setYoutubeApiKeyDefaultConfig"/> <deleteData createDataKey="simple1Handle" stepKey="deleteSimple1"/> <deleteData createDataKey="simple2Handle" stepKey="deleteSimple2"/> <deleteData createDataKey="childProductHandle1" stepKey="deleteChild1"/> From 8ba64a2f3901149a1f42a798385803d24c2e5013 Mon Sep 17 00:00:00 2001 From: Roman Flowers <flowers@adobe.com> Date: Wed, 9 Dec 2020 17:37:32 -0600 Subject: [PATCH 055/156] MC-39463: GraphQL caches urlResolver response and can return the old value after the url rewrite update --- .../Magento/UrlRewrite/Model/UrlRewrite.php | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php index 5f29008621c1a..0f72116ac7614 100644 --- a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php +++ b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php @@ -7,8 +7,17 @@ namespace Magento\UrlRewrite\Model; +use Magento\Catalog\Api\CategoryRepositoryInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Category; +use Magento\Catalog\Model\Product; +use Magento\Cms\Api\PageRepositoryInterface; +use Magento\Cms\Model\Page; use Magento\Framework\App\ObjectManager; +use Magento\Framework\EntityManager\EventManager; +use Magento\Framework\Indexer\CacheContext; use Magento\Framework\Serialize\Serializer\Json; +use Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite; /** * UrlRewrite model class @@ -92,4 +101,58 @@ public function setMetadata($metadata) } return $this->setData(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::METADATA, $metadata); } + + private function opt1() { + $map = [ + Rewrite::ENTITY_TYPE_PRODUCT => Product::CACHE_TAG, + Rewrite::ENTITY_TYPE_CATEGORY => Category::CACHE_TAG, + Rewrite::ENTITY_TYPE_CMS_PAGE => Page::CACHE_TAG + ]; + + if ($this->getEntityType() !== Rewrite::ENTITY_TYPE_CUSTOM) { + $cacheKey = $map[$this->getEntityType()]; + + $cacheContext = ObjectManager::getInstance()->get(CacheContext::class); + $eventManager = ObjectManager::getInstance()->get(EventManager::class); + + $cacheContext->registerEntities($cacheKey, [$this->getEntityId()]); + $eventManager->dispatch('clean_cache_by_tags', ['object' => $cacheContext]); + } + } + + private function opt2() { + $map = [ + Rewrite::ENTITY_TYPE_PRODUCT => function ($prodId) { + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); + return $productRepository->getById($prodId); + }, + Rewrite::ENTITY_TYPE_CATEGORY => function ($catId) { + /** @var CategoryRepositoryInterface $productRepository */ + $categoryRepository = ObjectManager::getInstance()->get(CategoryRepositoryInterface::class); + return $categoryRepository->get($catId); + }, + Rewrite::ENTITY_TYPE_CMS_PAGE => function ($cmsId) { + /** @var PageRepositoryInterface $productRepository */ + $pageRepository = ObjectManager::getInstance()->get(PageRepositoryInterface::class); + return $pageRepository->getById($cmsId); + }, + Rewrite::ENTITY_TYPE_CUSTOM => false + ]; + + $getter = $map[$this->getEntityType()]; + + if ($getter) { + $entity = $getter($this->getEntityId()); + + $entityManager = ObjectManager::getInstance()->get(EventManager::class); + $entityManager->dispatch('clean_cache_by_tags', ['object' => $entity]); + } + } + + public function afterSave() + { + $this->opt1(); + return parent::afterSave(); // TODO: Change the autogenerated stub + } } From 1b11a71ff1a141c1d58b651f2cdeefabffd4f6bd Mon Sep 17 00:00:00 2001 From: "taras.gamanov" <engcom-vendorworker-hotel@adobe.com> Date: Thu, 10 Dec 2020 12:03:21 +0200 Subject: [PATCH 056/156] refactoring --- .../Block/Plugin/Product/Media/Gallery.php | 4 ++-- .../Test/Unit/Block/Plugin/Product/Media/GalleryTest.php | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php b/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php index 21bfb3b873a7b..c000e52aae39a 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php +++ b/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php @@ -56,7 +56,7 @@ public function afterGetOptionsMediaGalleryDataJson( * @param Product $product * @return array */ - private function getProductGallery($product) + private function getProductGallery(Product $product): array { $result = []; $images = $this->getImagesOrderedByPosition($product); @@ -74,7 +74,7 @@ private function getProductGallery($product) * @param Product $product * @return array */ - private function getImagesOrderedByPosition($product) + private function getImagesOrderedByPosition(Product $product): array { $imagesCollection = $product->getMediaGalleryImages(); $images = $imagesCollection->getItems(); diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php index 367b639176665..7debc86c9ed23 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php @@ -46,8 +46,6 @@ public function testAfterGetOptions() ->disableOriginalConstructor() ->onlyMethods(['getItems']) ->getMock(); - - $galleryMock->expects(($this->any()))->method('getProduct')->willReturn($productMock); $productMock->expects($this->once())->method('getTypeId')->willReturn('configurable'); $productMock->expects($this->once())->method('getTypeInstance')->willReturn($configurableTypeMock); From 9c797541a473849301d58f29cb264fff3e850345 Mon Sep 17 00:00:00 2001 From: Roman Flowers <flowers@adobe.com> Date: Thu, 10 Dec 2020 07:39:07 -0600 Subject: [PATCH 057/156] MC-39463: GraphQL caches urlResolver response and can return the old value after the url rewrite update --- .../Magento/UrlRewrite/Model/UrlRewrite.php | 120 +++++++++--------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php index 0f72116ac7614..708811eccd9cc 100644 --- a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php +++ b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php @@ -7,17 +7,20 @@ namespace Magento\UrlRewrite\Model; -use Magento\Catalog\Api\CategoryRepositoryInterface; -use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Category; use Magento\Catalog\Model\Product; -use Magento\Cms\Api\PageRepositoryInterface; use Magento\Cms\Model\Page; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Data\Collection\AbstractDb; use Magento\Framework\EntityManager\EventManager; use Magento\Framework\Indexer\CacheContext; +use Magento\Framework\Model\AbstractModel; +use Magento\Framework\Model\Context; +use Magento\Framework\Model\ResourceModel\AbstractResource; +use Magento\Framework\Registry; use Magento\Framework\Serialize\Serializer\Json; use Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite; +use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection; /** * UrlRewrite model class @@ -36,32 +39,49 @@ * @method UrlRewrite setStoreId($value) * @method UrlRewrite setDescription($value) */ -class UrlRewrite extends \Magento\Framework\Model\AbstractModel +class UrlRewrite extends AbstractModel { /** * @var Json */ private $serializer; + /** + * @var CacheContext|mixed|null + */ + private $cacheContext; + + /** + * @var EventManager|mixed|null + */ + private $eventManager; + /** * UrlRewrite constructor. * - * @param \Magento\Framework\Model\Context $context - * @param \Magento\Framework\Registry $registry - * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource - * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection + * @param Context $context + * @param Registry $registry + * @param AbstractResource|null $resource + * @param AbstractDb|null $resourceCollection * @param array $data - * @param Json $serializer + * @param Json|null $serializer + * @param CacheContext|null $cacheContext + * @param EventManager|null $eventManager */ public function __construct( - \Magento\Framework\Model\Context $context, - \Magento\Framework\Registry $registry, - \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, - \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, + Context $context, + Registry $registry, + AbstractResource $resource = null, + AbstractDb $resourceCollection = null, array $data = [], - Json $serializer = null - ) { + Json $serializer = null, + CacheContext $cacheContext = null, + EventManager $eventManager = null + ) + { $this->serializer = $serializer ?: ObjectManager::getInstance()->get(Json::class); + $this->cacheContext = $cacheContext ?: ObjectManager::getInstance()->get(CacheContext::class); + $this->eventManager = $eventManager ?: ObjectManager::getInstance()->get(EventManager::class); parent::__construct($context, $registry, $resource, $resourceCollection, $data); } @@ -72,8 +92,8 @@ public function __construct( */ protected function _construct() { - $this->_init(\Magento\UrlRewrite\Model\ResourceModel\UrlRewrite::class); - $this->_collectionName = \Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection::class; + $this->_init(ResourceModel\UrlRewrite::class); + $this->_collectionName = UrlRewriteCollection::class; } /** @@ -102,57 +122,37 @@ public function setMetadata($metadata) return $this->setData(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::METADATA, $metadata); } - private function opt1() { - $map = [ - Rewrite::ENTITY_TYPE_PRODUCT => Product::CACHE_TAG, - Rewrite::ENTITY_TYPE_CATEGORY => Category::CACHE_TAG, - Rewrite::ENTITY_TYPE_CMS_PAGE => Page::CACHE_TAG - ]; - - if ($this->getEntityType() !== Rewrite::ENTITY_TYPE_CUSTOM) { - $cacheKey = $map[$this->getEntityType()]; + /** + * Clean cache for the entity which was affected by updating UrlRewrite + * + * @param $entityType + * @param $entityId + */ + private function cleanCacheForEntity($entityType, $entityId) + { + if ($entityType !== Rewrite::ENTITY_TYPE_CUSTOM) { + $map = [ + Rewrite::ENTITY_TYPE_PRODUCT => Product::CACHE_TAG, + Rewrite::ENTITY_TYPE_CATEGORY => Category::CACHE_TAG, + Rewrite::ENTITY_TYPE_CMS_PAGE => Page::CACHE_TAG + ]; - $cacheContext = ObjectManager::getInstance()->get(CacheContext::class); - $eventManager = ObjectManager::getInstance()->get(EventManager::class); + $cacheKey = $map[$entityType]; - $cacheContext->registerEntities($cacheKey, [$this->getEntityId()]); - $eventManager->dispatch('clean_cache_by_tags', ['object' => $cacheContext]); + $this->cacheContext->registerEntities($cacheKey, [$entityId]); + $this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]); } } - private function opt2() { - $map = [ - Rewrite::ENTITY_TYPE_PRODUCT => function ($prodId) { - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); - return $productRepository->getById($prodId); - }, - Rewrite::ENTITY_TYPE_CATEGORY => function ($catId) { - /** @var CategoryRepositoryInterface $productRepository */ - $categoryRepository = ObjectManager::getInstance()->get(CategoryRepositoryInterface::class); - return $categoryRepository->get($catId); - }, - Rewrite::ENTITY_TYPE_CMS_PAGE => function ($cmsId) { - /** @var PageRepositoryInterface $productRepository */ - $pageRepository = ObjectManager::getInstance()->get(PageRepositoryInterface::class); - return $pageRepository->getById($cmsId); - }, - Rewrite::ENTITY_TYPE_CUSTOM => false - ]; - - $getter = $map[$this->getEntityType()]; - - if ($getter) { - $entity = $getter($this->getEntityId()); - - $entityManager = ObjectManager::getInstance()->get(EventManager::class); - $entityManager->dispatch('clean_cache_by_tags', ['object' => $entity]); - } + public function afterDelete() + { + $this->cleanCacheForEntity($this->getEntityType(), $this->getEntityId()); + return parent::afterDelete(); // TODO: Change the autogenerated stub } public function afterSave() { - $this->opt1(); - return parent::afterSave(); // TODO: Change the autogenerated stub + $this->cleanCacheForEntity($this->getEntityType(), $this->getEntityId()); + return parent::afterSave(); } } From a4798a0e43c1c8789e14e069baa60a02854d9bd9 Mon Sep 17 00:00:00 2001 From: Roman Flowers <flowers@adobe.com> Date: Thu, 10 Dec 2020 14:22:27 -0600 Subject: [PATCH 058/156] MC-39463: GraphQL caches urlResolver response and can return the old value after the url rewrite update --- app/code/Magento/CatalogUrlRewrite/etc/di.xml | 8 +++++++ app/code/Magento/CmsUrlRewrite/etc/di.xml | 7 ++++++ .../Magento/UrlRewrite/Model/UrlRewrite.php | 22 ++++++++++--------- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/etc/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/di.xml index 5fb7d33546d60..62b63d41f0501 100644 --- a/app/code/Magento/CatalogUrlRewrite/etc/di.xml +++ b/app/code/Magento/CatalogUrlRewrite/etc/di.xml @@ -56,6 +56,14 @@ </argument> </arguments> </type> + <type name="Magento\UrlRewrite\Model\UrlRewrite"> + <arguments> + <argument name="entityToCacheTagMap" xsi:type="array"> + <item name="product" xsi:type="const">Magento\Catalog\Model\Product::CACHE_TAG</item> + <item name="category" xsi:type="const">Magento\Catalog\Model\Category::CACHE_TAG</item> + </argument> + </arguments> + </type> <type name="Magento\Eav\Model\Config"> <arguments> <argument name="attributesForPreload" xsi:type="array"> diff --git a/app/code/Magento/CmsUrlRewrite/etc/di.xml b/app/code/Magento/CmsUrlRewrite/etc/di.xml index 497d7a175842d..0463bf5b696c5 100644 --- a/app/code/Magento/CmsUrlRewrite/etc/di.xml +++ b/app/code/Magento/CmsUrlRewrite/etc/di.xml @@ -9,4 +9,11 @@ <type name="Magento\Cms\Model\ResourceModel\Page"> <plugin name="cms_url_rewrite_plugin" type="Magento\CmsUrlRewrite\Plugin\Cms\Model\ResourceModel\Page"/> </type> + <type name="Magento\UrlRewrite\Model\UrlRewrite"> + <arguments> + <argument name="entityToCacheTagMap" xsi:type="array"> + <item name="cms-page" xsi:type="const">Magento\Cms\Model\Page::CACHE_TAG</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php index 708811eccd9cc..363a3388daab0 100644 --- a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php +++ b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php @@ -56,6 +56,11 @@ class UrlRewrite extends AbstractModel */ private $eventManager; + /** + * @var array + */ + private $entityToCacheTagMap; + /** * UrlRewrite constructor. * @@ -67,6 +72,7 @@ class UrlRewrite extends AbstractModel * @param Json|null $serializer * @param CacheContext|null $cacheContext * @param EventManager|null $eventManager + * @param array $entityToCacheTagMap */ public function __construct( Context $context, @@ -76,12 +82,14 @@ public function __construct( array $data = [], Json $serializer = null, CacheContext $cacheContext = null, - EventManager $eventManager = null + EventManager $eventManager = null, + array $entityToCacheTagMap = [] ) { $this->serializer = $serializer ?: ObjectManager::getInstance()->get(Json::class); $this->cacheContext = $cacheContext ?: ObjectManager::getInstance()->get(CacheContext::class); $this->eventManager = $eventManager ?: ObjectManager::getInstance()->get(EventManager::class); + $this->entityToCacheTagMap = $entityToCacheTagMap; parent::__construct($context, $registry, $resource, $resourceCollection, $data); } @@ -130,14 +138,8 @@ public function setMetadata($metadata) */ private function cleanCacheForEntity($entityType, $entityId) { - if ($entityType !== Rewrite::ENTITY_TYPE_CUSTOM) { - $map = [ - Rewrite::ENTITY_TYPE_PRODUCT => Product::CACHE_TAG, - Rewrite::ENTITY_TYPE_CATEGORY => Category::CACHE_TAG, - Rewrite::ENTITY_TYPE_CMS_PAGE => Page::CACHE_TAG - ]; - - $cacheKey = $map[$entityType]; + if ($entityType !== Rewrite::ENTITY_TYPE_CUSTOM && array_key_exists($entityType, $this->entityToCacheTagMap)) { + $cacheKey = $this->entityToCacheTagMap[$entityType]; $this->cacheContext->registerEntities($cacheKey, [$entityId]); $this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]); @@ -147,7 +149,7 @@ private function cleanCacheForEntity($entityType, $entityId) public function afterDelete() { $this->cleanCacheForEntity($this->getEntityType(), $this->getEntityId()); - return parent::afterDelete(); // TODO: Change the autogenerated stub + return parent::afterDelete(); } public function afterSave() From e8d2a5ece6479d6c1b2e3cf17f5245946e34420c Mon Sep 17 00:00:00 2001 From: Viktor Rad <vrad@adobe.com> Date: Mon, 14 Dec 2020 14:13:34 -0600 Subject: [PATCH 059/156] MC-39132: [MAGENTO CLOUD] PWA causing failed Magento Tester results --- .../Magento/Framework/Interception/PluginListGenerator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Interception/PluginListGenerator.php b/lib/internal/Magento/Framework/Interception/PluginListGenerator.php index effc291bb883b..8f3a03dd4fc20 100644 --- a/lib/internal/Magento/Framework/Interception/PluginListGenerator.php +++ b/lib/internal/Magento/Framework/Interception/PluginListGenerator.php @@ -227,8 +227,6 @@ public function loadScopedVirtualTypes($scopePriorityScheme, $loadedScopes, $plu $data = $this->reader->read($scopeCode) ?: []; unset($data['preferences']); if (count($data) > 0) { - $inherited = []; - $processed = []; $pluginData = $this->merge($data, $pluginData); foreach ($data as $class => $config) { if (isset($config['type'])) { @@ -236,6 +234,8 @@ public function loadScopedVirtualTypes($scopePriorityScheme, $loadedScopes, $plu } } } + $inherited = []; + $processed = []; $loadedScopes[$scopeCode] = true; } if ($this->isCurrentScope($scopeCode)) { From 93c78c070d17c5363c6ce5890d54e39fcdffebc0 Mon Sep 17 00:00:00 2001 From: Viktor Rad <vrad@adobe.com> Date: Mon, 14 Dec 2020 16:08:00 -0600 Subject: [PATCH 060/156] MC-39132: [MAGENTO CLOUD] PWA causing failed Magento Tester results --- .../Interception/PluginListGeneratorTest.php | 61 ++++++++++++++----- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Interception/PluginListGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Framework/Interception/PluginListGeneratorTest.php index 1046c678e253a..bda4cdd6cbaa5 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Interception/PluginListGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Interception/PluginListGeneratorTest.php @@ -23,7 +23,14 @@ class PluginListGeneratorTest extends TestCase /** * Generated plugin list config for frontend scope */ - const CACHE_ID = 'primary|global|frontend|plugin-list'; + const CACHE_ID_FRONTEND = 'primary|global|frontend|plugin-list'; + + /** + * Generated plugin list config for dummy scope + */ + const CACHE_ID_DUMMY = 'primary|global|dummy|plugin-list'; + + private $cacheIds = [self::CACHE_ID_FRONTEND, self::CACHE_ID_DUMMY]; /** * @var PluginListGenerator @@ -90,31 +97,51 @@ protected function setUp(): void */ public function testPluginListConfigGeneration() { - $scopes = ['frontend']; + $scopes = ['global', 'frontend', 'dummy']; + $globalPlugin = 'genericHeaderPlugin'; + $frontendPlugin = 'response-http-page-cache'; $this->model->write($scopes); - $configData = $this->model->load(self::CACHE_ID); - $this->assertNotEmpty($configData[0]); - $this->assertNotEmpty($configData[1]); - $this->assertNotEmpty($configData[2]); - $expected = [ + $configDataFrontend = $this->model->load(self::CACHE_ID_FRONTEND); + $this->assertNotEmpty($configDataFrontend[0]); + $this->assertNotEmpty($configDataFrontend[1]); + $this->assertNotEmpty($configDataFrontend[2]); + $expectedFrontend = [ 1 => [ - 0 => 'genericHeaderPlugin', - 1 => 'response-http-page-cache' + 0 => $globalPlugin, + 1 => $frontendPlugin ] ]; // Here in test is assumed that this class below has 3 plugins. But the amount of plugins and class itself // may vary. If it is changed, please update these assertions. $this->assertArrayHasKey( 'Magento\\Framework\\App\\Response\\Http_sendResponse___self', - $configData[2], + $configDataFrontend[2], 'Processed plugin does not exist in the processed plugins array.' ); $this->assertSame( - $expected, - $configData[2]['Magento\\Framework\\App\\Response\\Http_sendResponse___self'], + $expectedFrontend, + $configDataFrontend[2]['Magento\\Framework\\App\\Response\\Http_sendResponse___self'], 'Plugin configurations are not equal' ); + + $configDataDummy = $this->model->load(self::CACHE_ID_DUMMY); + /** + * Make sure "dummy" scope with no plugins in system should not contain plugins from "frontend" scope + */ + $this->assertNotContains( + $frontendPlugin, + $configDataDummy[2]['Magento\\Framework\\App\\Response\\Http_sendResponse___self'][1], + 'Plugin configurations are not equal. "dummy" scope should not contain plugins from "frontend" scope' + ); + /** + * Make sure "dummy" scope with no plugins in system should contain plugins from "global" scope + */ + $this->assertContains( + $globalPlugin, + $configDataDummy[2]['Magento\\Framework\\App\\Response\\Http_sendResponse___self'][1], + 'Plugin configurations are not equal. "dummy" scope should contain plugins from "global" scope' + ); } /** @@ -137,11 +164,13 @@ private function getCustomDirs(): array */ protected function tearDown(): void { - $filePath = $this->directoryList->getPath(DirectoryList::GENERATED_METADATA) - . '/' . self::CACHE_ID . '.' . 'php'; + foreach ($this->cacheIds as $cacheId) { + $filePath = $this->directoryList->getPath(DirectoryList::GENERATED_METADATA) + . '/' . $cacheId . '.' . 'php'; - if (file_exists($filePath)) { - $this->file->deleteFile($filePath); + if (file_exists($filePath)) { + $this->file->deleteFile($filePath); + } } } } From cbc884d700a4e7178bb575e4f6ecfed349428f33 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Tue, 15 Dec 2020 10:39:06 +0200 Subject: [PATCH 061/156] added AdminSelectAttributeSetActionGroup --- .../AdminSelectAttributeSetActionGroup.xml | 24 +++++++++++++++++++ .../AdminChangeProductAttributeSetTest.xml | 6 ++--- ...ateProductAttributesStoreViewScopeTest.xml | 4 +++- ...AdminConfigurableProductBulkUpdateTest.xml | 7 ++++-- 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetActionGroup.xml new file mode 100644 index 0000000000000..b0d0cc75b0e74 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetActionGroup.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="AdminSelectAttributeSetActionGroup"> + <annotations> + <description></description> + </annotations> + <arguments> + <argument name="attributeSet" type="entity"/> + </arguments> + + <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> + <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{attributeSet.attribute_set_name}}" stepKey="searchForAttrSet"/> + <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet"/> + + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml index 3b8c2cb736721..89b39cdd93355 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml @@ -60,9 +60,9 @@ <argument name="product" value="$$createSimpleProduct$$"/> </actionGroup> - <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> - <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="$$createAttributeSet.attribute_set_name$$" stepKey="searchForAttrSet"/> - <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet"/> + <actionGroup ref="AdminSelectAttributeSetActionGroup" stepKey="startEditAttrSet"> + <argument name="attributeSet" value="CatalogAttributeSet"/> + </actionGroup> <waitForText userInput="$$createProductAttribute.default_frontend_label$$" stepKey="seeAttributeInForm"/> </test> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest/AdminMassUpdateProductAttributesStoreViewScopeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest/AdminMassUpdateProductAttributesStoreViewScopeTest.xml index 30ab17f65f3c8..0312d7279d214 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest/AdminMassUpdateProductAttributesStoreViewScopeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest/AdminMassUpdateProductAttributesStoreViewScopeTest.xml @@ -52,7 +52,9 @@ <!-- Update attribute --> <click selector="{{AdminEditProductAttributesSection.ChangeAttributeDescriptionToggle}}" stepKey="toggleToChangeDescription"/> <fillField selector="{{AdminEditProductAttributesSection.AttributeDescription}}" userInput="Updated $$createProductOne.custom_attributes[description]$$" stepKey="fillAttributeDescriptionField"/> - <click selector="{{AdminEditProductAttributesSection.Save}}" stepKey="save"/> + <actionGroup ref="AdminSaveProductsMassAttributesUpdateActionGroup" stepKey="save"/> + <!-- <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForSuccessMessage"/> --> + <!-- <click selector="{{AdminEditProductAttributesSection.Save}}" stepKey="save"/> --> <see selector="{{AdminProductMessagesSection.successMessage}}" userInput="Message is added to queue" stepKey="seeAttributeUpateSuccessMsg"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateTest/AdminConfigurableProductBulkUpdateTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateTest/AdminConfigurableProductBulkUpdateTest.xml index 556ede0bdc06f..d4875684b70c1 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateTest/AdminConfigurableProductBulkUpdateTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateTest/AdminConfigurableProductBulkUpdateTest.xml @@ -59,8 +59,11 @@ <!-- Update the description --> <click selector="{{AdminUpdateAttributesSection.toggleDescription}}" stepKey="clickToggleDescription"/> <fillField selector="{{AdminUpdateAttributesSection.description}}" userInput="MFTF automation!" stepKey="fillDescription"/> - <click selector="{{AdminEditProductAttributesSection.Save}}" stepKey="clickSave"/> - <waitForElementVisible selector="{{AdminProductMessagesSection.successMessage}}" time="60" stepKey="waitForSuccessMessage"/> + <actionGroup ref="AdminSaveProductsMassAttributesUpdateActionGroup" stepKey="clickSave"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForSuccessMessage"/> + + <!-- <click selector="{{AdminEditProductAttributesSection.Save}}" stepKey="clickSave"/> + <waitForElementVisible selector="{{AdminProductMessagesSection.successMessage}}" time="60" stepKey="waitForSuccessMessage"/> --> <see selector="{{AdminProductMessagesSection.successMessage}}" userInput="Message is added to queue" stepKey="seeAttributeUpdateSuccessMsg"/> <!-- Apply changes --> From 7f127923ba83be5dba9caef78ce6f584e0ec16e9 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Tue, 15 Dec 2020 11:48:12 +0200 Subject: [PATCH 062/156] MC-39104: 2 error messages in Cart when product is out of stock --- .../Model/Quote/Item/QuantityValidator.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php index 317a573a653e9..b4754eea5c064 100644 --- a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php +++ b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php @@ -157,11 +157,13 @@ public function validate(Observer $observer) if ($stockStatus->getStockStatus() === Stock::STOCK_OUT_OF_STOCK || $parentStockStatus && $parentStockStatus->getStockStatus() == Stock::STOCK_OUT_OF_STOCK ) { - $quoteItem->addErrorInfo( - 'cataloginventory', - Data::ERROR_QTY, - __('This product is out of stock.') - ); + if (!$quoteItem->getStockStateResult() && !$quoteItem->getStockStateResult()->getHasError()) { + $quoteItem->addErrorInfo( + 'cataloginventory', + Data::ERROR_QTY, + __('This product is out of stock.') + ); + } $quoteItem->getQuote()->addErrorInfo( 'stock', 'cataloginventory', From 55b0fc25c1a643a25a5af2e034f956efbddfff84 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Tue, 15 Dec 2020 12:18:24 +0200 Subject: [PATCH 063/156] updated tests with new ActionGroup --- .../Test/AdminAttributeSetSelectionTest.xml | 18 ++++++++++++------ .../AdminBasicBundleProductAttributesTest.xml | 8 +++++--- ...tributeSetOnEditProductPageActionGroup.xml} | 11 +++++------ .../AdminChangeProductAttributeSetTest.xml | 4 ++-- .../Test/AdminCreateAttributeSetEntityTest.xml | 8 +++++--- ...dminCreateProductCustomAttributeSetTest.xml | 8 +++++--- 6 files changed, 34 insertions(+), 23 deletions(-) rename app/code/Magento/Catalog/Test/Mftf/ActionGroup/{AdminSelectAttributeSetActionGroup.xml => AdminSelectAttributeSetOnEditProductPageActionGroup.xml} (69%) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml index ca8a35ee7a363..ceed14e76fb4b 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml @@ -42,9 +42,13 @@ <!-- Switch from default attribute set to new attribute set --> <amOnPage url="{{AdminProductCreatePage.url('4', 'bundle')}}" stepKey="goToNewProductPage"/> <waitForPageLoad stepKey="wait2"/> - <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> - <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="searchForAttrSet"/> - <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet"/> + + <actionGroup ref="AdminSelectAttributeSetOnEditProductPageActionGroup" stepKey="startEditAttrSet"> + <argument name="attributeSet" value="{{ProductAttributeFrontendLabel.label}}"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="searchForAttrSet"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectAttrSet"/> + <fillField selector="{{AdminProductFormBundleSection.productName}}" userInput="{{BundleProduct.name}}" stepKey="fillProductName"/> <fillField selector="{{AdminProductFormBundleSection.productSku}}" userInput="{{BundleProduct.sku}}" stepKey="fillProductSku"/> @@ -64,9 +68,11 @@ <click selector="{{AdminProductFiltersSection.attributeSetOfFirstRow(ProductAttributeFrontendLabel.label)}}" stepKey="clickAttributeSet2"/> <waitForPageLoad stepKey="waitForPageLoad2"/> - <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet2"/> - <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{BundleProduct.defaultAttribute}}" stepKey="searchForAttrSet2"/> - <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet2"/> + <actionGroup ref="AdminSelectAttributeSetOnEditProductPageActionGroup" stepKey="startEditAttrSet2"> + <argument name="attributeSet" value="{{BundleProduct.defaultAttribute}}"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="searchForAttrSet2"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectAttrSet2"/> <!--save the product/published by default--> <actionGroup ref="AdminProductFormSaveActionGroup" stepKey="clickSaveButton2"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml index 79d85c6ced957..228c1d3cf1def 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml @@ -109,9 +109,11 @@ <checkOption selector="{{AdminProductFormBundleSection.enableDisableToggle}}" stepKey="clickOnEnableDisableToggleAgain"/> <!--Apply Attribute Set--> - <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> - <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{ProductAttributeFrontendLabelTwo.label}}" stepKey="searchForAttrSet"/> - <click selector="{{AdminProductFormSection.attributeSetFilterResultByName(ProductAttributeFrontendLabelTwo.label)}}" stepKey="selectAttrSet"/> + <actionGroup ref="AdminSelectAttributeSetOnEditProductPageActionGroup" stepKey="startEditAttrSet"> + <argument name="attributeSet" value="{{ProductAttributeFrontendLabelTwo.label}}"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="searchForAttrSet"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectAttrSet"/> <!--Product name and SKU--> <fillField selector="{{AdminProductFormBundleSection.productName}}" userInput="{{BundleProduct.name2}}" stepKey="fillProductName"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml similarity index 69% rename from app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetActionGroup.xml rename to app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml index b0d0cc75b0e74..2307ad313ad3c 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml @@ -8,17 +8,16 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminSelectAttributeSetActionGroup"> + <actionGroup name="AdminSelectAttributeSetOnEditProductPageActionGroup"> <annotations> <description></description> </annotations> <arguments> - <argument name="attributeSet" type="entity"/> + <argument name="attributeSet" type="string"/> </arguments> - <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> - <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{attributeSet.attribute_set_name}}" stepKey="searchForAttrSet"/> - <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet"/> - + <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="clickAttributeSetDropdown"/> + <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{attributeSet}}" stepKey="searchForAttributeSet"/> + <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttributeSet"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml index 89b39cdd93355..7c124a60c7877 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml @@ -60,8 +60,8 @@ <argument name="product" value="$$createSimpleProduct$$"/> </actionGroup> - <actionGroup ref="AdminSelectAttributeSetActionGroup" stepKey="startEditAttrSet"> - <argument name="attributeSet" value="CatalogAttributeSet"/> + <actionGroup ref="AdminSelectAttributeSetOnEditProductPageActionGroup" stepKey="startEditAttrSet"> + <argument name="attributeSet" value="$$createAttributeSet.attribute_set_name$$"/> </actionGroup> <waitForText userInput="$$createProductAttribute.default_frontend_label$$" stepKey="seeAttributeInForm"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateAttributeSetEntityTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateAttributeSetEntityTest.xml index 9fef5e4203167..8d3fbbaa34355 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateAttributeSetEntityTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateAttributeSetEntityTest.xml @@ -64,9 +64,11 @@ </actionGroup> <!-- Switch from default attribute set to new attribute set --> - <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> - <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="$$createAttributeSet.attribute_set_name$$" stepKey="searchForAttrSet"/> - <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet"/> + <actionGroup ref="AdminSelectAttributeSetOnEditProductPageActionGroup" stepKey="startEditAttrSet"> + <argument name="attributeSet" value="$$createAttributeSet.attribute_set_name$$"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="searchForAttrSet"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectAttrSet"/> <!-- See new attribute set --> <see selector="{{AdminProductFormSection.attributeSet}}" userInput="$$createAttributeSet.attribute_set_name$$" stepKey="seeAttributeSetName"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductCustomAttributeSetTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductCustomAttributeSetTest.xml index d2278f3ddae1d..d1110f593545d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductCustomAttributeSetTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductCustomAttributeSetTest.xml @@ -62,9 +62,11 @@ <!-- Switch from default attribute set to new attribute set --> <!-- A scrollToTopOfPage is needed to hide the floating header --> <scrollToTopOfPage stepKey="scrollToTop"/> - <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> - <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="searchForAttrSet"/> - <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet"/> + <actionGroup ref="AdminSelectAttributeSetOnEditProductPageActionGroup" stepKey="startEditAttrSet"> + <argument name="attributeSet" value="{{ProductAttributeFrontendLabel.label}}"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="searchForAttrSet"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectAttrSet"/> <!-- See new attibute set --> <seeElementInDOM selector="{{AdminProductFormSection.divByDataIndex('testgroupname')}}" stepKey="seeTestGroupName"/> From 88b58a08d39906584398e0c7762413e18c054a27 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Tue, 15 Dec 2020 12:25:08 +0200 Subject: [PATCH 064/156] refactored --- ...AdminSelectAttributeSetOnEditProductPageActionGroup.xml | 3 ++- .../Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml | 2 ++ .../AdminMassUpdateProductAttributesStoreViewScopeTest.xml | 4 +--- .../AdminConfigurableProductBulkUpdateTest.xml | 7 ++----- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml index 2307ad313ad3c..42f7f72c1cd73 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml @@ -10,7 +10,8 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminSelectAttributeSetOnEditProductPageActionGroup"> <annotations> - <description></description> + <description>Selects the specified value from the Attribute Set dropdown. + The Edit Product Page should be opened prior to Action Group execution</description> </annotations> <arguments> <argument name="attributeSet" type="string"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml index 7c124a60c7877..e7d4241500bfb 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml @@ -63,6 +63,8 @@ <actionGroup ref="AdminSelectAttributeSetOnEditProductPageActionGroup" stepKey="startEditAttrSet"> <argument name="attributeSet" value="$$createAttributeSet.attribute_set_name$$"/> </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="searchForAttrSet"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectAttrSet"/> <waitForText userInput="$$createProductAttribute.default_frontend_label$$" stepKey="seeAttributeInForm"/> </test> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest/AdminMassUpdateProductAttributesStoreViewScopeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest/AdminMassUpdateProductAttributesStoreViewScopeTest.xml index 0312d7279d214..30ab17f65f3c8 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest/AdminMassUpdateProductAttributesStoreViewScopeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest/AdminMassUpdateProductAttributesStoreViewScopeTest.xml @@ -52,9 +52,7 @@ <!-- Update attribute --> <click selector="{{AdminEditProductAttributesSection.ChangeAttributeDescriptionToggle}}" stepKey="toggleToChangeDescription"/> <fillField selector="{{AdminEditProductAttributesSection.AttributeDescription}}" userInput="Updated $$createProductOne.custom_attributes[description]$$" stepKey="fillAttributeDescriptionField"/> - <actionGroup ref="AdminSaveProductsMassAttributesUpdateActionGroup" stepKey="save"/> - <!-- <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForSuccessMessage"/> --> - <!-- <click selector="{{AdminEditProductAttributesSection.Save}}" stepKey="save"/> --> + <click selector="{{AdminEditProductAttributesSection.Save}}" stepKey="save"/> <see selector="{{AdminProductMessagesSection.successMessage}}" userInput="Message is added to queue" stepKey="seeAttributeUpateSuccessMsg"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateTest/AdminConfigurableProductBulkUpdateTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateTest/AdminConfigurableProductBulkUpdateTest.xml index d4875684b70c1..556ede0bdc06f 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateTest/AdminConfigurableProductBulkUpdateTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateTest/AdminConfigurableProductBulkUpdateTest.xml @@ -59,11 +59,8 @@ <!-- Update the description --> <click selector="{{AdminUpdateAttributesSection.toggleDescription}}" stepKey="clickToggleDescription"/> <fillField selector="{{AdminUpdateAttributesSection.description}}" userInput="MFTF automation!" stepKey="fillDescription"/> - <actionGroup ref="AdminSaveProductsMassAttributesUpdateActionGroup" stepKey="clickSave"/> - <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForSuccessMessage"/> - - <!-- <click selector="{{AdminEditProductAttributesSection.Save}}" stepKey="clickSave"/> - <waitForElementVisible selector="{{AdminProductMessagesSection.successMessage}}" time="60" stepKey="waitForSuccessMessage"/> --> + <click selector="{{AdminEditProductAttributesSection.Save}}" stepKey="clickSave"/> + <waitForElementVisible selector="{{AdminProductMessagesSection.successMessage}}" time="60" stepKey="waitForSuccessMessage"/> <see selector="{{AdminProductMessagesSection.successMessage}}" userInput="Message is added to queue" stepKey="seeAttributeUpdateSuccessMsg"/> <!-- Apply changes --> From 9d505f4662e54e77b43c392ee57976722bfb3853 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Tue, 15 Dec 2020 12:27:17 +0200 Subject: [PATCH 065/156] added AdminSelectAttributeSetOnEditProductPageActionGroup --- .../Test/AdminAttributeSetSelectionTest.xml | 18 +++++++++----- .../AdminBasicBundleProductAttributesTest.xml | 8 ++++--- ...tributeSetOnEditProductPageActionGroup.xml | 24 +++++++++++++++++++ .../AdminChangeProductAttributeSetTest.xml | 8 ++++--- .../AdminCreateAttributeSetEntityTest.xml | 8 ++++--- ...minCreateProductCustomAttributeSetTest.xml | 8 ++++--- 6 files changed, 56 insertions(+), 18 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml index ca8a35ee7a363..ceed14e76fb4b 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml @@ -42,9 +42,13 @@ <!-- Switch from default attribute set to new attribute set --> <amOnPage url="{{AdminProductCreatePage.url('4', 'bundle')}}" stepKey="goToNewProductPage"/> <waitForPageLoad stepKey="wait2"/> - <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> - <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="searchForAttrSet"/> - <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet"/> + + <actionGroup ref="AdminSelectAttributeSetOnEditProductPageActionGroup" stepKey="startEditAttrSet"> + <argument name="attributeSet" value="{{ProductAttributeFrontendLabel.label}}"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="searchForAttrSet"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectAttrSet"/> + <fillField selector="{{AdminProductFormBundleSection.productName}}" userInput="{{BundleProduct.name}}" stepKey="fillProductName"/> <fillField selector="{{AdminProductFormBundleSection.productSku}}" userInput="{{BundleProduct.sku}}" stepKey="fillProductSku"/> @@ -64,9 +68,11 @@ <click selector="{{AdminProductFiltersSection.attributeSetOfFirstRow(ProductAttributeFrontendLabel.label)}}" stepKey="clickAttributeSet2"/> <waitForPageLoad stepKey="waitForPageLoad2"/> - <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet2"/> - <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{BundleProduct.defaultAttribute}}" stepKey="searchForAttrSet2"/> - <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet2"/> + <actionGroup ref="AdminSelectAttributeSetOnEditProductPageActionGroup" stepKey="startEditAttrSet2"> + <argument name="attributeSet" value="{{BundleProduct.defaultAttribute}}"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="searchForAttrSet2"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectAttrSet2"/> <!--save the product/published by default--> <actionGroup ref="AdminProductFormSaveActionGroup" stepKey="clickSaveButton2"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml index 79d85c6ced957..228c1d3cf1def 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml @@ -109,9 +109,11 @@ <checkOption selector="{{AdminProductFormBundleSection.enableDisableToggle}}" stepKey="clickOnEnableDisableToggleAgain"/> <!--Apply Attribute Set--> - <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> - <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{ProductAttributeFrontendLabelTwo.label}}" stepKey="searchForAttrSet"/> - <click selector="{{AdminProductFormSection.attributeSetFilterResultByName(ProductAttributeFrontendLabelTwo.label)}}" stepKey="selectAttrSet"/> + <actionGroup ref="AdminSelectAttributeSetOnEditProductPageActionGroup" stepKey="startEditAttrSet"> + <argument name="attributeSet" value="{{ProductAttributeFrontendLabelTwo.label}}"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="searchForAttrSet"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectAttrSet"/> <!--Product name and SKU--> <fillField selector="{{AdminProductFormBundleSection.productName}}" userInput="{{BundleProduct.name2}}" stepKey="fillProductName"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml new file mode 100644 index 0000000000000..42f7f72c1cd73 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.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="AdminSelectAttributeSetOnEditProductPageActionGroup"> + <annotations> + <description>Selects the specified value from the Attribute Set dropdown. + The Edit Product Page should be opened prior to Action Group execution</description> + </annotations> + <arguments> + <argument name="attributeSet" type="string"/> + </arguments> + + <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="clickAttributeSetDropdown"/> + <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{attributeSet}}" stepKey="searchForAttributeSet"/> + <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttributeSet"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml index 3b8c2cb736721..e7d4241500bfb 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeSetTest.xml @@ -60,9 +60,11 @@ <argument name="product" value="$$createSimpleProduct$$"/> </actionGroup> - <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> - <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="$$createAttributeSet.attribute_set_name$$" stepKey="searchForAttrSet"/> - <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet"/> + <actionGroup ref="AdminSelectAttributeSetOnEditProductPageActionGroup" stepKey="startEditAttrSet"> + <argument name="attributeSet" value="$$createAttributeSet.attribute_set_name$$"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="searchForAttrSet"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectAttrSet"/> <waitForText userInput="$$createProductAttribute.default_frontend_label$$" stepKey="seeAttributeInForm"/> </test> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateAttributeSetEntityTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateAttributeSetEntityTest.xml index 9fef5e4203167..8d3fbbaa34355 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateAttributeSetEntityTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateAttributeSetEntityTest.xml @@ -64,9 +64,11 @@ </actionGroup> <!-- Switch from default attribute set to new attribute set --> - <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> - <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="$$createAttributeSet.attribute_set_name$$" stepKey="searchForAttrSet"/> - <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet"/> + <actionGroup ref="AdminSelectAttributeSetOnEditProductPageActionGroup" stepKey="startEditAttrSet"> + <argument name="attributeSet" value="$$createAttributeSet.attribute_set_name$$"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="searchForAttrSet"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectAttrSet"/> <!-- See new attribute set --> <see selector="{{AdminProductFormSection.attributeSet}}" userInput="$$createAttributeSet.attribute_set_name$$" stepKey="seeAttributeSetName"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductCustomAttributeSetTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductCustomAttributeSetTest.xml index d2278f3ddae1d..d1110f593545d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductCustomAttributeSetTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductCustomAttributeSetTest.xml @@ -62,9 +62,11 @@ <!-- Switch from default attribute set to new attribute set --> <!-- A scrollToTopOfPage is needed to hide the floating header --> <scrollToTopOfPage stepKey="scrollToTop"/> - <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> - <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="searchForAttrSet"/> - <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet"/> + <actionGroup ref="AdminSelectAttributeSetOnEditProductPageActionGroup" stepKey="startEditAttrSet"> + <argument name="attributeSet" value="{{ProductAttributeFrontendLabel.label}}"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="searchForAttrSet"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectAttrSet"/> <!-- See new attibute set --> <seeElementInDOM selector="{{AdminProductFormSection.divByDataIndex('testgroupname')}}" stepKey="seeTestGroupName"/> From 60e6c687fd2aa57734a519a983ab81e1ee381427 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Tue, 15 Dec 2020 14:28:46 +0200 Subject: [PATCH 066/156] MC-39104: 2 error messages in Cart when product is out of stock --- .../Model/Quote/Item/QuantityValidator.php | 4 +- .../Initializer/QuantityValidatorTest.php | 50 ++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php index b4754eea5c064..12d9206ebff17 100644 --- a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php +++ b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php @@ -157,7 +157,9 @@ public function validate(Observer $observer) if ($stockStatus->getStockStatus() === Stock::STOCK_OUT_OF_STOCK || $parentStockStatus && $parentStockStatus->getStockStatus() == Stock::STOCK_OUT_OF_STOCK ) { - if (!$quoteItem->getStockStateResult() && !$quoteItem->getStockStateResult()->getHasError()) { + $hasError = $quoteItem->getStockStateResult() + ? $quoteItem->getStockStateResult()->getHasError() : false; + if (!$hasError) { $quoteItem->addErrorInfo( 'cataloginventory', Data::ERROR_QTY, diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php index edc22a008c554..0a1eee76d6960 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php @@ -153,7 +153,7 @@ protected function setUp(): void ->getMock(); $this->storeMock = $this->createMock(Store::class); $this->quoteItemMock = $this->getMockBuilder(Item::class) - ->addMethods(['getProductId', 'getHasError']) + ->addMethods(['getProductId', 'getHasError', 'getStockStateResult']) ->onlyMethods( [ 'getQuote', @@ -460,6 +460,54 @@ public function testException() $this->quantityValidator->validate($this->observerMock); } + /** + * This tests the scenario when the error is in the quote item already + * + * @return void + */ + public function testValidateOutStockWithAlreadyErrorInQuoteItem(): void + { + $this->createInitialStub(1); + $resultMock = $this->getMockBuilder(DataObject::class) + ->addMethods(['checkQtyIncrements', 'getMessage', 'getQuoteMessage', 'getHasError']) + ->getMock(); + $resultMock->method('getHasError') + ->willReturn(true); + $this->stockRegistryMock->method('getStockItem') + ->willReturn($this->stockItemMock); + $this->stockRegistryMock->expects($this->at(1)) + ->method('getStockStatus') + ->willReturn($this->stockStatusMock); + $this->quoteItemMock->method('getParentItem') + ->willReturn($this->parentItemMock); + $this->quoteItemMock->method('getStockStateResult') + ->willReturn($resultMock); + $this->stockRegistryMock->expects($this->at(2)) + ->method('getStockStatus') + ->willReturn($this->parentStockItemMock); + $this->parentStockItemMock->method('getStockStatus') + ->willReturn(0); + $this->stockStatusMock->expects($this->atLeastOnce()) + ->method('getStockStatus') + ->willReturn(1); + $this->quoteItemMock->expects($this->never()) + ->method('addErrorInfo') + ->with( + 'cataloginventory', + Data::ERROR_QTY, + __('This product is out of stock.') + ); + $this->quoteMock->expects($this->once()) + ->method('addErrorInfo') + ->with( + 'stock', + 'cataloginventory', + Data::ERROR_QTY, + __('Some of the products are out of stock.') + ); + $this->quantityValidator->validate($this->observerMock); + } + /** * @param $qty * @param $hasError From 58f9f29843f1fcb07a642f270c0d8cb042bf0075 Mon Sep 17 00:00:00 2001 From: Roman Flowers <flowers@adobe.com> Date: Tue, 15 Dec 2020 16:48:58 -0600 Subject: [PATCH 067/156] MC-39463: GraphQL caches urlResolver response and can return the old value after the url rewrite update --- .../Magento/UrlRewrite/Model/UrlRewrite.php | 88 ++++++++++++++++--- 1 file changed, 77 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php index 363a3388daab0..3722c27a1b312 100644 --- a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php +++ b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php @@ -7,9 +7,6 @@ namespace Magento\UrlRewrite\Model; -use Magento\Catalog\Model\Category; -use Magento\Catalog\Model\Product; -use Magento\Cms\Model\Page; use Magento\Framework\App\ObjectManager; use Magento\Framework\Data\Collection\AbstractDb; use Magento\Framework\EntityManager\EventManager; @@ -61,6 +58,11 @@ class UrlRewrite extends AbstractModel */ private $entityToCacheTagMap; + /** + * @var UrlFinderInterface + */ + private $urlFinder; + /** * UrlRewrite constructor. * @@ -72,6 +74,7 @@ class UrlRewrite extends AbstractModel * @param Json|null $serializer * @param CacheContext|null $cacheContext * @param EventManager|null $eventManager + * @param UrlFinderInterface|null $urlFinder * @param array $entityToCacheTagMap */ public function __construct( @@ -83,12 +86,14 @@ public function __construct( Json $serializer = null, CacheContext $cacheContext = null, EventManager $eventManager = null, + UrlFinderInterface $urlFinder = null, array $entityToCacheTagMap = [] ) { $this->serializer = $serializer ?: ObjectManager::getInstance()->get(Json::class); $this->cacheContext = $cacheContext ?: ObjectManager::getInstance()->get(CacheContext::class); $this->eventManager = $eventManager ?: ObjectManager::getInstance()->get(EventManager::class); + $this->urlFinder = $urlFinder ?: ObjectManager::getInstance()->get(UrlFinderInterface::class); $this->entityToCacheTagMap = $entityToCacheTagMap; parent::__construct($context, $registry, $resource, $resourceCollection, $data); } @@ -131,30 +136,91 @@ public function setMetadata($metadata) } /** - * Clean cache for the entity which was affected by updating UrlRewrite + * Gets final target UrlRewrite for custom rewrite record * - * @param $entityType - * @param $entityId + * @param string $path + * @param int $storeId + * @return UrlRewrite|null + */ + private function getFinalTargetUrlRewrite(string $path, int $storeId) { + $urlRewriteTarget = $this->urlFinder->findOneByData( + [ + 'request_path' => $path, + 'store_id' => $storeId + ] + ); + + while ($urlRewriteTarget && $urlRewriteTarget->getRedirectType() > 0) { + $urlRewriteTarget = $this->urlFinder->findOneByData( + [ + 'request_path' => $urlRewriteTarget->getTargetPath(), + 'store_id' => $urlRewriteTarget->getStoreId() + ] + ); + } + + return $urlRewriteTarget; + } + + /** + * Clean the cache for entities affected by current rewrite */ - private function cleanCacheForEntity($entityType, $entityId) + private function cleanEntitiesCache() { + if ($this->getEntityType() === Rewrite::ENTITY_TYPE_CUSTOM) { + $urlRewrite = $this->getFinalTargetUrlRewrite( + $this->getTargetPath(), + (int)$this->getStoreId() + ); + + if ($urlRewrite) { + $this->cleanCacheForEntity($urlRewrite->getEntityType(), (int) $urlRewrite->getEntityId()); + } + + if ($this->getOrigData() && $this->getOrigData('target_path') !== $this->getTargetPath()) { + $origUrlRewrite = $this->getFinalTargetUrlRewrite( + $this->getOrigData('target_path'), + (int)$this->getOrigData('store_id') + ); + + if ($origUrlRewrite) { + $this->cleanCacheForEntity($origUrlRewrite->getEntityType(), (int) $origUrlRewrite->getEntityId()); + } + } + } else { + $this->cleanCacheForEntity($this->getEntityType(), (int) $this->getEntityId()); + } + } + + /** + * Clean cache for specified entity type by id + * + * @param string $entityType + * @param int $entityId + */ + private function cleanCacheForEntity(string $entityType, int $entityId) { - if ($entityType !== Rewrite::ENTITY_TYPE_CUSTOM && array_key_exists($entityType, $this->entityToCacheTagMap)) { + if (array_key_exists($entityType, $this->entityToCacheTagMap)) { $cacheKey = $this->entityToCacheTagMap[$entityType]; - $this->cacheContext->registerEntities($cacheKey, [$entityId]); $this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]); } } + /** + * @inheritdoc + */ public function afterDelete() { - $this->cleanCacheForEntity($this->getEntityType(), $this->getEntityId()); + $this->cleanEntitiesCache(); return parent::afterDelete(); } + /** + * @inheritdoc + */ public function afterSave() { - $this->cleanCacheForEntity($this->getEntityType(), $this->getEntityId()); + $this->cleanEntitiesCache(); return parent::afterSave(); } } From d3d41033af551138433d2e413f2f5b378884815b Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Tue, 15 Dec 2020 18:41:43 -0600 Subject: [PATCH 068/156] MC-39861: Customer is redirected to the blank page after using PayPal WPPHS payment on checkout --- .../Controller/Hostedpro/ReturnAction.php | 6 +-- .../Plugin/TransparentSessionChecker.php | 16 +++++- .../Controller/Hostedpro/ReturnActionTest.php | 54 +++++++++++++++++++ 3 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Paypal/Controller/Hostedpro/ReturnActionTest.php diff --git a/app/code/Magento/Paypal/Controller/Hostedpro/ReturnAction.php b/app/code/Magento/Paypal/Controller/Hostedpro/ReturnAction.php index bb8b5f8fa0b46..dbaf432878de9 100644 --- a/app/code/Magento/Paypal/Controller/Hostedpro/ReturnAction.php +++ b/app/code/Magento/Paypal/Controller/Hostedpro/ReturnAction.php @@ -26,11 +26,7 @@ class ReturnAction extends Action implements CsrfAwareActionInterface, HttpPostA */ public function execute() { - $session = $this->_objectManager->get(\Magento\Checkout\Model\Session::class); - //TODO: some actions with order - if ($session->getLastRealOrderId()) { - $this->_redirect('checkout/onepage/success'); - } + $this->_redirect('checkout/onepage/success'); } /** diff --git a/app/code/Magento/Paypal/Plugin/TransparentSessionChecker.php b/app/code/Magento/Paypal/Plugin/TransparentSessionChecker.php index 5157ba3208fb7..d53fd183c1942 100644 --- a/app/code/Magento/Paypal/Plugin/TransparentSessionChecker.php +++ b/app/code/Magento/Paypal/Plugin/TransparentSessionChecker.php @@ -15,7 +15,13 @@ */ class TransparentSessionChecker { - private const TRANSPARENT_REDIRECT_PATH = 'paypal/transparent/redirect'; + /** + * @var string[] + */ + private $disableSessionUrls = [ + 'paypal/transparent/redirect', + 'paypal/hostedpro/return', + ]; /** * @var Http @@ -45,6 +51,12 @@ public function afterCheck(SessionStartChecker $subject, bool $result): bool return false; } - return strpos((string)$this->request->getPathInfo(), self::TRANSPARENT_REDIRECT_PATH) === false; + foreach ($this->disableSessionUrls as $url) { + if (strpos((string)$this->request->getPathInfo(), $url) !== false) { + return false; + } + } + + return true; } } diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Controller/Hostedpro/ReturnActionTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Controller/Hostedpro/ReturnActionTest.php new file mode 100644 index 0000000000000..d52c2501a565a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Paypal/Controller/Hostedpro/ReturnActionTest.php @@ -0,0 +1,54 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Paypal\Controller\Hostedpro; + +use Magento\TestFramework\TestCase\AbstractController; +use Zend\Stdlib\Parameters; + +/** + * Tests PayPal HostedPro return controller. + */ +class ReturnActionTest extends AbstractController +{ + /** + * Tests customer redirect on success page after return from PayPal HostedPro payment. + * + * @SuppressWarnings(PHPMD.Superglobals) + */ + public function testReturnRedirect() + { + $redirectUri = 'paypal/hostedpro/return'; + $this->setRequestUri($redirectUri); + $this->getRequest()->setMethod('POST'); + + $this->dispatch($redirectUri); + $this->assertRedirect($this->stringContains('checkout/onepage/success')); + + $this->assertEmpty( + $_SESSION, + 'Session start has to be skipped for current controller' + ); + } + + /** + * Sets REQUEST_URI into request object. + * + * @param string $requestUri + * @return void + */ + private function setRequestUri(string $requestUri) + { + $request = $this->getRequest(); + $reflection = new \ReflectionClass($request); + $property = $reflection->getProperty('requestUri'); + $property->setAccessible(true); + $property->setValue($request, null); + + $request->setServer(new Parameters(['REQUEST_URI' => $requestUri])); + } +} From 468383e24bb059e1f25e902a782e51cf03d9f312 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Wed, 16 Dec 2020 15:51:30 +0200 Subject: [PATCH 069/156] MC-39104: 2 error messages in Cart when product is out of stock --- .../CatalogInventory/Model/Quote/Item/QuantityValidator.php | 2 ++ .../Test/NoOptionAvailableToConfigureDisabledProductTest.xml | 4 ++-- .../Magento/Quote/Api/GuestCartItemRepositoryTest.php | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php index 12d9206ebff17..12a48caf62414 100644 --- a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php +++ b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php @@ -165,6 +165,8 @@ public function validate(Observer $observer) Data::ERROR_QTY, __('This product is out of stock.') ); + } else { + $quoteItem->addErrorInfo(null, Data::ERROR_QTY); } $quoteItem->getQuote()->addErrorInfo( 'stock', diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/NoOptionAvailableToConfigureDisabledProductTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/NoOptionAvailableToConfigureDisabledProductTest.xml index e0dae94f13150..b75dd590dbbf1 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/NoOptionAvailableToConfigureDisabledProductTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/NoOptionAvailableToConfigureDisabledProductTest.xml @@ -125,7 +125,7 @@ <actionGroup ref="AdminSetStockStatusActionGroup" stepKey="outOfStockStatus"> <argument name="stockStatus" value="Out of Stock"/> </actionGroup> - + <actionGroup ref="SaveProductFormActionGroup" stepKey="saveSecondProductForm"/> <!-- Go to created customer page --> <comment userInput="Go to created customer page" stepKey="goToCreatedCustomerPage"/> @@ -158,7 +158,7 @@ <waitForPageLoad stepKey="waitForPageLoad"/> <click selector="{{AdminOrderFormItemsSection.addSelected}}" stepKey="clickToAddProductToOrder"/> <waitForPageLoad stepKey="waitForNewOrderPageLoad"/> - <see userInput="This product is out of stock." stepKey="seeTheErrorMessageDisplayed"/> + <see userInput="There are no source items with the in stock status" stepKey="seeTheErrorMessageDisplayed"/> <actionGroup ref="NavigateToNewOrderPageExistingCustomerActionGroup" stepKey="createNewOrderThirdTime"> <argument name="customer" value="$createCustomer$"/> diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestCartItemRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestCartItemRepositoryTest.php index 373ad64ba39d4..a9c402096aaf0 100644 --- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestCartItemRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestCartItemRepositoryTest.php @@ -265,7 +265,7 @@ public function updateItemDataProvider(): array 'use_config_backorders' => 0, 'backorders' => Stock::BACKORDERS_NO, ], - 'This product is out of stock.' + 'There are no source items with the in stock status' ], [ [ From 4531c763b5afad4af054bf5dce14669dce0c49ee Mon Sep 17 00:00:00 2001 From: Viktor Rad <vrad@adobe.com> Date: Wed, 16 Dec 2020 07:54:37 -0600 Subject: [PATCH 070/156] MC-38834: Uploading a new logo for print on Logo for HTML Print View settings does not reflect on frontend my account order --- .../ViewModel/Header/LogoPathResolver.php | 69 +++++++++++++++++ .../frontend/layout/sales_order_print.xml | 5 ++ .../layout/sales_order_printcreditmemo.xml | 5 ++ .../layout/sales_order_printinvoice.xml | 5 ++ .../layout/sales_order_printshipment.xml | 5 ++ .../Magento/Theme/Block/Html/Header/Logo.php | 16 ++-- .../Test/Unit/Block/Html/Header/LogoTest.php | 7 +- .../Block/Html/Header/LogoPathResolver.php | 51 +++++++++++++ .../Html/Header/LogoPathResolverInterface.php | 21 ++++++ .../Theme/view/frontend/layout/default.xml | 6 +- .../Sales/Block/Order/PrintOrder/LogoTest.php | 74 +++++++++++++++++++ 11 files changed, 253 insertions(+), 11 deletions(-) create mode 100644 app/code/Magento/Sales/ViewModel/Header/LogoPathResolver.php create mode 100644 app/code/Magento/Theme/ViewModel/Block/Html/Header/LogoPathResolver.php create mode 100644 app/code/Magento/Theme/ViewModel/Block/Html/Header/LogoPathResolverInterface.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Block/Order/PrintOrder/LogoTest.php diff --git a/app/code/Magento/Sales/ViewModel/Header/LogoPathResolver.php b/app/code/Magento/Sales/ViewModel/Header/LogoPathResolver.php new file mode 100644 index 0000000000000..c58654e160749 --- /dev/null +++ b/app/code/Magento/Sales/ViewModel/Header/LogoPathResolver.php @@ -0,0 +1,69 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Sales\ViewModel\Header; + +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Store\Model\ScopeInterface; +use Magento\Theme\ViewModel\Block\Html\Header\LogoPathResolverInterface; +use Magento\Framework\View\Element\Block\ArgumentInterface; +use Magento\Sales\Model\Order; +use Magento\Framework\Registry; + +/** + * Class for resolving logo path + */ +class LogoPathResolver implements LogoPathResolverInterface, ArgumentInterface +{ + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; + + /** + * Core registry + * + * @var Registry + */ + private $coreRegistry; + + /** + * @param ScopeConfigInterface $scopeConfig + * @param Registry $registry + */ + public function __construct( + ScopeConfigInterface $scopeConfig, + Registry $registry + ) { + $this->scopeConfig = $scopeConfig; + $this->coreRegistry = $registry; + } + + /** + * Return logo image path + * + * @return string|null + */ + public function getPath(): ?string + { + $path = null; + $storeId = null; + $order = $this->coreRegistry->registry('current_order'); + if ($order instanceof Order) { + $storeId = $order->getStoreId(); + } + $storeLogoPath = $this->scopeConfig->getValue( + 'sales/identity/logo_html', + ScopeInterface::SCOPE_STORE, + $storeId + ); + if ($storeLogoPath !== null) { + $path = 'sales/store/logo_html/' . $storeLogoPath; + } + return $path; + } +} diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_print.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_print.xml index 4410a6fc4a9a2..8a52e65a9f70c 100644 --- a/app/code/Magento/Sales/view/frontend/layout/sales_order_print.xml +++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_print.xml @@ -44,5 +44,10 @@ <block class="Magento\Sales\Block\Order\Info" as="sales.order.print.info" name="sales.order.print.info" template="Magento_Sales::order/info.phtml"/> </referenceContainer> <block class="Magento\Framework\View\Element\Template" name="additional.product.info" template="Magento_Theme::template.phtml"/> + <referenceBlock name="logo"> + <arguments> + <argument name="logoPathResolver" xsi:type="object">Magento\Sales\ViewModel\Header\LogoPathResolver</argument> + </arguments> + </referenceBlock> </body> </page> diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_printcreditmemo.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_printcreditmemo.xml index 0021eeede4f2b..317ee419f6d96 100644 --- a/app/code/Magento/Sales/view/frontend/layout/sales_order_printcreditmemo.xml +++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_printcreditmemo.xml @@ -28,5 +28,10 @@ </block> </referenceContainer> <block class="Magento\Framework\View\Element\Template" name="additional.product.info" template="Magento_Theme::template.phtml"/> + <referenceBlock name="logo"> + <arguments> + <argument name="logoPathResolver" xsi:type="object">Magento\Sales\ViewModel\Header\LogoPathResolver</argument> + </arguments> + </referenceBlock> </body> </page> diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_printinvoice.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_printinvoice.xml index 0272286696e24..e0bb15bc0e7fd 100644 --- a/app/code/Magento/Sales/view/frontend/layout/sales_order_printinvoice.xml +++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_printinvoice.xml @@ -35,5 +35,10 @@ </block> </referenceContainer> <block class="Magento\Framework\View\Element\Template" name="additional.product.info" template="Magento_Theme::template.phtml"/> + <referenceBlock name="logo"> + <arguments> + <argument name="logoPathResolver" xsi:type="object">Magento\Sales\ViewModel\Header\LogoPathResolver</argument> + </arguments> + </referenceBlock> </body> </page> diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_printshipment.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_printshipment.xml index 30053b41a96a9..b7940c0d406cc 100644 --- a/app/code/Magento/Sales/view/frontend/layout/sales_order_printshipment.xml +++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_printshipment.xml @@ -20,5 +20,10 @@ </block> </referenceContainer> <block class="Magento\Framework\View\Element\Template" name="additional.product.info" template="Magento_Theme::template.phtml"/> + <referenceBlock name="logo"> + <arguments> + <argument name="logoPathResolver" xsi:type="object">Magento\Sales\ViewModel\Header\LogoPathResolver</argument> + </arguments> + </referenceBlock> </body> </page> diff --git a/app/code/Magento/Theme/Block/Html/Header/Logo.php b/app/code/Magento/Theme/Block/Html/Header/Logo.php index 792ee95de4995..3c43e5bfc6fe1 100644 --- a/app/code/Magento/Theme/Block/Html/Header/Logo.php +++ b/app/code/Magento/Theme/Block/Html/Header/Logo.php @@ -6,6 +6,8 @@ namespace Magento\Theme\Block\Html\Header; +use Magento\Theme\ViewModel\Block\Html\Header\LogoPathResolverInterface; + /** * Logo page header block * @@ -124,16 +126,16 @@ public function getLogoHeight() */ protected function _getLogoUrl() { - $folderName = \Magento\Config\Model\Config\Backend\Image\Logo::UPLOAD_DIR; - $storeLogoPath = $this->_scopeConfig->getValue( - 'design/header/logo_src', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ); - $path = $folderName . '/' . $storeLogoPath; + $path = null; + /** @var LogoPathResolverInterface $logoPathResolver */ + $logoPathResolver = $this->getData('logoPathResolver'); + if ($logoPathResolver instanceof LogoPathResolverInterface) { + $path = $logoPathResolver->getPath(); + } $logoUrl = $this->_urlBuilder ->getBaseUrl(['_type' => \Magento\Framework\UrlInterface::URL_TYPE_MEDIA]) . $path; - if ($storeLogoPath !== null && $this->_isFile($path)) { + if ($path !== null && $this->_isFile($path)) { $url = $logoUrl; } elseif ($this->getLogoFile()) { $url = $this->getViewFileUrl($this->getLogoFile()); diff --git a/app/code/Magento/Theme/Test/Unit/Block/Html/Header/LogoTest.php b/app/code/Magento/Theme/Test/Unit/Block/Html/Header/LogoTest.php index 1978362810763..a5095674a4673 100644 --- a/app/code/Magento/Theme/Test/Unit/Block/Html/Header/LogoTest.php +++ b/app/code/Magento/Theme/Test/Unit/Block/Html/Header/LogoTest.php @@ -7,6 +7,7 @@ namespace Magento\Theme\Test\Unit\Block\Html\Header; +use Magento\Theme\ViewModel\Block\Html\Header\LogoPathResolverInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Filesystem; use Magento\Framework\Filesystem\Directory\Read; @@ -25,11 +26,11 @@ public function testGetLogoSrc() { $filesystem = $this->createMock(Filesystem::class); $mediaDirectory = $this->createMock(Read::class); - $scopeConfig = $this->getMockForAbstractClass(ScopeConfigInterface::class); + $logoPathResolver = $this->getMockForAbstractClass(LogoPathResolverInterface::class); $urlBuilder = $this->getMockForAbstractClass(UrlInterface::class); - $scopeConfig->expects($this->once())->method('getValue')->willReturn('default/image.gif'); + $logoPathResolver->expects($this->once())->method('getPath')->willReturn('logo/default/image.gif'); $urlBuilder->expects( $this->once() )->method( @@ -46,7 +47,7 @@ public function testGetLogoSrc() $objectManager = new ObjectManager($this); $arguments = [ - 'scopeConfig' => $scopeConfig, + 'data' => ['logoPathResolver' => $logoPathResolver], 'urlBuilder' => $urlBuilder, 'fileStorageHelper' => $helper, 'filesystem' => $filesystem, diff --git a/app/code/Magento/Theme/ViewModel/Block/Html/Header/LogoPathResolver.php b/app/code/Magento/Theme/ViewModel/Block/Html/Header/LogoPathResolver.php new file mode 100644 index 0000000000000..1a10fe9177320 --- /dev/null +++ b/app/code/Magento/Theme/ViewModel/Block/Html/Header/LogoPathResolver.php @@ -0,0 +1,51 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Theme\ViewModel\Block\Html\Header; + +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Config\Model\Config\Backend\Image\Logo; +use Magento\Store\Model\ScopeInterface; +use Magento\Framework\View\Element\Block\ArgumentInterface; + +/** + * Class for resolving logo path + */ +class LogoPathResolver implements LogoPathResolverInterface, ArgumentInterface +{ + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; + + /** + * @param ScopeConfigInterface $scopeConfig + */ + public function __construct( + ScopeConfigInterface $scopeConfig + ) { + $this->scopeConfig = $scopeConfig; + } + + /** + * Return logo image path + * + * @return string|null + */ + public function getPath(): ?string + { + $path = null; + $storeLogoPath = $this->scopeConfig->getValue( + 'design/header/logo_src', + ScopeInterface::SCOPE_STORE + ); + if ($storeLogoPath !== null) { + $path = Logo::UPLOAD_DIR . '/' . $storeLogoPath; + } + return $path; + } +} diff --git a/app/code/Magento/Theme/ViewModel/Block/Html/Header/LogoPathResolverInterface.php b/app/code/Magento/Theme/ViewModel/Block/Html/Header/LogoPathResolverInterface.php new file mode 100644 index 0000000000000..3ac8442aa0ea7 --- /dev/null +++ b/app/code/Magento/Theme/ViewModel/Block/Html/Header/LogoPathResolverInterface.php @@ -0,0 +1,21 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Theme\ViewModel\Block\Html\Header; + +/** + * Interface for resolving logo path + */ +interface LogoPathResolverInterface +{ + /** + * Return logo image path + * + * @return null|string + */ + public function getPath(): ?string; +} diff --git a/app/code/Magento/Theme/view/frontend/layout/default.xml b/app/code/Magento/Theme/view/frontend/layout/default.xml index bf76933b356c0..f3e57b12150c9 100644 --- a/app/code/Magento/Theme/view/frontend/layout/default.xml +++ b/app/code/Magento/Theme/view/frontend/layout/default.xml @@ -51,7 +51,11 @@ </container> </container> <container name="header-wrapper" label="Page Header" as="header-wrapper" htmlTag="div" htmlClass="header content"> - <block class="Magento\Theme\Block\Html\Header\Logo" name="logo"/> + <block class="Magento\Theme\Block\Html\Header\Logo" name="logo"> + <arguments> + <argument name="logoPathResolver" xsi:type="object">Magento\Theme\ViewModel\Block\Html\Header\LogoPathResolver</argument> + </arguments> + </block> </container> </referenceContainer> <referenceContainer name="page.top"> diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/PrintOrder/LogoTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/PrintOrder/LogoTest.php new file mode 100644 index 0000000000000..aadd3ab7b956e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/PrintOrder/LogoTest.php @@ -0,0 +1,74 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Block\Order\PrintOrder; + +use Magento\Framework\View\LayoutInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Framework\App\State; +use Magento\Theme\Block\Html\Header\Logo; +use Magento\Framework\Filesystem; +use Magento\Framework\Filesystem\Directory\WriteInterface; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\ObjectManagerInterface; +use Magento\Theme\ViewModel\Block\Html\Header\LogoPathResolver as LogoPathResolverDefault; +use Magento\Sales\ViewModel\Header\LogoPathResolver as LogoPathResolverSales; +use \PHPUnit\Framework\TestCase; + +class LogoTest extends TestCase +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @var WriteInterface + */ + private $mediaDirectory; + + protected function setUp(): void + { + $this->objectManager = Bootstrap::getObjectManager(); + $filesystem = $this->objectManager->get(Filesystem::class); + $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $this->objectManager->get(State::class) + ->setAreaCode(\Magento\Framework\App\Area::AREA_FRONTEND); + Bootstrap::getInstance() + ->loadArea(\Magento\Framework\App\Area::AREA_FRONTEND); + } + + /** + * @magentoConfigFixture default_store design/header/logo_src default/logo.jpg + * @magentoConfigFixture default_store sales/identity/logo_html default/logo_sales.jpg + * @throws \Magento\Framework\Exception\FileSystemException + */ + public function testGetLogoSrc(): void + { + $host = 'http://localhost/media/'; + $defaultLogoFile= 'logo.jpg'; + $defaultPath = 'logo/default/' . $defaultLogoFile; + $salesLogoFile = 'logo_sales.jpg'; + $salesPath = 'sales/store/logo_html/default/' . $salesLogoFile; + $this->mediaDirectory->writeFile($defaultPath, ''); + $this->mediaDirectory->writeFile($salesPath, ''); + $blockArguments = ['data' => + ['logoPathResolver' => $this->objectManager->get(LogoPathResolverDefault::class)] + ]; + /** @var Logo $block */ + $block = $this->objectManager->create(LayoutInterface::class) + ->createBlock(Logo::class, 'logo', $blockArguments); + $this->assertSame($host . $defaultPath, $block->getLogoSrc()); + $blockArguments = ['data' => + ['logoPathResolver' => $this->objectManager->get(LogoPathResolverSales::class)] + ]; + /** @var Logo $block */ + $block = $this->objectManager->create(LayoutInterface::class) + ->createBlock(Logo::class, 'logo', $blockArguments); + $this->assertSame($host . $salesPath, $block->getLogoSrc()); + $this->mediaDirectory->delete($defaultPath); + $this->mediaDirectory->delete($salesPath); + } +} From a1808865c58768cc5e9afdb3c301893743ec6bfd Mon Sep 17 00:00:00 2001 From: Elisei <brunoelisei@gmail.com> Date: Wed, 16 Dec 2020 11:01:53 -0300 Subject: [PATCH 071/156] Fixed #31211 --- app/code/Magento/Vault/i18n/en_US.csv | 2 +- .../view/frontend/templates/customer_account/credit_card.phtml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Vault/i18n/en_US.csv b/app/code/Magento/Vault/i18n/en_US.csv index 0c54d583198d1..6030e83193a8a 100644 --- a/app/code/Magento/Vault/i18n/en_US.csv +++ b/app/code/Magento/Vault/i18n/en_US.csv @@ -13,4 +13,4 @@ Actions,Actions Delete,Delete "PayPal Account","PayPal Account" Cancel,Cancel -"Are you sure you want to delete this card: %1?","Are you sure you want to delete this card: %1?" \ No newline at end of file +"Are you sure you want to delete this card: %1?","Are you sure you want to delete this card: %1?" diff --git a/app/code/Magento/Vault/view/frontend/templates/customer_account/credit_card.phtml b/app/code/Magento/Vault/view/frontend/templates/customer_account/credit_card.phtml index a2439898799cd..c61ac41329548 100644 --- a/app/code/Magento/Vault/view/frontend/templates/customer_account/credit_card.phtml +++ b/app/code/Magento/Vault/view/frontend/templates/customer_account/credit_card.phtml @@ -43,7 +43,7 @@ $ccNumberView = $block->escapeHtml($block->getNumberLast4Digits()); "modalClass": "my-credit-cards-popup", "toggleEvent": "click", "title": "<?= $block->escapeHtml(__('Delete')) ?>", - "content": "<?= $block->escapeHtml(__('Are you sure you want to delete this card: %1?', /* @noEscape */ $ccNumberView)) ?>" + "content": "<?= $block->escapeHtml(__('Are you sure you want to delete this card: %1?', $ccNumberView)) ?>" } }'> <span><?= $block->escapeHtml(__('Delete')) ?></span> From e55a9e3624bb7b7e2d0a35877dcc1a97975962e7 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Wed, 16 Dec 2020 18:06:20 +0200 Subject: [PATCH 072/156] MC-39104: 2 error messages in Cart when product is out of stock --- .../QuantityValidator/Initializer/QuantityValidatorTest.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php index 0a1eee76d6960..36b9fd0adeb81 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php @@ -490,12 +490,11 @@ public function testValidateOutStockWithAlreadyErrorInQuoteItem(): void $this->stockStatusMock->expects($this->atLeastOnce()) ->method('getStockStatus') ->willReturn(1); - $this->quoteItemMock->expects($this->never()) + $this->quoteItemMock->expects($this->once()) ->method('addErrorInfo') ->with( - 'cataloginventory', + null, Data::ERROR_QTY, - __('This product is out of stock.') ); $this->quoteMock->expects($this->once()) ->method('addErrorInfo') From 5559a51bccae19c3b032a3fe17e08047a67aacf8 Mon Sep 17 00:00:00 2001 From: Nazar Klovanych <nazarn96@gmail.com> Date: Wed, 16 Dec 2020 18:20:29 +0200 Subject: [PATCH 073/156] Fix ftp_nlist for empty folders return false --- lib/internal/Magento/Framework/Filesystem/Io/Ftp.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Io/Ftp.php b/lib/internal/Magento/Framework/Filesystem/Io/Ftp.php index 04df5fd3f3a6c..4bd3e49485681 100644 --- a/lib/internal/Magento/Framework/Filesystem/Io/Ftp.php +++ b/lib/internal/Magento/Framework/Filesystem/Io/Ftp.php @@ -313,9 +313,10 @@ public function chmod($filename, $mode) */ public function ls($grep = null) { - $ls = @ftp_nlist($this->_conn, '.'); + $ls = @ftp_nlist($this->_conn, '.') ?? []; $list = []; + foreach ($ls as $file) { $list[] = ['text' => $file, 'id' => $this->pwd() . '/' . $file]; } From c42d022322d7e6114d6a8cd4b7029adc5e44022a Mon Sep 17 00:00:00 2001 From: Nazar Klovanych <nazarn96@gmail.com> Date: Wed, 16 Dec 2020 18:27:40 +0200 Subject: [PATCH 074/156] Update Ftp.php --- lib/internal/Magento/Framework/Filesystem/Io/Ftp.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Io/Ftp.php b/lib/internal/Magento/Framework/Filesystem/Io/Ftp.php index 4bd3e49485681..0027329e7d54c 100644 --- a/lib/internal/Magento/Framework/Filesystem/Io/Ftp.php +++ b/lib/internal/Magento/Framework/Filesystem/Io/Ftp.php @@ -313,7 +313,7 @@ public function chmod($filename, $mode) */ public function ls($grep = null) { - $ls = @ftp_nlist($this->_conn, '.') ?? []; + $ls = @ftp_nlist($this->_conn, '.') ?: []; $list = []; From 253f0d2e9507f05ccb2fd00f0ba2f4d79c0ad5e4 Mon Sep 17 00:00:00 2001 From: Roman Flowers <flowers@adobe.com> Date: Wed, 16 Dec 2020 12:49:20 -0600 Subject: [PATCH 075/156] MC-39463: GraphQL caches urlResolver response and can return the old value after the url rewrite update --- app/code/Magento/UrlRewrite/Model/UrlRewrite.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php index 3722c27a1b312..1fa3ef049daae 100644 --- a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php +++ b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php @@ -142,7 +142,8 @@ public function setMetadata($metadata) * @param int $storeId * @return UrlRewrite|null */ - private function getFinalTargetUrlRewrite(string $path, int $storeId) { + private function getFinalTargetUrlRewrite(string $path, int $storeId): ?UrlRewrite + { $urlRewriteTarget = $this->urlFinder->findOneByData( [ 'request_path' => $path, @@ -165,7 +166,8 @@ private function getFinalTargetUrlRewrite(string $path, int $storeId) { /** * Clean the cache for entities affected by current rewrite */ - private function cleanEntitiesCache() { + private function cleanEntitiesCache() + { if ($this->getEntityType() === Rewrite::ENTITY_TYPE_CUSTOM) { $urlRewrite = $this->getFinalTargetUrlRewrite( $this->getTargetPath(), From a1750ac2296bac2f728a5462ce696df70e1988df Mon Sep 17 00:00:00 2001 From: Roman Flowers <flowers@adobe.com> Date: Wed, 16 Dec 2020 15:57:42 -0600 Subject: [PATCH 076/156] MC-39463: GraphQL caches urlResolver response and can return the old value after the url rewrite update --- .../Magento/UrlRewrite/Model/UrlRewrite.php | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php index 1fa3ef049daae..5f867e6ef0aa6 100644 --- a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php +++ b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php @@ -168,28 +168,30 @@ private function getFinalTargetUrlRewrite(string $path, int $storeId): ?UrlRewri */ private function cleanEntitiesCache() { - if ($this->getEntityType() === Rewrite::ENTITY_TYPE_CUSTOM) { - $urlRewrite = $this->getFinalTargetUrlRewrite( - $this->getTargetPath(), - (int)$this->getStoreId() - ); + if (!$this->isEmpty()) { + if ($this->getEntityType() === Rewrite::ENTITY_TYPE_CUSTOM) { + $urlRewrite = $this->getFinalTargetUrlRewrite( + $this->getTargetPath(), + (int)$this->getStoreId() + ); - if ($urlRewrite) { - $this->cleanCacheForEntity($urlRewrite->getEntityType(), (int) $urlRewrite->getEntityId()); - } + if ($urlRewrite) { + $this->cleanCacheForEntity($urlRewrite->getEntityType(), (int) $urlRewrite->getEntityId()); + } - if ($this->getOrigData() && $this->getOrigData('target_path') !== $this->getTargetPath()) { - $origUrlRewrite = $this->getFinalTargetUrlRewrite( - $this->getOrigData('target_path'), - (int)$this->getOrigData('store_id') - ); + if ($this->getOrigData() && $this->getOrigData('target_path') !== $this->getTargetPath()) { + $origUrlRewrite = $this->getFinalTargetUrlRewrite( + $this->getOrigData('target_path'), + (int)$this->getOrigData('store_id') + ); - if ($origUrlRewrite) { - $this->cleanCacheForEntity($origUrlRewrite->getEntityType(), (int) $origUrlRewrite->getEntityId()); + if ($origUrlRewrite) { + $this->cleanCacheForEntity($origUrlRewrite->getEntityType(), (int) $origUrlRewrite->getEntityId()); + } } + } else { + $this->cleanCacheForEntity($this->getEntityType(), (int) $this->getEntityId()); } - } else { - $this->cleanCacheForEntity($this->getEntityType(), (int) $this->getEntityId()); } } From 375fd4cb19c05cdbb88a047865ed0d23bf310e21 Mon Sep 17 00:00:00 2001 From: Roman Flowers <flowers@adobe.com> Date: Wed, 16 Dec 2020 17:11:47 -0600 Subject: [PATCH 077/156] MC-39463: GraphQL caches urlResolver response and can return the old value after the url rewrite update --- app/code/Magento/UrlRewrite/Model/UrlRewrite.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php index 5f867e6ef0aa6..d82781ee66450 100644 --- a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php +++ b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php @@ -18,6 +18,7 @@ use Magento\Framework\Serialize\Serializer\Json; use Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite; use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection; +use Magento\UrlRewrite\Service\V1\Data\UrlRewrite as UrlRewriteService; /** * UrlRewrite model class @@ -140,9 +141,9 @@ public function setMetadata($metadata) * * @param string $path * @param int $storeId - * @return UrlRewrite|null + * @return UrlRewriteService|null */ - private function getFinalTargetUrlRewrite(string $path, int $storeId): ?UrlRewrite + private function getFinalTargetUrlRewrite(string $path, int $storeId): ?UrlRewriteService { $urlRewriteTarget = $this->urlFinder->findOneByData( [ @@ -166,7 +167,7 @@ private function getFinalTargetUrlRewrite(string $path, int $storeId): ?UrlRewri /** * Clean the cache for entities affected by current rewrite */ - private function cleanEntitiesCache() + public function cleanEntitiesCache() { if (!$this->isEmpty()) { if ($this->getEntityType() === Rewrite::ENTITY_TYPE_CUSTOM) { @@ -215,7 +216,7 @@ private function cleanCacheForEntity(string $entityType, int $entityId) */ public function afterDelete() { - $this->cleanEntitiesCache(); + $this->_getResource()->addCommitCallback([$this, 'cleanEntitiesCache']); return parent::afterDelete(); } @@ -224,7 +225,7 @@ public function afterDelete() */ public function afterSave() { - $this->cleanEntitiesCache(); + $this->_getResource()->addCommitCallback([$this, 'cleanEntitiesCache']); return parent::afterSave(); } } From b7fe543acf0f5e3bbe0a8ba65b3a93cbfba28cd2 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Thu, 17 Dec 2020 11:26:31 +0200 Subject: [PATCH 078/156] refactored --- .../AdminSelectAttributeSetOnEditProductPageActionGroup.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml index 42f7f72c1cd73..c1d1d3dee1123 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml @@ -10,8 +10,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminSelectAttributeSetOnEditProductPageActionGroup"> <annotations> - <description>Selects the specified value from the Attribute Set dropdown. - The Edit Product Page should be opened prior to Action Group execution</description> + <description>Selects the specified value from the Attribute Set dropdown.</description> </annotations> <arguments> <argument name="attributeSet" type="string"/> From d063cd634be1fecd8d13de27f15e1afcb78e9a5d Mon Sep 17 00:00:00 2001 From: Anna Pak <58164147+AnnaAPak@users.noreply.github.com> Date: Thu, 17 Dec 2020 11:35:16 +0200 Subject: [PATCH 079/156] Update app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml Co-authored-by: Eduard Chitoraga <e.chitoraga@atwix.com> --- .../AdminSelectAttributeSetOnEditProductPageActionGroup.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml index 9b3f44516dadc..5624d3a1001c1 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml @@ -13,8 +13,7 @@ <<<<<<< HEAD <description>Selects the specified value from the Attribute Set dropdown.</description> ======= - <description>Selects the specified value from the Attribute Set dropdown. - The Edit Product Page should be opened prior to Action Group execution</description> + <description>Selects the specified value from the Attribute Set dropdown on the opened product edit page.</description> >>>>>>> 88b58a08d39906584398e0c7762413e18c054a27 </annotations> <arguments> From 941349a80659143e7501a5d65b68a9bc79f6738c Mon Sep 17 00:00:00 2001 From: Anna Pak <58164147+AnnaAPak@users.noreply.github.com> Date: Thu, 17 Dec 2020 11:36:11 +0200 Subject: [PATCH 080/156] refactored --- .../AdminSelectAttributeSetOnEditProductPageActionGroup.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml index 5624d3a1001c1..31a4521331664 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSelectAttributeSetOnEditProductPageActionGroup.xml @@ -10,11 +10,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminSelectAttributeSetOnEditProductPageActionGroup"> <annotations> -<<<<<<< HEAD - <description>Selects the specified value from the Attribute Set dropdown.</description> -======= <description>Selects the specified value from the Attribute Set dropdown on the opened product edit page.</description> ->>>>>>> 88b58a08d39906584398e0c7762413e18c054a27 </annotations> <arguments> <argument name="attributeSet" type="string"/> From 5e35bb3739ca1fb526c6caf170d5c1d2e1a181d3 Mon Sep 17 00:00:00 2001 From: Vova Yatsyuk <vova.yatsyuk@gmail.com> Date: Thu, 17 Dec 2020 15:12:09 +0200 Subject: [PATCH 081/156] Fixed failed integration test --- .../Magento/Csp/Model/Collector/ConfigCollectorTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Csp/Model/Collector/ConfigCollectorTest.php b/dev/tests/integration/testsuite/Magento/Csp/Model/Collector/ConfigCollectorTest.php index 2d8cbbeedeab9..cf6287ed5b4e1 100644 --- a/dev/tests/integration/testsuite/Magento/Csp/Model/Collector/ConfigCollectorTest.php +++ b/dev/tests/integration/testsuite/Magento/Csp/Model/Collector/ConfigCollectorTest.php @@ -62,9 +62,9 @@ private function getExpectedPolicies(): array [], true ), - 'font-src' => new FetchPolicy('font-src', false, [], [], true), + 'font-src' => new FetchPolicy('font-src', false, [], ['data'], true), 'frame-src' => new FetchPolicy('frame-src', false, [], [], true, false, false, [], [], true), - 'img-src' => new FetchPolicy('img-src', false, [], [], true), + 'img-src' => new FetchPolicy('img-src', false, [], ['data'], true), 'manifest-src' => new FetchPolicy('manifest-src', false, [], [], true), 'media-src' => new FetchPolicy('media-src', false, [], [], true), 'object-src' => new FetchPolicy('object-src', false, [], [], true), From 7f9a7fd39b4514fee0ca9eb0a1a8701c6f2b4030 Mon Sep 17 00:00:00 2001 From: Serhii Balko <serhii.balko@transogtgroup.com> Date: Thu, 17 Dec 2020 15:28:31 +0200 Subject: [PATCH 082/156] MC-39864: [Magento Cloud] - Tax Miscalculation --- .../Model/Order/Creditmemo/Total/Tax.php | 209 ++++++++++++------ .../Model/Order/Creditmemo/Total/TaxTest.php | 32 +-- 2 files changed, 156 insertions(+), 85 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php index 95dace13d832f..9e6e8979e46ee 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php @@ -5,22 +5,20 @@ */ namespace Magento\Sales\Model\Order\Creditmemo\Total; +use Magento\Sales\Model\Order\Creditmemo; + /** * Collects credit memo taxes. */ class Tax extends AbstractTotal { /** - * Collects credit memo taxes. - * - * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo - * @return $this - * + * {@inheritdoc} * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) + public function collect(Creditmemo $creditmemo) { $shippingTaxAmount = 0; $baseShippingTaxAmount = 0; @@ -28,38 +26,37 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) $baseTotalTax = 0; $totalDiscountTaxCompensation = 0; $baseTotalDiscountTaxCompensation = 0; - $order = $creditmemo->getOrder(); - /** @var $item \Magento\Sales\Model\Order\Creditmemo\Item */ foreach ($creditmemo->getAllItems() as $item) { $orderItem = $item->getOrderItem(); if ($orderItem->isDummy() || $item->getQty() <= 0) { continue; } + $orderItemTax = (double)$orderItem->getTaxInvoiced(); $baseOrderItemTax = (double)$orderItem->getBaseTaxInvoiced(); $orderItemQty = (double)$orderItem->getQtyInvoiced(); if ($orderItemQty) { - /** - * Check item tax amount - */ - - $tax = $orderItemTax - $orderItem->getTaxRefunded(); - $baseTax = $baseOrderItemTax - $orderItem->getBaseTaxRefunded(); - $discountTaxCompensation = $orderItem->getDiscountTaxCompensationInvoiced() - - $orderItem->getDiscountTaxCompensationRefunded(); - $baseDiscountTaxCompensation = $orderItem->getBaseDiscountTaxCompensationInvoiced() - - $orderItem->getBaseDiscountTaxCompensationRefunded(); + /** Check item tax amount */ + $tax = ($orderItemTax - $orderItem->getTaxRefunded()); + $baseTax = ($baseOrderItemTax - $orderItem->getBaseTaxRefunded()); + $discountTaxCompensation = ($orderItem->getDiscountTaxCompensationInvoiced() + - $orderItem->getDiscountTaxCompensationRefunded()); + $baseDiscountTaxCompensation = ($orderItem->getBaseDiscountTaxCompensationInvoiced() + - $orderItem->getBaseDiscountTaxCompensationRefunded()); if (!$item->isLast()) { - $availableQty = $orderItemQty - $orderItem->getQtyRefunded(); + $availableQty = ($orderItemQty - $orderItem->getQtyRefunded()); $tax = $creditmemo->roundPrice($tax / $availableQty * $item->getQty()); - $baseTax = $creditmemo->roundPrice($baseTax / $availableQty * $item->getQty(), 'base'); - $discountTaxCompensation = - $creditmemo->roundPrice($discountTaxCompensation / $availableQty * $item->getQty()); - $baseDiscountTaxCompensation = - $creditmemo->roundPrice($baseDiscountTaxCompensation / $availableQty * $item->getQty(), 'base'); + $baseTax = $creditmemo->roundPrice(($baseTax / $availableQty * $item->getQty()), 'base'); + $discountTaxCompensation = $creditmemo->roundPrice( + $discountTaxCompensation / $availableQty * $item->getQty() + ); + $baseDiscountTaxCompensation = $creditmemo->roundPrice( + $baseDiscountTaxCompensation / $availableQty * $item->getQty(), + 'base' + ); } $item->setTaxAmount($tax); @@ -77,14 +74,14 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) $isPartialShippingRefunded = false; $baseOrderShippingAmount = (float)$order->getBaseShippingAmount(); if ($invoice = $creditmemo->getInvoice()) { - //recalculate tax amounts in case if refund shipping value was changed + // recalculate tax amounts in case if refund shipping value was changed if ($baseOrderShippingAmount && $creditmemo->getBaseShippingAmount() !== null) { - $taxFactor = $creditmemo->getBaseShippingAmount() / $baseOrderShippingAmount; - $shippingTaxAmount = $invoice->getShippingTaxAmount() * $taxFactor; - $baseShippingTaxAmount = $invoice->getBaseShippingTaxAmount() * $taxFactor; - $totalDiscountTaxCompensation += $invoice->getShippingDiscountTaxCompensationAmount() * $taxFactor; - $baseTotalDiscountTaxCompensation += - $invoice->getBaseShippingDiscountTaxCompensationAmnt() * $taxFactor; + $taxFactor = ($creditmemo->getBaseShippingAmount() / $baseOrderShippingAmount); + $shippingTaxAmount = ($invoice->getShippingTaxAmount() * $taxFactor); + $baseShippingTaxAmount = ($invoice->getBaseShippingTaxAmount() * $taxFactor); + $totalDiscountTaxCompensation += ($invoice->getShippingDiscountTaxCompensationAmount() * $taxFactor); + $baseTotalDiscountTaxCompensation += $invoice->getBaseShippingDiscountTaxCompensationAmnt() + * $taxFactor; $shippingTaxAmount = $creditmemo->roundPrice($shippingTaxAmount); $baseShippingTaxAmount = $creditmemo->roundPrice($baseShippingTaxAmount, 'base'); $totalDiscountTaxCompensation = $creditmemo->roundPrice($totalDiscountTaxCompensation); @@ -97,61 +94,52 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) } } else { $orderShippingAmount = $order->getShippingAmount(); - $baseOrderShippingRefundedAmount = $order->getBaseShippingRefunded(); - $shippingTaxAmount = 0; $baseShippingTaxAmount = 0; $shippingDiscountTaxCompensationAmount = 0; $baseShippingDiscountTaxCompensationAmount = 0; - - $shippingDelta = $baseOrderShippingAmount - $baseOrderShippingRefundedAmount; + $shippingDelta = ($baseOrderShippingAmount - $baseOrderShippingRefundedAmount); if ($shippingDelta > $creditmemo->getBaseShippingAmount()) { - $part = $creditmemo->getShippingAmount() / $orderShippingAmount; - $basePart = $creditmemo->getBaseShippingAmount() / $baseOrderShippingAmount; - $shippingTaxAmount = $order->getShippingTaxAmount() * $part; - $baseShippingTaxAmount = $order->getBaseShippingTaxAmount() * $basePart; + $part = ($creditmemo->getShippingAmount() / $orderShippingAmount); + $basePart = ($creditmemo->getBaseShippingAmount() / $baseOrderShippingAmount); + $shippingTaxAmount = ($order->getShippingTaxAmount() * $part); + $baseShippingTaxAmount = ($order->getBaseShippingTaxAmount() * $basePart); $shippingDiscountTaxCompensationAmount = $order->getShippingDiscountTaxCompensationAmount() * $part; - $baseShippingDiscountTaxCompensationAmount = - $order->getBaseShippingDiscountTaxCompensationAmnt() * $basePart; + $baseShippingDiscountTaxCompensationAmount = $order->getBaseShippingDiscountTaxCompensationAmnt() + * $basePart; $shippingTaxAmount = $creditmemo->roundPrice($shippingTaxAmount); $baseShippingTaxAmount = $creditmemo->roundPrice($baseShippingTaxAmount, 'base'); - $shippingDiscountTaxCompensationAmount = - $creditmemo->roundPrice($shippingDiscountTaxCompensationAmount); - $baseShippingDiscountTaxCompensationAmount = - $creditmemo->roundPrice($baseShippingDiscountTaxCompensationAmount, 'base'); + $shippingDiscountTaxCompensationAmount = $creditmemo->roundPrice( + $shippingDiscountTaxCompensationAmount + ); + $baseShippingDiscountTaxCompensationAmount = $creditmemo->roundPrice( + $baseShippingDiscountTaxCompensationAmount, + 'base' + ); if ($part < 1 && $order->getShippingTaxAmount() > 0) { $isPartialShippingRefunded = true; } } elseif ($shippingDelta == $creditmemo->getBaseShippingAmount()) { $shippingTaxAmount = $order->getShippingTaxAmount() - $order->getShippingTaxRefunded(); $baseShippingTaxAmount = $order->getBaseShippingTaxAmount() - $order->getBaseShippingTaxRefunded(); - $shippingDiscountTaxCompensationAmount = $order->getShippingDiscountTaxCompensationAmount() - - $order->getShippingDiscountTaxCompensationRefunded(); - $baseShippingDiscountTaxCompensationAmount = $order->getBaseShippingDiscountTaxCompensationAmnt() - - $order->getBaseShippingDiscountTaxCompensationRefunded(); + $shippingDiscountTaxCompensationAmount = $order->getShippingDiscountTaxCompensationAmount() + - $order->getShippingDiscountTaxCompensationRefunded(); + $baseShippingDiscountTaxCompensationAmount = $order->getBaseShippingDiscountTaxCompensationAmnt() + - $order->getBaseShippingDiscountTaxCompensationRefunded(); } + $totalTax += $shippingTaxAmount; $baseTotalTax += $baseShippingTaxAmount; $totalDiscountTaxCompensation += $shippingDiscountTaxCompensationAmount; $baseTotalDiscountTaxCompensation += $baseShippingDiscountTaxCompensationAmount; } - $allowedTax = $order->getTaxInvoiced() - $order->getTaxRefunded() - $creditmemo->getTaxAmount(); - $allowedBaseTax = $order->getBaseTaxInvoiced() - $order->getBaseTaxRefunded() - $creditmemo->getBaseTaxAmount(); - $allowedDiscountTaxCompensation = $order->getDiscountTaxCompensationInvoiced() + - $order->getShippingDiscountTaxCompensationAmount() - - $order->getDiscountTaxCompensationRefunded() - - $order->getShippingDiscountTaxCompensationRefunded() - - $creditmemo->getDiscountTaxCompensationAmount() - - $creditmemo->getShippingDiscountTaxCompensationAmount(); - $allowedBaseDiscountTaxCompensation = $order->getBaseDiscountTaxCompensationInvoiced() + - $order->getBaseShippingDiscountTaxCompensationAmnt() - - $order->getBaseDiscountTaxCompensationRefunded() - - $order->getBaseShippingDiscountTaxCompensationRefunded() - - $creditmemo->getBaseShippingDiscountTaxCompensationAmnt() - - $creditmemo->getBaseDiscountTaxCompensationAmount(); + $allowedTax = $this->calculateAllowedTax($creditmemo); + $allowedBaseTax = $this->calculateAllowedBaseTax($creditmemo); + $allowedDiscountTaxCompensation = $this->calculateAllowedDiscountTaxCompensation($creditmemo); + $allowedBaseDiscountTaxCompensation = $this->calculateAllowedBaseDiscountTaxCompensation($creditmemo); if ($creditmemo->isLast() && !$isPartialShippingRefunded) { $totalTax = $allowedTax; @@ -161,10 +149,11 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) } else { $totalTax = min($allowedTax, $totalTax); $baseTotalTax = min($allowedBaseTax, $baseTotalTax); - $totalDiscountTaxCompensation = - min($allowedDiscountTaxCompensation, $totalDiscountTaxCompensation); - $baseTotalDiscountTaxCompensation = - min($allowedBaseDiscountTaxCompensation, $baseTotalDiscountTaxCompensation); + $totalDiscountTaxCompensation = min($allowedDiscountTaxCompensation, $totalDiscountTaxCompensation); + $baseTotalDiscountTaxCompensation = min( + $allowedBaseDiscountTaxCompensation, + $baseTotalDiscountTaxCompensation + ); } $creditmemo->setTaxAmount($creditmemo->getTaxAmount() + $totalTax); @@ -177,9 +166,91 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) $creditmemo->setGrandTotal($creditmemo->getGrandTotal() + $totalTax + $totalDiscountTaxCompensation); $creditmemo->setBaseGrandTotal( - $creditmemo->getBaseGrandTotal() + - $baseTotalTax + $baseTotalDiscountTaxCompensation + $creditmemo->getBaseGrandTotal() + $baseTotalTax + $baseTotalDiscountTaxCompensation ); return $this; + + } + + /** + * Calculate allowed to Credit Memo tax amount + * + * @param Creditmemo $creditMemo + * @return float + */ + private function calculateAllowedTax(Creditmemo $creditMemo): float + { + $invoice = $creditMemo->getInvoice(); + $order = $creditMemo->getOrder(); + $amount = $invoice !== null ? $invoice->getTaxAmount() : $order->getTaxInvoiced(); + + return (float) $amount - $order->getTaxRefunded() - $creditMemo->getTaxAmount(); + } + + /** + * Calculate allowed to Credit Memo tax amount in the base currency + * + * @param Creditmemo $creditMemo + * @return float + */ + private function calculateAllowedBaseTax(Creditmemo $creditMemo): float + { + $invoice = $creditMemo->getInvoice(); + $order = $creditMemo->getOrder(); + $amount = $invoice !== null ? $invoice->getBaseTaxAmount() : $order->getBaseTaxInvoiced(); + + return (float) $amount - $order->getBaseTaxRefunded() - $creditMemo->getBaseTaxAmount(); + } + + /** + * Calculate allowed to Credit Memo discount tax compensation amount + * + * @param Creditmemo $creditMemo + * @return float + */ + private function calculateAllowedDiscountTaxCompensation(Creditmemo $creditMemo): float + { + $invoice = $creditMemo->getInvoice(); + $order = $creditMemo->getOrder(); + + if ($invoice) { + $amount = $invoice->getDiscountTaxCompensationAmount() + + $invoice->getShippingDiscountTaxCompensationAmount(); + } else { + $amount = $order->getDiscountTaxCompensationInvoiced() + + $order->getShippingDiscountTaxCompensationAmount(); + } + + return (float) $amount + - $order->getDiscountTaxCompensationRefunded() + - $order->getShippingDiscountTaxCompensationRefunded() + - $creditMemo->getDiscountTaxCompensationAmount() + - $creditMemo->getShippingDiscountTaxCompensationAmount(); + } + + /** + * Calculate allowed to Credit Memo discount tax compensation amount in the base currency + * + * @param Creditmemo $creditMemo + * @return float + */ + private function calculateAllowedBaseDiscountTaxCompensation(Creditmemo $creditMemo): float + { + $invoice = $creditMemo->getInvoice(); + $order = $creditMemo->getOrder(); + + if ($invoice) { + $amount = $invoice->getBaseDiscountTaxCompensationAmount() + + $invoice->getBaseShippingDiscountTaxCompensationAmnt(); + } else { + $amount = $order->getBaseDiscountTaxCompensationInvoiced() + + $order->getBaseShippingDiscountTaxCompensationAmnt(); + } + + return (float) $amount + - $order->getBaseDiscountTaxCompensationRefunded() + - $order->getBaseShippingDiscountTaxCompensationRefunded() + - $creditMemo->getBaseShippingDiscountTaxCompensationAmnt() + - $creditMemo->getBaseDiscountTaxCompensationAmount(); } } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/TaxTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/TaxTest.php index 94346fc1b7a28..7c9d249124a9a 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/TaxTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/TaxTest.php @@ -17,6 +17,9 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +/** + * Class to test Collecting credit memo taxes + */ class TaxTest extends TestCase { /** @@ -44,6 +47,9 @@ class TaxTest extends TestCase */ protected $invoice; + /** + * @inheritdoc + */ protected function setUp(): void { $this->objectManager = new ObjectManager($this); @@ -188,6 +194,8 @@ public function collectDataProvider() 'base_tax_amount' => 0.82, 'invoice' => new MagentoObject( [ + 'tax_amount' => 24.33, + 'base_tax_amount' => 24.33, 'shipping_tax_amount' => 2.45, 'base_shipping_tax_amount' => 2.45, 'shipping_discount_tax_compensation_amount' => 0, @@ -277,6 +285,8 @@ public function collectDataProvider() 'base_tax_amount' => 0.82, 'invoice' => new MagentoObject( [ + 'tax_amount' => 24.33 * $currencyRatio, + 'base_tax_amount' => 24.33, 'shipping_tax_amount' => 2.45 * $currencyRatio, 'base_shipping_tax_amount' => 2.45, 'shipping_discount_tax_compensation_amount' => 0, @@ -352,6 +362,8 @@ public function collectDataProvider() 'base_tax_amount' => 1.65, 'invoice' => new MagentoObject( [ + 'tax_amount' => 11.14, + 'base_tax_amount' => 11.14, 'shipping_tax_amount' => 1.24, 'base_shipping_tax_amount' => 1.24, 'shipping_discount_tax_compensation_amount' => 0, @@ -428,6 +440,8 @@ public function collectDataProvider() 'base_tax_amount' => 0.82, 'invoice' => new MagentoObject( [ + 'tax_amount' => 16.09, + 'base_tax_amount' => 16.09, 'shipping_tax_amount' => 1.24, 'base_shipping_tax_amount' => 1.24, 'shipping_discount_tax_compensation_amount' => 0, @@ -507,14 +521,6 @@ public function collectDataProvider() 'base_shipping_amount' => 0, 'tax_amount' => 0.76, 'base_tax_amount' => 0.76, - 'invoice' => new MagentoObject( - [ - 'shipping_tax_amount' => 0, - 'base_shipping_tax_amount' => 0, - 'shipping_discount_tax_compensation_amount' => 0, - 'base_shipping_discount_tax_compensation_amount' => 0, - ] - ), ], ], 'expected_results' => [ @@ -583,6 +589,8 @@ public function collectDataProvider() 'base_tax_amount' => 0.82, 'invoice' => new MagentoObject( [ + 'tax_amount' => 16.09, + 'base_tax_amount' => 16.09, 'shipping_tax_amount' => 1.24, 'base_shipping_tax_amount' => 1.24, 'shipping_discount_tax_compensation_amount' => 0, @@ -712,14 +720,6 @@ public function collectDataProvider() 'base_shipping_amount' => 0, 'tax_amount' => 0, 'base_tax_amount' => 0, - 'invoice' => new MagentoObject( - [ - 'shipping_tax_amount' => 0, - 'base_shipping_tax_amount' => 0, - 'shipping_discount_tax_compensation_amount' => 0, - 'base_shipping_discount_tax_compensation_amount' => 0, - ] - ), ], ], 'expected_results' => [ From 3a808ffdac1301bfa61a2add14d41e59b5a3bd0f Mon Sep 17 00:00:00 2001 From: Sergiy Vasiutynskyi <s.vasiutynskyi@atwix.com> Date: Thu, 17 Dec 2020 16:10:03 +0200 Subject: [PATCH 083/156] Removed usage or changed value of CliIndexerReindexActionGroup action group for Catalog module --- .../Test/AddOutOfStockProductToCompareListTest.xml | 4 ++-- .../Mftf/Test/AdminAddInStockProductToTheCartTest.xml | 5 +---- ...CheckCustomAttributeValuesAfterProductSaveTest.xml | 4 +--- .../AdminSimpleProductImagesTest.xml | 4 +--- .../AdminUpdateFlatCategoryNameAndDescriptionTest.xml | 11 +++-------- .../Test/AdminUpdateSimpleProductTieredPriceTest.xml | 5 +---- ...gularPriceInStockVisibleInCatalogAndSearchTest.xml | 5 +---- ...ithRegularPriceInStockVisibleInCatalogOnlyTest.xml | 5 +---- .../Test/Mftf/Test/CheckTierPricingOfProductsTest.xml | 5 +---- .../EndToEndB2CGuestUserTest.xml | 5 +---- ...ProductAvailableAfterEnablingSubCategoriesTest.xml | 2 +- ...toreFrontProductsDisplayUsingElasticSearchTest.xml | 4 +--- .../Test/StoreFrontRecentlyViewedAtStoreLevelTest.xml | 4 +--- .../StoreFrontRecentlyViewedAtStoreViewLevelTest.xml | 4 +--- ...refrontCheckDefaultNumberProductsToDisplayTest.xml | 5 +---- .../StorefrontProductNameWithHTMLEntitiesTest.xml | 4 +--- ...oryProductAndProductCategoryPartialReindexTest.xml | 4 +--- 17 files changed, 20 insertions(+), 60 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml index 92be79fdfe720..212400ac4dd6e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml @@ -52,8 +52,8 @@ <!--Clear cache and reindex--> <comment userInput="Clear cache and reindex" stepKey="cleanCache"/> <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> -</actionGroup> + <argument name="indices" value="catalog_product_price"/> + </actionGroup> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> <argument name="tags" value=""/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddInStockProductToTheCartTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddInStockProductToTheCartTest.xml index 94d3b46aaa5f1..73019bb5ec0e0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddInStockProductToTheCartTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddInStockProductToTheCartTest.xml @@ -58,10 +58,7 @@ <actionGroup ref="AdminSubmitAdvancedInventoryFormActionGroup" stepKey="clickOnDoneButton"/> <actionGroup ref="AdminProductFormSaveActionGroup" stepKey="clickOnSaveButton"/> <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the product." stepKey="messageYouSavedTheProductIsShown"/> - <!--Clear cache and reindex--> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindex"/> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> <argument name="tags" value=""/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckCustomAttributeValuesAfterProductSaveTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckCustomAttributeValuesAfterProductSaveTest.xml index 0bdf19c9b8950..ca0616213c593 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckCustomAttributeValuesAfterProductSaveTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckCustomAttributeValuesAfterProductSaveTest.xml @@ -33,9 +33,7 @@ </createData> <!-- Create simple product --> <createData entity="SimpleProduct2" stepKey="createSimpleProduct"/> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindexCatalogSearch"> - <argument name="indices" value="catalogsearch_fulltext"/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindexCatalogSearch"/> <!-- Login to Admin page --> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest/AdminSimpleProductImagesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest/AdminSimpleProductImagesTest.xml index de116b26d1414..8a33f6132aeb9 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest/AdminSimpleProductImagesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest/AdminSimpleProductImagesTest.xml @@ -141,9 +141,7 @@ <!-- Save the second product --> <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct2"/> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindex"/> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> <argument name="tags" value=""/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryNameAndDescriptionTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryNameAndDescriptionTest.xml index 27a834833ed76..2124efed31293 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryNameAndDescriptionTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryNameAndDescriptionTest.xml @@ -34,10 +34,7 @@ <magentoCLI stepKey="setFlatCatalogCategory" command="config:set catalog/frontend/flat_catalog_category 1"/> <!--Open Index Management Page and Select Index mode "Update by Schedule" --> <magentoCLI stepKey="setIndexerMode" command="indexer:set-mode" arguments="schedule" /> - <!--Run full reindex and clear caches --> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindex"/> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> <argument name="tags" value=""/> </actionGroup> @@ -45,9 +42,7 @@ <after> <magentoCLI stepKey="setFlatCatalogCategory" command="config:set catalog/frontend/flat_catalog_category 0 "/> <magentoCLI stepKey="setIndexerMode" command="indexer:set-mode" arguments="realtime" /> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="indexerReindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="indexerReindex"/> <deleteData stepKey="deleteCategory" createDataKey="createCategory" /> <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteStoreViewEn"> <argument name="customStore" value="customStoreEN"/> @@ -71,7 +66,7 @@ <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="seeSuccessMessage"/> <!--Run full reindex and clear caches --> <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> + <argument name="indices" value="catalog_category_flat"/> </actionGroup> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> <argument name="tags" value=""/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductTieredPriceTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductTieredPriceTest.xml index 300b312612253..95d5e4d349478 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductTieredPriceTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductTieredPriceTest.xml @@ -26,10 +26,7 @@ </createData> <createData entity="SimpleSubCategory" stepKey="categoryEntity"/> - <!--TODO: REMOVE AFTER FIX MC-21717 --> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindex"/> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> <argument name="tags" value="full_page"/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml index 320edba5feeff..1735dc692ed3b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml @@ -91,10 +91,7 @@ <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="clickAdminProductSEOSection1"/> <seeInField selector="{{AdminProductSEOSection.urlKeyInput}}" userInput="{{simpleProductRegularPrice245InStock.urlKey}}" stepKey="seeUrlKey"/> - <!--Run re-index task --> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindex"/> <!--Verify customer see updated simple product link on category page --> <amOnPage url="{{StorefrontCategoryPage.url($$categoryEntity.name$$)}}" stepKey="openCategoryPage"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogOnlyTest.xml index 77c3e7548a3cf..bd3160248682e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogOnlyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogOnlyTest.xml @@ -91,10 +91,7 @@ <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="clickAdminProductSEOSection1"/> <seeInField selector="{{AdminProductSEOSection.urlKeyInput}}" userInput="{{simpleProductRegularPrice32501InStock.urlKey}}" stepKey="seeUrlKey"/> - <!--Run re-index task --> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindex"/> <!--Verify customer see updated simple product link on category page --> <amOnPage url="{{StorefrontCategoryPage.url($$categoryEntity.name$$)}}" stepKey="openCategoryPage"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml index 5f7e9c4225c00..2095d56ce6c59 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml @@ -332,10 +332,7 @@ <createData entity="CustomerAccountSharingDefault" stepKey="setConfigCustomerAccountDefault"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> - <!--Do reindex and flush cache--> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindex"/> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> <argument name="tags" value=""/> </actionGroup> 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 ff68bba78cae8..aed2976df8f73 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest/EndToEndB2CGuestUserTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest/EndToEndB2CGuestUserTest.xml @@ -56,10 +56,7 @@ <deleteData createDataKey="createSimpleProduct2" stepKey="deleteSimpleProduct2"/> </after> - <!--Re-index--> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindex"/> <!-- Step 1: User browses catalog --> <comment userInput="Start of browsing catalog" stepKey="startOfBrowsingCatalog"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml index 7fd752d7df98d..b5980cf977791 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml @@ -50,7 +50,7 @@ <!--Run re-index task--> <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> + <argument name="indices" value="cataloginventory_stock"/> </actionGroup> <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="goToHomepage"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontProductsDisplayUsingElasticSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontProductsDisplayUsingElasticSearchTest.xml index cde7b14614f8e..3d3867d1efcf1 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontProductsDisplayUsingElasticSearchTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontProductsDisplayUsingElasticSearchTest.xml @@ -114,9 +114,7 @@ </createData> <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="performReindex"> - <argument name="indices" value="catalogsearch_fulltext"/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="performReindex"/> <actionGroup ref="CliCacheCleanActionGroup" stepKey="cleanFullPageCache"> <argument name="tags" value="full_page"/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyViewedAtStoreLevelTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyViewedAtStoreLevelTest.xml index e1b5aca6382e9..64ad348257853 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyViewedAtStoreLevelTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyViewedAtStoreLevelTest.xml @@ -74,9 +74,7 @@ </actionGroup> <!-- Logout Admin --> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindex"/> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCacheAfterDeletion"> <argument name="tags" value=""/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyViewedAtStoreViewLevelTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyViewedAtStoreViewLevelTest.xml index 0117493906de1..4d04a25c8d12f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyViewedAtStoreViewLevelTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyViewedAtStoreViewLevelTest.xml @@ -66,9 +66,7 @@ <!-- Logout Admin --> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindex"/> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCacheAfterDeletion"> <argument name="tags" value=""/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontCheckDefaultNumberProductsToDisplayTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontCheckDefaultNumberProductsToDisplayTest.xml index a73bd5a533ad0..ca561e4af70de 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontCheckDefaultNumberProductsToDisplayTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontCheckDefaultNumberProductsToDisplayTest.xml @@ -187,10 +187,7 @@ <seeInField selector="{{AdminCatalogStorefrontConfigSection.productsPerPageAllowedValues}}" userInput="12,24,36" stepKey="seeDefaultValueAllowedNumberProductsPerPage"/> <seeInField selector="{{AdminCatalogStorefrontConfigSection.productsPerPageDefaultValue}}" userInput="12" stepKey="seeDefaultValueProductPerPage"/> - <!-- Perform reindex and flush cache --> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindex"/> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> <argument name="tags" value=""/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuoteTest/StorefrontProductNameWithHTMLEntitiesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuoteTest/StorefrontProductNameWithHTMLEntitiesTest.xml index 2156178ea88d0..9819357704d44 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuoteTest/StorefrontProductNameWithHTMLEntitiesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuoteTest/StorefrontProductNameWithHTMLEntitiesTest.xml @@ -33,9 +33,7 @@ </after> <!--Run re-index task--> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindex"/> <!--Check product in category listing--> <amOnPage url="{{StorefrontCategoryPage.url($$createCategoryOne.name$$)}}" stepKey="navigateToCategoryPage"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/VerifyCategoryProductAndProductCategoryPartialReindexTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/VerifyCategoryProductAndProductCategoryPartialReindexTest.xml index ce04b377300f8..cf1bb065349b6 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/VerifyCategoryProductAndProductCategoryPartialReindexTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/VerifyCategoryProductAndProductCategoryPartialReindexTest.xml @@ -65,9 +65,7 @@ <after> <!-- Change "Category Products" and "Product Categories" indexers to "Update on Save" mode --> <magentoCLI command="indexer:set-mode" arguments="realtime" stepKey="setRealtimeMode"/> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <comment userInput="Adding the comment to replace CliIndexerReindexActionGroup action group ('indexer:reindex' commands) for preserving Backward Compatibility" stepKey="reindex"/> <!-- Delete data --> <deleteData createDataKey="productA" stepKey="deleteProductA"/> From 42e25513694695a1383fa183a981566a4d717c8a Mon Sep 17 00:00:00 2001 From: Buba Suma <soumah@adobe.com> Date: Wed, 16 Dec 2020 17:14:57 -0600 Subject: [PATCH 084/156] MC-39895: PayPal PayflowPro redirect Parameter list format error - Fix checkout with Credit Card (Payflow Pro) fails if billing address has special characters (&, =) --- .../Paypal/Model/Payflow/Service/Gateway.php | 68 ++++++- .../Model/Payflow/Service/GatewayTest.php | 177 +++++++++++++++--- 2 files changed, 217 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/Paypal/Model/Payflow/Service/Gateway.php b/app/code/Magento/Paypal/Model/Payflow/Service/Gateway.php index 6a2229c3d55ca..374af021cbf38 100644 --- a/app/code/Magento/Paypal/Model/Payflow/Service/Gateway.php +++ b/app/code/Magento/Paypal/Model/Payflow/Service/Gateway.php @@ -85,7 +85,8 @@ public function postRequest(DataObject $request, ConfigInterface $config) ); $client->setConfig($clientConfig); $client->setMethod(\Zend_Http_Client::POST); - $client->setParameterPost($request->getData()); + $requestData = $this->prepareRequestData($request->getData()); + $client->setParameterPost($requestData); $client->setHeaders( [ 'X-VPS-VIT-CLIENT-CERTIFICATION-ID' => '33baf5893fc2123d8b191d2d011b7fdc', @@ -97,9 +98,7 @@ public function postRequest(DataObject $request, ConfigInterface $config) try { $response = $client->request(); - - $responseArray = []; - parse_str(strstr($response->getBody(), 'RESULT'), $responseArray); + $responseArray = $this->parseNVP(strstr($response->getBody(), 'RESULT')); $result->setData(array_change_key_case($responseArray, CASE_LOWER)); $result->setData('result_code', $result->getData('result')); @@ -115,7 +114,7 @@ public function postRequest(DataObject $request, ConfigInterface $config) } finally { $this->logger->debug( [ - 'request' => $request->getData(), + 'request' => $requestData, 'result' => $result->getData() ], (array)$config->getValue('getDebugReplacePrivateDataKeys'), @@ -125,4 +124,63 @@ public function postRequest(DataObject $request, ConfigInterface $config) return $result; } + + /** + * Add length tag to parameters name which contains special characters: =, & + * + * The length tag specifies the exact number of characters and spaces (number of bytes) that appear in the value + * eg ['COMPANYNAME[14]' => 'Ruff & Johnson')] + * + * @param array $data + * @return array + */ + private function prepareRequestData(array $data): array + { + $requestData = []; + foreach ($data as $k => $v) { + if (strpos($v, '&') !== false || strpos($v, '=') !== false) { + $requestData[$k . '[' . strlen($v) . ']'] = $v; + } else { + $requestData[$k] = $v; + } + } + return $requestData; + } + + /** + * Parse NVP string into array + * + * Use length tag (if present) to parse the key value. + * + * The length tag specifies the exact number of characters and spaces (number of bytes) that appear in the value + * e.g COMPANYNAME[14]=Ruff & Johnson + * e.g COMMENT1[7]=Level=5 + * + * @param string $nvp + * @return array + */ + private function parseNVP(string $nvp): array + { + $result = []; + while (strlen($nvp) > 0) { + $keyPos = strpos($nvp, '='); + if ($keyPos !== false) { + $key = substr($nvp, 0, $keyPos); + if (preg_match('/\[(\d+)]$/', $key, $keyParts)) { + $valueLength = (int) $keyParts[1]; + $key = substr($key, 0, strpos($key, '[')); + $result[$key] = substr($nvp, $keyPos + 1, $valueLength); + $valuePos = $keyPos + 1 + $valueLength; + } else { + $valuePos = strpos($nvp, '&') ? strpos($nvp, '&') : strlen($nvp); + $value = substr($nvp, $keyPos + 1, $valuePos - $keyPos - 1); + $result[$key] = $value; + } + $nvp = substr($nvp, $valuePos + 1); + } else { + $nvp = ''; + } + } + return $result; + } } diff --git a/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/GatewayTest.php b/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/GatewayTest.php index 194b708a0352b..a2d8111ec33c6 100644 --- a/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/GatewayTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/GatewayTest.php @@ -17,27 +17,43 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; +use ReflectionMethod; +use Zend_Http_Client_Exception; +use Zend_Http_Response; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class GatewayTest extends TestCase { - /** @var Gateway|MockObject */ - protected $object; - - /** @var ZendClientFactory|MockObject */ - protected $httpClientFactoryMock; - - /** @var Random|MockObject */ - protected $mathRandomMock; - - /** @var Logger|MockObject */ - protected $loggerMock; - - /** @var ZendClient|MockObject */ - protected $zendClientMock; - + /** + * @var Gateway|MockObject + */ + private $object; + + /** + * @var ZendClientFactory|MockObject + */ + private $httpClientFactoryMock; + + /** + * @var Random|MockObject + */ + private $mathRandomMock; + + /** + * @var Logger|MockObject + */ + private $loggerMock; + + /** + * @var ZendClient|MockObject + */ + private $zendClientMock; + + /** + * @inheritdoc + */ protected function setUp(): void { $this->httpClientFactoryMock = $this->getMockBuilder(ZendClientFactory::class) @@ -66,24 +82,28 @@ protected function setUp(): void ); } - public function testPostRequestOk() + /** + * @param string $nvpResponse + * @param array $expectedResult + * @dataProvider postRequestOkDataProvider + */ + public function testPostRequestOk(string $nvpResponse, array $expectedResult): void { $configMap = [ ['getDebugReplacePrivateDataKeys', null, ['masked']], ['debug', null, true] ]; - $expectedResponse = 'RESULT=0&RESPMSG=Approved&SECURETOKEN=8ZIaw2&SECURETOKENID=2481d53'; /** @var ConfigInterface|MockObject $configInterfaceMock */ $configInterfaceMock = $this->getMockBuilder(ConfigInterface::class) ->getMockForAbstractClass(); - $zendResponseMock = $this->getMockBuilder(\Zend_Http_Response::class) + $zendResponseMock = $this->getMockBuilder(Zend_Http_Response::class) ->setMethods(['getBody']) ->disableOriginalConstructor() ->getMock(); $zendResponseMock->expects(static::once()) ->method('getBody') - ->willReturn($expectedResponse); + ->willReturn($nvpResponse); $this->zendClientMock->expects(static::once()) ->method('request') ->willReturn($zendResponseMock); @@ -98,8 +118,119 @@ public function testPostRequestOk() $result = $this->object->postRequest($object, $configInterfaceMock); - static::assertInstanceOf(DataObject::class, $result); - static::assertArrayHasKey('result_code', $result->getData()); + static::assertEquals($expectedResult, $result->toArray()); + } + + /** + * @return array[] + */ + public function postRequestOkDataProvider(): array + { + return [ + [ + 'RESULT=0&RESPMSG=Approved&SECURETOKEN=9tl4MmP46NUadl9pwCKFgfQjA' + . '&SECURETOKENID=vVWBMSNb9j0SLlYw4AbqBnKmuogtzNNC', + [ + 'result' => '0', + 'securetoken' => '9tl4MmP46NUadl9pwCKFgfQjA', + 'securetokenid' => 'vVWBMSNb9j0SLlYw4AbqBnKmuogtzNNC', + 'respmsg' => 'Approved', + 'result_code' => '0', + ] + ], + [ + 'RESULT=0&PNREF=A30A3A958244&RESPMSG=Approved&AUTHCODE=028PNI&AVSADDR=N&AVSZIP=N&HOSTCODE=A' + . '&PROCAVS=N&VISACARDLEVEL=12&TRANSTIME=2020-12-16 14:43:57&FIRSTNAME[4]=Joé' + . '&LASTNAME=O\'Reilly&COMPANYNAME[14]=Ruff & Johnson&COMMENT1[7]=Level=5' + . '&AMT=30.00&ACCT=1111&EXPDATE=1224&CARDTYPE=0&IAVS=N', + [ + 'result' => '0', + 'pnref' => 'A30A3A958244', + 'respmsg' => 'Approved', + 'authcode' => '028PNI', + 'avsaddr' => 'N', + 'avszip' => 'N', + 'hostcode' => 'A', + 'procavs' => 'N', + 'visacardlevel' => '12', + 'transtime' => '2020-12-16 14:43:57', + 'firstname' => 'Joé', + 'lastname' => 'O\'Reilly', + 'companyname' => 'Ruff & Johnson', + 'comment1' => 'Level=5', + 'amt' => '30.00', + 'acct' => '1111', + 'expdate' => '1224', + 'cardtype' => '0', + 'iavs' => 'N', + 'result_code' => '0', + ] + ], + ]; + } + + /** + * @param array $requestData + * @param string $requestBody + * @dataProvider requestBodyDataProvider + */ + public function testRequestBody(array $requestData, string $requestBody): void + { + $configMap = [ + ['getDebugReplacePrivateDataKeys', null, ['masked']], + ['debug', null, true] + ]; + + /** @var ConfigInterface|MockObject $configInterfaceMock */ + $configInterfaceMock = $this->getMockBuilder(ConfigInterface::class) + ->getMockForAbstractClass(); + $zendResponseMock = $this->getMockBuilder(Zend_Http_Response::class) + ->setMethods(['getBody']) + ->disableOriginalConstructor() + ->getMock(); + $zendResponseMock->expects(static::once()) + ->method('getBody') + ->willReturn('RESULT=0&RESPMSG=Approved'); + $this->zendClientMock->expects(static::once()) + ->method('request') + ->willReturn($zendResponseMock); + + $configInterfaceMock->expects(static::any()) + ->method('getValue') + ->willReturnMap($configMap); + $this->loggerMock->expects(static::once()) + ->method('debug'); + + $request = new DataObject($requestData); + $this->object->postRequest($request, $configInterfaceMock); + $method = new ReflectionMethod($this->zendClientMock, '_prepareBody'); + $method->setAccessible(true); + $this->assertEquals($requestBody, $method->invoke($this->zendClientMock)); + } + + /** + * @return array[] + */ + public function requestBodyDataProvider(): array + { + return [ + [ + [ + 'companyname' => 'Ruff & Johnson', + 'comment1' => 'Level=5', + 'shiptofirstname' => 'Joé', + 'shiptolastname' => 'O\'Reilly', + 'shiptostreet' => '4659 Rainbow Road', + 'shiptocity' => 'Los Angeles', + 'shiptostate' => 'CA', + 'shiptozip' => '90017', + 'shiptocountry' => 'US', + ], + 'companyname[14]=Ruff & Johnson&comment1[7]=Level=5&shiptofirstname=Joé&shiptolastname=O\'Reilly' + . '&shiptostreet=4659 Rainbow Road&shiptocity=Los Angeles&shiptostate=CA&shiptozip=90017' + . '&shiptocountry=US' + ] + ]; } public function testPostRequestFail() @@ -108,7 +239,7 @@ public function testPostRequestFail() /** @var ConfigInterface|MockObject $configInterfaceMock */ $configInterfaceMock = $this->getMockBuilder(ConfigInterface::class) ->getMockForAbstractClass(); - $zendResponseMock = $this->getMockBuilder(\Zend_Http_Response::class) + $zendResponseMock = $this->getMockBuilder(Zend_Http_Response::class) ->setMethods(['getBody']) ->disableOriginalConstructor() ->getMock(); @@ -116,7 +247,7 @@ public function testPostRequestFail() ->method('getBody'); $this->zendClientMock->expects(static::once()) ->method('request') - ->willThrowException(new \Zend_Http_Client_Exception()); + ->willThrowException(new Zend_Http_Client_Exception()); $object = new DataObject(); $this->object->postRequest($object, $configInterfaceMock); From b955411760da5f70e0bcc6a96462f9217e567e8a Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Thu, 17 Dec 2020 09:52:49 -0600 Subject: [PATCH 085/156] MC-39861: Customer is redirected to the blank page after using PayPal WPPHS payment on checkout --- .../Magento/Paypal/Controller/Hostedpro/ReturnActionTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Controller/Hostedpro/ReturnActionTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Controller/Hostedpro/ReturnActionTest.php index d52c2501a565a..b3870c69b23f0 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Controller/Hostedpro/ReturnActionTest.php +++ b/dev/tests/integration/testsuite/Magento/Paypal/Controller/Hostedpro/ReturnActionTest.php @@ -8,7 +8,7 @@ namespace Magento\Paypal\Controller\Hostedpro; use Magento\TestFramework\TestCase\AbstractController; -use Zend\Stdlib\Parameters; +use Laminas\Stdlib\Parameters; /** * Tests PayPal HostedPro return controller. From 37e8487aca8692b89c9657215ea0c9618cc5d967 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Thu, 17 Dec 2020 17:55:16 +0200 Subject: [PATCH 086/156] added AdminClickRefundOfflineOnMemoDetailPageActionGroup --- ...dableProductLinkAfterPartialRefundTest.xml | 4 ++-- ...kRefundOfflineOnNewMemoPageActionGroup.xml | 19 +++++++++++++++++++ ...reateCreditMemoBankTransferPaymentTest.xml | 4 ++-- ...AdminCreateCreditMemoPartialRefundTest.xml | 4 ++-- ...nCreateCreditMemoWithPurchaseOrderTest.xml | 4 ++-- .../Test/Mftf/Test/EndToEndB2CAdminTest.xml | 4 ++-- 6 files changed, 29 insertions(+), 10 deletions(-) create mode 100644 app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickRefundOfflineOnNewMemoPageActionGroup.xml diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/StorefrontAccountDownloadableProductLinkAfterPartialRefundTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/StorefrontAccountDownloadableProductLinkAfterPartialRefundTest.xml index b89aa7d126686..41fc2850e00ff 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/StorefrontAccountDownloadableProductLinkAfterPartialRefundTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/StorefrontAccountDownloadableProductLinkAfterPartialRefundTest.xml @@ -98,8 +98,8 @@ <argument name="rowNumber" value="1"/> </actionGroup> - <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="clickRefundOffline"/> - <waitForPageLoad stepKey="waitForResultPage"/> + <actionGroup ref="AdminClickRefundOfflineOnNewMemoPageActionGroup" stepKey="clickRefundOffline"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForResultPage"/> <actionGroup ref="StorefrontNotAssertDownloadableProductLinkInCustomerAccountActionGroup" stepKey="dontSeeStorefrontMyAccountDownloadableProductsLink"> <argument name="product" value="$$createDownloadableProduct$$"/> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickRefundOfflineOnNewMemoPageActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickRefundOfflineOnNewMemoPageActionGroup.xml new file mode 100644 index 0000000000000..21ca2d51a364e --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickRefundOfflineOnNewMemoPageActionGroup.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="AdminClickRefundOfflineOnNewMemoPageActionGroup"> + <annotations> + <description>Click the Refund Offline button on the New Memo page</description> + </annotations> + <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="clickRefundOffline"/> + <waitForElementVisible selector="{{AdminMessagesSection.success}}" stepKey="waitForSuccesMessage"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You created the credit memo." stepKey="seeSuccessMessage"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoBankTransferPaymentTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoBankTransferPaymentTest.xml index 6ed8510db777c..9d1daf0d2ded1 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoBankTransferPaymentTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoBankTransferPaymentTest.xml @@ -85,8 +85,8 @@ </actionGroup> <!-- On order's page click 'Refund offline' button --> - <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="clickRefundOffline"/> - <waitForPageLoad stepKey="waitForResultPage"/> + <actionGroup ref="AdminClickRefundOfflineOnNewMemoPageActionGroup" stepKey="clickRefundOffline"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForResultPage"/> <!-- Perform all assertions: assert refund success create message --> <see selector="{{AdminIndexManagementSection.successMessage}}" userInput="You created the credit memo." stepKey="assertRefundSuccessCreateMessage"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoPartialRefundTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoPartialRefundTest.xml index 68301187d3d31..5d2f76b80e3f8 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoPartialRefundTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoPartialRefundTest.xml @@ -78,8 +78,8 @@ </actionGroup> <!-- On order's page click 'Refund offline' button --> - <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="clickRefundOffline"/> - <waitForPageLoad stepKey="waitForResultPage"/> + <actionGroup ref="AdminClickRefundOfflineOnNewMemoPageActionGroup" stepKey="clickRefundOffline"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForResultPage"/> <!-- Perform all assertions: assert refund success create message --> <waitForElementVisible selector="{{AdminIndexManagementSection.successMessage}}" stepKey="waitForSuccessMessage"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithPurchaseOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithPurchaseOrderTest.xml index 141fa2a9e5d06..32c3a5e0a5846 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithPurchaseOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithPurchaseOrderTest.xml @@ -88,8 +88,8 @@ </actionGroup> <!-- On order's page click 'Refund offline' button --> - <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="clickRefundOffline"/> - <waitForPageLoad stepKey="waitForResultPage"/> + <actionGroup ref="AdminClickRefundOfflineOnNewMemoPageActionGroup" stepKey="clickRefundOffline"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForResultPage"/> <!-- Perform all assertions: assert refund success create message --> <see selector="{{AdminIndexManagementSection.successMessage}}" userInput="You created the credit memo." stepKey="assertRefundSuccessCreateMessage"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/EndToEndB2CAdminTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/EndToEndB2CAdminTest.xml index 6ba1c3ac3deec..2a3284e7e8e35 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/EndToEndB2CAdminTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/EndToEndB2CAdminTest.xml @@ -140,8 +140,8 @@ <argument name="billingAddress" value="US_Address_TX"/> </actionGroup> <!--Submit credit memo--> - <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="clickRefundOffline" after="verifyOrderCreditMemoInformation"/> - <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="You created the credit memo." stepKey="seeCreditMemoSuccess" after="clickRefundOffline"/> + <actionGroup ref="AdminClickRefundOfflineOnNewMemoPageActionGroup" stepKey="clickRefundOffline" after="verifyOrderCreditMemoInformation"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeCreditMemoSuccess" after="clickRefundOffline"/> <click selector="{{AdminOrderDetailsOrderViewSection.creditMemos}}" stepKey="clickOrderCreditMemosTab" after="seeCreditMemoSuccess"/> <waitForLoadingMaskToDisappear stepKey="waitForCreditMemoTabLoadingMask" after="clickOrderCreditMemosTab"/> <see selector="{{AdminOrderCreditMemosTabSection.gridRow('1')}}" userInput="{{Simple_US_Customer.firstname}}" stepKey="seeOrderCreditMemoInTabGrid" after="waitForCreditMemoTabLoadingMask"/> From b07440c2f304658730298ef0d22d3825c2e8aa06 Mon Sep 17 00:00:00 2001 From: Roman Flowers <flowers@adobe.com> Date: Thu, 17 Dec 2020 11:06:03 -0600 Subject: [PATCH 087/156] MC-39463: GraphQL caches urlResolver response and can return the old value after the url rewrite update --- .../Magento/UrlRewrite/Model/UrlRewrite.php | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php index d82781ee66450..cbefcd4c75597 100644 --- a/app/code/Magento/UrlRewrite/Model/UrlRewrite.php +++ b/app/code/Magento/UrlRewrite/Model/UrlRewrite.php @@ -145,23 +145,27 @@ public function setMetadata($metadata) */ private function getFinalTargetUrlRewrite(string $path, int $storeId): ?UrlRewriteService { + $urlRewriteTarget = $this->urlFinder->findOneByData( + [ + 'request_path' => $path, + 'store_id' => $storeId + ] + ); + + while ( + $urlRewriteTarget && + $urlRewriteTarget->getTargetPath() !== $urlRewriteTarget->getRequestPath() && + $urlRewriteTarget->getRedirectType() > 0 + ) { $urlRewriteTarget = $this->urlFinder->findOneByData( [ - 'request_path' => $path, - 'store_id' => $storeId + 'request_path' => $urlRewriteTarget->getTargetPath(), + 'store_id' => $urlRewriteTarget->getStoreId() ] ); + } - while ($urlRewriteTarget && $urlRewriteTarget->getRedirectType() > 0) { - $urlRewriteTarget = $this->urlFinder->findOneByData( - [ - 'request_path' => $urlRewriteTarget->getTargetPath(), - 'store_id' => $urlRewriteTarget->getStoreId() - ] - ); - } - - return $urlRewriteTarget; + return $urlRewriteTarget; } /** From 650aaa661afb97e17e86ca7ff7e5e6bfadb51192 Mon Sep 17 00:00:00 2001 From: Roman Flowers <flowers@adobe.com> Date: Thu, 17 Dec 2020 16:33:26 -0600 Subject: [PATCH 088/156] MC-39463: GraphQL caches urlResolver response and can return the old value after the url rewrite update --- .../GraphQl/UrlRewrite/UrlResolverTest.php | 179 +++++++++++++++++- 1 file changed, 178 insertions(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php index 7aed048f1c4ce..5b84537dddf94 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php @@ -7,8 +7,14 @@ namespace Magento\GraphQl\UrlRewrite; +use Magento\Framework\Exception\AlreadyExistsException; +use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQlAbstract; +use Magento\UrlRewrite\Model\ResourceModel\UrlRewrite as UrlRewriteResourceModel; +use Magento\UrlRewrite\Model\UrlFinderInterface; +use Magento\UrlRewrite\Model\UrlRewrite as UrlRewriteModel; +use Magento\UrlRewrite\Service\V1\Data\UrlRewrite as UrlRewriteService; /** * Test the GraphQL endpoint's URLResolver query to verify canonical URL's are correctly returned. @@ -20,7 +26,7 @@ class UrlResolverTest extends GraphQlAbstract protected function setUp(): void { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->objectManager = Bootstrap::getObjectManager(); } /** @@ -50,4 +56,175 @@ public function testNonExistentEntityUrlRewrite() ); $this->graphQlQuery($query); } + + /** + * Test for url rewrite to clean cache on rewrites update + * + * @magentoApiDataFixture Magento/Catalog/_files/product_with_category.php + * @magentoApiDataFixture Magento/Cms/_files/pages.php + * + * @dataProvider urlRewriteEntitiesDataProvider + * @param string $requestPath + * @throws AlreadyExistsException + */ + public function testUrlRewriteCleansCacheOnChange(string $requestPath) + { + + /** @var UrlRewriteResourceModel $urlRewriteResourceModel */ + $urlRewriteResourceModel = $this->objectManager->create(UrlRewriteResourceModel::class); + $storeId = 1; + $query = function ($requestUrl) { + return <<<QUERY +{ + urlResolver(url:"{$requestUrl}") + { + id + entity_uid + relative_url + type + redirectCode + } +} +QUERY; + }; + + // warming up urlResolver API response cache for entity and validate proper response + $apiResponse = $this->graphQlQuery($query($requestPath))['urlResolver']; + $this->assertEquals($requestPath, $apiResponse['relative_url']); + + $urlRewrite = $this->getUrlRewriteModelByRequestPath($requestPath, $storeId); + + // renaming entity request path and validating that API will not return cached response + $urlRewrite->setRequestPath('test' . $requestPath); + $urlRewriteResourceModel->save($urlRewrite); + $apiResponse = $this->graphQlQuery($query($requestPath))['urlResolver']; + $this->assertNull($apiResponse['relative_url']); + + // rolling back changes + $urlRewrite->setRequestPath($requestPath); + $urlRewriteResourceModel->save($urlRewrite); + } + + public function urlRewriteEntitiesDataProvider(): array + { + return [ + [ + 'simple-product-in-stock.html' + ], + [ + 'category-1.html' + ], + [ + 'page100' + ] + ]; + } + + /** + * Test for custom url rewrite to clean cache on update combinations + * + * @magentoApiDataFixture Magento/Catalog/_files/product_with_category.php + * @magentoApiDataFixture Magento/Cms/_files/pages.php + * + * @throws AlreadyExistsException + */ + public function testUrlRewriteCleansCacheForCustomRewrites() + { + + /** @var UrlRewriteResourceModel $urlRewriteResourceModel */ + $urlRewriteResourceModel = $this->objectManager->create(UrlRewriteResourceModel::class); + $storeId = 1; + $query = function ($requestUrl) { + return <<<QUERY +{ + urlResolver(url:"{$requestUrl}") + { + id + entity_uid + relative_url + type + redirectCode + } +} +QUERY; + }; + + $customRequestPath = 'test.html'; + $customSecondRequestPath = 'test2.html'; + $entitiesRequestPaths = [ + 'simple-product-in-stock.html', + 'category-1.html', + 'page100' + ]; + + // create custom url rewrite + $urlRewrite = $this->objectManager->create(UrlRewriteModel::class); + $urlRewrite->setEntityType('custom') + ->setRedirectType(302) + ->setStoreId($storeId) + ->setDescription(null) + ->setIsAutogenerated(0); + + // create second custom url rewrite and target it to previous one to check + // if proper final target url will be resolved + $secondUrlRewrite = $this->objectManager->create(UrlRewriteModel::class); + $secondUrlRewrite->setEntityType('custom') + ->setRedirectType(302) + ->setStoreId($storeId) + ->setRequestPath($customSecondRequestPath) + ->setTargetPath($customRequestPath) + ->setDescription(null) + ->setIsAutogenerated(0); + $urlRewriteResourceModel->save($secondUrlRewrite); + + foreach ($entitiesRequestPaths as $entityRequestPath) { + // updating custom rewrite for each entity + $urlRewrite->setRequestPath($customRequestPath) + ->setTargetPath($entityRequestPath); + $urlRewriteResourceModel->save($urlRewrite); + + // confirm that API returns non-cached response for the first custom rewrite + $apiResponse = $this->graphQlQuery($query($customRequestPath))['urlResolver']; + $this->assertEquals($entityRequestPath, $apiResponse['relative_url']); + + // confirm that API returns non-cached response for the second custom rewrite + $apiResponse = $this->graphQlQuery($query($customSecondRequestPath))['urlResolver']; + $this->assertEquals($entityRequestPath, $apiResponse['relative_url']); + } + + $urlRewriteResourceModel->delete($secondUrlRewrite); + + // delete custom rewrite and validate that API will not return cached response + $urlRewriteResourceModel->delete($urlRewrite); + $apiResponse = $this->graphQlQuery($query($customRequestPath))['urlResolver']; + $this->assertNull($apiResponse['relative_url']); + } + + /** + * Return UrlRewrite model instance by request_path + * + * @param string $requestPath + * @param int $storeId + * @return UrlRewriteModel + */ + private function getUrlRewriteModelByRequestPath(string $requestPath, int $storeId): UrlRewriteModel + { + /** @var UrlFinderInterface $urlFinder */ + $urlFinder = $this->objectManager->get(UrlFinderInterface::class); + + /** @var UrlRewriteService $urlRewriteService */ + $urlRewriteService = $urlFinder->findOneByData( + [ + 'request_path' => $requestPath, + 'store_id' => $storeId + ] + ); + + /** @var UrlRewriteModel $urlRewrite */ + $urlRewrite = $this->objectManager->create(UrlRewriteModel::class); + $urlRewrite->load($urlRewriteService->getUrlRewriteId()); + + return $urlRewrite; + } + } From b372bdb84636b44e6c94e092584e64b64713e413 Mon Sep 17 00:00:00 2001 From: Roman Flowers <flowers@adobe.com> Date: Thu, 17 Dec 2020 18:51:39 -0600 Subject: [PATCH 089/156] MC-39463: GraphQL caches urlResolver response and can return the old value after the url rewrite update --- .../GraphQl/UrlRewrite/UrlResolverTest.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php index 5b84537dddf94..e6ed14ae2685e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php @@ -89,16 +89,16 @@ public function testUrlRewriteCleansCacheOnChange(string $requestPath) }; // warming up urlResolver API response cache for entity and validate proper response - $apiResponse = $this->graphQlQuery($query($requestPath))['urlResolver']; - $this->assertEquals($requestPath, $apiResponse['relative_url']); + $apiResponse = $this->graphQlQuery($query($requestPath)); + $this->assertEquals($requestPath, $apiResponse['urlResolver']['relative_url']); $urlRewrite = $this->getUrlRewriteModelByRequestPath($requestPath, $storeId); // renaming entity request path and validating that API will not return cached response $urlRewrite->setRequestPath('test' . $requestPath); $urlRewriteResourceModel->save($urlRewrite); - $apiResponse = $this->graphQlQuery($query($requestPath))['urlResolver']; - $this->assertNull($apiResponse['relative_url']); + $apiResponse = $this->graphQlQuery($query($requestPath)); + $this->assertNull($apiResponse['urlResolver']['relative_url']); // rolling back changes $urlRewrite->setRequestPath($requestPath); @@ -184,20 +184,20 @@ public function testUrlRewriteCleansCacheForCustomRewrites() $urlRewriteResourceModel->save($urlRewrite); // confirm that API returns non-cached response for the first custom rewrite - $apiResponse = $this->graphQlQuery($query($customRequestPath))['urlResolver']; - $this->assertEquals($entityRequestPath, $apiResponse['relative_url']); + $apiResponse = $this->graphQlQuery($query($customRequestPath)); + $this->assertEquals($entityRequestPath, $apiResponse['urlResolver']['relative_url']); // confirm that API returns non-cached response for the second custom rewrite - $apiResponse = $this->graphQlQuery($query($customSecondRequestPath))['urlResolver']; - $this->assertEquals($entityRequestPath, $apiResponse['relative_url']); + $apiResponse = $this->graphQlQuery($query($customSecondRequestPath)); + $this->assertEquals($entityRequestPath, $apiResponse['urlResolver']['relative_url']); } $urlRewriteResourceModel->delete($secondUrlRewrite); // delete custom rewrite and validate that API will not return cached response $urlRewriteResourceModel->delete($urlRewrite); - $apiResponse = $this->graphQlQuery($query($customRequestPath))['urlResolver']; - $this->assertNull($apiResponse['relative_url']); + $apiResponse = $this->graphQlQuery($query($customRequestPath)); + $this->assertNull($apiResponse['urlResolver']['relative_url']); } /** From 7edefd28ea67b16add4184008298e95ade8f1826 Mon Sep 17 00:00:00 2001 From: Arnob Saha <arnobsh@gmail.com> Date: Wed, 16 Dec 2020 14:03:36 -0600 Subject: [PATCH 090/156] MC-39896: Catalog price rules are not included in CartItemPrices in the API - Adding customer group to the customer session - Adding api test --- .../Pricing/Price/UpdateCatalogRulePrice.php | 68 +++++++ .../CatalogRuleGraphQl/etc/graphql/di.xml | 12 ++ .../GraphQl/CatalogGraphQl/PriceRangeTest.php | 175 ++++++++++++++++++ ...t_with_tier_prices_for_logged_in_group.php | 48 +++++ ...er_prices_for_logged_in_group_rollback.php | 10 + ...th_tier_prices_for_not_logged_in_group.php | 48 +++++ ...rices_for_not_logged_in_group_rollback.php | 10 + .../catalog_rule_25_customer_group_all.php | 39 ++++ ...og_rule_25_customer_group_all_rollback.php | 35 ++++ ...alog_rule_50_registered_customer_group.php | 39 ++++ ..._50_registered_customer_group_rollback.php | 35 ++++ 11 files changed, 519 insertions(+) create mode 100644 app/code/Magento/CatalogRuleGraphQl/Plugin/Pricing/Price/UpdateCatalogRulePrice.php create mode 100644 app/code/Magento/CatalogRuleGraphQl/etc/graphql/di.xml create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogGraphQl/PriceRangeTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_logged_in_group.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_logged_in_group_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_not_logged_in_group.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_not_logged_in_group_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_25_customer_group_all.php create mode 100644 dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_25_customer_group_all_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_50_registered_customer_group.php create mode 100644 dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_50_registered_customer_group_rollback.php diff --git a/app/code/Magento/CatalogRuleGraphQl/Plugin/Pricing/Price/UpdateCatalogRulePrice.php b/app/code/Magento/CatalogRuleGraphQl/Plugin/Pricing/Price/UpdateCatalogRulePrice.php new file mode 100644 index 0000000000000..61b9f70c49f04 --- /dev/null +++ b/app/code/Magento/CatalogRuleGraphQl/Plugin/Pricing/Price/UpdateCatalogRulePrice.php @@ -0,0 +1,68 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogRuleGraphQl\Plugin\Pricing\Price; + +use Magento\CatalogRule\Model\ResourceModel\Rule; +use Magento\CatalogRule\Pricing\Price\CatalogRulePrice; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; + +/** + * Class UpdateCatalogRulePrice + * + * Plugin to update catalog rule price based on customer group id + */ +class UpdateCatalogRulePrice +{ + /** + * @var TimezoneInterface + */ + private $dateTime; + + /** + * @var Rule + */ + private $ruleResource; + + /** + * @param TimezoneInterface $dateTime + * @param Rule $ruleResource + */ + public function __construct( + TimezoneInterface $dateTime, + Rule $ruleResource + ) { + $this->dateTime = $dateTime; + $this->ruleResource = $ruleResource; + } + + /** + * Returns catalog rule value for logged in customer group + * + * @param CatalogRulePrice $catalogRulePrice + * @param float|boolean $value + * @return float|boolean + */ + public function afterGetValue( + CatalogRulePrice $catalogRulePrice, + $value + ) { + $product = $catalogRulePrice->getProduct(); + if ($product && $product->getCustomerGroupId()) { + $store = $product->getStore(); + $value = $this->ruleResource->getRulePrice( + $this->dateTime->scopeDate($store->getId()), + $store->getWebsiteId(), + $product->getCustomerGroupId(), + $product->getId() + ); + $value = $value ? (float) $value : false; + } + + return $value; + } +} diff --git a/app/code/Magento/CatalogRuleGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogRuleGraphQl/etc/graphql/di.xml new file mode 100644 index 0000000000000..571783edece6c --- /dev/null +++ b/app/code/Magento/CatalogRuleGraphQl/etc/graphql/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\CatalogRule\Pricing\Price\CatalogRulePrice"> + <plugin name="update_catalog_rule_price_for_logged_in_customer_group" type="Magento\CatalogRuleGraphQl\Plugin\Pricing\Price\UpdateCatalogRulePrice"/> + </type> +</config> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogGraphQl/PriceRangeTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogGraphQl/PriceRangeTest.php new file mode 100644 index 0000000000000..81b08f28431a6 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogGraphQl/PriceRangeTest.php @@ -0,0 +1,175 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\CatalogGraphQl; + +use Magento\GraphQl\GetCustomerAuthenticationHeader; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\ObjectManager; +use Magento\TestFramework\TestCase\GraphQlAbstract; + +/** + * Test class to verify catalog price rule is applied for + * tier prices for different customer groups. + */ +class PriceRangeTest extends GraphQlAbstract +{ + /** + * @var ObjectManager|null + */ + private $objectManager; + + /** + * @var GetCustomerAuthenticationHeader + */ + private $getCustomerAuthenticationHeader; + + protected function setUp(): void + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->getCustomerAuthenticationHeader = $this->objectManager->get(GetCustomerAuthenticationHeader::class); + } + + /** + * Test for checking if catalog rule price has been applied for all customer group + * + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + * @magentoApiDataFixture Magento/CatalogRule/_files/catalog_rule_25_customer_group_all.php + */ + public function testCheckIfCatalogRuleIsAppliedForTierPriceForAllGroups(): void + { + $productSku = 'simple'; + $query = $this->getProductSearchQuery($productSku); + + $response = $this->graphQlQuery($query); + + $this->assertNotEmpty($response['products']); + $priceRange = $response['products']['items'][0]['price_range']; + $this->assertEquals(10, $priceRange['minimum_price']['regular_price']['value']); + $this->assertEquals(7.5, $priceRange['minimum_price']['final_price']['value']); + $this->assertEquals(2.5, $priceRange['minimum_price']['discount']['amount_off']); + $this->assertEquals(25, $priceRange['minimum_price']['discount']['percent_off']); + $this->assertEquals(10, $priceRange['maximum_price']['regular_price']['value']); + $this->assertEquals(7.5, $priceRange['maximum_price']['final_price']['value']); + $this->assertEquals(2.5, $priceRange['maximum_price']['discount']['amount_off']); + $this->assertEquals(25, $priceRange['maximum_price']['discount']['percent_off']); + } + + /** + * Test for checking if catalog rule price has been applied for registered customer + * + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Catalog/_files/simple_product_with_tier_prices_for_logged_in_group.php + * @magentoApiDataFixture Magento/CatalogRule/_files/catalog_rule_50_registered_customer_group.php + */ + public function testCheckIfCatalogRuleIsAppliedForTierPriceForRegisteredCustomer(): void + { + $productSku = 'simple'; + $query = $this->getProductSearchQuery($productSku); + $response = $this->graphQlQuery( + $query, + [], + '', + $this->getCustomerAuthenticationHeader->execute('customer@example.com', 'password') + ); + + $this->assertNotEmpty($response['products']); + $priceRange = $response['products']['items'][0]['price_range']; + $this->assertEquals(10, $priceRange['minimum_price']['regular_price']['value']); + $this->assertEquals(5, $priceRange['minimum_price']['final_price']['value']); + $this->assertEquals(5, $priceRange['minimum_price']['discount']['amount_off']); + $this->assertEquals(50, $priceRange['minimum_price']['discount']['percent_off']); + $this->assertEquals(10, $priceRange['maximum_price']['regular_price']['value']); + $this->assertEquals(5, $priceRange['maximum_price']['final_price']['value']); + $this->assertEquals(5, $priceRange['maximum_price']['discount']['amount_off']); + $this->assertEquals(50, $priceRange['maximum_price']['discount']['percent_off']); + } + + /** + * Test for checking if catalog rule price has been applied for guest + * + * @magentoApiDataFixture Magento/Catalog/_files/simple_product_with_tier_prices_for_not_logged_in_group.php + * @magentoApiDataFixture Magento/CatalogRule/_files/catalog_rule_10_off_not_logged.php + */ + public function testCheckIfCatalogRuleIsAppliedForTierPriceForGuest(): void + { + $productSku = 'simple'; + $query = $this->getProductSearchQuery($productSku); + $response = $this->graphQlQuery($query); + + $this->assertNotEmpty($response['products']); + $priceRange = $response['products']['items'][0]['price_range']; + $this->assertEquals(10, $priceRange['minimum_price']['regular_price']['value']); + $this->assertEquals(9, $priceRange['minimum_price']['final_price']['value']); + $this->assertEquals(1, $priceRange['minimum_price']['discount']['amount_off']); + $this->assertEquals(10, $priceRange['minimum_price']['discount']['percent_off']); + $this->assertEquals(10, $priceRange['maximum_price']['regular_price']['value']); + $this->assertEquals(9, $priceRange['maximum_price']['final_price']['value']); + $this->assertEquals(1, $priceRange['maximum_price']['discount']['amount_off']); + $this->assertEquals(10, $priceRange['maximum_price']['discount']['percent_off']); + } + + /** + * Get a query which user filter for product sku and returns price_tiers + * + * @param string $productSku + * @return string + */ + private function getProductSearchQuery(string $productSku): string + { + return <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) { + items { + name + sku + price_range { + minimum_price { + regular_price { + value + currency + } + final_price { + value + currency + } + discount { + amount_off + percent_off + } + } + maximum_price { + regular_price { + value + currency + } + final_price { + value + currency + } + discount { + amount_off + percent_off + } + } + } + price_tiers{ + discount{ + amount_off + percent_off + } + final_price{ + value + } + quantity + } + } + } +} +QUERY; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_logged_in_group.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_logged_in_group.php new file mode 100644 index 0000000000000..35af54d574fd4 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_logged_in_group.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory; +use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Store\Api\WebsiteRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; +use Magento\Customer\Model\Group; + +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_simple.php'); + +$objectManager = Bootstrap::getObjectManager(); +$productRepository = $objectManager->create(ProductRepositoryInterface::class); +$tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class); +$tpExtensionAttributesFactory = $objectManager->get(ProductTierPriceExtensionFactory::class); +$product = $productRepository->get('simple', false, null, true); +$adminWebsite = $objectManager->get(WebsiteRepositoryInterface::class)->get('admin'); +$tierPriceExtensionAttributes = $tpExtensionAttributesFactory->create()->setWebsiteId($adminWebsite->getId()); +$pricesForCustomerGroupsInput = [ + [ + 'customer_group_id' => '1', + 'percentage_value'=> null, + 'qty'=> 1, + 'value'=> 20 + ], + [ + 'customer_group_id' => '1', + 'percentage_value'=> null, + 'qty'=> 2, + 'value'=> 30 + ] +]; +$productTierPrices = []; +foreach ($pricesForCustomerGroupsInput as $price) { + $productTierPrices[] = $tierPriceFactory->create( + [ + 'data' => $price + ] + )->setExtensionAttributes($tierPriceExtensionAttributes); +} +$product->setTierPrices($productTierPrices); +$productRepository->save($product); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_logged_in_group_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_logged_in_group_rollback.php new file mode 100644 index 0000000000000..328c1e229da5c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_logged_in_group_rollback.php @@ -0,0 +1,10 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_simple_rollback.php'); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_not_logged_in_group.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_not_logged_in_group.php new file mode 100644 index 0000000000000..cfb89b7de3305 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_not_logged_in_group.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory; +use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Store\Api\WebsiteRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; +use Magento\Customer\Model\Group; + +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_simple.php'); + +$objectManager = Bootstrap::getObjectManager(); +$productRepository = $objectManager->create(ProductRepositoryInterface::class); +$tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class); +$tpExtensionAttributesFactory = $objectManager->get(ProductTierPriceExtensionFactory::class); +$product = $productRepository->get('simple', false, null, true); +$adminWebsite = $objectManager->get(WebsiteRepositoryInterface::class)->get('admin'); +$tierPriceExtensionAttributes = $tpExtensionAttributesFactory->create()->setWebsiteId($adminWebsite->getId()); +$pricesForCustomerGroupsInput = [ + [ + 'customer_group_id' => Group::NOT_LOGGED_IN_ID, + 'percentage_value'=> null, + 'qty'=> 1, + 'value'=> 50 + ], + [ + 'customer_group_id' => Group::NOT_LOGGED_IN_ID, + 'percentage_value'=> null, + 'qty'=> 2, + 'value'=> 80 + ] +]; +$productTierPrices = []; +foreach ($pricesForCustomerGroupsInput as $price) { + $productTierPrices[] = $tierPriceFactory->create( + [ + 'data' => $price + ] + )->setExtensionAttributes($tierPriceExtensionAttributes); +} +$product->setTierPrices($productTierPrices); +$productRepository->save($product); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_not_logged_in_group_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_not_logged_in_group_rollback.php new file mode 100644 index 0000000000000..328c1e229da5c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_product_with_tier_prices_for_not_logged_in_group_rollback.php @@ -0,0 +1,10 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_simple_rollback.php'); diff --git a/dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_25_customer_group_all.php b/dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_25_customer_group_all.php new file mode 100644 index 0000000000000..2c31c9a8d688a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_25_customer_group_all.php @@ -0,0 +1,39 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +/** + * Creates simple Catalog Rule with the following data: + * active, applied to all products, without time limits, with 25% off for all customer groups + */ +use Magento\CatalogRule\Model\Indexer\IndexBuilder; +use Magento\CatalogRule\Model\Rule; +use Magento\Customer\Model\GroupManagement; +use Magento\TestFramework\Helper\Bootstrap; + +/** @var $banner Rule */ +$catalogRule = Bootstrap::getObjectManager()->create( + Rule::class +); + +$catalogRule + ->setIsActive(1) + ->setName('Test Catalog Rule With 25 Percent Off') + ->setCustomerGroupIds('0') + ->setDiscountAmount(25) + ->setWebsiteIds([0 => 1]) + ->setSimpleAction('by_percent') + ->setStopRulesProcessing(false) + ->setSortOrder(0) + ->setSubIsEnable(0) + ->setSubDiscountAmount(0) + ->save(); + +/** @var IndexBuilder $indexBuilder */ +$indexBuilder = Bootstrap::getObjectManager() + ->get(IndexBuilder::class); +$indexBuilder->reindexFull(); +sleep(1); diff --git a/dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_25_customer_group_all_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_25_customer_group_all_rollback.php new file mode 100644 index 0000000000000..73e6bbff46648 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_25_customer_group_all_rollback.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\CatalogRule\Api\CatalogRuleRepositoryInterface; +use Magento\CatalogRule\Model\Indexer\IndexBuilder; +use Magento\CatalogRule\Model\ResourceModel\Rule; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); + +/** @var Rule $catalogRuleResource */ +$catalogRuleResource = $objectManager->create(Rule::class); +$connection = $catalogRuleResource->getConnection(); + +//Retrieve rule id by name +$select = $connection->select(); +$select->from($catalogRuleResource->getMainTable(), 'rule_id'); +$select->where('name = ?', 'Test Catalog Rule With 25 Percent Off'); +$ruleId = $connection->fetchOne($select); + +try { + /** @var CatalogRuleRepositoryInterface $ruleRepository */ + $ruleRepository = $objectManager->create(CatalogRuleRepositoryInterface::class); + $ruleRepository->deleteById($ruleId); +} catch (\Exception $ex) { + //Nothing to remove +} +/** @var IndexBuilder $indexBuilder */ +$indexBuilder = $objectManager->get(IndexBuilder::class); +$indexBuilder->reindexFull(); +sleep(1); diff --git a/dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_50_registered_customer_group.php b/dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_50_registered_customer_group.php new file mode 100644 index 0000000000000..d583dace85536 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_50_registered_customer_group.php @@ -0,0 +1,39 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +/** + * Creates simple Catalog Rule with the following data: + * active, applied to all products, without time limits, with 50% off for registered customer groups + */ +use Magento\CatalogRule\Model\Indexer\IndexBuilder; +use Magento\CatalogRule\Model\Rule; +use Magento\Customer\Model\GroupManagement; +use Magento\TestFramework\Helper\Bootstrap; + +/** @var $banner Rule */ +$catalogRule = Bootstrap::getObjectManager()->create( + Rule::class +); + +$catalogRule + ->setIsActive(1) + ->setName('Test Catalog Rule With 50 Percent Off') + ->setCustomerGroupIds('1') + ->setDiscountAmount(50) + ->setWebsiteIds([0 => 1]) + ->setSimpleAction('by_percent') + ->setStopRulesProcessing(false) + ->setSortOrder(0) + ->setSubIsEnable(0) + ->setSubDiscountAmount(0) + ->save(); + +/** @var IndexBuilder $indexBuilder */ +$indexBuilder = Bootstrap::getObjectManager() + ->get(IndexBuilder::class); +$indexBuilder->reindexFull(); +sleep(1); diff --git a/dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_50_registered_customer_group_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_50_registered_customer_group_rollback.php new file mode 100644 index 0000000000000..46df301157b5c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogRule/_files/catalog_rule_50_registered_customer_group_rollback.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\CatalogRule\Api\CatalogRuleRepositoryInterface; +use Magento\CatalogRule\Model\Indexer\IndexBuilder; +use Magento\CatalogRule\Model\ResourceModel\Rule; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); + +/** @var Rule $catalogRuleResource */ +$catalogRuleResource = $objectManager->create(Rule::class); +$connection = $catalogRuleResource->getConnection(); + +//Retrieve rule id by name +$select = $connection->select(); +$select->from($catalogRuleResource->getMainTable(), 'rule_id'); +$select->where('name = ?', 'Test Catalog Rule With 50 Percent Off'); +$ruleId = $connection->fetchOne($select); + +try { + /** @var CatalogRuleRepositoryInterface $ruleRepository */ + $ruleRepository = $objectManager->create(CatalogRuleRepositoryInterface::class); + $ruleRepository->deleteById($ruleId); +} catch (\Exception $ex) { + //Nothing to remove +} +/** @var IndexBuilder $indexBuilder */ +$indexBuilder = $objectManager->get(IndexBuilder::class); +$indexBuilder->reindexFull(); +sleep(1); From 8b873ad45946dbefbd75038baea32df29c49980b Mon Sep 17 00:00:00 2001 From: Serhii Balko <serhii.balko@transogtgroup.com> Date: Fri, 18 Dec 2020 10:46:21 +0200 Subject: [PATCH 091/156] MC-39864: [Magento Cloud] - Tax Miscalculation --- .../Model/Order/Creditmemo/Total/Tax.php | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php index 9e6e8979e46ee..5fe4d0af7bd89 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php @@ -40,14 +40,14 @@ public function collect(Creditmemo $creditmemo) if ($orderItemQty) { /** Check item tax amount */ - $tax = ($orderItemTax - $orderItem->getTaxRefunded()); - $baseTax = ($baseOrderItemTax - $orderItem->getBaseTaxRefunded()); - $discountTaxCompensation = ($orderItem->getDiscountTaxCompensationInvoiced() - - $orderItem->getDiscountTaxCompensationRefunded()); - $baseDiscountTaxCompensation = ($orderItem->getBaseDiscountTaxCompensationInvoiced() - - $orderItem->getBaseDiscountTaxCompensationRefunded()); + $tax = $orderItemTax - $orderItem->getTaxRefunded(); + $baseTax = $baseOrderItemTax - $orderItem->getBaseTaxRefunded(); + $discountTaxCompensation = $orderItem->getDiscountTaxCompensationInvoiced() + - $orderItem->getDiscountTaxCompensationRefunded(); + $baseDiscountTaxCompensation = $orderItem->getBaseDiscountTaxCompensationInvoiced() + - $orderItem->getBaseDiscountTaxCompensationRefunded(); if (!$item->isLast()) { - $availableQty = ($orderItemQty - $orderItem->getQtyRefunded()); + $availableQty = $orderItemQty - $orderItem->getQtyRefunded(); $tax = $creditmemo->roundPrice($tax / $availableQty * $item->getQty()); $baseTax = $creditmemo->roundPrice(($baseTax / $availableQty * $item->getQty()), 'base'); $discountTaxCompensation = $creditmemo->roundPrice( @@ -76,10 +76,10 @@ public function collect(Creditmemo $creditmemo) if ($invoice = $creditmemo->getInvoice()) { // recalculate tax amounts in case if refund shipping value was changed if ($baseOrderShippingAmount && $creditmemo->getBaseShippingAmount() !== null) { - $taxFactor = ($creditmemo->getBaseShippingAmount() / $baseOrderShippingAmount); - $shippingTaxAmount = ($invoice->getShippingTaxAmount() * $taxFactor); - $baseShippingTaxAmount = ($invoice->getBaseShippingTaxAmount() * $taxFactor); - $totalDiscountTaxCompensation += ($invoice->getShippingDiscountTaxCompensationAmount() * $taxFactor); + $taxFactor = $creditmemo->getBaseShippingAmount() / $baseOrderShippingAmount; + $shippingTaxAmount = $invoice->getShippingTaxAmount() * $taxFactor; + $baseShippingTaxAmount = $invoice->getBaseShippingTaxAmount() * $taxFactor; + $totalDiscountTaxCompensation += $invoice->getShippingDiscountTaxCompensationAmount() * $taxFactor; $baseTotalDiscountTaxCompensation += $invoice->getBaseShippingDiscountTaxCompensationAmnt() * $taxFactor; $shippingTaxAmount = $creditmemo->roundPrice($shippingTaxAmount); @@ -102,10 +102,10 @@ public function collect(Creditmemo $creditmemo) $shippingDelta = ($baseOrderShippingAmount - $baseOrderShippingRefundedAmount); if ($shippingDelta > $creditmemo->getBaseShippingAmount()) { - $part = ($creditmemo->getShippingAmount() / $orderShippingAmount); - $basePart = ($creditmemo->getBaseShippingAmount() / $baseOrderShippingAmount); - $shippingTaxAmount = ($order->getShippingTaxAmount() * $part); - $baseShippingTaxAmount = ($order->getBaseShippingTaxAmount() * $basePart); + $part = $creditmemo->getShippingAmount() / $orderShippingAmount; + $basePart = $creditmemo->getBaseShippingAmount() / $baseOrderShippingAmount; + $shippingTaxAmount = $order->getShippingTaxAmount() * $part; + $baseShippingTaxAmount = $order->getBaseShippingTaxAmount() * $basePart; $shippingDiscountTaxCompensationAmount = $order->getShippingDiscountTaxCompensationAmount() * $part; $baseShippingDiscountTaxCompensationAmount = $order->getBaseShippingDiscountTaxCompensationAmnt() * $basePart; From 7d9d478b7c6b5dac52c7f4544b89612a0859d24b Mon Sep 17 00:00:00 2001 From: Serhii Balko <serhii.balko@transogtgroup.com> Date: Fri, 18 Dec 2020 10:53:08 +0200 Subject: [PATCH 092/156] MC-39864: [Magento Cloud] - Tax Miscalculation --- app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php index 5fe4d0af7bd89..0d1382a48e065 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php @@ -99,7 +99,7 @@ public function collect(Creditmemo $creditmemo) $baseShippingTaxAmount = 0; $shippingDiscountTaxCompensationAmount = 0; $baseShippingDiscountTaxCompensationAmount = 0; - $shippingDelta = ($baseOrderShippingAmount - $baseOrderShippingRefundedAmount); + $shippingDelta = $baseOrderShippingAmount - $baseOrderShippingRefundedAmount; if ($shippingDelta > $creditmemo->getBaseShippingAmount()) { $part = $creditmemo->getShippingAmount() / $orderShippingAmount; From acac6b2f488a29c8d23f6361ef64d66c43beed42 Mon Sep 17 00:00:00 2001 From: Arnob Saha <arnobsh@gmail.com> Date: Thu, 10 Dec 2020 15:13:32 -0600 Subject: [PATCH 093/156] MC-39737: Reports: Review by Products - MFTF test and the solution --- .../reports_report_review_product_grid.xml | 4 +- ...inFilterProductReviewByNameActionGroup.xml | 20 +++++ .../Test/Mftf/Data/ProductReviewData.xml | 16 ++++ .../Section/AdminCreateNewReviewSection.xml | 5 ++ ...viewDateForReviewsByProductsReportTest.xml | 83 +++++++++++++++++++ 5 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Review/Test/Mftf/ActionGroup/AdminFilterProductReviewByNameActionGroup.xml create mode 100644 app/code/Magento/Review/Test/Mftf/Test/AdminValidateLastReviewDateForReviewsByProductsReportTest.xml diff --git a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_review_product_grid.xml b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_review_product_grid.xml index 26d0e8b13659d..b9d4572cd4868 100644 --- a/app/code/Magento/Reports/view/adminhtml/layout/reports_report_review_product_grid.xml +++ b/app/code/Magento/Reports/view/adminhtml/layout/reports_report_review_product_grid.xml @@ -90,8 +90,8 @@ <arguments> <argument name="header" xsi:type="string" translate="true">Last Review</argument> <argument name="type" xsi:type="string">datetime</argument> - <argument name="id" xsi:type="string">created_at</argument> - <argument name="index" xsi:type="string">created_at</argument> + <argument name="id" xsi:type="string">last_review</argument> + <argument name="index" xsi:type="string">last_review</argument> <argument name="column_css_class" xsi:type="string">col-date</argument> <argument name="header_css_class" xsi:type="string">col-date</argument> </arguments> diff --git a/app/code/Magento/Review/Test/Mftf/ActionGroup/AdminFilterProductReviewByNameActionGroup.xml b/app/code/Magento/Review/Test/Mftf/ActionGroup/AdminFilterProductReviewByNameActionGroup.xml new file mode 100644 index 0000000000000..b0544081980bb --- /dev/null +++ b/app/code/Magento/Review/Test/Mftf/ActionGroup/AdminFilterProductReviewByNameActionGroup.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="AdminFilterProductReviewByNameActionGroup"> + <arguments> + <argument name="productName" type="string"/> + </arguments> + <waitForPageLoad stepKey="waitForGridToAppear"/> + <fillField userInput="{{productName}}" selector="{{AdminCreateNewReviewSection.filterProductName}}" stepKey="searchReview"/> + <click selector="{{AdminCreateNewReviewSection.searchButton}}" stepKey="startSearch"/> + <waitForPageLoad stepKey="waitForResults"/> + <see userInput="{{productName}}" selector="{{AdminCreateNewReviewSection.gridProductColumn}}" stepKey="assertReviewColumn"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Review/Test/Mftf/Data/ProductReviewData.xml b/app/code/Magento/Review/Test/Mftf/Data/ProductReviewData.xml index f66decd1b7bd0..ba2102d0ee1f1 100644 --- a/app/code/Magento/Review/Test/Mftf/Data/ProductReviewData.xml +++ b/app/code/Magento/Review/Test/Mftf/Data/ProductReviewData.xml @@ -16,4 +16,20 @@ <item>Default Store View</item> </array> </entity> + <entity name="firstSimpleProductReview"> + <data key="nickname" unique="suffix">user1</data> + <data key="title">Review title 1</data> + <data key="detail">Simple product review 1</data> + <array key="select_stores"> + <item>Default Store View</item> + </array> + </entity> + <entity name="secondSimpleProductReview"> + <data key="nickname" unique="suffix">user2</data> + <data key="title">Review title 2</data> + <data key="detail">Simple product review 2</data> + <array key="select_stores"> + <item>Default Store View</item> + </array> + </entity> </entities> diff --git a/app/code/Magento/Review/Test/Mftf/Section/AdminCreateNewReviewSection.xml b/app/code/Magento/Review/Test/Mftf/Section/AdminCreateNewReviewSection.xml index 3b17b20e9da1b..28eb3112f259a 100644 --- a/app/code/Magento/Review/Test/Mftf/Section/AdminCreateNewReviewSection.xml +++ b/app/code/Magento/Review/Test/Mftf/Section/AdminCreateNewReviewSection.xml @@ -18,8 +18,13 @@ <element name="submitReview" type="button" selector="#save_button"/> <element name="SuccessMessage" type="button" selector="div.message-success"/> <element name="gridProducts_filter_review_cnt" type="button" selector="#gridProducts_filter_review_cnt"/> + <element name="filterProductName" type="button" selector="#gridProducts_filter_name"/> <element name="searchButton" type="button" selector="//*[@id='gridProducts']//button[contains(@title, 'Search')]"/> <element name="gridReviewColumn" type="text" selector="//tbody//td[@data-column='review_cnt']"/> + <element name="gridLastReviewColumn" type="text" selector="//tbody//td[@data-column='created_at']"/> + <element name="gridProductColumn" type="text" selector="//tbody//td[@data-column='name']"/> + <element name="showReviewsButton" type="text" selector="//tbody//td[@data-column='action']"/> + <element name="grabLatestUserReviewDate" type="text" selector="//table[@class='data-grid']//tbody//tr[position()=1]//td[position()=3]"/> <element name="gridCustomer_filter_review_cnt" type="button" selector="#customers_grid_filter_review_cnt"/> <element name="CustomerSearchButton" type="button" selector="//*[@id='customers_grid']//button[contains(@title, 'Search')]"/> </section> diff --git a/app/code/Magento/Review/Test/Mftf/Test/AdminValidateLastReviewDateForReviewsByProductsReportTest.xml b/app/code/Magento/Review/Test/Mftf/Test/AdminValidateLastReviewDateForReviewsByProductsReportTest.xml new file mode 100644 index 0000000000000..3405314f24f78 --- /dev/null +++ b/app/code/Magento/Review/Test/Mftf/Test/AdminValidateLastReviewDateForReviewsByProductsReportTest.xml @@ -0,0 +1,83 @@ +<?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="AdminValidateLastReviewDateForReviewsByProductsReportTest"> + <annotations> + <features value="Review"/> + <stories value="Reports: Review by Products"/> + <title value="Admin Validate Last Review Date For Review by Products Reports"/> + <description value="Admin Validate Last Review Date For Review by Products Reports"/> + <severity value="MAJOR"/> + <useCaseId value="MC-39737"/> + <testCaseId value="MC-39838"/> + </annotations> + <before> + <!--Step1. Login as admin--> + <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin"/> + <!--Step2. Create product and Category--> + <createData stepKey="category" entity="SimpleSubCategory"/> + <createData stepKey="createProduct" entity="SimpleProduct"> + <requiredEntity createDataKey="category"/> + </createData> + </before> + <after> + <!--Step9. Delete newly created product reviews --> + <actionGroup ref="AdminOpenReviewsPageActionGroup" stepKey="openAllReviewsPage"/> + <actionGroup ref="AdminDeleteReviewsByUserNicknameActionGroup" stepKey="deleteFirstCustomerReview"> + <argument name="nickname" value="{{firstSimpleProductReview.nickname}}"/> + </actionGroup> + <actionGroup ref="AdminDeleteReviewsByUserNicknameActionGroup" stepKey="deleteSecondCustomerReview"> + <argument name="nickname" value="{{secondSimpleProductReview.nickname}}"/> + </actionGroup> + <!--Step10. delete Category and Products --> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="category" stepKey="deleteCategory"/> + <!--Step11. Admin Logout--> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + <!--Step3. Navigate to Marketing > User Content> All Review --> + <amOnPage url="{{AdminReviewsPage.url}}" stepKey="openReviewsPage"/> + <waitForPageLoad time="30" stepKey="waitForPageLoadCreatedReviewOne"/> + + <!--Step4. Add First and Second Review For Same Product--> + <actionGroup ref="AdminAddProductReviewActionGroup" stepKey="addFirstReview"> + <argument name="review" value="firstSimpleProductReview"/> + <argument name="sku" value="$$createProduct.sku$$"/> + </actionGroup> + <amOnPage url="{{AdminReviewsPage.url}}" stepKey="openReviewsPageAgain"/> + <waitForPageLoad time="30" stepKey="waitForPageLoadCreatedReviewTwo"/> + <actionGroup ref="AdminAddProductReviewActionGroup" stepKey="addSecondReview"> + <argument name="review" value="secondSimpleProductReview"/> + <argument name="sku" value="$$createProduct.sku$$"/> + </actionGroup> + <!--Step5. Navigate to Reports > Reviews > By Products --> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="navigateToReportsByProductsPage"> + <argument name="menuUiId" value="{{AdminMenuReports.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuReportsReviewsByProducts.dataUiId}}"/> + </actionGroup> + <!--Step6. Search product review by product name --> + <actionGroup ref="AdminFilterProductReviewByNameActionGroup" stepKey="navigateToReportsReview"> + <argument name="productName" value="$$createProduct.name$$"/> + </actionGroup> + <!--Step7. Click 'Show Reviews' to see review details--> + <grabTextFrom selector="{{AdminCreateNewReviewSection.gridLastReviewColumn}}" stepKey="grabLastReviewDate"/> + <click selector="{{AdminCreateNewReviewSection.showReviewsButton}}" stepKey="showReviewsPage"/> + <waitForPageLoad stepKey="waitForReviewListPageToLoad"/> + <!--Step8. Assert product last review date matches latest user review date--> + <fillField selector="{{AdminReviewGridSection.nickname}}" userInput="{{secondSimpleProductReview.nickname}}" stepKey="fillNickname"/> + <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickApplyFilters"/> + <waitForPageLoad stepKey="waitForGridViewPageToLoad"/> + <grabTextFrom selector="{{AdminCreateNewReviewSection.grabLatestUserReviewDate}}" stepKey="grabLatestUserReviewDate"/> + <assertEquals stepKey="assertReviewDate"> + <actualResult type="string">$grabLastReviewDate</actualResult> + <expectedResult type="string">$grabLatestUserReviewDate</expectedResult> + </assertEquals> + </test> +</tests> From 125b01a296c165afd53d8f13ceb35b0e13716702 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <engcom-vendorworker-foxtrot@adobe.com> Date: Fri, 18 Dec 2020 11:52:56 +0200 Subject: [PATCH 094/156] magento/magento2#31131: [MFTF] Refactoring of AddOutOfStockProductToCompareListTest. --- .../AddOutOfStockProductToCompareListTest.xml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml index 7f4228a21f3d5..995fa4c7e5977 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml @@ -20,6 +20,7 @@ <group value="Catalog"/> </annotations> <before> + <comment userInput="Adding the comment for preserving Backward Compatibility" stepKey="loginAsAdmin"/> <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/> <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> <argument name="tags" value=""/> @@ -35,8 +36,9 @@ <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> <argument name="tags" value=""/> </actionGroup> - <deleteData createDataKey="product" stepKey="deleteProduct"/> - <deleteData createDataKey="category" stepKey="deleteCategory"/> + <deleteData createDataKey="product" stepKey="deleteProduct"/> + <deleteData createDataKey="category" stepKey="deleteCategory"/> + <comment userInput="Adding the comment for preserving Backward Compatibility" stepKey="logout"/> </after> <comment userInput="Open product page | Comment is kept to preserve the step key for backward compatibility" stepKey="openProdPage"/> <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="goToSimpleProductPage"/> @@ -48,10 +50,10 @@ <comment userInput="'Add to compare' link is not available | Comment is kept to preserve the step key for backward compatibility" stepKey="addToCompareLinkAvailability"/> <dontSeeElement selector="{{StorefrontProductInfoMainSection.productAddToCompare}}" stepKey="dontSeeAddToCompareLink"/> - + <comment userInput="Turn on 'out of stock' config | Comment is kept to preserve the step key for backward compatibility" stepKey="onOutOfStockConfig"/> <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockEnable.path}} {{CatalogInventoryOptionsShowOutOfStockEnable.value}}" stepKey="setConfigShowOutOfStockTrue"/> - + <comment userInput="Clear cache and reindex | Comment is kept to preserve the step key for backward compatibility" stepKey="cleanCache"/> <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> <argument name="indices" value=""/> @@ -72,13 +74,13 @@ <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForProdAddToCmpList"/> <comment userInput="Assert success message | Comment is kept to preserve the step key for backward compatibility" stepKey="assertSuccessMsg"/> <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="grabTextFromSuccessMessage"/> - + <actionGroup ref="StorefrontAddProductToCompareActionGroup" stepKey="assertSuccessMessage"> <argument name="productVar" value="$$product$$"/> </actionGroup> <comment userInput="See product in the comparison list | Comment is kept to preserve the step key for backward compatibility" stepKey="seeProductInComparisonList"/> - + <actionGroup ref="StorefrontGoToCategoryPageActionGroup" stepKey="openCategoryPage"> <argument name="categoryName" value="$$category.name$$"/> </actionGroup> @@ -112,13 +114,13 @@ <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="grabTextFromSuccessMessage2"/> <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="assertSuccessMessage2"/> - <comment userInput="Check that product displays on add to compare widget | Comment is kept to preserve the step key for backward compatibility" stepKey="checkProdNameOnWidget"/> + <comment userInput="Check that product displays on add to compare widget | Comment is kept to preserve the step key for backward compatibility" stepKey="checkProdNameOnWidget"/> <seeElement selector="{{StorefrontComparisonSidebarSection.ProductTitleByName($$product.name$$)}}" stepKey="seeProdNameOnCmpWidget"/> <comment userInput="See product in the compare page" stepKey="seeProductInComparePage"/> <actionGroup ref="StorefrontOpenAndCheckComparisionActionGroup" stepKey="navigateToComparePage2"/> <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForStorefrontProductComparePageLoad2"/> - + <actionGroup ref="SeeProductInComparisonListActionGroup" stepKey="seeProductInCompareList2"> <argument name="productVar" value="$$product$$"/> </actionGroup> From 01eb68279d3f49adb66c14c351c5dd9576c39b6f Mon Sep 17 00:00:00 2001 From: Oleg Aleksin <olega@ven.com> Date: Fri, 18 Dec 2020 10:45:17 +0200 Subject: [PATCH 095/156] Fix issue with logging each cookie as separate context --- .../Magento/Framework/Stdlib/Cookie/PhpCookieManager.php | 5 ++++- .../Stdlib/Test/Unit/Cookie/PhpCookieManagerTest.php | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/Cookie/PhpCookieManager.php b/lib/internal/Magento/Framework/Stdlib/Cookie/PhpCookieManager.php index a5fe6f6c61506..64f04c62bbf64 100644 --- a/lib/internal/Magento/Framework/Stdlib/Cookie/PhpCookieManager.php +++ b/lib/internal/Magento/Framework/Stdlib/Cookie/PhpCookieManager.php @@ -212,7 +212,10 @@ private function checkAbilityToSendCookie($name, $value) if ($numCookies > static::MAX_NUM_COOKIES) { $this->logger->warning( new Phrase('Unable to send the cookie. Maximum number of cookies would be exceeded.'), - array_merge($_COOKIE, ['user-agent' => $this->httpHeader->getHttpUserAgent()]) + [ + 'cookies' => $_COOKIE, + 'user-agent' => $this->httpHeader->getHttpUserAgent() + ] ); } diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/Cookie/PhpCookieManagerTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/Cookie/PhpCookieManagerTest.php index e41cbdfe51638..87e10981c802c 100644 --- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/Cookie/PhpCookieManagerTest.php +++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/Cookie/PhpCookieManagerTest.php @@ -565,7 +565,10 @@ public function testSetTooManyCookies() ->method('warning') ->with( new Phrase('Unable to send the cookie. Maximum number of cookies would be exceeded.'), - array_merge($_COOKIE, ['user-agent' => $userAgent]) + [ + 'cookies' => $_COOKIE, + 'user-agent' => $userAgent + ] ); $this->cookieManager->setPublicCookie( From a391a9fe2833030f7a25730c289cc7f6746b41fe Mon Sep 17 00:00:00 2001 From: SmVladyslav <vlatame.tsg@gmail.com> Date: Fri, 18 Dec 2020 17:49:56 +0200 Subject: [PATCH 096/156] MC-35725: Price range of a Bundle Product is displayed incorrectly in the case of options with tier price --- .../Pricing/Price/BundleSelectionFactory.php | 5 +- .../Bundle/Pricing/Price/FinalPriceTest.php | 72 +++++++++++++++++ ...dle_product_with_tier_price_selections.php | 81 +++++++++++++++++++ ...ct_with_tier_price_selections_rollback.php | 33 ++++++++ .../three_simple_products_with_tier_price.php | 68 ++++++++++++++++ ...mple_products_with_tier_price_rollback.php | 31 +++++++ 6 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 dev/tests/integration/testsuite/Magento/Bundle/Pricing/Price/FinalPriceTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Bundle/_files/bundle_product_with_tier_price_selections.php create mode 100644 dev/tests/integration/testsuite/Magento/Bundle/_files/bundle_product_with_tier_price_selections_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/three_simple_products_with_tier_price.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/three_simple_products_with_tier_price_rollback.php diff --git a/app/code/Magento/Bundle/Pricing/Price/BundleSelectionFactory.php b/app/code/Magento/Bundle/Pricing/Price/BundleSelectionFactory.php index a28d721cc9a4e..52a024dc9fac3 100644 --- a/app/code/Magento/Bundle/Pricing/Price/BundleSelectionFactory.php +++ b/app/code/Magento/Bundle/Pricing/Price/BundleSelectionFactory.php @@ -52,9 +52,12 @@ public function create( $quantity, array $arguments = [] ) { + $quantity = $quantity ? (float)$quantity : 1.; + $selection->setQty($quantity); + $arguments['bundleProduct'] = $bundleProduct; $arguments['saleableItem'] = $selection; - $arguments['quantity'] = $quantity ? (float)$quantity : 1.; + $arguments['quantity'] = $quantity; return $this->objectManager->create(self::SELECTION_CLASS_DEFAULT, $arguments); } diff --git a/dev/tests/integration/testsuite/Magento/Bundle/Pricing/Price/FinalPriceTest.php b/dev/tests/integration/testsuite/Magento/Bundle/Pricing/Price/FinalPriceTest.php new file mode 100644 index 0000000000000..6b1ab58035568 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Bundle/Pricing/Price/FinalPriceTest.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Bundle\Pricing\Price; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * 'Final Price' model integration tests. + * + * @magentoDbIsolation disabled + */ +class FinalPriceTest extends TestCase +{ + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @inheritDoc + */ + protected function setUp(): void + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + } + + /** + * Check minimal and maximal prices are calculated correctly for Bundle product selections with Tier Prices. + * + * @return void + * @magentoDataFixture Magento/Bundle/_files/bundle_product_with_tier_price_selections.php + */ + public function testGetPriceForBundleSelectionsWithTierPrices(): void + { + $priceModel = $this->getPriceModel('bundle_with_tier_price_selections'); + $this->assertEquals(15.0, $priceModel->getMinimalPrice()->getValue()); + $this->assertEquals(45.0, $priceModel->getMaximalPrice()->getValue()); + } + + /** + * Create and retrieve Price Model for provided Product SKU. + * + * @param string $productSku + * @return FinalPrice + */ + private function getPriceModel(string $productSku): FinalPrice + { + $bundleProduct = $this->productRepository->get($productSku); + + return $this->objectManager->create( + FinalPrice::class, + [ + 'saleableItem' => $bundleProduct, + 'quantity' => 0., + ] + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/bundle_product_with_tier_price_selections.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/bundle_product_with_tier_price_selections.php new file mode 100644 index 0000000000000..5ef6daa5d11da --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/bundle_product_with_tier_price_selections.php @@ -0,0 +1,81 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Bundle\Model\Product\Price; +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\Type\AbstractType; +use Magento\Catalog\Model\Product\Visibility; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Bundle\Model\PrepareBundleLinks; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/three_simple_products_with_tier_price.php'); + +$objectManager = Bootstrap::getObjectManager(); +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +/** @var ProductInterfaceFactory $productFactory */ +$productFactory = $objectManager->get(ProductInterfaceFactory::class); +/** @var PrepareBundleLinks $prepareBundleLinks */ +$prepareBundleLinks = $objectManager->get(PrepareBundleLinks::class); +/** @var StoreManagerInterface $storeManager */ +$storeManager = $objectManager->get(StoreManagerInterface::class); +$defaultWebsiteId = $storeManager->getWebsite('base')->getId(); + +$bundleProduct = $productFactory->create(); +$bundleProduct->setTypeId(Type::TYPE_BUNDLE) + ->setAttributeSetId($bundleProduct->getDefaultAttributeSetId()) + ->setWebsiteIds([$defaultWebsiteId]) + ->setName('Bundle Product') + ->setSku('bundle_with_tier_price_selections') + ->setVisibility(Visibility::VISIBILITY_BOTH) + ->setStatus(Status::STATUS_ENABLED) + ->setStockData( + [ + 'use_config_manage_stock' => 1, + 'qty' => 100, + 'is_qty_decimal' => 0, + 'is_in_stock' => 1, + ] + ) + ->setSkuType(0) + ->setPriceView(0) + ->setPriceType(Price::PRICE_TYPE_DYNAMIC) + ->setPrice(null) + ->setWeightType(0) + ->setShipmentType(AbstractType::SHIPMENT_TOGETHER); + +$bundleOptionsData = [ + [ + 'title' => 'Option 1', + 'default_title' => 'Option 1', + 'type' => 'select', + 'required' => 1, + ], +]; +$bundleSelectionsData = [ + [ + [ + 'sku' => 'simple_1', + 'selection_qty' => 3, + ], + [ + 'sku' => 'simple_2', + 'selection_qty' => 3, + ], + [ + 'sku' => 'simple_3', + 'selection_qty' => 3, + ], + ] +]; +$bundleProduct = $prepareBundleLinks->execute($bundleProduct, $bundleOptionsData, $bundleSelectionsData); +$productRepository->save($bundleProduct); diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/bundle_product_with_tier_price_selections_rollback.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/bundle_product_with_tier_price_selections_rollback.php new file mode 100644 index 0000000000000..e8d0ed513e839 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/bundle_product_with_tier_price_selections_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\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Registry; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance() + ->requireDataFixture('Magento/Catalog/_files/three_simple_products_with_tier_price_rollback.php'); + +$objectManager = Bootstrap::getObjectManager(); +/** @var Registry $registry */ +$registry = $objectManager->get(Registry::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +try { + $product = $productRepository->get('bundle_with_tier_price_selections', false, null, true); + $productRepository->delete($product); +} catch (NoSuchEntityException $e) { + //Product already removed +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/three_simple_products_with_tier_price.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/three_simple_products_with_tier_price.php new file mode 100644 index 0000000000000..2b04935e46941 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/three_simple_products_with_tier_price.php @@ -0,0 +1,68 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory; +use Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory; +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\Customer\Model\Group; +use Magento\Store\Api\Data\WebsiteInterface; +use Magento\Store\Api\WebsiteRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); +/** @var ProductTierPriceInterfaceFactory $tierPriceFactory */ +$tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class); +/** @var ProductTierPriceExtensionFactory $tpExtensionAttributes */ +$tpExtensionAttributesFactory = $objectManager->get(ProductTierPriceExtensionFactory::class); + +/** @var WebsiteInterface $adminWebsite */ +$adminWebsite = $objectManager->get(WebsiteRepositoryInterface::class)->get('admin'); +$tierPriceExtensionAttributes = $tpExtensionAttributesFactory->create() + ->setWebsiteId($adminWebsite->getId()) + ->setPercentageValue(50); + +$tierPrice = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => Group::CUST_GROUP_ALL, + 'qty' => 2, + ], + ] +)->setExtensionAttributes($tierPriceExtensionAttributes); + +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +$productNumber = 1; +foreach ([10, 20, 30] as $price) { + /** @var $product Product */ + $product = $objectManager->create(Product::class); + $product->setTypeId(Type::TYPE_SIMPLE) + ->setAttributeSetId($product->getDefaultAttributeSetId()) + ->setWebsiteIds([1]) + ->setName('Simple Product ' . $productNumber) + ->setSku('simple_' . $productNumber) + ->setPrice($price) + ->setWeight(1) + ->setTierPrices([$tierPrice]) + ->setVisibility(Visibility::VISIBILITY_BOTH) + ->setStatus(Status::STATUS_ENABLED) + ->setStockData( + [ + 'use_config_manage_stock' => 1, + 'qty' => 100, + 'is_qty_decimal' => 0, + 'is_in_stock' => 1, + ] + ); + + $productRepository->save($product); + $productNumber++; +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/three_simple_products_with_tier_price_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/three_simple_products_with_tier_price_rollback.php new file mode 100644 index 0000000000000..9dbf7a38371b6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/three_simple_products_with_tier_price_rollback.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Registry; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); +/** @var Registry $registry */ +$registry = $objectManager->get(Registry::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +foreach (['simple_1', 'simple_2', 'simple_3'] as $sku) { + try { + $product = $productRepository->get($sku, false, null, true); + $productRepository->delete($product); + } catch (NoSuchEntityException $e) { + //Product already removed + } +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); From ed57b0ffdd696649a6b9d91d8f7dec5c615b6d8d Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Fri, 18 Dec 2020 10:51:14 -0600 Subject: [PATCH 097/156] MC-38810: Product Export CSV not parsed correctly in excel due to text area attributes content - fixed export - fixed import - added tests for export and import --- .../Model/Export/ProductTest.php | 58 ++++++++++++++++++ .../Model/Import/ProductTest.php | 61 +++++++++++++++++++ ...import_with_json_and_markup_attributes.csv | 3 + .../DependenciesShowFrameworkCommandTest.php | 4 +- .../expected/framework-dependencies.csv | 2 +- lib/internal/Magento/Framework/File/Csv.php | 7 ++- .../Framework/Filesystem/Driver/File.php | 7 ++- .../Filesystem/Driver/StatefulFile.php | 2 +- .../Framework/Filesystem/DriverInterface.php | 2 +- .../Framework/Filesystem/File/Read.php | 2 +- .../Filesystem/File/ReadInterface.php | 2 +- 11 files changed, 140 insertions(+), 10 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_json_and_markup_attributes.csv 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 dd36f90757398..4d844a7c6f229 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php @@ -108,6 +108,64 @@ public function testExport(): void $this->assertEquals(1, $occurrencesCount); } + /** + * Verify successful export of the product with custom attributes containing json and markup + * + * @magentoDataFixture Magento/Catalog/_files/product_text_attribute.php + * @magentoDataFixture Magento/Catalog/_files/second_product_simple.php + * @magentoDbIsolation enabled + * @dataProvider exportWithJsonAndMarkupTextAttributeDataProvider + * @param string $attributeData + * @param string $expectedResult + * @return void + */ + public function testExportWithJsonAndMarkupTextAttribute(string $attributeData, string $expectedResult): void + { + /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); + $product = $productRepository->get('simple2'); + + /** @var \Magento\Eav\Model\Config $eavConfig */ + $eavConfig = $objectManager->get(\Magento\Eav\Model\Config::class); + $eavConfig->clear(); + $attribute = $eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, 'text_attribute'); + $attribute->setDefaultValue($attributeData); + /** @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface $productAttributeRepository */ + $productAttributeRepository = $objectManager->get(\Magento\Catalog\Api\ProductAttributeRepositoryInterface::class); + $productAttributeRepository->save($attribute); + $product->setCustomAttribute('text_attribute', $attribute->getDefaultValue()); + $productRepository->save($product); + + $this->model->setWriter( + $this->objectManager->create( + \Magento\ImportExport\Model\Export\Adapter\Csv::class + ) + ); + $exportData = $this->model->export(); + $this->assertStringContainsString('Simple Product2', $exportData); + $this->assertStringContainsString($expectedResult, $exportData); + } + + /** + * @return array + */ + public function exportWithJsonAndMarkupTextAttributeDataProvider(): array + { + return [ + 'json' => [ + '{"type": "basic", "unit": "inch", "sign": "(\")", "size": "1.5\""}', + '"text_attribute={""type"": ""basic"", ""unit"": ""inch"", ""sign"": ""(\"")"", ""size"": ""1.5\""""}"' + ], + 'markup' => [ + '<div data-content>Element type is basic, measured in inches ' . + '(marked with sign (\")) with size 1.5\", mid-price range</div>', + '"text_attribute=<div data-content>Element type is basic, measured in inches ' . + '(marked with sign (\"")) with size 1.5\"", mid-price range</div>"' + ], + ]; + } + /** * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_data_special_chars.php * @magentoDbIsolation enabled diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 3ca6754c77767..82d75cdce29c7 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -2344,6 +2344,67 @@ public function testProductWithWrappedAdditionalAttributes() ); } + /** + * @magentoDataFixture Magento/Catalog/_files/product_text_attribute.php + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled + * @dataProvider importWithJsonAndMarkupTextAttributeDataProvider + * @param string $productSku + * @param string $expectedResult + * @return void + */ + public function testImportWithJsonAndMarkupTextAttribute(string $productSku, string $expectedResult): void + { + // added by _files/product_import_with_json_and_markup_attributes.csv + $this->importedProducts = [ + 'SkuProductWithJson', + 'SkuProductWithMarkup', + ]; + + $importParameters =[ + 'behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, + 'entity' => 'catalog_product', + \Magento\ImportExport\Model\Import::FIELDS_ENCLOSURE => 0 + ]; + $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class); + $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); + $source = $this->objectManager->create( + \Magento\ImportExport\Model\Import\Source\Csv::class, + [ + 'file' => __DIR__ . '/_files/products_to_import_with_json_and_markup_attributes.csv', + 'directory' => $directory + ] + ); + $this->_model->setParameters($importParameters); + $this->_model->setSource($source); + $errors = $this->_model->validateData(); + $this->assertTrue($errors->getErrorsCount() == 0); + $this->_model->importData(); + $productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Catalog\Api\ProductRepositoryInterface::class + ); + $product = $productRepository->get($productSku); + $this->assertEquals($expectedResult, $product->getData('text_attribute')); + } + + /** + * @return array + */ + public function importWithJsonAndMarkupTextAttributeDataProvider(): array + { + return [ + 'import of attribute with json' => [ + 'SkuProductWithJson', + '{"type": "basic", "unit": "inch", "sign": "(\")", "size": "1.5\""}' + ], + 'import of attribute with markup' => [ + 'SkuProductWithMarkup', + '<div data-content>Element type is basic, measured in inches ' . + '(marked with sign (\")) with size 1.5\", mid-price range</div>' + ], + ]; + } + /** * Import and check data from file. * diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_json_and_markup_attributes.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_json_and_markup_attributes.csv new file mode 100644 index 0000000000000..e8372c19c8ff2 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_json_and_markup_attributes.csv @@ -0,0 +1,3 @@ +sku,product_type,name,price,attribute_set_code,categories,additional_attributes +SkuProductWithJson,simple,"Product With Json Attribute",100,Default,"Default Category/Category 1","text_attribute={""type"": ""basic"", ""unit"": ""inch"", ""sign"": ""(\"")"", ""size"": ""1.5\""""}" +SkuProductWithMarkup,simple,"Product With Markup Attribute",100,Default,"Default Category/Category 1","text_attribute=<div data-content>Element type is basic, measured in inches (marked with sign (\"")) with size 1.5\"", mid-price range</div>" diff --git a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/DependenciesShowFrameworkCommandTest.php b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/DependenciesShowFrameworkCommandTest.php index d07ec84b6eddc..b1c7843dfad32 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/DependenciesShowFrameworkCommandTest.php +++ b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/DependenciesShowFrameworkCommandTest.php @@ -70,11 +70,11 @@ public function testExecute() ); $this->assertStringContainsString('"Dependencies for each module:",' . PHP_EOL, $fileContents); $this->assertStringContainsString( - '"Magento\A",1' . PHP_EOL . '" -- Magento\Framework",2' . PHP_EOL, + 'Magento\A,1' . PHP_EOL . '" -- Magento\Framework",2' . PHP_EOL, $fileContents ); $this->assertStringContainsString( - '"Magento\B",1' . PHP_EOL . '" -- Magento\Framework",2' . PHP_EOL, + 'Magento\B,1' . PHP_EOL . '" -- Magento\Framework",2' . PHP_EOL, $fileContents ); } diff --git a/dev/tests/integration/testsuite/Magento/Setup/Module/Dependency/_files/expected/framework-dependencies.csv b/dev/tests/integration/testsuite/Magento/Setup/Module/Dependency/_files/expected/framework-dependencies.csv index e1c5732b94dcb..9f358f3fa7a25 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Module/Dependency/_files/expected/framework-dependencies.csv +++ b/dev/tests/integration/testsuite/Magento/Setup/Module/Dependency/_files/expected/framework-dependencies.csv @@ -2,7 +2,7 @@ ,3 "Dependencies for each module:", -"Magento\FirstModule",3 +Magento\FirstModule,3 " -- Magento\LibFirst",1 " -- Magento\LibSecond",2 " -- Magento\Third",1 diff --git a/lib/internal/Magento/Framework/File/Csv.php b/lib/internal/Magento/Framework/File/Csv.php index 1b1decdb5327c..e33b38562bf57 100644 --- a/lib/internal/Magento/Framework/File/Csv.php +++ b/lib/internal/Magento/Framework/File/Csv.php @@ -30,6 +30,11 @@ class Csv */ protected $_enclosure = '"'; + /** + * @var string + */ + private $escape = "\0"; + /** * @var File */ @@ -96,7 +101,7 @@ public function getData($file) } $fh = fopen($file, 'r'); - while ($rowData = fgetcsv($fh, $this->_lineLength, $this->_delimiter, $this->_enclosure)) { + while ($rowData = fgetcsv($fh, $this->_lineLength, $this->_delimiter, $this->_enclosure, $this->escape)) { $data[] = $rowData; } fclose($fh); diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/File.php b/lib/internal/Magento/Framework/Filesystem/Driver/File.php index bc08f67228849..7b508942c107d 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/File.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/File.php @@ -647,7 +647,7 @@ public function fileRead($resource, $length) * @return array|bool|null * @throws FileSystemException */ - public function fileGetCsv($resource, $length = 0, $delimiter = ',', $enclosure = '"', $escape = '\\') + public function fileGetCsv($resource, $length = 0, $delimiter = ',', $enclosure = '"', $escape = "\0") { $result = @fgetcsv($resource, $length, $delimiter, $enclosure, $escape); if ($result === null) { @@ -801,7 +801,10 @@ public function filePutCsv($resource, array $data, $delimiter = ',', $enclosure } } - $result = @fputcsv($resource, $data, $delimiter, $enclosure); + // Escape symbol is needed to fix known issue in PHP broken fputcsv escaping functionality + // where backslash followed by double quote breaks file consistency + $escape = "\0"; + $result = @fputcsv($resource, $data, $delimiter, $enclosure, $escape); if (!$result) { throw new FileSystemException( new Phrase( diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/StatefulFile.php b/lib/internal/Magento/Framework/Filesystem/Driver/StatefulFile.php index beeb1e928262c..9f69a38527ab3 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/StatefulFile.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/StatefulFile.php @@ -642,7 +642,7 @@ public function fileRead($resource, $length) * @return array|bool|null * @throws FileSystemException */ - public function fileGetCsv($resource, $length = 0, $delimiter = ',', $enclosure = '"', $escape = '\\') + public function fileGetCsv($resource, $length = 0, $delimiter = ',', $enclosure = '"', $escape = "\0") { $result = @fgetcsv($resource, $length, $delimiter, $enclosure, $escape); if ($result === null) { diff --git a/lib/internal/Magento/Framework/Filesystem/DriverInterface.php b/lib/internal/Magento/Framework/Filesystem/DriverInterface.php index afea4d3bc7b07..706077522c675 100644 --- a/lib/internal/Magento/Framework/Filesystem/DriverInterface.php +++ b/lib/internal/Magento/Framework/Filesystem/DriverInterface.php @@ -276,7 +276,7 @@ public function fileRead($resource, $length); * @return array|bool|null * @throws FileSystemException */ - public function fileGetCsv($resource, $length = 0, $delimiter = ',', $enclosure = '"', $escape = '\\'); + public function fileGetCsv($resource, $length = 0, $delimiter = ',', $enclosure = '"', $escape = "\0"); /** * Returns position of read/write pointer diff --git a/lib/internal/Magento/Framework/Filesystem/File/Read.php b/lib/internal/Magento/Framework/Filesystem/File/Read.php index f48e50b7d693d..41e2cd255dd5d 100644 --- a/lib/internal/Magento/Framework/Filesystem/File/Read.php +++ b/lib/internal/Magento/Framework/Filesystem/File/Read.php @@ -124,7 +124,7 @@ public function readLine($length, $ending = null) * @param string $escape [optional] * @return array|bool|null */ - public function readCsv($length = 0, $delimiter = ',', $enclosure = '"', $escape = '\\') + public function readCsv($length = 0, $delimiter = ',', $enclosure = '"', $escape = "\0") { return $this->driver->fileGetCsv($this->resource, $length, $delimiter, $enclosure, $escape); } diff --git a/lib/internal/Magento/Framework/Filesystem/File/ReadInterface.php b/lib/internal/Magento/Framework/Filesystem/File/ReadInterface.php index e27086709d8b1..4277e2b5693e7 100644 --- a/lib/internal/Magento/Framework/Filesystem/File/ReadInterface.php +++ b/lib/internal/Magento/Framework/Filesystem/File/ReadInterface.php @@ -46,7 +46,7 @@ public function readLine($length, $ending = null); * @param string $escape [optional] * @return array|bool false on end of file */ - public function readCsv($length = 0, $delimiter = ',', $enclosure = '"', $escape = '\\'); + public function readCsv($length = 0, $delimiter = ',', $enclosure = '"', $escape = "\0"); /** * Returns the current position From 876c8052f96d6770254277ff4dd39bce5e935d50 Mon Sep 17 00:00:00 2001 From: mastiuhin-olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Fri, 18 Dec 2020 22:26:18 +0200 Subject: [PATCH 098/156] MC-24495: Cannot save order with "file"-type address attribute. --- .../Model/Address/AbstractAddress.php | 7 +-- .../Customer/Model/Metadata/Form/File.php | 20 +++++++- .../Unit/Model/Metadata/Form/FileTest.php | 16 +++--- .../Adminhtml/Order/AddressSave.php | 50 ++++++++++++++++++- .../Magento/Sales/Model/AdminOrder/Create.php | 43 +++++++++++++++- 5 files changed, 119 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/Customer/Model/Address/AbstractAddress.php b/app/code/Magento/Customer/Model/Address/AbstractAddress.php index 8421fc92f8c4a..d1364dc0aeba6 100644 --- a/app/code/Magento/Customer/Model/Address/AbstractAddress.php +++ b/app/code/Magento/Customer/Model/Address/AbstractAddress.php @@ -331,10 +331,11 @@ protected function _implodeArrayValues($value) return ''; } - $isScalar = false; + $isScalar = true; foreach ($value as $val) { - if (is_scalar($val)) { - $isScalar = true; + if (!is_scalar($val)) { + $isScalar = false; + break; } } if ($isScalar) { diff --git a/app/code/Magento/Customer/Model/Metadata/Form/File.php b/app/code/Magento/Customer/Model/Metadata/Form/File.php index 17cfc0325ef41..1add044c50c9e 100644 --- a/app/code/Magento/Customer/Model/Metadata/Form/File.php +++ b/app/code/Magento/Customer/Model/Metadata/Form/File.php @@ -100,6 +100,7 @@ public function __construct( FileProcessorFactory $fileProcessorFactory = null, IoFile $ioFile = null ) { + $value = $this->prepareFileValue($value); parent::__construct($localeDate, $logger, $attribute, $localeResolver, $value, $entityTypeCode, $isAjax); $this->urlEncoder = $urlEncoder; $this->_fileValidator = $fileValidator; @@ -302,11 +303,11 @@ public function validateValue($value) public function compactValue($value) { if ($this->getIsAjaxRequest()) { - return $this; + return ''; } // Remove outdated file (in the case of file uploader UI component) - if (empty($value) && !empty($this->_value)) { + if (!empty($this->_value) && !empty($value['delete'])) { $this->fileProcessor->removeUploadedFile($this->_value); return $value; } @@ -420,4 +421,19 @@ protected function getFileProcessor() { return $this->fileProcessor; } + + /** + * Prepare File value. + * + * @param array|string $value + * @return array|string + */ + private function prepareFileValue($value) + { + if (is_array($value) && isset($value['value'])) { + $value = $value['value']; + } + + return $value; + } } diff --git a/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/FileTest.php b/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/FileTest.php index 3c5016df230f9..b0e9805bb3d2a 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/FileTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/FileTest.php @@ -347,7 +347,7 @@ public function testCompactValueIsAjax() ] ); - $this->assertSame($model, $model->compactValue('aValue')); + $this->assertSame('', $model->compactValue('aValue')); } public function testCompactValueNoDelete() @@ -362,12 +362,12 @@ public function testCompactValueNoDelete() ] ); - $this->fileProcessorMock->expects($this->once()) + $this->fileProcessorMock->expects($this->any()) ->method('removeUploadedFile') ->with('value') ->willReturnSelf(); - $this->assertSame([], $model->compactValue([])); + $this->assertSame('value', $model->compactValue([])); } public function testCompactValueDelete() @@ -377,11 +377,11 @@ public function testCompactValueDelete() $mediaDirMock = $this->getMockForAbstractClass( \Magento\Framework\Filesystem\Directory\WriteInterface::class ); - $mediaDirMock->expects($this->once()) + $mediaDirMock->expects($this->any()) ->method('delete') ->with(self::ENTITY_TYPE . '/' . 'value'); - $this->fileSystemMock->expects($this->once()) + $this->fileSystemMock->expects($this->any()) ->method('getDirectoryWrite') ->with(DirectoryList::MEDIA) ->will($this->returnValue($mediaDirMock)); @@ -394,7 +394,7 @@ public function testCompactValueDelete() ] ); - $this->assertSame('', $model->compactValue(['delete' => true])); + $this->assertIsArray($model->compactValue(['delete' => true])); } public function testCompactValueTmpFile() @@ -589,12 +589,12 @@ public function testCompactValueRemoveUiComponentValue() ] ); - $this->fileProcessorMock->expects($this->once()) + $this->fileProcessorMock->expects($this->any()) ->method('removeUploadedFile') ->with($value) ->willReturnSelf(); - $this->assertEquals([], $model->compactValue([])); + $this->assertEquals($value, $model->compactValue([])); } public function testCompactValueNoAction() diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/AddressSave.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddressSave.php index 5633e16d7d3d0..03ff35d17775e 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/AddressSave.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddressSave.php @@ -27,6 +27,7 @@ use Magento\Framework\Exception\LocalizedException; use Magento\Framework\App\ObjectManager; use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Customer\Model\AttributeMetadataDataProvider; /** * Sales address save @@ -52,6 +53,11 @@ class AddressSave extends Order implements HttpPostActionInterface */ private $orderAddressRepository; + /** + * @var AttributeMetadataDataProvider + */ + private $attributeMetadataDataProvider; + /** * @param Context $context * @param Registry $coreRegistry @@ -82,7 +88,8 @@ public function __construct( OrderRepositoryInterface $orderRepository, LoggerInterface $logger, RegionFactory $regionFactory = null, - OrderAddressRepositoryInterface $orderAddressRepository = null + OrderAddressRepositoryInterface $orderAddressRepository = null, + AttributeMetadataDataProvider $attributeMetadataDataProvider = null ) { $this->regionFactory = $regionFactory ?: ObjectManager::getInstance()->get(RegionFactory::class); $this->orderAddressRepository = $orderAddressRepository ?: ObjectManager::getInstance() @@ -100,6 +107,8 @@ public function __construct( $orderRepository, $logger ); + $this->attributeMetadataDataProvider = $attributeMetadataDataProvider ?: ObjectManager::getInstance() + ->get(AttributeMetadataDataProvider::class); } /** @@ -115,6 +124,7 @@ public function execute() OrderAddressInterface::class )->load($addressId); $data = $this->getRequest()->getPostValue(); + $data = $this->truncateCustomFileAttributes($data); $data = $this->updateRegionData($data); $resultRedirect = $this->resultRedirectFactory->create(); if ($data && $address->getId()) { @@ -139,7 +149,7 @@ public function execute() return $resultRedirect->setPath('sales/*/'); } } - + /** * Update region data * @@ -155,4 +165,40 @@ private function updateRegionData($attributeValues) } return $attributeValues; } + + /** + * Truncates custom file attributes from a request. + * + * As custom file type attributes are not working workaround is introduced. + * + * @param array $data + * @return array + */ + private function truncateCustomFileAttributes(array $data): array + { + $foundedArrays = []; + + foreach ($data as $value) { + if (is_array($value)) { + $foundedArrays = $value; + } + } + + if (empty($foundedArrays)) { + return $data; + } + + $attributesList = $this->attributeMetadataDataProvider->loadAttributesCollection( + 'customer_address', + 'adminhtml_customer_address' + ); + $attributesList->addFieldToFilter('is_user_defined', 1); + $attributesList->addFieldToFilter('frontend_input', 'file'); + + foreach ($attributesList as $customFileAttribute) { + unset($data[$customFileAttribute->getAttributeCode()]); + } + + return $data; + } } diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php index 5d621f1632837..c8d3a506c2e67 100644 --- a/app/code/Magento/Sales/Model/AdminOrder/Create.php +++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php @@ -7,10 +7,12 @@ namespace Magento\Sales\Model\AdminOrder; use Magento\Customer\Api\AddressMetadataInterface; +use Magento\Customer\Api\Data\AttributeMetadataInterface; use Magento\Customer\Model\Metadata\Form as CustomerForm; use Magento\Framework\Api\ExtensibleDataObjectConverter; use Magento\Framework\App\ObjectManager; use Magento\Quote\Model\Quote\Address; +use Magento\Quote\Model\Quote\Address\CustomAttributeListInterface; use Magento\Quote\Model\Quote\Item; use Magento\Sales\Api\Data\OrderAddressInterface; use Magento\Sales\Model\Order; @@ -250,6 +252,11 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ */ private $storeManager; + /** + * @var CustomAttributeListInterface + */ + private $customAttributeList; + /** * @param \Magento\Framework\ObjectManagerInterface $objectManager * @param \Magento\Framework\Event\ManagerInterface $eventManager @@ -282,6 +289,7 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer * @param ExtensibleDataObjectConverter|null $dataObjectConverter * @param StoreManagerInterface $storeManager + * @param CustomAttributeListInterface|null $customAttributeList * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -315,7 +323,8 @@ public function __construct( array $data = [], \Magento\Framework\Serialize\Serializer\Json $serializer = null, ExtensibleDataObjectConverter $dataObjectConverter = null, - StoreManagerInterface $storeManager = null + StoreManagerInterface $storeManager = null, + CustomAttributeListInterface $customAttributeList = null ) { $this->_objectManager = $objectManager; $this->_eventManager = $eventManager; @@ -350,6 +359,8 @@ public function __construct( $this->dataObjectConverter = $dataObjectConverter ?: ObjectManager::getInstance() ->get(ExtensibleDataObjectConverter::class); $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class); + $this->customAttributeList = $customAttributeList ?: ObjectManager::getInstance() + ->get(CustomAttributeListInterface::class); } /** @@ -1530,7 +1541,8 @@ public function setBillingAddress($address) $billingAddress->setData('save_in_address_book', $saveInAddressBook); $quote = $this->getQuote(); - if (!$quote->isVirtual() && $this->getShippingAddress()->getSameAsBilling()) { + $shippingAddress = $this->getShippingAddress(); + if (!$quote->isVirtual() && $shippingAddress->getSameAsBilling()) { $address['save_in_address_book'] = 0; $this->setShippingAddress($address); } @@ -1543,9 +1555,36 @@ public function setBillingAddress($address) } $quote->setBillingAddress($billingAddress); + if ($shippingAddress->getSameAsBilling()) { + $this->synchronizeAddressesFileAttributes(); + } + return $this; } + /** + * Synchronizes addresses file attributes. + * + * @return void + */ + private function synchronizeAddressesFileAttributes(): void + { + $billingAddress = $this->getBillingAddress(); + $shippingAddress = $this->getShippingAddress(); + + /** @var AttributeMetadataInterface[] $customAttributes */ + $customAttributes = $this->customAttributeList->getAttributes(); + foreach ($customAttributes as $attribute) { + $attributeCode = $attribute->getAttributeCode(); + if ($attribute->getFrontendInput() === 'file' && + !empty($billingAddress->getData($attributeCode)) && + empty($shippingAddress->getData($attributeCode)) + ) { + $shippingAddress->setData($attributeCode, $billingAddress->getData($attributeCode)); + } + } + } + /** * Set shipping method * From 5d69b324e160493f50dfb66e04721be1a97abc62 Mon Sep 17 00:00:00 2001 From: Roman Flowers <flowers@adobe.com> Date: Fri, 18 Dec 2020 16:32:25 -0600 Subject: [PATCH 099/156] MC-39463: GraphQL caches urlResolver response and can return the old value after the url rewrite update --- .../testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php index e6ed14ae2685e..e3f8cadb5f94a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php @@ -98,7 +98,7 @@ public function testUrlRewriteCleansCacheOnChange(string $requestPath) $urlRewrite->setRequestPath('test' . $requestPath); $urlRewriteResourceModel->save($urlRewrite); $apiResponse = $this->graphQlQuery($query($requestPath)); - $this->assertNull($apiResponse['urlResolver']['relative_url']); + $this->assertNull($apiResponse); // rolling back changes $urlRewrite->setRequestPath($requestPath); @@ -197,7 +197,7 @@ public function testUrlRewriteCleansCacheForCustomRewrites() // delete custom rewrite and validate that API will not return cached response $urlRewriteResourceModel->delete($urlRewrite); $apiResponse = $this->graphQlQuery($query($customRequestPath)); - $this->assertNull($apiResponse['urlResolver']['relative_url']); + $this->assertNull($apiResponse); } /** From e24dcb909b78bda488e85ab7cbe78439207cc058 Mon Sep 17 00:00:00 2001 From: Arnob Saha <arnobsh@gmail.com> Date: Fri, 18 Dec 2020 22:11:45 -0600 Subject: [PATCH 100/156] MC-39477: Cart Price rule not working where condition has Category "IS NOT" - Testing operator and the test --- app/code/Magento/Rule/Model/Condition/AbstractCondition.php | 2 +- .../Test/Unit/Model/Condition/AbstractConditionTest.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php index 67fc3590ac501..d5d3b80755360 100644 --- a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php +++ b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php @@ -838,7 +838,7 @@ public function validateAttribute($validatedValue) } } } elseif (is_array($value)) { - if (!is_array($validatedValue)) { + if (!is_array($validatedValue) || empty($validatedValue)) { return false; } $result = array_intersect($value, $validatedValue); diff --git a/app/code/Magento/Rule/Test/Unit/Model/Condition/AbstractConditionTest.php b/app/code/Magento/Rule/Test/Unit/Model/Condition/AbstractConditionTest.php index 3c55eacaff559..91f1c4b942f75 100644 --- a/app/code/Magento/Rule/Test/Unit/Model/Condition/AbstractConditionTest.php +++ b/app/code/Magento/Rule/Test/Unit/Model/Condition/AbstractConditionTest.php @@ -91,6 +91,10 @@ public function validateAttributeDataProvider() [1, '>=', '1', true], [1, '>=', 0, false], [0, '<', [1], false], + + [[1], '!{}', [], false], + [[1], '!{}', [1], false], + [[1], '!{}', [0], false], ]; } @@ -176,6 +180,8 @@ public function validateAttributeArrayInputTypeDataProvider() [[3], '{}', [], false, 'grid'], [1, '{}', 1, false, 'grid'], [1, '!{}', [1, 2, 3], false, 'grid'], + [1, '!{}', [], false, 'grid'], + [[1], '!{}', [], false, 'grid'], [[1], '{}', null, false, 'grid'], [null, '{}', null, true, 'input'], [null, '!{}', null, false, 'input'], From 9bb960fdda8d541073a45b8009206836ec4f0f31 Mon Sep 17 00:00:00 2001 From: Roman Flowers <flowers@adobe.com> Date: Sat, 19 Dec 2020 08:57:07 -0600 Subject: [PATCH 101/156] MC-39463: GraphQL caches urlResolver response and can return the old value after the url rewrite update --- .../testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php index e3f8cadb5f94a..4a4b617d7c28e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php @@ -98,7 +98,7 @@ public function testUrlRewriteCleansCacheOnChange(string $requestPath) $urlRewrite->setRequestPath('test' . $requestPath); $urlRewriteResourceModel->save($urlRewrite); $apiResponse = $this->graphQlQuery($query($requestPath)); - $this->assertNull($apiResponse); + $this->assertNull($apiResponse['urlResolver']); // rolling back changes $urlRewrite->setRequestPath($requestPath); @@ -197,7 +197,7 @@ public function testUrlRewriteCleansCacheForCustomRewrites() // delete custom rewrite and validate that API will not return cached response $urlRewriteResourceModel->delete($urlRewrite); $apiResponse = $this->graphQlQuery($query($customRequestPath)); - $this->assertNull($apiResponse); + $this->assertNull($apiResponse['urlResolver']); } /** From d2745c59c545dff90a371528dab648b1df021dce Mon Sep 17 00:00:00 2001 From: Arnob Saha <arnobsh@gmail.com> Date: Sat, 19 Dec 2020 21:45:23 -0600 Subject: [PATCH 102/156] MC-39763: Ratings data not rendering on review detail page - Adding review id with rating --- app/code/Magento/Review/Block/View.php | 3 +- .../Review/view/frontend/templates/view.phtml | 24 ++- .../Magento/Review/Block/ViewTest.php | 143 ++++++++++++++++++ .../_files/product_review_with_rating.php | 86 +++++++++++ .../product_review_with_rating_rollback.php | 11 ++ 5 files changed, 259 insertions(+), 8 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Review/Block/ViewTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Review/_files/product_review_with_rating.php create mode 100644 dev/tests/integration/testsuite/Magento/Review/_files/product_review_with_rating_rollback.php diff --git a/app/code/Magento/Review/Block/View.php b/app/code/Magento/Review/Block/View.php index fcfa11faa169d..bbdd246835f9e 100644 --- a/app/code/Magento/Review/Block/View.php +++ b/app/code/Magento/Review/Block/View.php @@ -103,9 +103,10 @@ public function getBackUrl() */ public function getRating() { + $reviewId = $this->getReviewId() ?: $this->getReviewData()->getId(); if (!$this->getRatingCollection()) { $ratingCollection = $this->_voteFactory->create()->getResourceCollection()->setReviewFilter( - $this->getReviewId() + $reviewId )->setStoreFilter( $this->_storeManager->getStore()->getId() )->addRatingInfo( diff --git a/app/code/Magento/Review/view/frontend/templates/view.phtml b/app/code/Magento/Review/view/frontend/templates/view.phtml index b51353b7df685..3fd2fc85f8853 100644 --- a/app/code/Magento/Review/view/frontend/templates/view.phtml +++ b/app/code/Magento/Review/view/frontend/templates/view.phtml @@ -33,16 +33,26 @@ <caption class="table-caption"><?= $block->escapeHtml(__('Product Rating')) ?></caption> <?php foreach ($block->getRating() as $_rating): ?> <?php if ($_rating->getPercent()): ?> + <?php $rating = ceil($_rating->getPercent()) ?> <tr> - <td class="label"><?= $block->escapeHtml(__($_rating->getRatingCode())) ?></td> + <td class="label" width="10%"> + <?= $block->escapeHtml(__($_rating->getRatingCode())) ?> + </td> <td class="value"> - <div class="rating-box"> - <div class="rating"/> + <?php $ratingId = $_rating->getRatingId() ?> + <div class="rating-summary item" + id="rating-div-<?= $block->escapeHtml($ratingId) ?>"> + <div class="rating-result" title="<?= /* @noEscape */ $rating ?>%"> + <span> + <span><?= /* @noEscape */ $rating ?>%</span> + </span> + </div> + <?= /* @noEscape */ $secureRenderer->renderStyleAsTag( + "width:" . /* @noEscape */ $rating . "%", + 'div#rating-div-'.$_rating->getRatingId(). + '>div.rating-result>span:first-child' + ) ?> </div> - <?= /* @noEscape */ $secureRenderer->renderStyleAsTag( - "width:" . /* @noEscape */ ceil($_rating->getPercent()) . "%;", - 'div.rating-box div.rating' - ) ?> </td> </tr> <?php endif; ?> diff --git a/dev/tests/integration/testsuite/Magento/Review/Block/ViewTest.php b/dev/tests/integration/testsuite/Magento/Review/Block/ViewTest.php new file mode 100644 index 0000000000000..74bb31d7cb48d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Review/Block/ViewTest.php @@ -0,0 +1,143 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Review\Block; + +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\Customer\Model\Session; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Registry; +use Magento\Framework\View\LayoutInterface; +use Magento\Review\Model\ResourceModel\Review\Product\CollectionFactory; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\Xpath; +use PHPUnit\Framework\TestCase; + +/** + * Test for displaying product review block. + * + * @magentoAppArea frontend + * @magentoDbIsolation enabled + */ +class ViewTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Session */ + private $customerSession; + + /** @var CollectionFactory */ + private $collectionFactory; + + /** @var Registry */ + private $registry; + + /** @var View */ + private $block; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->customerSession = $this->objectManager->get(Session::class); + $this->collectionFactory = $this->objectManager->get(CollectionFactory::class); + $this->registry = $this->objectManager->get(Registry::class); + $this->block = $this->objectManager->get(LayoutInterface::class)->createBlock(View::class); + } + + /** + * @inheritdoc + */ + protected function tearDown(): void + { + $this->registry->unregister('current_review'); + $this->registry->unregister('current_product'); + $this->registry->unregister('product'); + $this->customerSession->setCustomerId(null); + + parent::tearDown(); + } + + /** + * Test product review block + * + * @magentoDataFixture Magento/Review/_files/product_review_with_rating.php + * + * @return void + * @throws NoSuchEntityException + */ + public function testProductReviewBlock(): void + { + $this->customerSession->setCustomerId(1); + $review = $this->collectionFactory->create()->addCustomerFilter(1)->getFirstItem(); + $this->registerReview($review); + $this->assertNotNull($review->getReviewId()); + + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + /** @var ProductInterface $product */ + $product = $productRepository->get('simple', false, null, true); + $this->registerProduct($product); + + $blockHtml = $this->block->setReviewId($review->getReviewId())->toHtml(); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf("//div[contains(@class, 'details')]/h3[contains(text(), '%s')]", $review->getName()), + $blockHtml + ), + 'Product name wasn\'t found.' + ); + $ratings = $this->block->getRating(); + $this->assertCount(2, $ratings); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//a[contains(@class, 'action back')]/span[contains(text(), '%s')]", + __('Back to Product Reviews') + ), + $blockHtml + ), + sprintf('%s button wasn\'t found.', __('Back to Product Reviews')) + ); + } + + /** + * Register the product + * + * @param ProductInterface $product + * @return void + */ + private function registerProduct(ProductInterface $product): void + { + $this->registry->unregister('current_product'); + $this->registry->unregister('product'); + $this->registry->register('current_product', $product); + $this->registry->register('product', $product); + } + + /** + * Register the current review + * + * @param Product $review + * @return void + */ + private function registerReview(Product $review): void + { + $this->registry->unregister('current_review'); + $this->registry->register('current_review', $review); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Review/_files/product_review_with_rating.php b/dev/tests/integration/testsuite/Magento/Review/_files/product_review_with_rating.php new file mode 100644 index 0000000000000..47a402ae44fc4 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Review/_files/product_review_with_rating.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Backend\App\Area\FrontNameResolver; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Customer\Model\CustomerRegistry; +use Magento\Framework\Registry; +use Magento\Review\Model\Rating; +use Magento\Review\Model\Rating\Option; +use Magento\Review\Model\ResourceModel\Review\Collection; +use Magento\Review\Model\Review; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Bootstrap::getInstance()->loadArea( + FrontNameResolver::AREA_CODE +); +Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer.php'); +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_simple.php'); + +$objectManager = Bootstrap::getObjectManager(); +/** @var CustomerRegistry $customerRegistry */ +$customerRegistry = $objectManager->create(CustomerRegistry::class); +$customer = $customerRegistry->retrieve(1); +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->create(ProductRepositoryInterface::class); +$product = $productRepository->get('simple'); +$storeId = $objectManager->get( + StoreManagerInterface::class +)->getStore()->getId(); + +$review = $objectManager->create( + Review::class, + ['data' => [ + 'customer_id' => $customer->getId(), + 'title' => 'Review Summary', + 'detail' => 'Review text', + 'nickname' => 'Nickname', + ]] +); + +$review + ->setEntityId($review->getEntityIdByCode(Review::ENTITY_PRODUCT_CODE)) + ->setEntityPkValue($product->getId()) + ->setStatusId(Review::STATUS_APPROVED) + ->setStoreId($storeId) + ->setStores([$storeId]) + ->save(); + +$objectManager->get(Registry::class)->register( + 'review_data', + $review +); + +/** @var Collection $ratingCollection */ +$ratingCollection = $objectManager->create( + Rating::class +)->getCollection() + ->setPageSize(2) + ->setCurPage(1); + +foreach ($ratingCollection as $rating) { + $rating->setStores([$storeId])->setIsActive(1)->save(); +} + +foreach ($ratingCollection as $rating) { + $ratingOption = $objectManager + ->create(Option::class) + ->getCollection() + ->setPageSize(1) + ->setCurPage(2) + ->addRatingFilter($rating->getId()) + ->getFirstItem(); + $rating->setReviewId($review->getId()) + ->addOptionVote($ratingOption->getId(), $product->getId()); +} + +$objectManager->get(Registry::class)->register( + 'rating_data', + $ratingCollection->getFirstItem() +); diff --git a/dev/tests/integration/testsuite/Magento/Review/_files/product_review_with_rating_rollback.php b/dev/tests/integration/testsuite/Magento/Review/_files/product_review_with_rating_rollback.php new file mode 100644 index 0000000000000..0931d881a6fdc --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Review/_files/product_review_with_rating_rollback.php @@ -0,0 +1,11 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer_rollback.php'); +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_simple_rollback.php'); From 2a712558d59eac9d4474c3e62142976b5c53dab1 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Mon, 21 Dec 2020 12:02:19 +0200 Subject: [PATCH 103/156] refactored AdminSortProductsGridByActionGroup --- ...ngeWebSiteAssignedToProductActionGroup.xml | 21 ++++++++++ .../AdminSortProductsGridByActionGroup.xml | 22 +++++++++++ .../Mftf/Test/AdminSortingByWebsitesTest.xml | 39 +++++++++---------- 3 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminChangeWebSiteAssignedToProductActionGroup.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSortProductsGridByActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminChangeWebSiteAssignedToProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminChangeWebSiteAssignedToProductActionGroup.xml new file mode 100644 index 0000000000000..76a0af8f63fd5 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminChangeWebSiteAssignedToProductActionGroup.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"> + <actionGroup name="AdminChangeWebSiteAssignedToProductActionGroup" extends="AddWebsiteToProductActionGroup"> + <annotations> + <description>Extends AddWebsiteToProductActionGroup. Changes website assigned to product from websiteToDeselect to website</description> + </annotations> + <arguments> + <argument name="websiteToDeselect" type="string"/> + </arguments> + + <uncheckOption selector="{{ProductInWebsitesSection.website(websiteToDeselect)}}" stepKey="uncheckWebsite" after="checkWebsite"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSortProductsGridByActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSortProductsGridByActionGroup.xml new file mode 100644 index 0000000000000..92c714c2478b0 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSortProductsGridByActionGroup.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="AdminSortProductsGridByActionGroup"> + <annotations> + <description>Sorts the Product Grid by field</description> + </annotations> + <arguments> + <argument name="field" type="string"/> + </arguments> + + <click selector="{{AdminProductGridSection.columnHeader(field)}}" stepKey="clickWebsitesHeaderToSort"/> + <waitForLoadingMaskToDisappear stepKey="waitForApplyingChanges"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSortingByWebsitesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSortingByWebsitesTest.xml index 73aeed3af4fb0..76843b3a40fcb 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSortingByWebsitesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSortingByWebsitesTest.xml @@ -25,7 +25,7 @@ </createData> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - <!--Create new website --> + <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createAdditionalWebsite"> <argument name="newWebsiteName" value="{{customWebsite.name}}"/> <argument name="websiteCode" value="{{customWebsite.code}}"/> @@ -54,31 +54,30 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> - <!--Assign Custom Website to Simple Product --> - <actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="navigateToCatalogProductGrid"/> - - <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> + <actionGroup ref="AdminClearFiltersActionGroup" stepKey="navigateToCatalogProductGrid"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickClearFiltersInitial"/> <actionGroup ref="OpenEditProductOnBackendActionGroup" stepKey="assignCustomWebsiteToProduct"> <argument name="product" value="$$productAssignedToCustomWebsite$$"/> </actionGroup> - <scrollTo selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="scrollToWebsites"/> - <conditionalClick selector="{{ProductInWebsitesSection.sectionHeader}}" dependentSelector="{{AdminProductContentSection.sectionHeaderShow}}" visible="false" stepKey="expandSection"/> - <waitForPageLoad stepKey="waitForPageOpened"/> - <uncheckOption selector="{{ProductInWebsitesSection.website(_defaultWebsite.name)}}" stepKey="deselectMainWebsite"/> - <checkOption selector="{{ProductInWebsitesSection.website(customWebsite.name)}}" stepKey="selectWebsite"/> - - <actionGroup ref="AdminProductFormSaveActionGroup" stepKey="clickSave"/> - <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="seeSaveProductMessageAgain"/> + <actionGroup ref="AdminChangeWebSiteAssignedToProductActionGroup" stepKey="scrollToWebsites"> + <argument name="website" value="{{customWebsite.name}}"/> + <argument name="websiteToDeselect" value="{{_defaultWebsite.name}}"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="expandSection"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForPageOpened"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="deselectMainWebsite"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="selectWebsite"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="clickSave"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="seeSaveProductMessageAgain"/> - <!--Navigate To Product Grid To Check Website Sorting--> <actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="navigateToCatalogProductGridToSortByWebsite"/> - - <!--Sorting works (By Websites) ASC--> - <click selector="{{AdminProductGridSection.columnHeader('Websites')}}" stepKey="clickWebsitesHeaderToSortAsc"/> + <actionGroup ref="AdminSortProductsGridByActionGroup" stepKey="clickWebsitesHeaderToSortAsc"> + <argument name="field" value="Websites"/> + </actionGroup> <see selector="{{AdminProductGridSection.productGridContentsOnRow('1')}}" userInput="Main Website" stepKey="checkIfProduct1WebsitesAsc"/> - - <!--Sorting works (By Websites) DESC--> - <click selector="{{AdminProductGridSection.columnHeader('Websites')}}" stepKey="clickWebsitesHeaderToSortDesc"/> + <actionGroup ref="AdminSortProductsGridByActionGroup" stepKey="clickWebsitesHeaderToSortDesc"> + <argument name="field" value="Websites"/> + </actionGroup> <see selector="{{AdminProductGridSection.productGridContentsOnRow('1')}}" userInput="{{customWebsite.name}}" stepKey="checkIfProduct1WebsitesDesc"/> </test> </tests> From 38fc6c6e907f1bc574e8d8365195b8a04ab3d1b8 Mon Sep 17 00:00:00 2001 From: Serhii Balko <serhii.balko@transogtgroup.com> Date: Mon, 21 Dec 2020 12:21:08 +0200 Subject: [PATCH 104/156] MC-39864: [Magento Cloud] - Tax Miscalculation --- .../Model/Order/Creditmemo/Total/Tax.php | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php index 0d1382a48e065..eba84dcfb6364 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php @@ -182,9 +182,10 @@ private function calculateAllowedTax(Creditmemo $creditMemo): float { $invoice = $creditMemo->getInvoice(); $order = $creditMemo->getOrder(); - $amount = $invoice !== null ? $invoice->getTaxAmount() : $order->getTaxInvoiced(); + $amount = $invoice !== null ? $invoice->getTaxAmount() + : $order->getTaxInvoiced() - $order->getTaxRefunded(); - return (float) $amount - $order->getTaxRefunded() - $creditMemo->getTaxAmount(); + return (float) $amount - $creditMemo->getTaxAmount(); } /** @@ -197,9 +198,10 @@ private function calculateAllowedBaseTax(Creditmemo $creditMemo): float { $invoice = $creditMemo->getInvoice(); $order = $creditMemo->getOrder(); - $amount = $invoice !== null ? $invoice->getBaseTaxAmount() : $order->getBaseTaxInvoiced(); + $amount = $invoice !== null ? $invoice->getBaseTaxAmount() + : $order->getBaseTaxInvoiced() - $order->getBaseTaxRefunded(); - return (float) $amount - $order->getBaseTaxRefunded() - $creditMemo->getBaseTaxAmount(); + return (float) $amount - $creditMemo->getBaseTaxAmount(); } /** @@ -218,12 +220,12 @@ private function calculateAllowedDiscountTaxCompensation(Creditmemo $creditMemo) + $invoice->getShippingDiscountTaxCompensationAmount(); } else { $amount = $order->getDiscountTaxCompensationInvoiced() - + $order->getShippingDiscountTaxCompensationAmount(); + + $order->getShippingDiscountTaxCompensationAmount() + - $order->getDiscountTaxCompensationRefunded() + - $order->getShippingDiscountTaxCompensationRefunded(); } return (float) $amount - - $order->getDiscountTaxCompensationRefunded() - - $order->getShippingDiscountTaxCompensationRefunded() - $creditMemo->getDiscountTaxCompensationAmount() - $creditMemo->getShippingDiscountTaxCompensationAmount(); } @@ -244,12 +246,12 @@ private function calculateAllowedBaseDiscountTaxCompensation(Creditmemo $creditM + $invoice->getBaseShippingDiscountTaxCompensationAmnt(); } else { $amount = $order->getBaseDiscountTaxCompensationInvoiced() - + $order->getBaseShippingDiscountTaxCompensationAmnt(); + + $order->getBaseShippingDiscountTaxCompensationAmnt() + - $order->getBaseDiscountTaxCompensationRefunded() + - $order->getBaseShippingDiscountTaxCompensationRefunded(); } return (float) $amount - - $order->getBaseDiscountTaxCompensationRefunded() - - $order->getBaseShippingDiscountTaxCompensationRefunded() - $creditMemo->getBaseShippingDiscountTaxCompensationAmnt() - $creditMemo->getBaseDiscountTaxCompensationAmount(); } From e45a9447c469ca49489aa6314301140132571c43 Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Mon, 21 Dec 2020 12:25:56 +0200 Subject: [PATCH 105/156] MC-39718: Process Manager always exits successfully if the amount of functions(i.e. indexer dimensions) is lower than the MAGE_INDEXER_THREADS_COUNT env variable --- .../Magento/Indexer/Model/ProcessManager.php | 5 +- .../Test/Unit/Model/ProcessManagerTest.php | 183 ++++++++++++++++++ 2 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Indexer/Test/Unit/Model/ProcessManagerTest.php diff --git a/app/code/Magento/Indexer/Model/ProcessManager.php b/app/code/Magento/Indexer/Model/ProcessManager.php index 2b25c8c6a3d15..b6fd158364dea 100644 --- a/app/code/Magento/Indexer/Model/ProcessManager.php +++ b/app/code/Magento/Indexer/Model/ProcessManager.php @@ -111,9 +111,12 @@ private function multiThreadsExecute($userFunctions) $this->startChildProcess($userFunction); } } - // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock,Magento2.Functions.DiscouragedFunction + // phpcs:ignore Magento2.Functions.DiscouragedFunction while (pcntl_waitpid(0, $status) != -1) { //Waiting for the completion of child processes + if ($status > 0) { + $this->failInChildProcess = true; + } } if ($this->failInChildProcess) { diff --git a/app/code/Magento/Indexer/Test/Unit/Model/ProcessManagerTest.php b/app/code/Magento/Indexer/Test/Unit/Model/ProcessManagerTest.php new file mode 100644 index 0000000000000..9e9d2a5c81aba --- /dev/null +++ b/app/code/Magento/Indexer/Test/Unit/Model/ProcessManagerTest.php @@ -0,0 +1,183 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Indexer\Test\Unit\Model; + +use Magento\Framework\App\ResourceConnection; +use Magento\Indexer\Model\ProcessManager; +use PHPUnit\Framework\TestCase; + +/** + * Class covers process manager execution test logic + */ +class ProcessManagerTest extends TestCase +{ + /** + * @dataProvider functionsWithErrorProvider + * @param array $userFunctions + * @param int $threadsCount + * @return void + */ + public function testFailureInChildProcessHandleMultiThread(array $userFunctions, int $threadsCount): void + { + $connectionMock = $this->createMock(ResourceConnection::class); + $processManager = new ProcessManager( + $connectionMock, + null, + $threadsCount + ); + + try { + $processManager->execute($userFunctions); + $this->fail('Exception was not handled'); + } catch (\RuntimeException $exception) { + $this->assertEquals('Fail in child process', $exception->getMessage()); + } + } + + /** + * Closure functions data provider for multi thread execution + * + * @return array + * @SuppressWarnings(PHPMD.ExitExpression) + */ + public function functionsWithErrorProvider(): array + { + return [ + 'more_threads_than_functions' => [ + 'user_functions' => [ + // @codingStandardsIgnoreStart + function () { + exit(1); + }, + function () { + exit(0); + }, + function () { + exit(0); + }, + // @codingStandardsIgnoreEnd + ], + 'threads_count' => 4, + ], + 'less_threads_than_functions' => [ + 'user_functions' => [ + // @codingStandardsIgnoreStart + function () { + exit(1); + }, + function () { + exit(0); + }, + function () { + exit(0); + }, + // @codingStandardsIgnoreEnd + ], + 'threads_count' => 2, + ], + 'equal_threads_and_functions' => [ + 'user_functions' => [ + // @codingStandardsIgnoreStart + function () { + exit(1); + }, + function () { + exit(0); + }, + function () { + exit(0); + }, + // @codingStandardsIgnoreEnd + ], + 'threads_count' => 3, + ], + ]; + } + + /** + * @dataProvider successFunctionsProvider + * @param array $userFunctions + * @param int $threadsCount + * @return void + */ + public function testSuccessChildProcessHandleMultiThread(array $userFunctions, int $threadsCount): void + { + $connectionMock = $this->createMock(ResourceConnection::class); + $processManager = new ProcessManager( + $connectionMock, + null, + $threadsCount + ); + + try { + $processManager->execute($userFunctions); + } catch (\RuntimeException $exception) { + $this->fail('Exception was not handled'); + } + } + + /** + * Closure functions data provider for multi thread execution + * + * @return array + * @SuppressWarnings(PHPMD.ExitExpression) + */ + public function successFunctionsProvider(): array + { + return [ + 'more_threads_than_functions' => [ + 'user_functions' => [ + // @codingStandardsIgnoreStart + function () { + exit(0); + }, + function () { + exit(0); + }, + function () { + exit(0); + }, + // @codingStandardsIgnoreEnd + ], + 'threads_count' => 4, + ], + 'less_threads_than_functions' => [ + 'user_functions' => [ + // @codingStandardsIgnoreStart + function () { + exit(0); + }, + function () { + exit(0); + }, + function () { + exit(0); + }, + // @codingStandardsIgnoreEnd + ], + 'threads_count' => 2, + ], + 'equal_threads_and_functions' => [ + 'user_functions' => [ + // @codingStandardsIgnoreStart + function () { + exit(0); + }, + function () { + exit(0); + }, + function () { + exit(0); + }, + // @codingStandardsIgnoreEnd + ], + 'threads_count' => 3, + ], + ]; + } +} From d12f17198aec95cce37442933fc24264e6f540e8 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Mon, 21 Dec 2020 14:19:11 +0200 Subject: [PATCH 106/156] MC-39037: Report tabs are not aligned and not able to view properly --- .../view/adminhtml/templates/widget/grid/extended.phtml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml index d4aa14250837f..4bdee469e2fa4 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml @@ -14,12 +14,13 @@ * getPagerVisibility() * getVarNamePage() */ -$numColumns = count($block->getColumns()); /** * @var \Magento\Backend\Block\Widget\Grid\Extended $block * @var \Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer */ +$numColumns = count($block->getColumns()); + ?> <?php if ($block->getCollection()): ?> <?php if ($block->canDisplayContainer()): ?> @@ -285,7 +286,9 @@ $numColumns = count($block->getColumns()); </table> </div> + <?php if ($block->canDisplayContainer()): ?> </div> + <?php endif; ?> <?php /** @var \Magento\Framework\Json\Helper\Data $jsonHelper */ $jsonHelper = $block->getData('jsonHelper'); From a2764054a2e661d5c052610d6945d9963ca63d5e Mon Sep 17 00:00:00 2001 From: mastiuhin-olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Mon, 21 Dec 2020 18:10:46 +0200 Subject: [PATCH 107/156] MC-24495: Cannot save order with "file"-type address attribute. --- .../Sales/Controller/Adminhtml/Order/AddressSave.php | 6 +++--- app/code/Magento/Sales/Model/AdminOrder/Create.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/AddressSave.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddressSave.php index 03ff35d17775e..879baa948e919 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/AddressSave.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddressSave.php @@ -176,15 +176,15 @@ private function updateRegionData($attributeValues) */ private function truncateCustomFileAttributes(array $data): array { - $foundedArrays = []; + $foundArrays = []; foreach ($data as $value) { if (is_array($value)) { - $foundedArrays = $value; + $foundArrays = $value; } } - if (empty($foundedArrays)) { + if (empty($foundArrays)) { return $data; } diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php index c8d3a506c2e67..6bd6e8e4e83e1 100644 --- a/app/code/Magento/Sales/Model/AdminOrder/Create.php +++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php @@ -1576,9 +1576,9 @@ private function synchronizeAddressesFileAttributes(): void $customAttributes = $this->customAttributeList->getAttributes(); foreach ($customAttributes as $attribute) { $attributeCode = $attribute->getAttributeCode(); - if ($attribute->getFrontendInput() === 'file' && - !empty($billingAddress->getData($attributeCode)) && - empty($shippingAddress->getData($attributeCode)) + if ($attribute->getFrontendInput() === 'file' + && !empty($billingAddress->getData($attributeCode)) + && empty($shippingAddress->getData($attributeCode)) ) { $shippingAddress->setData($attributeCode, $billingAddress->getData($attributeCode)); } From 7b2440af23763655f6a9cd88fef8dde56f61d8a6 Mon Sep 17 00:00:00 2001 From: Arnob Saha <arnobsh@gmail.com> Date: Tue, 22 Dec 2020 05:13:34 -0600 Subject: [PATCH 108/156] MC-39617: Category Selector limit category upto 5 from the root - Adding JS code to process the tree --- .../templates/catalog/category/widget/tree.phtml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/widget/tree.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/widget/tree.phtml index 6c92ddcf36243..cf64c57c720b7 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/widget/tree.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/widget/tree.phtml @@ -77,6 +77,16 @@ $scriptString .= <<<script dataUrl: '{$block->escapeJs($block->escapeUrl($block->getLoadTreeUrl()))}' }); + categoryLoader.processResponse = function (response, parent, callback) { + var config = JSON.parse(response.responseText); + + this.buildCategoryTree(parent, config); + + if (typeof callback == "function") { + callback(this, parent); + } + }; + categoryLoader.buildCategoryTree = function(parent, config) { if (!config) return null; @@ -164,8 +174,10 @@ $scriptString .= <<<script }; categoryLoader.on("beforeload", function(treeLoader, node) { - $('{$block->escapeJs($_divId)}').fire('category:beforeLoad', {treeLoader:treeLoader}); treeLoader.baseParams.id = node.attributes.id; + treeLoader.baseParams.store = node.attributes.store; + treeLoader.baseParams.form_key = FORM_KEY; + $('{$block->escapeJs($_divId)}').fire('category:beforeLoad', {treeLoader:treeLoader}); }); tree{$block->escapeJs($block->getId())} = new Ext.tree.TreePanel.Enhanced('{$block->escapeJs($_divId)}', { From 6404f8d4b128967cf6913c0c00ec64875fcb23c1 Mon Sep 17 00:00:00 2001 From: Serhii Balko <serhii.balko@transogtgroup.com> Date: Tue, 22 Dec 2020 13:27:37 +0200 Subject: [PATCH 109/156] MC-40012: [On-Premise] Failure to allocate memory error when exporting customer addresses in admin --- .../Model/Export/Address.php | 109 +++++++++++++----- .../Test/Unit/Model/Export/AddressTest.php | 89 +++++--------- 2 files changed, 109 insertions(+), 89 deletions(-) diff --git a/app/code/Magento/CustomerImportExport/Model/Export/Address.php b/app/code/Magento/CustomerImportExport/Model/Export/Address.php index 03ce884a44d20..a2d38767432d9 100644 --- a/app/code/Magento/CustomerImportExport/Model/Export/Address.php +++ b/app/code/Magento/CustomerImportExport/Model/Export/Address.php @@ -5,6 +5,17 @@ */ namespace Magento\CustomerImportExport\Model\Export; +use Magento\Customer\Model\ResourceModel\Address\Collection; +use Magento\Customer\Model\ResourceModel\Address\CollectionFactory; +use Magento\Eav\Model\Config; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\DB\Select; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\ImportExport\Model\Export\Entity\AbstractEav; +use Magento\ImportExport\Model\Export\Factory; +use Magento\ImportExport\Model\ResourceModel\CollectionByPagesIteratorFactory; +use Magento\Store\Model\StoreManagerInterface; + /** * Customer address export * @@ -13,7 +24,7 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 100.0.2 */ -class Address extends \Magento\ImportExport\Model\Export\Entity\AbstractEav +class Address extends AbstractEav { /**#@+ * Permanent column names @@ -93,7 +104,7 @@ class Address extends \Magento\ImportExport\Model\Export\Entity\AbstractEav /** * Customer addresses collection * - * @var \Magento\Customer\Model\ResourceModel\Address\Collection + * @var Collection */ protected $_addressCollection; @@ -118,31 +129,31 @@ class Address extends \Magento\ImportExport\Model\Export\Entity\AbstractEav * * @var array */ - protected $_customers = []; + protected $_customers; /** - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\ImportExport\Model\Export\Factory $collectionFactory - * @param \Magento\ImportExport\Model\ResourceModel\CollectionByPagesIteratorFactory $resourceColFactory - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Eav\Model\Config $eavConfig + * @param ScopeConfigInterface $scopeConfig + * @param StoreManagerInterface $storeManager + * @param Factory $collectionFactory + * @param CollectionByPagesIteratorFactory $resourceColFactory + * @param TimezoneInterface $localeDate + * @param Config $eavConfig * @param \Magento\Customer\Model\ResourceModel\Customer\CollectionFactory $customerColFactory - * @param \Magento\CustomerImportExport\Model\Export\CustomerFactory $eavCustomerFactory - * @param \Magento\Customer\Model\ResourceModel\Address\CollectionFactory $addressColFactory + * @param CustomerFactory $eavCustomerFactory + * @param CollectionFactory $addressColFactory * @param array $data * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( - \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, - \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\ImportExport\Model\Export\Factory $collectionFactory, - \Magento\ImportExport\Model\ResourceModel\CollectionByPagesIteratorFactory $resourceColFactory, - \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, - \Magento\Eav\Model\Config $eavConfig, + ScopeConfigInterface $scopeConfig, + StoreManagerInterface $storeManager, + Factory $collectionFactory, + CollectionByPagesIteratorFactory $resourceColFactory, + TimezoneInterface $localeDate, + Config $eavConfig, \Magento\Customer\Model\ResourceModel\Customer\CollectionFactory $customerColFactory, - \Magento\CustomerImportExport\Model\Export\CustomerFactory $eavCustomerFactory, - \Magento\Customer\Model\ResourceModel\Address\CollectionFactory $addressColFactory, + CustomerFactory $eavCustomerFactory, + CollectionFactory $addressColFactory, array $data = [] ) { parent::__construct( @@ -178,19 +189,20 @@ public function __construct( */ protected function _initCustomers() { - if (empty($this->_customers)) { + if ($this->_customers === null) { + $this->_customers = []; // add customer default addresses column name to customer attribute mapping array $this->_customerCollection->addAttributeToSelect(self::$_defaultAddressAttributeMapping); // filter customer collection $this->_customerCollection = $this->_customerEntity->filterEntityCollection($this->_customerCollection); - $customers = []; - $addCustomer = function (\Magento\Customer\Model\Customer $customer) use (&$customers) { - $customers[$customer->getId()] = $customer->getData(); - }; + $selectIds = $this->_customerCollection->getAllIdsSql(); + $this->_customerCollection->setPageSize($this->_pageSize); + $pageCount = $this->_customerCollection->getLastPageNumber(); - $this->_byPagesIterator->iterate($this->_customerCollection, $this->_pageSize, [$addCustomer]); - $this->_customers = $customers; + for ($pageNum = 1; $pageNum <= $pageCount; $pageNum++) { + $this->_customers += $this->loadCustomerData($selectIds, $pageNum); + } } return $this; @@ -211,7 +223,7 @@ protected function _getHeaderColumns() /** * Get customers collection * - * @return \Magento\Customer\Model\ResourceModel\Address\Collection + * @return Collection */ protected function _getEntityCollection() { @@ -227,7 +239,7 @@ public function export() { // skip and filter by customer address attributes $this->_prepareEntityCollection($this->_getEntityCollection()); - $this->_getEntityCollection()->setCustomerFilter(array_keys($this->_customers)); + $this->_getEntityCollection()->setCustomerFilter(array_keys($this->getCustomers())); // prepare headers $this->getWriter()->setHeaderCols($this->_getHeaderColumns()); @@ -248,7 +260,7 @@ public function exportItem($item) $row = $this->_addAttributeValuesToRow($item); /** @var $customer \Magento\Customer\Model\Customer */ - $customer = $this->_customers[$item->getParentId()]; + $customer = $this->getCustomers()[$item->getParentId()]; // Fill row with default address attributes values foreach (self::$_defaultAddressAttributeMapping as $columnName => $attributeCode) { @@ -274,10 +286,8 @@ public function exportItem($item) */ public function setParameters(array $parameters) { - // push filters from post into export customer model + // push filters from post into export customer model $this->_customerEntity->setParameters($parameters); - $this->_initCustomers(); - return parent::setParameters($parameters); } @@ -290,4 +300,39 @@ public function getEntityTypeCode() { return $this->getAttributeCollection()->getEntityTypeCode(); } + + /** + * Get Customers Data + * + * @return array + */ + private function getCustomers(): array + { + $this->_initCustomers(); + return $this->_customers; + } + + /** + * Load Customers Data + * + * @param Select $selectIds + * @param int $pageNum + * @return array + */ + private function loadCustomerData(Select $selectIds, int $pageNum = 0): array + { + $select = $this->_customerCollection->getConnection()->select(); + $select->from( + ['customer' => $this->_customerCollection->getTable('customer_entity')], + ['entity_id', 'email', 'store_id', 'website_id', 'default_billing', 'default_shipping'] + )->where( + 'customer.entity_id IN (?)', $selectIds + ); + + if ($pageNum > 0) { + $select->limitPage($pageNum, $this->_pageSize); + } + + return $this->_customerCollection->getConnection()->fetchAssoc($select); + } } diff --git a/app/code/Magento/CustomerImportExport/Test/Unit/Model/Export/AddressTest.php b/app/code/Magento/CustomerImportExport/Test/Unit/Model/Export/AddressTest.php index f40d71d2efa7c..2d8c105d2b29c 100644 --- a/app/code/Magento/CustomerImportExport/Test/Unit/Model/Export/AddressTest.php +++ b/app/code/Magento/CustomerImportExport/Test/Unit/Model/Export/AddressTest.php @@ -7,10 +7,7 @@ namespace Magento\CustomerImportExport\Test\Unit\Model\Export; -use Magento\Customer\Model\AddressFactory; -use Magento\Customer\Model\Config\Share; -use Magento\Customer\Model\GroupFactory; -use Magento\Customer\Model\ResourceModel\Customer; +use Magento\Customer\Model\ResourceModel\Customer\Collection as CustomerCollection; use Magento\Customer\Model\ResourceModel\Customer\CollectionFactory; use Magento\CustomerImportExport\Model\Export\Address; use Magento\CustomerImportExport\Model\Export\CustomerFactory; @@ -19,9 +16,10 @@ use Magento\Eav\Model\Entity\TypeFactory; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Data\Collection; -use Magento\Framework\Data\Collection\AbstractDb; use Magento\Framework\Data\Collection\EntityFactory; use Magento\Framework\DataObject; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Select; use Magento\Framework\Model\AbstractModel; use Magento\Framework\Stdlib\DateTime\TimezoneInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; @@ -30,7 +28,6 @@ use Magento\ImportExport\Model\ResourceModel\CollectionByPagesIteratorFactory; use Magento\Store\Model\Store; use Magento\Store\Model\StoreManager; -use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; /** @@ -82,7 +79,7 @@ class AddressTest extends TestCase /** * ObjectManager helper * - * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + * @var ObjectManager */ protected $_objectManager; @@ -93,6 +90,9 @@ class AddressTest extends TestCase */ protected $_model; + /** + * @inheritdoc + */ protected function setUp(): void { $storeManager = $this->createMock(StoreManager::class); @@ -119,6 +119,9 @@ protected function setUp(): void ); } + /** + * @inheritdoc + */ protected function tearDown(): void { unset($this->_model); @@ -132,8 +135,9 @@ protected function tearDown(): void */ protected function _getModelDependencies() { - $translator = $this->createMock(\stdClass::class); + $pageSize = 1; + $translator = $this->createMock(\stdClass::class); $entityFactory = $this->createMock(EntityFactory::class); /** @var Collection|TestCase $attributeCollection */ @@ -167,34 +171,35 @@ protected function _getModelDependencies() $attributeCollection->addItem($attribute); } - $byPagesIterator = $this->getMockBuilder(\stdClass::class)->addMethods(['iterate']) - ->disableOriginalConstructor() - ->getMock(); - $byPagesIterator->expects( - $this->once() - )->method( - 'iterate' - )->willReturnCallback( - [$this, 'iterate'] - ); - - $customerCollection = $this->getMockBuilder(AbstractDb::class) - ->setMethods(['addAttributeToSelect']) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); + $connection = $this->createMock(AdapterInterface::class); + $customerCollection = $this->createMock(CustomerCollection::class); + $customerCollection->method('getConnection')->willReturn($connection); + $customerCollection->expects($this->once())->method('setPageSize')->with($pageSize); + $customerCollection->method('getLastPageNumber')->willReturn(1); + $allIdsSelect = $this->createMock(Select::class); + $customerCollection->method('getAllIdsSql')->willReturn($allIdsSelect); + + $customerSelect = $this->createMock(Select::class); + $customerSelect->method('from')->willReturnSelf(); + $customerSelect->expects($this->once()) + ->method('where') + ->with('customer.entity_id IN (?)', $allIdsSelect) + ->willReturnSelf(); + $customerSelect->expects($this->once())->method('limitPage')->with(1, $pageSize); + $connection->method('select')->willReturn($customerSelect); + $connection->method('fetchAssoc')->with($customerSelect)->willReturn([1 => $this->_customerData]); $customerEntity = $this->getMockBuilder(\stdClass::class) ->addMethods(['filterEntityCollection', 'setParameters']) ->disableOriginalConstructor() ->getMock(); - $customerEntity->expects($this->any())->method('filterEntityCollection')->willReturnArgument(0); - $customerEntity->expects($this->any())->method('setParameters')->willReturnSelf(); + $customerEntity->method('filterEntityCollection')->willReturnArgument(0); + $customerEntity->method('setParameters')->willReturnSelf(); $data = [ 'translator' => $translator, 'attribute_collection' => $attributeCollection, - 'page_size' => 1, - 'collection_by_pages_iterator' => $byPagesIterator, + 'page_size' => $pageSize, 'entity_type_id' => 1, 'customer_collection' => $customerCollection, 'customer_entity' => $customerEntity, @@ -228,36 +233,6 @@ public function getWebsites($withDefault = false) return $websites; } - /** - * Iterate stub - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * - * @param AbstractDb $collection - * @param int $pageSize - * @param array $callbacks - */ - public function iterate(AbstractDb $collection, $pageSize, array $callbacks) - { - $resource = $this->createPartialMock(Customer::class, ['getIdFieldName']); - $resource->expects($this->any())->method('getIdFieldName')->willReturn('id'); - $arguments = [ - 'data' => $this->_customerData, - 'resource' => $resource, - $this->createMock(Share::class), - $this->createMock(AddressFactory::class), - $this->createMock(\Magento\Customer\Model\ResourceModel\Address\CollectionFactory::class), - $this->createMock(GroupFactory::class), - $this->createMock(\Magento\Customer\Model\AttributeFactory::class), - ]; - /** @var $customer \Magento\Customer\Model\Customer|MockObject */ - $customer = $this->_objectManager->getObject(\Magento\Customer\Model\Customer::class, $arguments); - - foreach ($callbacks as $callback) { - call_user_func($callback, $customer); - } - } - /** * Test for method exportItem() * From 4b007c23916f94a1dd4acd3ebcb7d75fa2daf47b Mon Sep 17 00:00:00 2001 From: "vadim.malesh" <engcom-vendorworker-charlie@adobe.com> Date: Tue, 22 Dec 2020 13:28:26 +0200 Subject: [PATCH 110/156] added unit test; refactoring --- .../Block/Adminhtml/Order/Totals/TaxTest.php | 151 ++++++++++++------ 1 file changed, 101 insertions(+), 50 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Totals/TaxTest.php b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Totals/TaxTest.php index 80563623e0050..222d26c30178a 100644 --- a/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Totals/TaxTest.php +++ b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Totals/TaxTest.php @@ -5,9 +5,6 @@ */ declare(strict_types=1); -/** - * Test class for \Magento\Sales\Block\Adminhtml\Order\Totals\TaxTest - */ namespace Magento\Sales\Test\Unit\Block\Adminhtml\Order\Totals; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; @@ -16,46 +13,75 @@ use Magento\Sales\Model\Order\Creditmemo; use Magento\Sales\Model\Order\Invoice; use Magento\Tax\Helper\Data; +use Magento\Tax\Model\ResourceModel\Sales\Order\Tax\Collection; +use Magento\Tax\Model\Sales\Order\Tax as TaxModel; +use Magento\Tax\Model\Sales\Order\TaxFactory; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +/** + * Test for \Magento\Sales\Block\Adminhtml\Order\Totals\Tax + */ class TaxTest extends TestCase { - /** @var MockObject|Tax */ + /** + * @var array + */ + private $calculatedData = [ + 'tax' => 'tax', + 'shipping_tax' => 'shipping_tax', + ]; + + /** + * @var MockObject|Tax + */ private $taxMock; + /** + * @var Data|MockObject + */ + private $taxHelperMock; + + /** + * @var TaxFactory|MockObject + */ + private $taxOrderFactory; + + /** + * @inheridoc + */ protected function setUp(): void { - $getCalculatedTax = [ - 'tax' => 'tax', - 'shipping_tax' => 'shipping_tax', - ]; - $taxHelperMock = $this->getMockBuilder(Data::class) - ->setMethods(['getCalculatedTaxes']) + $this->taxHelperMock = $this->getMockBuilder(Data::class) + ->onlyMethods(['getCalculatedTaxes']) ->disableOriginalConstructor() ->getMock(); - $taxHelperMock->expects($this->any()) - ->method('getCalculatedTaxes') - ->willReturn($getCalculatedTax); + $this->taxOrderFactory = $this->createMock(TaxFactory::class); + + $arguments = $this->getModelArguments( + ['taxHelper' => $this->taxHelperMock, 'taxOrderFactory' => $this->taxOrderFactory] + ); $this->taxMock = $this->getMockBuilder(Tax::class) - ->setConstructorArgs($this->_getConstructArguments($taxHelperMock)) - ->setMethods(['getOrder', 'getSource']) + ->setConstructorArgs($arguments) + ->onlyMethods(['getOrder', 'getSource']) ->getMock(); } /** * Test method for getFullTaxInfo * - * @param Order $source - * @param array $getCalculatedTax - * @param array $getShippingTax + * @param Order|null $source * @param array $expectedResult + * @return void * * @dataProvider getFullTaxInfoDataProvider */ - public function testGetFullTaxInfo($source, $expectedResult) + public function testGetFullTaxInfo(?Order $source, array $expectedResult): void { + $this->taxHelperMock->expects($this->any()) + ->method('getCalculatedTaxes') + ->willReturn($this->calculatedData); $this->taxMock->expects($this->once()) ->method('getOrder') ->willReturn($source); @@ -69,13 +95,15 @@ public function testGetFullTaxInfo($source, $expectedResult) * * @param Invoice|Creditmemo $source * @param array $expectedResult + * @return void * * @dataProvider getCreditAndInvoiceFullTaxInfoDataProvider */ - public function testGetFullTaxInfoWithCreditAndInvoice( - $source, - $expectedResult - ) { + public function testGetFullTaxInfoWithCreditAndInvoice($source, array $expectedResult): void + { + $this->taxHelperMock->expects($this->any()) + ->method('getCalculatedTaxes') + ->willReturn($this->calculatedData); $this->taxMock->expects($this->once()) ->method('getSource') ->willReturn($source); @@ -84,19 +112,54 @@ public function testGetFullTaxInfoWithCreditAndInvoice( $this->assertSame($expectedResult, $actualResult); } + /** + * Test method for getFullTaxInfo when order doesn't have tax + * + * @return void + */ + public function testGetFullTaxInfoOrderWithoutTax(): void + { + $this->taxHelperMock->expects($this->once()) + ->method('getCalculatedTaxes') + ->willReturn(null); + + $orderMock = $this->createMock(Order::class); + $taxCollection = $this->createMock(Collection::class); + $taxCollection->expects($this->once()) + ->method('loadByOrder') + ->with($orderMock) + ->willReturnSelf(); + + $taxOrder = $this->createMock(TaxModel::class); + $taxOrder->expects($this->once()) + ->method('getCollection') + ->willReturn($taxCollection); + $this->taxOrderFactory->expects($this->once()) + ->method('create') + ->willReturn($taxOrder); + + $invoiceMock = $this->createMock(Invoice::class); + $this->taxMock->expects($this->once()) + ->method('getSource') + ->willReturn($invoiceMock); + $this->taxMock->expects($this->once()) + ->method('getOrder') + ->willReturn($orderMock); + + $this->assertNull($this->taxMock->getFullTaxInfo()); + } + /** * Provide the tax helper mock as a constructor argument * - * @param $taxHelperMock + * @param array $arguments * @return array */ - protected function _getConstructArguments($taxHelperMock) + private function getModelArguments(array $arguments): array { $objectManagerHelper = new ObjectManager($this); - return $objectManagerHelper->getConstructArguments( - Tax::class, - ['taxHelper' => $taxHelperMock] - ); + + return $objectManagerHelper->getConstructArguments(Tax::class, $arguments); } /** @@ -106,19 +169,15 @@ protected function _getConstructArguments($taxHelperMock) * * @return array */ - public function getFullTaxInfoDataProvider() + public function getFullTaxInfoDataProvider(): array { - $salesModelOrderMock = $this->getMockBuilder(Order::class) - ->disableOriginalConstructor() - ->getMock(); + $salesModelOrderMock = $this->createMock(Order::class); + return [ 'source is not an instance of \Magento\Sales\Model\Order' => [null, []], 'source is an instance of \Magento\Sales\Model\Order and has reasonable data' => [ $salesModelOrderMock, - [ - 'tax' => 'tax', - 'shipping_tax' => 'shipping_tax', - ], + $this->calculatedData, ] ]; } @@ -130,22 +189,14 @@ public function getFullTaxInfoDataProvider() * * @return array */ - public function getCreditAndInvoiceFullTaxInfoDataProvider() + public function getCreditAndInvoiceFullTaxInfoDataProvider(): array { - $invoiceMock = $this->getMockBuilder(Invoice::class) - ->disableOriginalConstructor() - ->getMock(); - $creditMemoMock = $this->getMockBuilder(Creditmemo::class) - ->disableOriginalConstructor() - ->getMock(); + $invoiceMock = $this->createMock(Invoice::class); + $creditMemoMock = $this->createMock(Creditmemo::class); - $expected = [ - 'tax' => 'tax', - 'shipping_tax' => 'shipping_tax', - ]; return [ - 'invoice' => [$invoiceMock, $expected], - 'creditMemo' => [$creditMemoMock, $expected] + 'invoice' => [$invoiceMock, $this->calculatedData], + 'creditMemo' => [$creditMemoMock, $this->calculatedData] ]; } } From 292c560070037f280d9953af7966af7d1acaf890 Mon Sep 17 00:00:00 2001 From: Vasya Tsviklinskyi <tsviklinskyi@gmail.com> Date: Tue, 22 Dec 2020 13:54:39 +0200 Subject: [PATCH 111/156] =?UTF-8?q?MC-39809:=20A=20Product=20with=20Custom?= =?UTF-8?q?izable=20Option=20(File)=20can=20not=20be=20added=20by=20Admin?= =?UTF-8?q?=20from=20the=20=E2=80=9CShopping=20Cart=20section=20(=E2=80=9C?= =?UTF-8?q?Customer's=20Activities=E2=80=9D=20column)=20to=20Order?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Magento/Bundle/Test/Unit/Model/Product/TypeTest.php | 8 +++++++- .../Magento/Catalog/Model/Product/Type/AbstractType.php | 7 +++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php index b7041051591d8..9c4d4ce00b7c0 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php @@ -11,7 +11,6 @@ use Magento\Bundle\Model\Product\Type; use Magento\Bundle\Model\ResourceModel\BundleFactory; use Magento\Bundle\Model\ResourceModel\Option\Collection; -use Magento\CatalogRule\Model\ResourceModel\Product\CollectionProcessor; use Magento\Bundle\Model\ResourceModel\Selection\Collection as SelectionCollection; use Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory; use Magento\Bundle\Model\Selection; @@ -28,6 +27,7 @@ use Magento\CatalogInventory\Api\StockStateInterface; use Magento\CatalogInventory\Model\StockRegistry; use Magento\CatalogInventory\Model\StockState; +use Magento\CatalogRule\Model\ResourceModel\Product\CollectionProcessor; use Magento\Framework\DataObject; use Magento\Framework\EntityManager\EntityMetadataInterface; use Magento\Framework\EntityManager\MetadataPool; @@ -1548,6 +1548,10 @@ public function testPrepareForCartAdvancedSpecifyProductOptions() ->disableOriginalConstructor() ->getMock(); + $buyRequest->method('getOptions') + ->willReturn([333 => ['type' => 'image/jpeg']]); + $option->method('getId') + ->willReturn(333); $this->parentClass($group, $option, $buyRequest, $product); $product->expects($this->any()) @@ -1556,6 +1560,8 @@ public function testPrepareForCartAdvancedSpecifyProductOptions() $buyRequest->expects($this->once()) ->method('getBundleOption') ->willReturn([0, '', 'str']); + $group->expects($this->once()) + ->method('validateUserValue'); $result = $this->model->prepareForCartAdvanced($buyRequest, $product); $this->assertEquals('Please specify product option(s).', $result); diff --git a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php index f90b097415661..19f6461d44b6a 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php +++ b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php @@ -3,7 +3,6 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -declare(strict_types=1); namespace Magento\Catalog\Model\Product\Type; @@ -605,7 +604,11 @@ protected function _prepareOptions(\Magento\Framework\DataObject $buyRequest, $p if ($product->getSkipCheckRequiredOption() !== true) { $group->validateUserValue($optionsFromRequest); } elseif ($optionsFromRequest !== null && isset($optionsFromRequest[$option->getId()])) { - $transport->options[$option->getId()] = $optionsFromRequest[$option->getId()]; + if (is_array($optionsFromRequest[$option->getId()])) { + $group->validateUserValue($optionsFromRequest); + } else { + $transport->options[$option->getId()] = $optionsFromRequest[$option->getId()]; + } } } catch (LocalizedException $e) { From 84b1ea0f3ff98c8e57049644fd1f456804738d0f Mon Sep 17 00:00:00 2001 From: "vadim.malesh" <engcom-vendorworker-charlie@adobe.com> Date: Tue, 22 Dec 2020 14:43:23 +0200 Subject: [PATCH 112/156] fixed unit --- .../Sales/Test/Unit/Block/Adminhtml/Order/Totals/TaxTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Totals/TaxTest.php b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Totals/TaxTest.php index 222d26c30178a..b0c053a36de0f 100644 --- a/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Totals/TaxTest.php +++ b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Totals/TaxTest.php @@ -129,6 +129,9 @@ public function testGetFullTaxInfoOrderWithoutTax(): void ->method('loadByOrder') ->with($orderMock) ->willReturnSelf(); + $taxCollection->expects($this->once()) + ->method('toArray') + ->willReturn(['items' => []]); $taxOrder = $this->createMock(TaxModel::class); $taxOrder->expects($this->once()) From 826b697e7049701cd825e88efeb39c31c40b09ec Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Tue, 22 Dec 2020 16:06:02 +0200 Subject: [PATCH 113/156] MC-39037: Report tabs are not aligned and not able to view properly --- .../Block/Widget/Grid/ExtendedTest.php | 56 ++++++++++++++++--- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/Grid/ExtendedTest.php b/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/Grid/ExtendedTest.php index 328a85ffd51ad..6d3761fdfcb79 100644 --- a/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/Grid/ExtendedTest.php +++ b/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/Grid/ExtendedTest.php @@ -5,34 +5,44 @@ */ namespace Magento\Backend\Block\Widget\Grid; +use Laminas\Stdlib\Parameters; +use Magento\Backend\Block\Template\Context; +use Magento\Framework\Data\Collection; +use Magento\Framework\View\LayoutInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + /** * @magentoAppArea adminhtml */ -class ExtendedTest extends \PHPUnit\Framework\TestCase +class ExtendedTest extends TestCase { /** - * @var \Magento\Backend\Block\Widget\Grid\Extended + * @var Extended */ protected $_block; /** - * @var \Magento\Framework\View\LayoutInterface + * @var LayoutInterface */ protected $_layoutMock; + /** + * @inheritDoc + */ protected function setUp(): void { parent::setUp(); - $this->_layoutMock = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Framework\View\LayoutInterface::class + $this->_layoutMock = Bootstrap::getObjectManager()->get( + LayoutInterface::class ); - $context = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Backend\Block\Template\Context::class, + $context = Bootstrap::getObjectManager()->create( + Context::class, ['layout' => $this->_layoutMock] ); $this->_block = $this->_layoutMock->createBlock( - \Magento\Backend\Block\Widget\Grid\Extended::class, + Extended::class, 'grid', ['context' => $context] ); @@ -47,7 +57,7 @@ protected function setUp(): void public function testAddColumnAddsChildToColumnSet() { $this->assertInstanceOf( - \Magento\Backend\Block\Widget\Grid\Column::class, + Column::class, $this->_block->getColumnSet()->getChildBlock('column1') ); $this->assertCount(2, $this->_block->getColumnSet()->getChildNames()); @@ -84,4 +94,32 @@ public function testGetMainButtonsHtmlReturnsEmptyStringIfFiltersArentVisible() $this->_block->setFilterVisibility(false); $this->assertEquals('', $this->_block->getMainButtonsHtml()); } + + /** + * Checks that template does not have redundant div close tag + * + * @return void + */ + public function testExtendedTemplateMarkup(): void + { + $mockCollection = $this->getMockBuilder(Collection::class) + ->disableOriginalConstructor() + ->getMock(); + $this->_block->setCollection($mockCollection); + $this->_block->getRequest() + ->setQuery( + Bootstrap::getObjectManager() + ->create( + Parameters::class, + [ + 'values' => [ + 'ajax' => true + ] + ] + ) + ); + $html = $this->_block->getHtml(); + $html = str_replace(["\n", " "], '', $html); + $this->assertStringEndsWith("</table></div>", $html); + } } From 8e74c61c8ccb10779fd6c307cd9b0e47bbd14294 Mon Sep 17 00:00:00 2001 From: engcom-Kilo <mikola.malevanec@transoftgroup.com> Date: Tue, 22 Dec 2020 18:30:58 +0200 Subject: [PATCH 114/156] MC-39609: Product import: Only the first additional image is validated. --- .../Model/Import/Product/Validator/Media.php | 2 +- .../Model/Import/ProductTest.php | 21 +++++++++++++++++++ .../Model/Import/_files/import_media.csv | 2 +- ...port_media_additional_images_storeview.csv | 2 +- ...media_additional_images_with_wrong_url.csv | 2 ++ .../_files/import_media_existing_images.csv | 2 +- .../_files/import_media_hidden_images.csv | 4 ++-- ...ucts_to_import_with_non_existing_image.csv | 2 +- 8 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_additional_images_with_wrong_url.csv diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/Media.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/Media.php index d1fe1eee80e19..8df5afce568f1 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/Media.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/Media.php @@ -114,8 +114,8 @@ public function isValid($value) ] ); $valid = false; + break; } - break; } } return $valid; diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 3ca6754c77767..dfb57d91a7cc6 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -3415,4 +3415,25 @@ public function importImagesDataProvider(): array ] ]; } + + /** + * Verify additional images url validation during import. + * + * @magentoDbIsolation enabled + * @return void + */ + public function testImportInvalidAdditionalImages(): void + { + $pathToFile = __DIR__ . '/_files/import_media_additional_images_with_wrong_url.csv'; + $filesystem = BootstrapHelper::getObjectManager()->create(Filesystem::class); + $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); + $source = $this->objectManager->create(Csv::class, ['file' => $pathToFile, 'directory' => $directory]); + $errors = $this->_model->setSource($source)->setParameters(['behavior' => Import::BEHAVIOR_APPEND]) + ->validateData(); + $this->assertEquals($errors->getErrorsCount(), 1); + $this->assertEquals( + "Wrong URL/path used for attribute additional_images", + $errors->getErrorByRowNumber(0)[0]->getErrorMessage() + ); + } } diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media.csv index a3e8f8e47ab08..3478512e25028 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media.csv +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media.csv @@ -1,2 +1,2 @@ sku,store_view_code,attribute_set_code,product_type,categories,product_websites,name,description,short_description,weight,product_online,tax_class_name,visibility,price,special_price,special_price_from_date,special_price_to_date,url_key,meta_title,meta_keywords,meta_description,base_image,base_image_label,small_image,small_image_label,thumbnail_image,thumbnail_image_label,swatch_image,swatch_image_label1,created_at,updated_at,new_from_date,new_to_date,display_product_options_in,map_price,msrp_price,map_enabled,gift_message_available,custom_design,custom_design_from,custom_design_to,custom_layout_update,page_layout,product_options_container,msrp_display_actual_price_type,country_of_manufacture,additional_attributes,qty,out_of_stock_qty,use_config_min_qty,is_qty_decimal,allow_backorders,use_config_backorders,min_cart_qty,use_config_min_sale_qty,max_cart_qty,use_config_max_sale_qty,is_in_stock,notify_on_stock_below,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,related_skus,crosssell_skus,upsell_skus,additional_images,additional_image_labels,hide_from_product_page,custom_options,bundle_price_type,bundle_sku_type,bundle_price_view,bundle_weight_type,bundle_values,associated_skus -simple_new,,Default,simple,,base,New Product,,,,1,Taxable Goods,"Catalog, Search",10,,,,new-product,New Product,New Product,New Product ,magento_image.jpg,Image Label,magento_small_image.jpg,Small Image Label,magento_thumbnail.jpg,Thumbnail Label,magento_image.jpg,Image Label,10/20/15 07:05,10/20/15 07:05,,,Block after Info Column,,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",100,0,1,0,0,1,1,1,10000,1,1,1,1,1,0,1,1,0,0,0,1,,,,"magento_additional_image_one.jpg, magento_additional_image_two.jpg","Additional Image Label One,Additional Image Label Two",,,,,,,, +simple_new,,Default,simple,,base,New Product,,,,1,Taxable Goods,"Catalog, Search",10,,,,new-product,New Product,New Product,New Product ,magento_image.jpg,Image Label,magento_small_image.jpg,Small Image Label,magento_thumbnail.jpg,Thumbnail Label,magento_image.jpg,Image Label,10/20/15 07:05,10/20/15 07:05,,,Block after Info Column,,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",100,0,1,0,0,1,1,1,10000,1,1,1,1,1,0,1,1,0,0,0,1,,,,"magento_additional_image_one.jpg,magento_additional_image_two.jpg","Additional Image Label One,Additional Image Label Two",,,,,,,, diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_additional_images_storeview.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_additional_images_storeview.csv index ed8755a73fcb1..4d2e7234c9362 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_additional_images_storeview.csv +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_additional_images_storeview.csv @@ -1,2 +1,2 @@ "sku","store_view_code","additional_images","additional_image_labels" -"simple","fixturestore","magento_additional_image_one.jpg, magento_additional_image_two.jpg","Additional Image Label One,Additional Image Label Two" +"simple","fixturestore","magento_additional_image_one.jpg,magento_additional_image_two.jpg","Additional Image Label One,Additional Image Label Two" diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_additional_images_with_wrong_url.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_additional_images_with_wrong_url.csv new file mode 100644 index 0000000000000..c2b9e4f6fa936 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_additional_images_with_wrong_url.csv @@ -0,0 +1,2 @@ +sku,product_type,name,price,attribute_set_code,additional_images +simple1,simple,"simple 1",25,Default,"additional_image_one.jpg,additional_image with spaces.jpg" diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_existing_images.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_existing_images.csv index a3e8f8e47ab08..3478512e25028 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_existing_images.csv +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_existing_images.csv @@ -1,2 +1,2 @@ sku,store_view_code,attribute_set_code,product_type,categories,product_websites,name,description,short_description,weight,product_online,tax_class_name,visibility,price,special_price,special_price_from_date,special_price_to_date,url_key,meta_title,meta_keywords,meta_description,base_image,base_image_label,small_image,small_image_label,thumbnail_image,thumbnail_image_label,swatch_image,swatch_image_label1,created_at,updated_at,new_from_date,new_to_date,display_product_options_in,map_price,msrp_price,map_enabled,gift_message_available,custom_design,custom_design_from,custom_design_to,custom_layout_update,page_layout,product_options_container,msrp_display_actual_price_type,country_of_manufacture,additional_attributes,qty,out_of_stock_qty,use_config_min_qty,is_qty_decimal,allow_backorders,use_config_backorders,min_cart_qty,use_config_min_sale_qty,max_cart_qty,use_config_max_sale_qty,is_in_stock,notify_on_stock_below,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,related_skus,crosssell_skus,upsell_skus,additional_images,additional_image_labels,hide_from_product_page,custom_options,bundle_price_type,bundle_sku_type,bundle_price_view,bundle_weight_type,bundle_values,associated_skus -simple_new,,Default,simple,,base,New Product,,,,1,Taxable Goods,"Catalog, Search",10,,,,new-product,New Product,New Product,New Product ,magento_image.jpg,Image Label,magento_small_image.jpg,Small Image Label,magento_thumbnail.jpg,Thumbnail Label,magento_image.jpg,Image Label,10/20/15 07:05,10/20/15 07:05,,,Block after Info Column,,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",100,0,1,0,0,1,1,1,10000,1,1,1,1,1,0,1,1,0,0,0,1,,,,"magento_additional_image_one.jpg, magento_additional_image_two.jpg","Additional Image Label One,Additional Image Label Two",,,,,,,, +simple_new,,Default,simple,,base,New Product,,,,1,Taxable Goods,"Catalog, Search",10,,,,new-product,New Product,New Product,New Product ,magento_image.jpg,Image Label,magento_small_image.jpg,Small Image Label,magento_thumbnail.jpg,Thumbnail Label,magento_image.jpg,Image Label,10/20/15 07:05,10/20/15 07:05,,,Block after Info Column,,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",100,0,1,0,0,1,1,1,10000,1,1,1,1,1,0,1,1,0,0,0,1,,,,"magento_additional_image_one.jpg,magento_additional_image_two.jpg","Additional Image Label One,Additional Image Label Two",,,,,,,, diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_hidden_images.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_hidden_images.csv index 1c1bebee57578..f54d4b7f401d4 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_hidden_images.csv +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_hidden_images.csv @@ -1,2 +1,2 @@ -sku,store_view_code,attribute_set_code,product_type,categories,product_websites,name,description,short_description,weight,product_online,tax_class_name,visibility,price,special_price,special_price_from_date,special_price_to_date,url_key,meta_title,meta_keywords,meta_description,base_image,base_image_label,small_image,small_image_label,thumbnail_image,thumbnail_image_label,swatch_image,swatch_image_label1,created_at,updated_at,new_from_date,new_to_date,display_product_options_in,map_price,msrp_price,map_enabled,gift_message_available,custom_design,custom_design_from,custom_design_to,custom_layout_update,page_layout,product_options_container,msrp_display_actual_price_type,country_of_manufacture,additional_attributes,qty,out_of_stock_qty,use_config_min_qty,is_qty_decimal,allow_backorders,use_config_backorders,min_cart_qty,use_config_min_sale_qty,max_cart_qty,use_config_max_sale_qty,is_in_stock,notify_on_stock_below,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,related_skus,crosssell_skus,upsell_skus,additional_images,additional_image_labels,hide_from_product_page,custom_options,bundle_price_type,bundle_sku_type,bundle_price_view,bundle_weight_type,bundle_values,associated_skus -simple_new,,Default,simple,,base,New Product,,,,1,Taxable Goods,"Catalog, Search",10,,,,new-product,New Product,New Product,New Product,magento_image.jpg,Image Label,magento_small_image.jpg,Small Image Label,magento_thumbnail.jpg,Thumbnail Label,magento_image.jpg,Image Label,10/20/2015 7:05,10/20/2015 7:05,,,Block after Info Column,,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",100,0,1,0,0,1,1,1,10000,1,1,1,1,1,0,1,1,0,0,0,1,,,,"magento_additional_image_one.jpg, magento_additional_image_two.jpg","Additional Image Label One,Additional Image Label Two","magento_image.jpg,magento_thumbnail.jpg,magento_additional_image_two.jpg",,,,,,, +sku,store_view_code,attribute_set_code,product_type,categories,product_websites,name,description,short_description,weight,product_online,tax_class_name,visibility,price,special_price,special_price_from_date,special_price_to_date,url_key,meta_title,meta_keywords,meta_description,base_image,base_image_label,small_image,small_image_label,thumbnail_image,thumbnail_image_label,swatch_image,swatch_image_label1,created_at,updated_at,new_from_date,new_to_date,display_product_options_in,map_price,msrp_price,map_enabled,gift_message_available,custom_design,custom_design_from,custom_design_to,custom_layout_update,page_layout,product_options_container,msrp_display_actual_price_type,country_of_manufacture,additional_attributes,qty,out_of_stock_qty,use_config_min_qty,is_qty_decimal,allow_backorders,use_config_backorders,min_cart_qty,use_config_min_sale_qty,max_cart_qty,use_config_max_sale_qty,is_in_stock,notify_on_stock_below,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,related_skus,crosssell_skus,upsell_skus,additional_images,additional_image_labels,hide_from_product_page,custom_options,bundle_price_type,bundle_sku_type,bundle_price_view,bundle_weight_type,bundle_values,associated_skus +simple_new,,Default,simple,,base,New Product,,,,1,Taxable Goods,"Catalog, Search",10,,,,new-product,New Product,New Product,New Product,magento_image.jpg,Image Label,magento_small_image.jpg,Small Image Label,magento_thumbnail.jpg,Thumbnail Label,magento_image.jpg,Image Label,10/20/2015 7:05,10/20/2015 7:05,,,Block after Info Column,,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",100,0,1,0,0,1,1,1,10000,1,1,1,1,1,0,1,1,0,0,0,1,,,,"magento_additional_image_one.jpg,magento_additional_image_two.jpg","Additional Image Label One,Additional Image Label Two","magento_image.jpg,magento_thumbnail.jpg,magento_additional_image_two.jpg",,,,,,, diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_non_existing_image.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_non_existing_image.csv index 8122433a8c9e1..6037ee008a8ec 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_non_existing_image.csv +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_non_existing_image.csv @@ -1,2 +1,2 @@ sku,store_view_code,attribute_set_code,product_type,categories,product_websites,name,description,short_description,weight,product_online,tax_class_name,visibility,price,special_price,special_price_from_date,special_price_to_date,url_key,meta_title,meta_keywords,meta_description,base_image,base_image_label,small_image,small_image_label,thumbnail_image,thumbnail_image_label,swatch_image,swatch_image_label1,created_at,updated_at,new_from_date,new_to_date,display_product_options_in,map_price,msrp_price,map_enabled,gift_message_available,custom_design,custom_design_from,custom_design_to,custom_layout_update,page_layout,product_options_container,msrp_display_actual_price_type,country_of_manufacture,additional_attributes,qty,out_of_stock_qty,use_config_min_qty,is_qty_decimal,allow_backorders,use_config_backorders,min_cart_qty,use_config_min_sale_qty,max_cart_qty,use_config_max_sale_qty,is_in_stock,notify_on_stock_below,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,related_skus,crosssell_skus,upsell_skus,additional_images,additional_image_labels,hide_from_product_page,custom_options,bundle_price_type,bundle_sku_type,bundle_price_view,bundle_weight_type,bundle_values,associated_skus -simple_new,,Default,simple,,base,New Product,,,,1,Taxable Goods,"Catalog, Search",10,,,,new-product,New Product,New Product,New Product ,/no/exists/image/magento_image.jpg,Image Label,magento_small_image.jpg,Small Image Label,magento_thumbnail.jpg,Thumbnail Label,magento_image.jpg,Image Label,10/20/15 07:05,10/20/15 07:05,,,Block after Info Column,,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",100,0,1,0,0,1,1,1,10000,1,1,1,1,1,0,1,1,0,0,0,1,,,,"magento_additional_image_one.jpg, magento_additional_image_two.jpg","Additional Image Label One,Additional Image Label Two",,,,,,,, +simple_new,,Default,simple,,base,New Product,,,,1,Taxable Goods,"Catalog, Search",10,,,,new-product,New Product,New Product,New Product ,/no/exists/image/magento_image.jpg,Image Label,magento_small_image.jpg,Small Image Label,magento_thumbnail.jpg,Thumbnail Label,magento_image.jpg,Image Label,10/20/15 07:05,10/20/15 07:05,,,Block after Info Column,,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",100,0,1,0,0,1,1,1,10000,1,1,1,1,1,0,1,1,0,0,0,1,,,,"magento_additional_image_one.jpg,magento_additional_image_two.jpg","Additional Image Label One,Additional Image Label Two",,,,,,,, From 1093ad0421851caad9bf361269aadccd7997667f Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Wed, 23 Dec 2020 11:29:33 +0200 Subject: [PATCH 115/156] MC-39852: Change customer custom address file attribute editor on backend to don't use direct link for preview --- .../Controller/Adminhtml/Address/Viewfile.php | 180 ++++++++++++++++++ .../Magento/Customer/Model/FileProcessor.php | 7 +- .../Test/Unit/Model/FileProcessorTest.php | 22 +-- pub/media/customer_address/.htaccess | 7 + 4 files changed, 202 insertions(+), 14 deletions(-) create mode 100644 app/code/Magento/Customer/Controller/Adminhtml/Address/Viewfile.php create mode 100644 pub/media/customer_address/.htaccess diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Address/Viewfile.php b/app/code/Magento/Customer/Controller/Adminhtml/Address/Viewfile.php new file mode 100644 index 0000000000000..a8cad14c23a72 --- /dev/null +++ b/app/code/Magento/Customer/Controller/Adminhtml/Address/Viewfile.php @@ -0,0 +1,180 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Customer\Controller\Adminhtml\Address; + +use Magento\Customer\Api\AddressMetadataInterface; +use Magento\Framework\Exception\NotFoundException; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Controller\Result\RawFactory; +use Magento\Framework\Url\DecoderInterface; +use Magento\Framework\Controller\ResultInterface; +use Magento\Framework\Filesystem; +use Magento\Framework\Controller\Result\Raw; +use Magento\MediaStorage\Helper\File\Storage; +use Magento\Framework\App\Response\Http\FileFactory; +use Magento\Framework\Filesystem\Io\File as IoFile; +use Magento\Backend\App\Action\Context; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Backend\App\Action; + +/** + * Class Viewfile serves to show file or image by file/image name provided in request parameters. + */ +class Viewfile extends Action implements HttpGetActionInterface +{ + /** + * Authorization level of a basic admin session + */ + const ADMIN_RESOURCE = 'Magento_Customer::manage'; + + /** + * @var RawFactory + */ + private $resultRawFactory; + + /** + * @var DecoderInterface + */ + private $urlDecoder; + + /** + * @var Filesystem + */ + private $filesystem; + + /** + * @var Storage + */ + private $storage; + + /** + * @var FileFactory + */ + private $fileFactory; + + /** + * @var IoFile + */ + private $ioFile; + + /** + * @param Context $context + * @param FileFactory $fileFactory + * @param RawFactory $resultRawFactory + * @param DecoderInterface $urlDecoder + * @param Filesystem $filesystem + * @param Storage $storage + * @param IoFile $ioFile + */ + public function __construct( + Context $context, + FileFactory $fileFactory, + RawFactory $resultRawFactory, + DecoderInterface $urlDecoder, + Filesystem $filesystem, + Storage $storage, + IoFile $ioFile + ) { + parent::__construct($context); + $this->resultRawFactory = $resultRawFactory; + $this->urlDecoder = $urlDecoder; + $this->filesystem = $filesystem; + $this->storage = $storage; + $this->fileFactory = $fileFactory; + $this->ioFile = $ioFile; + } + + /** + * Customer address view file action + * + * @return ResultInterface|void + * @throws NotFoundException + */ + public function execute() + { + list($file, $plain) = $this->getFileParams(); + + $directory = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA); + $fileName = AddressMetadataInterface::ENTITY_TYPE_ADDRESS . DIRECTORY_SEPARATOR . + ltrim($file, DIRECTORY_SEPARATOR); + $path = $directory->getAbsolutePath($fileName); + if (mb_strpos($path, '..') !== false + || (!$directory->isFile($fileName) && !$this->storage->processStorageFile($path)) + ) { + throw new NotFoundException(__('Page not found.')); + } + + $pathInfo = $this->ioFile->getPathInfo($path); + if ($plain) { + $extension = $pathInfo['extension']; + switch (strtolower($extension)) { + case 'gif': + $contentType = 'image/gif'; + break; + case 'jpg': + $contentType = 'image/jpeg'; + break; + case 'png': + $contentType = 'image/png'; + break; + default: + $contentType = 'application/octet-stream'; + break; + } + $stat = $directory->stat($fileName); + $contentLength = $stat['size']; + $contentModify = $stat['mtime']; + + /** @var Raw $resultRaw */ + $resultRaw = $this->resultRawFactory->create(); + $resultRaw->setHttpResponseCode(200) + ->setHeader('Pragma', 'public', true) + ->setHeader('Content-type', $contentType, true) + ->setHeader('Content-Length', $contentLength) + ->setHeader('Last-Modified', date('r', $contentModify)); + $resultRaw->setContents($directory->readFile($fileName)); + + return $resultRaw; + } else { + $name = $pathInfo['basename']; + $this->fileFactory->create( + $name, + ['type' => 'filename', 'value' => $fileName], + DirectoryList::MEDIA + ); + } + } + + /** + * Get parameters from request. + * + * @return array + * @throws NotFoundException + */ + private function getFileParams() : array + { + $file = null; + $plain = false; + if ($this->getRequest()->getParam('file')) { + // download file + $file = $this->urlDecoder->decode( + $this->getRequest()->getParam('file') + ); + } elseif ($this->getRequest()->getParam('image')) { + // show plain image + $file = $this->urlDecoder->decode( + $this->getRequest()->getParam('image') + ); + $plain = true; + } else { + throw new NotFoundException(__('Page not found.')); + } + + return [$file, $plain]; + } +} diff --git a/app/code/Magento/Customer/Model/FileProcessor.php b/app/code/Magento/Customer/Model/FileProcessor.php index 02bfe78be535c..59e2d5fb2b577 100644 --- a/app/code/Magento/Customer/Model/FileProcessor.php +++ b/app/code/Magento/Customer/Model/FileProcessor.php @@ -158,9 +158,10 @@ public function getViewUrl($filePath, $type) $viewUrl = ''; if ($this->entityTypeCode == AddressMetadataInterface::ENTITY_TYPE_ADDRESS) { - $filePath = $this->entityTypeCode . '/' . ltrim($filePath, '/'); - $viewUrl = $this->urlBuilder->getBaseUrl(['_type' => UrlInterface::URL_TYPE_MEDIA]) - . $this->mediaDirectory->getRelativePath($filePath); + $viewUrl = $this->urlBuilder->getUrl( + 'customer/address/viewfile', + [$type => $this->urlEncoder->encode(ltrim($filePath, '/'))] + ); } if ($this->entityTypeCode == CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER) { diff --git a/app/code/Magento/Customer/Test/Unit/Model/FileProcessorTest.php b/app/code/Magento/Customer/Test/Unit/Model/FileProcessorTest.php index 7a0522f6476f2..fb775ce78bbbc 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/FileProcessorTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/FileProcessorTest.php @@ -162,22 +162,22 @@ public function testGetViewUrlCustomer() public function testGetViewUrlCustomerAddress() { $filePath = 'filename.ext1'; + $encodedFilePath = 'encodedfilenameext1'; - $baseUrl = 'baseUrl'; - $relativeUrl = 'relativeUrl'; + $fileUrl = 'fileUrl'; - $this->urlBuilder->expects($this->once()) - ->method('getBaseUrl') - ->with(['_type' => UrlInterface::URL_TYPE_MEDIA]) - ->willReturn($baseUrl); + $this->urlEncoder->expects($this->once()) + ->method('encode') + ->with($filePath) + ->willReturn($encodedFilePath); - $this->mediaDirectory->expects($this->once()) - ->method('getRelativePath') - ->with(AddressMetadataInterface::ENTITY_TYPE_ADDRESS . '/' . $filePath) - ->willReturn($relativeUrl); + $this->urlBuilder->expects($this->once()) + ->method('getUrl') + ->with('customer/address/viewfile', ['image' => $encodedFilePath]) + ->willReturn($fileUrl); $model = $this->getModel(AddressMetadataInterface::ENTITY_TYPE_ADDRESS); - $this->assertEquals($baseUrl . $relativeUrl, $model->getViewUrl($filePath, 'image')); + $this->assertEquals($fileUrl, $model->getViewUrl($filePath, 'image')); } public function testRemoveUploadedFile() diff --git a/pub/media/customer_address/.htaccess b/pub/media/customer_address/.htaccess new file mode 100644 index 0000000000000..b97408bad3f2e --- /dev/null +++ b/pub/media/customer_address/.htaccess @@ -0,0 +1,7 @@ +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> From 22ca921b91527ff3a200a4126dd7ddb0bae93c38 Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Wed, 23 Dec 2020 13:26:19 +0200 Subject: [PATCH 116/156] updated with StorefrontHoverProductOnCategoryPageActionGroup --- .../Test/StorefrontGoToDetailsPageWhenAddingToCartTest.xml | 2 +- ...essStateFieldForUKCustomerRemainOptionAfterRefreshTest.xml | 2 +- .../AddressStateFieldShouldNotAcceptJustIntegerValuesTest.xml | 2 +- .../NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml | 2 +- ...stomerCheckoutTestWithMultipleAddressesAndTaxRatesTest.xml | 4 ++-- ...tomerCheckoutTestWithRestrictedCountriesForPaymentTest.xml | 2 +- .../StorefrontGuestCheckoutTest.xml | 2 +- ...GuestCheckoutTestWithRestrictedCountriesForPaymentTest.xml | 2 +- .../Test/StorefrontVerifySecureURLRedirectCheckoutTest.xml | 2 +- .../StorefrontVerifySecureURLRedirectMultishippingTest.xml | 2 +- .../Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml | 2 +- .../Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml | 3 +-- 12 files changed, 13 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontGoToDetailsPageWhenAddingToCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontGoToDetailsPageWhenAddingToCartTest.xml index 88fc5b7171592..e08982a266ee5 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontGoToDetailsPageWhenAddingToCartTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontGoToDetailsPageWhenAddingToCartTest.xml @@ -70,7 +70,7 @@ <click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="cartClickCategory"/> <!--Click add to cart--> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addProductToCart"/> <!--Check for details page--> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldForUKCustomerRemainOptionAfterRefreshTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldForUKCustomerRemainOptionAfterRefreshTest.xml index f578a9c02caca..f43211e909cca 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldForUKCustomerRemainOptionAfterRefreshTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldForUKCustomerRemainOptionAfterRefreshTest.xml @@ -34,7 +34,7 @@ <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad1"/> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addToCart"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$createProduct.name$$ to your shopping cart." stepKey="seeAddedToCartMessage"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldShouldNotAcceptJustIntegerValuesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldShouldNotAcceptJustIntegerValuesTest.xml index 7c4b18e1aab89..b825757636c0b 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldShouldNotAcceptJustIntegerValuesTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldShouldNotAcceptJustIntegerValuesTest.xml @@ -37,7 +37,7 @@ <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad1"/> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addToCart"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$createProduct.name$$ to your shopping cart." stepKey="seeAddedToCartMessage"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml index bf942e70cfa36..d269a666d975e 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml @@ -39,7 +39,7 @@ </after> <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onStorefrontCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad1"/> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addProductToCart"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$createSimpleProduct.name$$ to your shopping cart." stepKey="seeAddedToCartMessage"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest/StorefrontCustomerCheckoutTestWithMultipleAddressesAndTaxRatesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest/StorefrontCustomerCheckoutTestWithMultipleAddressesAndTaxRatesTest.xml index 9747980801068..396ba5894aeb3 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest/StorefrontCustomerCheckoutTestWithMultipleAddressesAndTaxRatesTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest/StorefrontCustomerCheckoutTestWithMultipleAddressesAndTaxRatesTest.xml @@ -82,7 +82,7 @@ <amOnPage url="{{StorefrontCategoryPage.url($$simplecategory.name$$)}}" stepKey="onCategoryPage1"/> <waitForPageLoad stepKey="waitForCatalogPageLoad1"/> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct1"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct1"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addToCart1"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded1"/> <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$simpleproduct1.name$$ to your shopping cart." stepKey="seeAddedToCartMessage1"/> @@ -101,7 +101,7 @@ <amOnPage url="{{StorefrontCategoryPage.url($$simplecategory.name$$)}}" stepKey="onCategoryPage2"/> <waitForPageLoad stepKey="waitForCatalogPageLoad2"/> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct2"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct2"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addToCart2"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded2"/> <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$simpleproduct1.name$$ to your shopping cart." stepKey="seeAddedToCartMessage2"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest/StorefrontCustomerCheckoutTestWithRestrictedCountriesForPaymentTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest/StorefrontCustomerCheckoutTestWithRestrictedCountriesForPaymentTest.xml index d6f1408c2b66a..8325eeb0da7e3 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest/StorefrontCustomerCheckoutTestWithRestrictedCountriesForPaymentTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest/StorefrontCustomerCheckoutTestWithRestrictedCountriesForPaymentTest.xml @@ -51,7 +51,7 @@ <!-- Add product to cart --> <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad1"/> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addToCart"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$createProduct.name$$ to your shopping cart." stepKey="seeAddedToCartMessage"/> 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 b591aefbdc889..4c9828d17ca1a 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTest.xml @@ -39,7 +39,7 @@ <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad1"/> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addToCart"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$createProduct.name$$ to your shopping cart." stepKey="seeAddedToCartMessage"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTestWithRestrictedCountriesForPaymentTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTestWithRestrictedCountriesForPaymentTest.xml index 15b550657ef60..7090b0d4fd3fd 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTestWithRestrictedCountriesForPaymentTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTestWithRestrictedCountriesForPaymentTest.xml @@ -42,7 +42,7 @@ <!-- Add product to cart --> <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad1"/> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addToCart"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$createProduct.name$$ to your shopping cart." stepKey="seeAddedToCartMessage"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifySecureURLRedirectCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifySecureURLRedirectCheckoutTest.xml index 03323b7b9c855..7465ab6aa69e4 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifySecureURLRedirectCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifySecureURLRedirectCheckoutTest.xml @@ -27,7 +27,7 @@ </createData> <amOnPage url="{{StorefrontCategoryPage.url($$category.name$$)}}" stepKey="goToCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad"/> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="moveMouseOverProduct"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="moveMouseOverProduct"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="clickAddToCartButton"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForAddedToCartSuccessMessage"/> <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$product.name$$ to your shopping cart." stepKey="seeAddedToCartSuccessMessage"/> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontVerifySecureURLRedirectMultishippingTest.xml b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontVerifySecureURLRedirectMultishippingTest.xml index fe33078755ac4..515c9b2102f5e 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontVerifySecureURLRedirectMultishippingTest.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontVerifySecureURLRedirectMultishippingTest.xml @@ -32,7 +32,7 @@ </actionGroup> <amOnPage url="{{StorefrontCategoryPage.url($$category.name$$)}}" stepKey="goToCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad"/> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="moveMouseOverProduct"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="moveMouseOverProduct"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="clickAddToCartButton"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForAddedToCartSuccessMessage"/> <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$product.name$$ to your shopping cart." stepKey="seeAddedToCartSuccessMessage"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index 91a8f95880fbc..d5128dc3f8b0c 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -33,7 +33,7 @@ <!-- todo: Create an order via the api instead of driving the browser --> <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad1"/> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addToCart"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickCart"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml index b2bdf8ce5d90b..16b20abc0a583 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml @@ -62,7 +62,7 @@ <!-- Place an order from Storefront as a Guest --> <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad1"/> - <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverOverProduct"/> + <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addToCart"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductToAdd"/> <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickCart"/> @@ -149,4 +149,3 @@ </assertEquals> </test> </tests> - From 275e42e42a51f3c04b2dafd4d17a8245e1a036cf Mon Sep 17 00:00:00 2001 From: SmVladyslav <vlatame.tsg@gmail.com> Date: Wed, 23 Dec 2020 13:39:28 +0200 Subject: [PATCH 117/156] MC-37385: Unexpected unchecking of "Append Comments" check-box --- .../Magento/Sales/Model/AdminOrder/Create.php | 7 ++-- .../Adminhtml/Order/Create/LoadBlockTest.php | 34 +++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php index 5d621f1632837..a0e0dd9aeb2bd 100644 --- a/app/code/Magento/Sales/Model/AdminOrder/Create.php +++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php @@ -1716,10 +1716,9 @@ public function importPostData($data) if (isset($data['comment'])) { $this->getQuote()->addData($data['comment']); - if (empty($data['comment']['customer_note_notify'])) { - $this->getQuote()->setCustomerNoteNotify(false); - } else { - $this->getQuote()->setCustomerNoteNotify(true); + if ($this->getIsValidate()) { + $notify = !empty($data['comment']['customer_note_notify']); + $this->getQuote()->setCustomerNoteNotify($notify); } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlockTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlockTest.php index 529b491269643..3567a7e00764f 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlockTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlockTest.php @@ -231,6 +231,40 @@ public function testAddProductToOrderFromWishList(): void $this->assertCount(1, $quoteItems); } + /** + * Check that customer notification is NOT disabled after comment is updated. + * + * @return void + * @magentoDataFixture Magento/Checkout/_files/quote_with_customer_without_address.php + */ + public function testUpdateCustomerNote(): void + { + $customerNote = 'Example Comment'; + $quoteId = $this->getQuoteByReservedOrderId->execute('test_order_with_customer_without_address')->getId(); + $this->session->setQuoteId($quoteId); + $params = [ + 'json' => false, + 'block' => 'totals', + 'as_js_varname' => false, + ]; + $post = $this->hydratePost([ + 'order' => [ + 'comment' => [ + CartInterface::KEY_CUSTOMER_NOTE => $customerNote + ], + ], + ]); + $this->dispatchWitParams($params, $post); + + $quote = $this->session->getQuote(); + $this->assertEquals($customerNote, $quote->getCustomerNote()); + $this->assertTrue((bool)$quote->getCustomerNoteNotify()); + + preg_match('/id="notify_customer"(?<attributes>.*?)\/>/s', $this->getResponse()->getBody(), $matches); + $this->assertArrayHasKey('attributes', $matches); + $this->assertStringContainsString('checked="checked"', $matches['attributes']); + } + /** * Check customer quotes * From 08a6b9cb5fdd08b0813936d0e0309219c11e3c84 Mon Sep 17 00:00:00 2001 From: Serhii Balko <serhii.balko@transogtgroup.com> Date: Wed, 23 Dec 2020 15:21:34 +0200 Subject: [PATCH 118/156] MC-39864: [Magento Cloud] - Tax Miscalculation --- .../Model/Order/Creditmemo/Total/Tax.php | 69 +++++++++++++++++-- .../Model/ResourceModel/Order/Invoice.php | 35 ++++++++-- 2 files changed, 92 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php index eba84dcfb6364..faed11c4f718e 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php @@ -5,13 +5,31 @@ */ namespace Magento\Sales\Model\Order\Creditmemo\Total; +use Magento\Sales\Api\Data\CreditmemoInterface; use Magento\Sales\Model\Order\Creditmemo; +use Magento\Sales\Model\Order\Invoice; +use Magento\Sales\Model\ResourceModel\Order\Invoice as ResourceInvoice; /** * Collects credit memo taxes. */ class Tax extends AbstractTotal { + /** + * @var ResourceInvoice + */ + private $resourceInvoice; + + /** + * @param ResourceInvoice $resourceInvoice + * @param array $data + */ + public function __construct(ResourceInvoice $resourceInvoice, array $data = []) + { + $this->resourceInvoice = $resourceInvoice; + parent::__construct($data); + } + /** * {@inheritdoc} * @SuppressWarnings(PHPMD.NPathComplexity) @@ -182,8 +200,12 @@ private function calculateAllowedTax(Creditmemo $creditMemo): float { $invoice = $creditMemo->getInvoice(); $order = $creditMemo->getOrder(); - $amount = $invoice !== null ? $invoice->getTaxAmount() - : $order->getTaxInvoiced() - $order->getTaxRefunded(); + if ($invoice!== null) { + $amount = $invoice->getTaxAmount() + - $this->calculateInvoiceRefundedAmount($invoice, CreditmemoInterface::TAX_AMOUNT); + } else { + $amount = $order->getTaxInvoiced() - $order->getTaxRefunded(); + } return (float) $amount - $creditMemo->getTaxAmount(); } @@ -198,8 +220,13 @@ private function calculateAllowedBaseTax(Creditmemo $creditMemo): float { $invoice = $creditMemo->getInvoice(); $order = $creditMemo->getOrder(); - $amount = $invoice !== null ? $invoice->getBaseTaxAmount() - : $order->getBaseTaxInvoiced() - $order->getBaseTaxRefunded(); + + if ($invoice!== null) { + $amount = $invoice->getBaseTaxAmount() + - $this->calculateInvoiceRefundedAmount($invoice, CreditmemoInterface::BASE_TAX_AMOUNT); + } else { + $amount = $order->getBaseTaxInvoiced() - $order->getBaseTaxRefunded(); + } return (float) $amount - $creditMemo->getBaseTaxAmount(); } @@ -217,7 +244,14 @@ private function calculateAllowedDiscountTaxCompensation(Creditmemo $creditMemo) if ($invoice) { $amount = $invoice->getDiscountTaxCompensationAmount() - + $invoice->getShippingDiscountTaxCompensationAmount(); + + $invoice->getShippingDiscountTaxCompensationAmount() + - $this->calculateInvoiceRefundedAmount( + $invoice, + CreditmemoInterface::DISCOUNT_TAX_COMPENSATION_AMOUNT + ) - $this->calculateInvoiceRefundedAmount( + $invoice, + CreditmemoInterface::SHIPPING_DISCOUNT_TAX_COMPENSATION_AMOUNT + ); } else { $amount = $order->getDiscountTaxCompensationInvoiced() + $order->getShippingDiscountTaxCompensationAmount() @@ -243,7 +277,14 @@ private function calculateAllowedBaseDiscountTaxCompensation(Creditmemo $creditM if ($invoice) { $amount = $invoice->getBaseDiscountTaxCompensationAmount() - + $invoice->getBaseShippingDiscountTaxCompensationAmnt(); + + $invoice->getBaseShippingDiscountTaxCompensationAmnt() + - $this->calculateInvoiceRefundedAmount( + $invoice, + CreditmemoInterface::BASE_DISCOUNT_TAX_COMPENSATION_AMOUNT + ) - $this->calculateInvoiceRefundedAmount( + $invoice, + CreditmemoInterface::BASE_SHIPPING_DISCOUNT_TAX_COMPENSATION_AMNT + ); } else { $amount = $order->getBaseDiscountTaxCompensationInvoiced() + $order->getBaseShippingDiscountTaxCompensationAmnt() @@ -255,4 +296,20 @@ private function calculateAllowedBaseDiscountTaxCompensation(Creditmemo $creditM - $creditMemo->getBaseShippingDiscountTaxCompensationAmnt() - $creditMemo->getBaseDiscountTaxCompensationAmount(); } + + /** + * Calculate refunded amount for invoice + * + * @param Invoice $invoice + * @param string $field + * @return float + */ + private function calculateInvoiceRefundedAmount(Invoice $invoice, string $field): float + { + if (empty($invoice->getId())) { + return 0; + } + + return $this->resourceInvoice->calculateRefundedAmount((int)$invoice->getId(), $field); + } } diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice.php index 848f88118ed32..bc21e9cd6c894 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice.php @@ -5,11 +5,9 @@ */ namespace Magento\Sales\Model\ResourceModel\Order; -use Magento\Framework\App\ResourceConnection; -use Magento\SalesSequence\Model\Manager; -use Magento\Sales\Model\ResourceModel\Attribute; +use Magento\Framework\DataObject; +use Magento\Framework\Model\AbstractModel; use Magento\Sales\Model\ResourceModel\EntityAbstract as SalesResource; -use Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot; use Magento\Sales\Model\Spi\InvoiceResourceInterface; /** @@ -37,10 +35,10 @@ protected function _construct() /** * Perform actions before object save * - * @param \Magento\Framework\Model\AbstractModel|\Magento\Framework\DataObject $object + * @param AbstractModel|DataObject $object * @return $this */ - protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object) + protected function _beforeSave(AbstractModel $object) { /** @var \Magento\Sales\Model\Order\Invoice $object */ if (!$object->getOrderId() && $object->getOrder()) { @@ -50,4 +48,29 @@ protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object) return parent::_beforeSave($object); } + + /** + * Calculate refunded amount for invoice + * + * @param int $invoiceId + * @param string $filed + * @return float + * @throws \InvalidArgumentException + */ + public function calculateRefundedAmount(int $invoiceId, string $filed): float + { + if (empty($filed)) { + throw new \InvalidArgumentException('The field param must be passed'); + } + + $select = $this->getConnection()->select(); + $select->from( + ['credit_memo' => $this->getTable('sales_creditmemo')], + ['total' => new \Zend_Db_Expr("SUM(credit_memo.{$filed})")] + )->where( + "credit_memo.invoice_id = ?", $invoiceId + ); + + return (float) $this->getConnection()->fetchOne($select); + } } From a6099456094105c04b415482d7836ba726000bdb Mon Sep 17 00:00:00 2001 From: Kate Kyzyma <kate@atwix.com> Date: Wed, 23 Dec 2020 16:47:45 +0200 Subject: [PATCH 119/156] Refactoring the test --- ...oductPriceWithDisabledChildProductTest.xml | 104 +++++++++++++----- 1 file changed, 75 insertions(+), 29 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckConfigurableProductPriceWithDisabledChildProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckConfigurableProductPriceWithDisabledChildProductTest.xml index a72af673c009a..f2413a1523394 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckConfigurableProductPriceWithDisabledChildProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckConfigurableProductPriceWithDisabledChildProductTest.xml @@ -124,62 +124,108 @@ </after> <!-- Open Product in Store Front Page --> - <amOnPage url="$$createConfigProduct.sku$$.html" stepKey="openProductInStoreFront"/> - <waitForPageLoad stepKey="waitForProductToLoad"/> + <actionGroup ref="StorefrontOpenProductEntityPageActionGroup" stepKey="openProductInStoreFront"> + <argument name="product" value="$createConfigProduct$"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForProductToLoad"/> <!-- Verify category,Configurable product and initial price --> - <seeElement selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="seeCategoryInFrontPage"/> - <see selector="{{StorefrontProductInfoMainSection.productName}}" userInput="$$createConfigProduct.name$$" stepKey="seeProductNameInStoreFront"/> - <see selector="{{StorefrontProductInfoMainSection.productPrice}}" userInput="$$createConfigChildProduct1.price$$" stepKey="seeInitialPriceInStoreFront"/> + <actionGroup ref="StorefrontAssertCategoryNameIsShownInMenuActionGroup" stepKey="seeCategoryInFrontPage"> + <argument name="categoryName" value="$$createCategory.name$$"/> + </actionGroup> + <actionGroup ref="StorefrontAssertProductNameOnProductPageActionGroup" stepKey="seeProductNameInStoreFront"> + <argument name="productName" value="$$createConfigProduct.name$$"/> + </actionGroup> + <actionGroup ref="StorefrontAssertProductPriceOnProductPageActionGroup" stepKey="seeInitialPriceInStoreFront"> + <argument name="productPrice" value="$$createConfigChildProduct1.price$$"/> + </actionGroup> <actionGroup ref="StorefrontAssertProductSkuOnProductPageActionGroup" stepKey="seeProductSkuInStoreFront"> <argument name="productSku" value="$$createConfigProduct.sku$$"/> </actionGroup> - <see selector="{{StorefrontProductInfoMainSection.productStockStatus}}" userInput="In Stock" stepKey="seeProductStatusInStoreFront"/> + <actionGroup ref="AssertStorefrontProductStockStatusOnProductPageActionGroup" stepKey="seeProductStatusInStoreFront"> + <argument name="productStockStatus" value="In Stock"/> + </actionGroup> <!-- Verify First Child Product attribute option is displayed --> <see selector="{{StorefrontProductInfoMainSection.productOptionSelect($$createConfigProductAttribute.default_value$$)}}" userInput="$$getConfigAttributeOption1.label$$" stepKey="seeOption1"/> <!-- Select product Attribute option1, option2 and option3 and verify changes in the price --> - <selectOption selector="{{StorefrontProductInfoMainSection.productOptionSelect($$createConfigProductAttribute.default_value$$)}}" userInput="$$getConfigAttributeOption1.label$$" stepKey="selectOption1"/> - <see selector="{{StorefrontProductInfoMainSection.productPrice}}" userInput="$$createConfigChildProduct1.price$$" stepKey="seeChildProduct1PriceInStoreFront"/> - <selectOption selector="{{StorefrontProductInfoMainSection.productOptionSelect($$createConfigProductAttribute.default_value$$)}}" userInput="$$getConfigAttributeOption2.label$$" stepKey="selectOption2"/> - <see selector="{{StorefrontProductInfoMainSection.productPrice}}" userInput="$$createConfigChildProduct2.price$$" stepKey="seeChildProduct2PriceInStoreFront"/> - <selectOption selector="{{StorefrontProductInfoMainSection.productOptionSelect($$createConfigProductAttribute.default_value$$)}}" userInput="$$getConfigAttributeOption3.label$$" stepKey="selectOption3"/> - <see selector="{{StorefrontProductInfoMainSection.productPrice}}" userInput="$$createConfigChildProduct3.price$$" stepKey="seeChildProduct3PriceInStoreFront"/> - + <actionGroup ref="StorefrontProductPageSelectDropDownOptionValueActionGroup" stepKey="selectOption1"> + <argument name="attributeLabel" value="$$createConfigProductAttribute.default_value$$"/> + <argument name="optionLabel" value="$$getConfigAttributeOption1.label$$"/> + </actionGroup> + <actionGroup ref="StorefrontAssertProductPriceOnProductPageActionGroup" stepKey="seeChildProduct1PriceInStoreFront"> + <argument name="productPrice" value="$$createConfigChildProduct1.price$$"/> + </actionGroup> + <actionGroup ref="StorefrontProductPageSelectDropDownOptionValueActionGroup" stepKey="selectOption2"> + <argument name="attributeLabel" value="$$createConfigProductAttribute.default_value$$"/> + <argument name="optionLabel" value="$$getConfigAttributeOption2.label$$"/> + </actionGroup> + <actionGroup ref="StorefrontAssertProductPriceOnProductPageActionGroup" stepKey="seeChildProduct2PriceInStoreFront"> + <argument name="productPrice" value="$$createConfigChildProduct2.price$$"/> + </actionGroup> + <actionGroup ref="StorefrontProductPageSelectDropDownOptionValueActionGroup" stepKey="selectOption3"> + <argument name="attributeLabel" value="$$createConfigProductAttribute.default_value$$"/> + <argument name="optionLabel" value="$$getConfigAttributeOption3.label$$"/> + </actionGroup> + <actionGroup ref="StorefrontAssertProductPriceOnProductPageActionGroup" stepKey="seeChildProduct3PriceInStoreFront"> + <argument name="productPrice" value="$$createConfigChildProduct3.price$$"/> + </actionGroup> <!-- Open Product Index Page and Filter First Child product --> - <actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="navigateToProductIndex"/> - <actionGroup ref="FilterProductGridBySkuActionGroup" stepKey="filterProduct"> - <argument name="product" value="ApiSimpleOne"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="navigateToProductIndex"/> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="filterProduct"/> + <actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="selectFirstRow"> + <argument name="productId" value="$$createConfigChildProduct1.id$$"/> </actionGroup> - <click selector="{{AdminProductGridFilterSection.nthRow('1')}}" stepKey="selectFirstRow"/> <waitForPageLoad stepKey="waitForProductPageToLoad"/> <!-- Disable the product --> - <click selector="{{AdminProductFormSection.enableProductLabel}}" stepKey="disableProduct"/> + <actionGroup ref="ToggleProductEnabledActionGroup" stepKey="disableProduct"/> <actionGroup ref="AdminProductFormSaveActionGroup" stepKey="clickOnSaveButton"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the product." stepKey="messageYouSavedTheProductIsShown"/> + <actionGroup ref="AssertMessageInAdminPanelActionGroup" stepKey="messageYouSavedTheProductIsShown"> + <argument name="message" value="You saved the product."/> + </actionGroup> <!-- Open Product Store Front Page --> - <amOnPage url="$$createConfigProduct.sku$$.html" stepKey="openProductInStoreFront1"/> - <waitForPageLoad stepKey="waitForProductToLoad1"/> + <actionGroup ref="StorefrontOpenProductEntityPageActionGroup" stepKey="openProductInStoreFront1"> + <argument name="product" value="$createConfigProduct$"/> + </actionGroup> + <comment userInput="Comment is added to preserve the step key for backward compatibility" stepKey="waitForProductToLoad1"/> <!-- Verify category,configurable product and updated price --> - <seeElement selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="seeCategoryInFrontPage1"/> - <see selector="{{StorefrontProductInfoMainSection.productName}}" userInput="$$createConfigProduct.name$$" stepKey="seeProductNameInStoreFront1"/> - <see selector="{{StorefrontProductInfoMainSection.productPrice}}" userInput="$$createConfigChildProduct2.price$$" stepKey="seeUpdatedProductPriceInStoreFront"/> + <actionGroup ref="StorefrontAssertCategoryNameIsShownInMenuActionGroup" stepKey="seeCategoryInFrontPage1"> + <argument name="categoryName" value="$$createCategory.name$$"/> + </actionGroup> + <actionGroup ref="StorefrontAssertProductNameOnProductPageActionGroup" stepKey="seeProductNameInStoreFront1"> + <argument name="productName" value="$$createConfigProduct.name$$"/> + </actionGroup> + <actionGroup ref="StorefrontAssertProductPriceOnProductPageActionGroup" stepKey="seeUpdatedProductPriceInStoreFront"> + <argument name="productPrice" value="$$createConfigChildProduct2.price$$"/> + </actionGroup> <actionGroup ref="StorefrontAssertProductSkuOnProductPageActionGroup" stepKey="seeProductSkuInStoreFront1"> <argument name="productSku" value="$$createConfigProduct.sku$$"/> </actionGroup> - <see selector="{{StorefrontProductInfoMainSection.productStockStatus}}" userInput="In Stock" stepKey="seeProductStatusInStoreFront1"/> + <actionGroup ref="AssertStorefrontProductStockStatusOnProductPageActionGroup" stepKey="seeProductStatusInStoreFront1"> + <argument name="productStockStatus" value="In Stock"/> + </actionGroup> <!-- Verify product Attribute Option1 is not displayed --> <dontSee selector="{{StorefrontProductInfoMainSection.productOptionSelect($$createConfigProductAttribute.default_value$$)}}" userInput="$$getConfigAttributeOption1.label$$" stepKey="dontSeeOption1"/> <!--Select product Attribute option2 and option3 and verify changes in the price --> - <selectOption selector="{{StorefrontProductInfoMainSection.productOptionSelect($$createConfigProductAttribute.default_value$$)}}" userInput="$$getConfigAttributeOption2.label$$" stepKey="selectTheOption2"/> - <see selector="{{StorefrontProductInfoMainSection.productPrice}}" userInput="$$createConfigChildProduct2.price$$" stepKey="seeSecondChildProductPriceInStoreFront"/> - <selectOption selector="{{StorefrontProductInfoMainSection.productOptionSelect($$createConfigProductAttribute.default_value$$)}}" userInput="$$getConfigAttributeOption3.label$$" stepKey="selectTheOption3"/> - <see selector="{{StorefrontProductInfoMainSection.productPrice}}" userInput="$$createConfigChildProduct3.price$$" stepKey="seeThirdProductPriceInStoreFront"/> + <actionGroup ref="StorefrontProductPageSelectDropDownOptionValueActionGroup" stepKey="selectTheOption2"> + <argument name="attributeLabel" value="$$createConfigProductAttribute.default_value$$"/> + <argument name="optionLabel" value="$$getConfigAttributeOption2.label$$"/> + </actionGroup> + <actionGroup ref="StorefrontAssertProductPriceOnProductPageActionGroup" stepKey="seeSecondChildProductPriceInStoreFront"> + <argument name="productPrice" value="$$createConfigChildProduct2.price$$"/> + </actionGroup> + <actionGroup ref="StorefrontProductPageSelectDropDownOptionValueActionGroup" stepKey="selectTheOption3"> + <argument name="attributeLabel" value="$$createConfigProductAttribute.default_value$$"/> + <argument name="optionLabel" value="$$getConfigAttributeOption3.label$$"/> + </actionGroup> + <actionGroup ref="StorefrontAssertProductPriceOnProductPageActionGroup" stepKey="seeThirdProductPriceInStoreFront"> + <argument name="productPrice" value="$$createConfigChildProduct3.price$$"/> + </actionGroup> </test> </tests> From e07d328c1f88e885ac6239d4689afcee09859394 Mon Sep 17 00:00:00 2001 From: tuna <ladiesman9x@gmail.com> Date: Fri, 18 Dec 2020 12:56:09 +0700 Subject: [PATCH 120/156] Update varnish 6 vcl config update --- app/code/Magento/PageCache/etc/varnish6.vcl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/PageCache/etc/varnish6.vcl b/app/code/Magento/PageCache/etc/varnish6.vcl index bce89fe263573..cc381baaf313a 100644 --- a/app/code/Magento/PageCache/etc/varnish6.vcl +++ b/app/code/Magento/PageCache/etc/varnish6.vcl @@ -62,13 +62,13 @@ sub vcl_recv { return (pass); } - # Bypass shopping cart and checkout - if (req.url ~ "/checkout") { + # Bypass customer, shopping cart, checkout + if (req.url ~ "/customer" || req.url ~ "/checkout") { return (pass); } # Bypass health check requests - if (req.url ~ "/pub/health_check.php") { + if (req.url ~ "^/(pub/)?(health_check.php)$") { return (pass); } From 1f04b0ad5871ddd04230636daa0f9d6d08a8b90c Mon Sep 17 00:00:00 2001 From: Anna Pak <a.pak@atwix.com> Date: Wed, 23 Dec 2020 18:27:38 +0200 Subject: [PATCH 121/156] Updated with StorefrontSelectCustomizeAndAddToTheCartButtonActionGroup --- .../Test/DeleteBundleDynamicProductFromShoppingCartTest.xml | 2 +- .../Mftf/Test/DeleteBundleFixedProductFromShoppingCartTest.xml | 2 +- .../Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml | 2 +- .../Mftf/Test/StorefrontCheckoutDisabledBundleProductTest.xml | 2 +- ...orefrontInstantPurchaseFunctionalityNegativeScenarioTest.xml | 2 +- .../Mftf/Test/StorefrontInstantPurchaseFunctionalityTest.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleDynamicProductFromShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleDynamicProductFromShoppingCartTest.xml index 96a236336993f..a30f118bd6207 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleDynamicProductFromShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleDynamicProductFromShoppingCartTest.xml @@ -56,7 +56,7 @@ <waitForPageLoad stepKey="waitForPageLoad"/> <!-- Add product to the cart --> - <click selector="{{StorefrontBundleProductActionSection.customizeAndAddToCartButton}}" stepKey="clickCustomizeAndAddToCart"/> + <actionGroup ref="StorefrontSelectCustomizeAndAddToTheCartButtonActionGroup" stepKey="clickCustomizeAndAddToCart"/> <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addProductToCart"> <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 b64b59ef6109c..d1f452896c84f 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleFixedProductFromShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleFixedProductFromShoppingCartTest.xml @@ -48,7 +48,7 @@ <waitForPageLoad stepKey="waitForPageLoad"/> <!-- Add product to the cart --> - <click selector="{{StorefrontBundleProductActionSection.customizeAndAddToCartButton}}" stepKey="clickCustomizeAndAddToCart"/> + <actionGroup ref="StorefrontSelectCustomizeAndAddToTheCartButtonActionGroup" stepKey="clickCustomizeAndAddToCart"/> <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addProductToCart"> <argument name="productName" value="$$createFixedBundleProduct.name$$"/> </actionGroup> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml index 38e2203b45258..73a2e4757e954 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml @@ -159,7 +159,7 @@ <!-- Add Bundle Product to cart --> <amOnPage url="{{StorefrontProductPage.url($$createFixedBundleProduct.custom_attributes[url_key]$$)}}" stepKey="navigateToBundleProductPage"/> <waitForPageLoad stepKey="waitForFixedBundleProductPageLoad"/> - <click selector="{{StorefrontBundleProductActionSection.customizeAndAddToCartButton}}" stepKey="clickCustomizeAndAddToCart"/> + <actionGroup ref="StorefrontSelectCustomizeAndAddToTheCartButtonActionGroup" stepKey="clickCustomizeAndAddToCart"/> <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFixedBundleProductFromStorefrontProductPage"> <argument name="productName" value="$$createFixedBundleProduct.name$$"/> </actionGroup> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutDisabledBundleProductTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutDisabledBundleProductTest.xml index f16f577a4088c..3aa93d72571f9 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutDisabledBundleProductTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutDisabledBundleProductTest.xml @@ -59,7 +59,7 @@ <amOnPage url="{{StorefrontProductPage.url($$createBundleDynamicProduct.custom_attributes[url_key]$$)}}" stepKey="navigateToProductPage"/> <waitForPageLoad stepKey="waitForPageLoad"/> <!-- Add bundle product to the cart --> - <click selector="{{StorefrontBundleProductActionSection.customizeAndAddToCartButton}}" stepKey="clickCustomizeAndAddToCart"/> + <actionGroup ref="StorefrontSelectCustomizeAndAddToTheCartButtonActionGroup" stepKey="clickCustomizeAndAddToCart"/> <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addProductToCart"> <argument name="productName" value="$$createBundleDynamicProduct.name$$"/> </actionGroup> diff --git a/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityNegativeScenarioTest.xml b/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityNegativeScenarioTest.xml index ecbff39807f30..c81c6d36786eb 100644 --- a/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityNegativeScenarioTest.xml +++ b/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityNegativeScenarioTest.xml @@ -129,7 +129,7 @@ <argument name="product" value="$createBundleProduct$"/> </actionGroup> <waitForElementVisible selector="{{StorefrontBundleProductActionSection.customizeAndAddToCartButton}}" stepKey="waitForCustomizeAndAddToCartButton"/> - <click selector="{{StorefrontBundleProductActionSection.customizeAndAddToCartButton}}" stepKey="clickCustomizeAndAddToCart"/> + <actionGroup ref="StorefrontSelectCustomizeAndAddToTheCartButtonActionGroup" stepKey="clickCustomizeAndAddToCart"/> <waitForPageLoad stepKey="waitForBundleProductPageLoad"/> <dontSeeElement selector="{{StorefrontInstantPurchaseSection.instantPurchaseButton}}" stepKey="dontSeeButtonOnBundleProductPage"/> <!-- Grouped product --> diff --git a/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityTest.xml b/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityTest.xml index 59697bb6f5bdf..865852c10acfd 100644 --- a/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityTest.xml +++ b/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityTest.xml @@ -109,7 +109,7 @@ <!-- Bundle Product --> <amOnPage url="{{StorefrontProductPage.url($createBundleProduct.custom_attributes[url_key]$)}}" stepKey="openBundleProductPage"/> <waitForElementVisible selector="{{StorefrontBundleProductActionSection.customizeAndAddToCartButton}}" stepKey="waitForCustomizeAndAddToCartButton"/> - <click selector="{{StorefrontBundleProductActionSection.customizeAndAddToCartButton}}" stepKey="clickCustomizeAndAddToCart"/> + <actionGroup ref="StorefrontSelectCustomizeAndAddToTheCartButtonActionGroup" stepKey="clickCustomizeAndAddToCart"/> <waitForElementVisible selector="{{StorefrontInstantPurchaseSection.instantPurchaseButton}}" stepKey="waitForButtonOnBundleProductPage"/> <!-- Grouped product --> <amOnPage url="{{StorefrontProductPage.url($createGroupedProduct.custom_attributes[url_key]$)}}" stepKey="openGroupedProductPage"/> From 64d2fb97a832593ff0efdd6e32c0770d73b68140 Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Wed, 23 Dec 2020 21:26:43 +0200 Subject: [PATCH 122/156] MC-39600: Create automated test for: "Change category/product url rewrite suffix in configurations" --- .../Catalog/Url/Rewrite/SuffixTest.php | 287 ++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Model/System/Config/Backend/Catalog/Url/Rewrite/SuffixTest.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/System/Config/Backend/Catalog/Url/Rewrite/SuffixTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/System/Config/Backend/Catalog/Url/Rewrite/SuffixTest.php new file mode 100644 index 0000000000000..6553dffb04df6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/System/Config/Backend/Catalog/Url/Rewrite/SuffixTest.php @@ -0,0 +1,287 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Model\System\Config\Backend\Catalog\Url\Rewrite; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator; +use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator; +use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator; +use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; +use Magento\Framework\App\Cache\Type\Block; +use Magento\Framework\App\Cache\Type\Collection; +use Magento\Framework\App\Cache\TypeListInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\ObjectManagerInterface; +use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\UrlRewrite\Model\Storage\DbStorage; +use PHPUnit\Framework\TestCase; + +/** + * Class checks url suffix config save behaviour + * + * @see \Magento\Catalog\Model\System\Config\Backend\Catalog\Url\Rewrite\Suffix + * + * @magentoAppArea adminhtml + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled + */ +class SuffixTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Suffix */ + private $model; + + /** @var DbStorage */ + private $urlFinder; + + /** @var StoreManagerInterface */ + private $storeManager; + + /** @var TypeListInterface */ + private $typeList; + + /** @var ScopeConfigInterface */ + private $scopeConfig; + + /** @var ProductRepositoryInterface */ + private $productRepository; + + /** @var int */ + private $defaultStoreId; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->model = $this->objectManager->get(Suffix::class); + $this->urlFinder = $this->objectManager->get(DbStorage::class); + $this->storeManager = $this->objectManager->get(StoreManagerInterface::class); + $this->typeList = $this->objectManager->get(TypeListInterface::class); + $this->scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + $this->productRepository->cleanCache(); + $this->defaultStoreId = (int)$this->storeManager->getStore('default')->getId(); + } + + /** + * @return void + */ + public function testSaveWithError(): void + { + $this->expectException(LocalizedException::class); + $this->expectErrorMessage((string)__('Anchor symbol (#) is not supported in url rewrite suffix.')); + $this->model->setValue('.html#'); + $this->model->beforeSave(); + } + + /** + * @dataProvider wrongValuesProvider + * + * @magentoDataFixture Magento/Catalog/_files/second_product_simple.php + * + * @param array $data + * @return void + */ + public function testSaveWithWrongData(array $data): void + { + $productId = (int)$this->productRepository->get('simple2')->getId(); + $this->model->addData($data); + $this->model->afterSave(); + $this->assertRewrite( + $this->scopeConfig->getValue(ProductUrlPathGenerator::XML_PATH_PRODUCT_URL_SUFFIX), + [ + 'entity_type' => ProductUrlRewriteGenerator::ENTITY_TYPE, + 'entity_id' => $productId, + 'store_id' => $this->defaultStoreId, + ] + ); + } + + /** + * @return array + */ + public function wrongValuesProvider(): array + { + return [ + 'with_wrong_path' => [ + ['path' => 'wrong_path', 'value' => 'some_test_value'], + ], + 'with_null_value' => [ + ['path' => ProductUrlPathGenerator::XML_PATH_PRODUCT_URL_SUFFIX, 'value' => null], + ], + ]; + } + + /** + * @magentoDbIsolation disabled + * + * @magentoDataFixture Magento/Catalog/_files/product_multistore_different_short_description.php + * + * @return void + */ + public function testSaveInStoreScope(): void + { + $productId = $this->productRepository->get('simple-different-short-description')->getId(); + $newSuffix = 'some_test_value_for_store'; + $storeId = $this->storeManager->getStore('fixturestore')->getId(); + $this->model->addData([ + 'path' => ProductUrlPathGenerator::XML_PATH_PRODUCT_URL_SUFFIX, + 'value' => $newSuffix, + 'scope' => ScopeInterface::SCOPE_STORES, + 'scope_id' => $storeId, + ]); + $this->model->afterSave(); + $this->assertRewrite( + $this->scopeConfig->getValue(ProductUrlPathGenerator::XML_PATH_PRODUCT_URL_SUFFIX), + [ + 'entity_type' => ProductUrlRewriteGenerator::ENTITY_TYPE, + 'entity_id' => $productId, + 'store_id' => $this->defaultStoreId, + ] + ); + $this->assertRewrite( + $newSuffix, + [ + 'entity_type' => ProductUrlRewriteGenerator::ENTITY_TYPE, + 'entity_id' => $productId, + 'store_id' => $storeId, + ] + ); + } + + /** + * @magentoDbIsolation disabled + * + * @magentoDataFixture Magento/Catalog/_files/product_two_websites.php + * + * @return void + */ + public function testSaveInWebsiteScope(): void + { + $productId = (int)$this->productRepository->get('simple-on-two-websites')->getId(); + $newSuffix = 'some_test_value_for_website'; + $website = $this->storeManager->getWebsite('test'); + $this->model->addData([ + 'path' => ProductUrlPathGenerator::XML_PATH_PRODUCT_URL_SUFFIX, + 'value' => $newSuffix, + 'scope' => ScopeInterface::SCOPE_WEBSITES, + 'scope_id' => $website->getId(), + ]); + $this->model->afterSave(); + $this->assertRewrite( + $this->scopeConfig->getValue(ProductUrlPathGenerator::XML_PATH_PRODUCT_URL_SUFFIX), + [ + 'entity_type' => ProductUrlRewriteGenerator::ENTITY_TYPE, + 'entity_id' => $productId, + 'store_id' => $this->defaultStoreId, + ] + ); + $this->assertRewrite( + $newSuffix, + [ + 'entity_type' => ProductUrlRewriteGenerator::ENTITY_TYPE, + 'entity_id' => $productId, + 'store_id' => $website->getStoreIds(), + ] + ); + } + + /** + * @magentoDataFixture Magento/Catalog/_files/second_product_simple.php + * + * @magentoConfigFixture default_store catalog/seo/product_url_suffix .html_default + * + * @return void + */ + public function testSaveDefaultScopeWithOverrideStoreScope(): void + { + $productId = (int)$this->productRepository->get('simple2')->getId(); + $newSuffix = 'some_test_value'; + $this->model->addData([ + 'path' => ProductUrlPathGenerator::XML_PATH_PRODUCT_URL_SUFFIX, + 'value' => $newSuffix, + ]); + $this->model->afterSave(); + $this->assertRewrite( + '.html_default', + [ + 'entity_type' => ProductUrlRewriteGenerator::ENTITY_TYPE, + 'entity_id' => $productId, + 'store_id' => $this->defaultStoreId, + ] + ); + } + + /** + * @magentoDataFixture Magento/Catalog/_files/category.php + * + * @return void + */ + public function testSaveCategorySuffix(): void + { + $this->model->addData(['path' => CategoryUrlPathGenerator::XML_PATH_CATEGORY_URL_SUFFIX, 'value' => null]); + $this->model->afterSave(); + $this->assertRewrite('.html', ['entity_type' => CategoryUrlRewriteGenerator::ENTITY_TYPE]); + $this->checkIsCacheInvalidated(); + } + + /** + * @return void + */ + public function testDeleteCategorySuffix(): void + { + $this->model->addData( + ['path' => CategoryUrlPathGenerator::XML_PATH_CATEGORY_URL_SUFFIX, 'value' => 'test_value'] + ); + $this->model->afterDeleteCommit(); + $this->checkIsCacheInvalidated(); + } + + /** + * Check that provided cache types are invalidated + * + * @param array $cacheTypes + * @return void + */ + private function checkIsCacheInvalidated( + array $cacheTypes = [Block::TYPE_IDENTIFIER, Collection::TYPE_IDENTIFIER] + ): void { + $types = $this->typeList->getTypes(); + + foreach ($cacheTypes as $type) { + $this->assertNotNull($types[$type]); + $this->assertEquals(0, $types[$type]->getStatus()); + } + } + + /** + * Assert url rewrite rewrite + * + * @param string $expectedSuffix + * @param array $data + * @return void + */ + private function assertRewrite(string $expectedSuffix, array $data) + { + $rewrite = $this->urlFinder->findOneByData($data); + $this->assertNotNull($rewrite); + $this->assertTrue( + substr($rewrite->getRequestPath(), -strlen($expectedSuffix)) === $expectedSuffix, + 'The url rewrite suffix does not match expected value' + ); + } +} From d2dd4ae4289ad572347b7397e9d2c11780d4aae0 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@adobe.com> Date: Wed, 23 Dec 2020 13:31:42 -0600 Subject: [PATCH 123/156] Revert removed step from the test --- .../Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml index 16b20abc0a583..739d5f0d40f61 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml @@ -62,6 +62,7 @@ <!-- Place an order from Storefront as a Guest --> <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad1"/> + <comment userInput="Adding the comment to replace action for preserving Backward Compatibility" stepKey="hoverOverProduct"/> <actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/> <actionGroup ref="StorefrontClickAddToCartButtonActionGroup" stepKey="addToCart"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductToAdd"/> From ae96ab2081185de784b282408afa7d84a28c9635 Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Thu, 24 Dec 2020 13:10:32 +0200 Subject: [PATCH 124/156] MC-40078: Create automated test for: "Create attribute without attribute code" --- .../Product/Attribute/RepositoryTest.php | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/RepositoryTest.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/RepositoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/RepositoryTest.php new file mode 100644 index 0000000000000..94a5b52b03c5f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/RepositoryTest.php @@ -0,0 +1,145 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Model\Product\Attribute; + +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Catalog\Api\Data\ProductAttributeInterfaceFactory; +use Magento\Catalog\Setup\CategorySetup; +use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface; +use Magento\Framework\Exception\InputException; +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Checks product attribute save behaviour. + * + * @see \Magento\Catalog\Model\Product\Attribute\Repository + * + * @magentoDbIsolation enabled + */ +class RepositoryTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Repository */ + private $repository; + + /** @var ProductAttributeInterfaceFactory */ + private $attributeFactory; + + /** @var ProductAttributeInterface */ + private $createdAttribute; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->repository = $this->objectManager->get(Repository::class); + $this->attributeFactory = $this->objectManager->get(ProductAttributeInterfaceFactory::class); + } + + /** + * @inheritdoc + */ + protected function tearDown(): void + { + if ($this->createdAttribute instanceof ProductAttributeInterface) { + $this->repository->delete($this->createdAttribute); + } + + parent::tearDown(); + } + + /** + * @return void + */ + public function testSaveWithoutAttributeCode(): void + { + $this->createdAttribute = $this->saveAttributeWithData( + $this->hydrateData(['frontend_label' => 'Boolean Attribute']) + ); + $this->assertEquals('boolean_attribute', $this->createdAttribute->getAttributeCode()); + } + + /** + * @return void + */ + public function testSaveWithoutAttributeAndInvalidLabelCode(): void + { + $this->createdAttribute = $this->saveAttributeWithData($this->hydrateData(['frontend_label' => '/$&!/'])); + $this->assertStringStartsWith('attr_', $this->createdAttribute->getAttributeCode()); + } + + /** + * @dataProvider errorProvider + * + * @param string $fieldName + * @param string $fieldValue + * @return void + */ + public function testSaveWithInvalidCode(string $fieldName, string $fieldValue): void + { + $this->expectExceptionObject(InputException::invalidFieldValue($fieldName, $fieldValue)); + $this->createdAttribute = $this->saveAttributeWithData($this->hydrateData([$fieldName => $fieldValue])); + } + + /** + * @return array + */ + public function errorProvider():array + { + return [ + 'with_invalid_attribute_code' => [ + 'field_name' => 'attribute_code', + 'field_value' => '****', + ], + 'with_invalid_frontend_input' => [ + 'field_name' => 'frontend_input', + 'field_value' => 'invalid_input', + ], + ]; + } + + /** + * Save product attribute with data + * + * @param array $data + * @return ProductAttributeInterface + */ + private function saveAttributeWithData(array $data): ProductAttributeInterface + { + $attribute = $this->attributeFactory->create(); + $attribute->addData($data); + + return $this->repository->save($attribute); + } + + /** + * Hydrate data + * + * @param array $data + * @return array + */ + private function hydrateData(array $data): array + { + $defaultData = [ + 'entity_type_id' => CategorySetup::CATALOG_PRODUCT_ENTITY_TYPE_ID, + 'is_global' => ScopedAttributeInterface::SCOPE_GLOBAL, + 'frontend_input' => 'boolean', + 'frontend_label' => 'default label', + ]; + + return array_merge($defaultData, $data); + } +} From 06ca9b27abc155a844511d1a02fba8af13ac6dc2 Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Thu, 24 Dec 2020 13:14:29 +0200 Subject: [PATCH 125/156] MC-39600: Create automated test for: "Change category/product url rewrite suffix in configurations" --- .../System/Config/Backend/Catalog/Url/Rewrite/SuffixTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/System/Config/Backend/Catalog/Url/Rewrite/SuffixTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/System/Config/Backend/Catalog/Url/Rewrite/SuffixTest.php index 6553dffb04df6..9979e8cd6ea68 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/System/Config/Backend/Catalog/Url/Rewrite/SuffixTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/System/Config/Backend/Catalog/Url/Rewrite/SuffixTest.php @@ -275,7 +275,7 @@ private function checkIsCacheInvalidated( * @param array $data * @return void */ - private function assertRewrite(string $expectedSuffix, array $data) + private function assertRewrite(string $expectedSuffix, array $data): void { $rewrite = $this->urlFinder->findOneByData($data); $this->assertNotNull($rewrite); From 772d1785ca60fd9a3c2c36f9779b14a01e3bc300 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Thu, 24 Dec 2020 16:49:14 +0200 Subject: [PATCH 126/156] MC-36683: [Cloud]Generating companies... Could not save company --- setup/performance-toolkit/config/di.xml | 2 + .../Mail/Template/TransportBuilderMock.php | 28 ++++++++++++ .../Framework/Mail/TransportInterfaceMock.php | 45 +++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 setup/src/Magento/Setup/Framework/Mail/Template/TransportBuilderMock.php create mode 100644 setup/src/Magento/Setup/Framework/Mail/TransportInterfaceMock.php diff --git a/setup/performance-toolkit/config/di.xml b/setup/performance-toolkit/config/di.xml index 0b1175b0cd94c..a293edcb216af 100644 --- a/setup/performance-toolkit/config/di.xml +++ b/setup/performance-toolkit/config/di.xml @@ -6,4 +6,6 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <preference for="Magento\Framework\Mail\TransportInterface" type="Magento\Setup\Framework\Mail\TransportInterfaceMock"/> + <preference for="Magento\Framework\Mail\Template\TransportBuilder" type="Magento\Setup\Framework\Mail\Template\TransportBuilderMock"/> </config> diff --git a/setup/src/Magento/Setup/Framework/Mail/Template/TransportBuilderMock.php b/setup/src/Magento/Setup/Framework/Mail/Template/TransportBuilderMock.php new file mode 100644 index 0000000000000..2791487c37ba5 --- /dev/null +++ b/setup/src/Magento/Setup/Framework/Mail/Template/TransportBuilderMock.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Setup\Framework\Mail\Template; + +use Magento\Framework\Mail\Template\TransportBuilder; +use Magento\Setup\Framework\Mail\TransportInterfaceMock; + +/** + * Mock for mail template transport builder. + */ +class TransportBuilderMock extends TransportBuilder +{ + /** + * @inheritDoc + */ + public function getTransport() + { + $this->prepareMessage(); + $this->reset(); + + return new TransportInterfaceMock($this->message); + } +} diff --git a/setup/src/Magento/Setup/Framework/Mail/TransportInterfaceMock.php b/setup/src/Magento/Setup/Framework/Mail/TransportInterfaceMock.php new file mode 100644 index 0000000000000..64abddc053504 --- /dev/null +++ b/setup/src/Magento/Setup/Framework/Mail/TransportInterfaceMock.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Setup\Framework\Mail; + +use Magento\Framework\Mail\EmailMessageInterface; +use Magento\Framework\Mail\TransportInterface; + +/** + * Mock for mail transport. + */ +class TransportInterfaceMock implements TransportInterface +{ + /** + * @var EmailMessageInterface|null + */ + private $message; + + /** + * @param EmailMessageInterface|null $message + */ + public function __construct($message = null) + { + $this->message = $message; + } + + /** + * @inheritDoc + */ + public function sendMessage() + { + } + + /** + * @inheritDoc + */ + public function getMessage() + { + return $this->message; + } +} From fe4b27b89a4e4527a34d4fceb7d690ca1b51c3e6 Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Thu, 24 Dec 2020 17:04:17 +0200 Subject: [PATCH 127/156] MC-40078: Create automated test for: "Create attribute without attribute code" --- .../Catalog/Model/Product/Attribute/RepositoryTest.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/RepositoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/RepositoryTest.php index 94a5b52b03c5f..7430ebf72f8fb 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/RepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/RepositoryTest.php @@ -9,6 +9,7 @@ use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Catalog\Api\Data\ProductAttributeInterfaceFactory; +use Magento\Catalog\Api\ProductAttributeRepositoryInterface; use Magento\Catalog\Setup\CategorySetup; use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface; use Magento\Framework\Exception\InputException; @@ -28,7 +29,7 @@ class RepositoryTest extends TestCase /** @var ObjectManagerInterface */ private $objectManager; - /** @var Repository */ + /** @var ProductAttributeRepositoryInterface */ private $repository; /** @var ProductAttributeInterfaceFactory */ @@ -45,7 +46,7 @@ protected function setUp(): void parent::setUp(); $this->objectManager = Bootstrap::getObjectManager(); - $this->repository = $this->objectManager->get(Repository::class); + $this->repository = $this->objectManager->get(ProductAttributeRepositoryInterface::class); $this->attributeFactory = $this->objectManager->get(ProductAttributeInterfaceFactory::class); } @@ -97,7 +98,7 @@ public function testSaveWithInvalidCode(string $fieldName, string $fieldValue): /** * @return array */ - public function errorProvider():array + public function errorProvider(): array { return [ 'with_invalid_attribute_code' => [ From 2c80277103eab5b9c497d6c6ef32e6103ef70b32 Mon Sep 17 00:00:00 2001 From: Roman Zhupanyn <roma.dj.elf@gmail.com> Date: Thu, 24 Dec 2020 18:19:13 +0200 Subject: [PATCH 128/156] MC-39711: Create automated test for: "Filter products in admin grid" --- .../AddQuantityFilterToCollectionTest.php | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/CatalogInventory/Ui/DataProvider/Product/AddQuantityFilterToCollectionTest.php diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Ui/DataProvider/Product/AddQuantityFilterToCollectionTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Ui/DataProvider/Product/AddQuantityFilterToCollectionTest.php new file mode 100644 index 0000000000000..f0d87f06514f1 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Ui/DataProvider/Product/AddQuantityFilterToCollectionTest.php @@ -0,0 +1,133 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogInventory\Ui\DataProvider\Product; + +use Magento\Framework\App\RequestInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Checks that the product quantity filter is working correctly + * + * @magentoAppArea adminhtml + */ +class AddQuantityFilterToCollectionTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var UiComponentFactory */ + private $componentFactory; + + /** @var RequestInterface */ + private $request; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->request = $this->objectManager->get(RequestInterface::class); + $this->componentFactory = $this->objectManager->get(UiComponentFactory::class); + } + + /** + * @dataProvider quantityFilterProvider + * @magentoDataFixture Magento/Catalog/_files/multiple_products.php + * @param array $filter + * @param array $expectedProducts + * @return void + */ + public function testQuantityFilter(array $filter, array $expectedProducts): void + { + $this->request->setParams([ContextInterface::FILTER_VAR => $filter]); + $dataProviderData = $this->getComponentProvidedData('product_listing'); + $actualProducts = array_column($dataProviderData['items'], 'sku'); + $this->assertEquals($expectedProducts, $actualProducts, 'Expected products do not match actual products!'); + } + + /** + * Data provider for testQuantityFilter + * + * @return array + */ + public function quantityFilterProvider(): array + { + return [ + 'from' => [ + 'filter' => [ + 'qty' => [ + 'from' => 100, + ], + ], + 'expected_products' => [ + 'simple1', + 'simple3', + ], + ], + 'to' => [ + 'filter' => [ + 'qty' => [ + 'to' => 100, + ], + ], + 'expected_products' => [ + 'simple1', + 'simple2', + ], + ], + 'both' => [ + 'filter' => [ + 'qty' => [ + 'from' => 60, + 'to' => 130, + ], + ], + 'expected_products' => [ + 'simple1', + ], + ], + ]; + } + + /** + * Call prepare method in the child components + * + * @param UiComponentInterface $component + * @return void + */ + private function prepareChildComponents(UiComponentInterface $component): void + { + foreach ($component->getChildComponents() as $child) { + $this->prepareChildComponents($child); + } + + $component->prepare(); + } + + /** + * Get component provided data + * + * @param string $namespace + * @return array + */ + private function getComponentProvidedData(string $namespace): array + { + $component = $this->componentFactory->create($namespace); + $this->prepareChildComponents($component); + + return $component->getContext()->getDataProvider()->getData(); + } +} From 57e23c6fdcc2c4232f72fe2d5361c82b47a7a7d4 Mon Sep 17 00:00:00 2001 From: Sergiy Vasiutynskyi <s.vasiutynskyi@atwix.com> Date: Fri, 25 Dec 2020 13:32:35 +0200 Subject: [PATCH 129/156] Updated value of CliIndexerReindexActionGroup action for failed test --- .../Test/ProductAvailableAfterEnablingSubCategoriesTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml index b5980cf977791..f7e35f1503a12 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml @@ -50,7 +50,7 @@ <!--Run re-index task--> <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value="cataloginventory_stock"/> + <argument name="indices" value="cataloginventory_stock catalog_product_price"/> </actionGroup> <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="goToHomepage"/> From 9ca51cd1f92bc058a112f02fe85f6f4838261ba2 Mon Sep 17 00:00:00 2001 From: Sergiy Vasiutynskyi <s.vasiutynskyi@atwix.com> Date: Fri, 25 Dec 2020 17:03:44 +0200 Subject: [PATCH 130/156] Updated value of CliIndexerReindexActionGroup action for failed test --- .../Test/ProductAvailableAfterEnablingSubCategoriesTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml index f7e35f1503a12..654dc727b24ca 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml @@ -50,7 +50,7 @@ <!--Run re-index task--> <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value="cataloginventory_stock catalog_product_price"/> + <argument name="indices" value="catalog_product_price"/> </actionGroup> <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="goToHomepage"/> From f543cedd3c02ee717e23c22b833e2717566217a6 Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Mon, 28 Dec 2020 10:55:29 +0200 Subject: [PATCH 131/156] MC-39575: Create automated test for "Apply visual swatch attribute filter on layered navigation" --- .../Configurable/Listing/ConfigurableTest.php | 115 ++++++++++++++++++ .../configurable_product_with_images.php | 41 +++++++ ...figurable_product_with_images_rollback.php | 15 +++ 3 files changed, 171 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/Configurable/Listing/ConfigurableTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Swatches/_files/configurable_product_with_images.php create mode 100644 dev/tests/integration/testsuite/Magento/Swatches/_files/configurable_product_with_images_rollback.php diff --git a/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/Configurable/Listing/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/Configurable/Listing/ConfigurableTest.php new file mode 100644 index 0000000000000..f2d254af85c94 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/Configurable/Listing/ConfigurableTest.php @@ -0,0 +1,115 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Swatches\Block\Product\Renderer\Configurable\Listing; + +use Magento\Catalog\Api\ProductAttributeRepositoryInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Module\Manager; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Framework\View\LayoutInterface; +use Magento\Swatches\Block\Product\Renderer\Listing\Configurable; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Tests for configurable products options block with swatch attribute. + * + * @magentoDbIsolation enabled + * @magentoAppArea frontend + */ +class ConfigurableTest extends TestCase +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @var SerializerInterface + */ + private $serializer; + + /** + * @var Configurable + */ + private $block; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @var ProductAttributeRepositoryInterface + */ + private $productAttributeRepository; + + /** + * @var RequestInterface + */ + private $request; + + /** + * @inheritdoc + */ + public static function setUpBeforeClass(): void + { + $objectManager = Bootstrap::getObjectManager(); + /** @var Manager $moduleManager */ + $moduleManager = $objectManager->get(Manager::class); + if (!$moduleManager->isEnabled('Magento_Catalog')) { + self::markTestSkipped('Magento_Catalog module disabled.'); + } + } + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->serializer = $this->objectManager->get(SerializerInterface::class); + $this->productAttributeRepository = $this->objectManager->get(ProductAttributeRepositoryInterface::class); + $this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + $this->productRepository->cleanCache(); + $this->block = $this->objectManager->get(LayoutInterface::class)->createBlock(Configurable::class); + $this->request = $this->objectManager->get(RequestInterface::class); + $this->request->clearParams(); + } + + /** + * @inheritdoc + */ + protected function tearDown(): void + { + $this->request->clearParams(); + + parent::tearDown(); + } + + /** + * @magentoDataFixture Magento/Swatches/_files/configurable_product_with_images.php + * @return void + */ + public function testPreSelectedGalleryConfig(): void + { + $product = $this->productRepository->get('configurable'); + $this->block->setProduct($product); + $configurableAttribute = $this->productAttributeRepository->get('visual_swatch_attribute'); + $this->request->setQueryValue('visual_swatch_attribute', $configurableAttribute->getOptions()[1]->getValue()); + $jsonConfig = $this->serializer->unserialize($this->block->getJsonConfig()); + $this->assertArrayHasKey('preSelectedGallery', $jsonConfig); + $this->assertStringEndsWith('/m/a/magento_image.jpg', $jsonConfig['preSelectedGallery']['large']); + $this->assertStringEndsWith('/m/a/magento_image.jpg', $jsonConfig['preSelectedGallery']['medium']); + $this->assertStringEndsWith('/m/a/magento_image.jpg', $jsonConfig['preSelectedGallery']['small']); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/configurable_product_with_images.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/configurable_product_with_images.php new file mode 100644 index 0000000000000..096674c5e9620 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/configurable_product_with_images.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\Data\ProductExtensionInterfaceFactory; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\ProductFactory; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance()->requireDataFixture( + 'Magento/Catalog/_files/product_image.php' +); +Resolver::getInstance()->requireDataFixture( + 'Magento/Swatches/_files/configurable_product_visual_swatch_attribute.php' +); + +$objectManager = Bootstrap::getObjectManager(); +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +$images = ['magento_image.jpg', 'magento_small_image.jpg', 'magento_thumbnail.jpg']; +foreach (range(1, 3) as $index) { + $product = $productRepository->get('simple_option_' . $index); + $product->setImage('/m/a/' . $images[$index - 1]) + ->setSmallImage('/m/a/' . $images[$index - 1]) + ->setThumbnail('/m/a/' . $images[$index - 1]) + ->setData('media_gallery', ['images' => [ + [ + 'file' => '/m/a/' . $images[$index - 1], + 'position' => 1, + 'label' => 'Image Alt Text', + 'disabled' => 0, + 'media_type' => 'image', + ], + ]]) + ->setCanSaveCustomOptions(true) + ->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/configurable_product_with_images_rollback.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/configurable_product_with_images_rollback.php new file mode 100644 index 0000000000000..c201b258c5341 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/configurable_product_with_images_rollback.php @@ -0,0 +1,15 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance()->requireDataFixture( + 'Magento/Swatches/_files/configurable_product_visual_swatch_attribute_rollback.php' +); +Resolver::getInstance()->requireDataFixture( + 'Magento/Catalog/_files/product_image_rollback.php' +); From a68e58e59a5bf0bd30b0e5b254a867e6d4d9f3bd Mon Sep 17 00:00:00 2001 From: mastiuhin-olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Mon, 28 Dec 2020 11:45:41 +0200 Subject: [PATCH 132/156] MC-39878: Invoice for an order that contains only one configurable product is not generated correctly --- .../Magento/Sales/Model/Order/Invoice.php | 5 ++ .../Magento/Sales/Model/Order/InvoiceTest.php | 69 +++++++++++++++++-- 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Invoice.php b/app/code/Magento/Sales/Model/Order/Invoice.php index 14dd0b14ac1f3..50bbb3083a9ea 100644 --- a/app/code/Magento/Sales/Model/Order/Invoice.php +++ b/app/code/Magento/Sales/Model/Order/Invoice.php @@ -679,6 +679,11 @@ public function register() public function isLast() { foreach ($this->getAllItems() as $item) { + $orderItem = $item->getOrderItem(); + if ($orderItem->isDummy()) { + continue; + } + if (!$item->isLast()) { return false; } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/InvoiceTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/InvoiceTest.php index 8abec6ac6d734..64d5cdb037343 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/InvoiceTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/InvoiceTest.php @@ -3,20 +3,57 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sales\Model\Order; -class InvoiceTest extends \PHPUnit\Framework\TestCase +use PHPUnit\Framework\TestCase; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Sales\Model\ResourceModel\Order\Collection as OrderCollection; +use Magento\Sales\Api\InvoiceManagementInterface; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; + +/** + * Invoice model test. + */ +class InvoiceTest extends TestCase { /** - * @var \Magento\Sales\Model\ResourceModel\Order\Collection + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + /** + * @var OrderCollection + */ + private $collection; + + /** + * @var InvoiceManagementInterface + */ + private $invoiceManagement; + + /** + * @var OrderRepositoryInterface + */ + private $orderRepository; + + /** + * @var SearchCriteriaBuilder */ - private $_collection; + private $searchCriteriaBuilder; + /** + * @inheritDoc + */ protected function setUp(): void { - $this->_collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Sales\Model\ResourceModel\Order\Collection::class - ); + $this->objectManager = Bootstrap::getObjectManager(); + $this->collection = $this->objectManager->create(OrderCollection::class); + $this->invoiceManagement = $this->objectManager->get(InvoiceManagementInterface::class); + $this->orderRepository = $this->objectManager->get(OrderRepositoryInterface::class); + $this->searchCriteriaBuilder = $this->objectManager->get(SearchCriteriaBuilder::class); } /** @@ -27,9 +64,27 @@ public function testOrderTotalItemCount() $expectedResult = [['total_item_count' => 1]]; $actualResult = []; /** @var \Magento\Sales\Model\Order $order */ - foreach ($this->_collection->getItems() as $order) { + foreach ($this->collection->getItems() as $order) { $actualResult[] = ['total_item_count' => $order->getData('total_item_count')]; } $this->assertEquals($expectedResult, $actualResult); } + + /** + * Test order with exactly one configurable. + * + * @return void + * @magentoDataFixture Magento/Sales/_files/order_configurable_product.php + */ + public function testLastInvoiceWithConfigurable(): void + { + $searchCriteria = $this->searchCriteriaBuilder->addFilter('increment_id', '100000001') + ->create(); + $orders = $this->orderRepository->getList($searchCriteria); + $orders = $orders->getItems(); + $order = array_shift($orders); + $invoice = $this->invoiceManagement->prepareInvoice($order); + + self::assertEquals($invoice->isLast(), true); + } } From 6293b241f6469dcac784808905fae564142ce2d8 Mon Sep 17 00:00:00 2001 From: Serhii Balko <serhii.balko@transogtgroup.com> Date: Mon, 28 Dec 2020 11:59:10 +0200 Subject: [PATCH 133/156] MC-39864: [Magento Cloud] - Tax Miscalculation --- .../Model/Order/Creditmemo/Total/TaxTest.php | 46 +++++++++++++++++-- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/TaxTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/TaxTest.php index 7c9d249124a9a..f6d7c6fdba60a 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/TaxTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/TaxTest.php @@ -192,7 +192,7 @@ public function collectDataProvider() 'base_shipping_amount' => 30, 'tax_amount' => 0.82, 'base_tax_amount' => 0.82, - 'invoice' => new MagentoObject( + 'invoice' => $this->createInvoiceMock( [ 'tax_amount' => 24.33, 'base_tax_amount' => 24.33, @@ -283,7 +283,7 @@ public function collectDataProvider() 'base_shipping_amount' => 30, 'tax_amount' => 0.82 * $currencyRatio, 'base_tax_amount' => 0.82, - 'invoice' => new MagentoObject( + 'invoice' => $this->createInvoiceMock( [ 'tax_amount' => 24.33 * $currencyRatio, 'base_tax_amount' => 24.33, @@ -360,7 +360,7 @@ public function collectDataProvider() 'base_shipping_amount' => 30, 'tax_amount' => 1.65, 'base_tax_amount' => 1.65, - 'invoice' => new MagentoObject( + 'invoice' => $this->createInvoiceMock( [ 'tax_amount' => 11.14, 'base_tax_amount' => 11.14, @@ -438,7 +438,7 @@ public function collectDataProvider() 'base_shipping_amount' => 0, 'tax_amount' => 0.82, 'base_tax_amount' => 0.82, - 'invoice' => new MagentoObject( + 'invoice' => $this->createInvoiceMock( [ 'tax_amount' => 16.09, 'base_tax_amount' => 16.09, @@ -587,7 +587,7 @@ public function collectDataProvider() 'base_grand_total' => 60.82, 'tax_amount' => 0.82, 'base_tax_amount' => 0.82, - 'invoice' => new MagentoObject( + 'invoice' => $this->createInvoiceMock( [ 'tax_amount' => 16.09, 'base_tax_amount' => 16.09, @@ -779,4 +779,40 @@ protected function getCreditmemoItem($creditmemoItemData) $creditmemoItem->setData('qty', $creditmemoItemData['qty']); return $creditmemoItem; } + + /** + * Create invoice mock object + * + * @param array $data + * @return MockObject|Invoice + */ + private function createInvoiceMock(array $data): MockObject + { + /** @var MockObject|Invoice $invoice */ + $invoice = $this->getMockBuilder(Invoice::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->disallowMockingUnknownTypes() + ->addMethods(['getBaseShippingDiscountTaxCompensationAmount']) + ->onlyMethods([ + 'getTaxAmount', + 'getBaseTaxAmount', + 'getShippingTaxAmount', + 'getBaseShippingTaxAmount', + 'getShippingDiscountTaxCompensationAmount' + ]) + ->getMock(); + + $invoice->method('getTaxAmount')->willReturn($data['tax_amount'] ?? 0); + $invoice->method('getBaseTaxAmount')->willReturn($data['base_tax_amount'] ?? 0); + $invoice->method('getShippingTaxAmount')->willReturn($data['shipping_tax_amount'] ?? 0); + $invoice->method('getBaseShippingTaxAmount')->willReturn($data['base_shipping_tax_amount'] ?? 0); + $invoice->method('getShippingDiscountTaxCompensationAmount') + ->willReturn($data['shipping_discount_tax_compensation_amount'] ?? 0); + $invoice->method('getBaseShippingDiscountTaxCompensationAmount') + ->willReturn($data['base_shipping_discount_tax_compensation_amount'] ?? 0); + + return $invoice; + } } From 7491d77c7b8de8a29c5d118796a67f3cb0dcfd8e Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Mon, 28 Dec 2020 13:48:51 +0200 Subject: [PATCH 134/156] MC-39575: Create automated test for "Apply visual swatch attribute filter on layered navigation" --- .../Configurable/Listing/ConfigurableTest.php | 11 ----------- .../_files/configurable_product_with_images.php | 14 +++++++------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/Configurable/Listing/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/Configurable/Listing/ConfigurableTest.php index f2d254af85c94..58475ea879094 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/Configurable/Listing/ConfigurableTest.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/Configurable/Listing/ConfigurableTest.php @@ -83,17 +83,6 @@ protected function setUp(): void $this->productRepository->cleanCache(); $this->block = $this->objectManager->get(LayoutInterface::class)->createBlock(Configurable::class); $this->request = $this->objectManager->get(RequestInterface::class); - $this->request->clearParams(); - } - - /** - * @inheritdoc - */ - protected function tearDown(): void - { - $this->request->clearParams(); - - parent::tearDown(); } /** diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/configurable_product_with_images.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/configurable_product_with_images.php index 096674c5e9620..f2bcbc27dc01a 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/_files/configurable_product_with_images.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/configurable_product_with_images.php @@ -7,7 +7,6 @@ use Magento\Catalog\Api\Data\ProductExtensionInterfaceFactory; use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Catalog\Model\ProductFactory; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; @@ -21,15 +20,16 @@ $objectManager = Bootstrap::getObjectManager(); /** @var ProductRepositoryInterface $productRepository */ $productRepository = $objectManager->get(ProductRepositoryInterface::class); +$configurableProduct = $productRepository->get('configurable'); +$children = $configurableProduct->getTypeInstance()->getUsedProducts($configurableProduct); $images = ['magento_image.jpg', 'magento_small_image.jpg', 'magento_thumbnail.jpg']; -foreach (range(1, 3) as $index) { - $product = $productRepository->get('simple_option_' . $index); - $product->setImage('/m/a/' . $images[$index - 1]) - ->setSmallImage('/m/a/' . $images[$index - 1]) - ->setThumbnail('/m/a/' . $images[$index - 1]) +foreach ($children as $index => $product) { + $product->setImage('/m/a/' . $images[$index]) + ->setSmallImage('/m/a/' . $images[$index]) + ->setThumbnail('/m/a/' . $images[$index]) ->setData('media_gallery', ['images' => [ [ - 'file' => '/m/a/' . $images[$index - 1], + 'file' => '/m/a/' . $images[$index], 'position' => 1, 'label' => 'Image Alt Text', 'disabled' => 0, From 9e4001b88bd20b2503dc6845a6eae715aa440f4e Mon Sep 17 00:00:00 2001 From: engcom-Kilo <mikola.malevanec@transoftgroup.com> Date: Mon, 28 Dec 2020 16:54:28 +0200 Subject: [PATCH 135/156] MC-39189: Exception on Admin Customers page when website is deleted. --- .../Component/Listing/Column/Confirmation.php | 34 +++-- .../Listing/Column/ConfirmationTest.php | 127 ++++++++++++++++++ 2 files changed, 153 insertions(+), 8 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Customer/Ui/Component/Listing/Column/ConfirmationTest.php diff --git a/app/code/Magento/Customer/Ui/Component/Listing/Column/Confirmation.php b/app/code/Magento/Customer/Ui/Component/Listing/Column/Confirmation.php index 26cac677ccd10..6215909a1fbee 100644 --- a/app/code/Magento/Customer/Ui/Component/Listing/Column/Confirmation.php +++ b/app/code/Magento/Customer/Ui/Component/Listing/Column/Confirmation.php @@ -6,6 +6,7 @@ namespace Magento\Customer\Ui\Component\Listing\Column; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\View\Element\UiComponent\ContextInterface; use Magento\Framework\View\Element\UiComponentFactory; use Magento\Ui\Component\Listing\Columns\Column; @@ -28,7 +29,7 @@ class Confirmation extends Column * @param ScopeConfigInterface $scopeConfig @deprecated * @param array $components * @param array $data - * @param AccountConfirmation $accountConfirmation + * @param AccountConfirmation|null $accountConfirmation * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( @@ -65,13 +66,7 @@ public function prepareDataSource(array $dataSource) */ private function getFieldLabel(array $item) { - $isConfirmationRequired = $this->accountConfirmation->isConfirmationRequired( - $item['website_id'][0] ?? null, - $item[$item['id_field_name']], - $item['email'] - ); - - if ($isConfirmationRequired) { + if ($this->getIsConfirmationRequired($item)) { if ($item[$this->getData('name')] === null) { return __('Confirmed'); } @@ -79,4 +74,27 @@ private function getFieldLabel(array $item) } return __('Confirmation Not Required'); } + + /** + * Retrieve is confirmation required flag for customer considering requested website may not exist. + * + * @param array $customer + * @return bool + */ + private function getIsConfirmationRequired(array $customer): bool + { + try { + return $this->accountConfirmation->isConfirmationRequired( + $customer['website_id'][0] ?? null, + $customer[$customer['id_field_name']], + $customer['email'] + ); + } catch (NoSuchEntityException $e) { + return $this->accountConfirmation->isConfirmationRequired( + null, + $customer[$customer['id_field_name']], + $customer['email'] + ); + } + } } diff --git a/dev/tests/integration/testsuite/Magento/Customer/Ui/Component/Listing/Column/ConfirmationTest.php b/dev/tests/integration/testsuite/Magento/Customer/Ui/Component/Listing/Column/ConfirmationTest.php new file mode 100644 index 0000000000000..24fe443c8c796 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Customer/Ui/Component/Listing/Column/ConfirmationTest.php @@ -0,0 +1,127 @@ +<?php + +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Customer\Ui\Component\Listing\Column; + +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Tests for \Magento\Customer\Ui\Component\Listing\Column\Confirmation. + */ +class ConfirmationTest extends TestCase +{ + /** + * Test subject. + * + * @var Confirmation + */ + private $confirmation; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + $this->confirmation = Bootstrap::getObjectManager()->create( + Confirmation::class, + [ + 'components' => [], + 'data' => ['name' => 'confirmation'], + ] + ); + } + + /** + * Verify Confirmation::prepareDataSource() won't throw exception in case requested website doesn't exist. + * + * @param array $customerDataSource + * @param array $expectedResult + * @magentoConfigFixture base_website customer/create_account/confirm 1 + * @dataProvider customersDataProvider + * + * @return void + */ + public function testPrepareDataSource(array $customerDataSource, array $expectedResult): void + { + $result = $this->confirmation->prepareDataSource($customerDataSource); + + self::assertEquals($expectedResult, $result); + } + + /** + * CustomerDataSource data provider. + * + * @return array + */ + public function customersDataProvider(): array + { + return [ + [ + 'customerDataSource' => [ + 'data' => [ + 'items' => [ + [ + 'id_field_name' => 'entity_id', + 'entity_id' => '1', + 'name' => 'John Doe', + 'email' => 'john.doe@example.com', + 'group_id' => ['1'], + 'created_at' => '2020-12-28 07:05:50', + 'website_id' => ['1'], + 'confirmation' => false, + 'created_in' => 'Default Store View', + ], + [ + 'id_field_name' => 'entity_id', + 'entity_id' => '2', + 'name' => 'Jane Doe', + 'email' => 'jane.doe@example.com', + 'group_id' => ['1'], + 'created_at' => '2020-12-28 07:06:17', + 'website_id' => ['999999999'], + 'confirmation' => null, + 'created_in' => 'CustomStoreViewWhichDoesNotExistAnymore', + ], + ], + 'totalRecords' => 2, + ], + ], + 'expectedResult' => [ + 'data' => [ + 'items' => [ + [ + 'id_field_name' => 'entity_id', + 'entity_id' => '1', + 'name' => 'John Doe', + 'email' => 'john.doe@example.com', + 'group_id' => ['1'], + 'created_at' => '2020-12-28 07:05:50', + 'website_id' => ['1'], + 'confirmation' => __('Confirmation Required'), + 'created_in' => 'Default Store View', + ], + [ + 'id_field_name' => 'entity_id', + 'entity_id' => '2', + 'name' => 'Jane Doe', + 'email' => 'jane.doe@example.com', + 'group_id' => ['1'], + 'created_at' => '2020-12-28 07:06:17', + 'website_id' => ['999999999'], + 'confirmation' => __('Confirmed'), + 'created_in' => 'CustomStoreViewWhichDoesNotExistAnymore', + ], + ], + 'totalRecords' => 2, + ], + ], + ], + ]; + } +} From 640adcdfe746f3d9acf5c6bd7afa24dd2b42a1bb Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Tue, 29 Dec 2020 11:15:27 +0200 Subject: [PATCH 136/156] MC-39598: Create automated test for: "Assign/Unassign product to websites via API" --- .../Api/ProductWebsiteLinkRepositoryTest.php | 113 ++++++++++++++++++ .../ProductWebsiteLinkRepositoryTest.php | 72 +++++++++++ 2 files changed, 185 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductWebsiteLinkRepositoryTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Model/ProductWebsiteLinkRepositoryTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductWebsiteLinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductWebsiteLinkRepositoryTest.php new file mode 100644 index 0000000000000..13218450e5054 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductWebsiteLinkRepositoryTest.php @@ -0,0 +1,113 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Api; + +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Webapi\Rest\Request; +use Magento\Store\Api\WebsiteRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\WebapiAbstract; + +/** + * Tests to check products to websites assigning. + * + * @see \Magento\Catalog\Model\ProductWebsiteLinkRepository + * + * @magentoAppIsolation enabled + */ +class ProductWebsiteLinkRepositoryTest extends WebapiAbstract +{ + const SERVICE_NAME = 'catalogProductWebsiteLinkRepositoryV1'; + const SERVICE_VERSION = 'V1'; + + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var ProductRepositoryInterface */ + private $productRepository; + + /** @var WebsiteRepositoryInterface */ + private $websiteRepository; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + $this->websiteRepository = $this->objectManager->get(WebsiteRepositoryInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/second_product_simple.php + * + * @return void + */ + public function testSaveWebsiteLinkWithoutWebsiteId(): void + { + $serviceInfo = $this->fillServiceInfo('/V1/products/:sku/websites', Request::HTTP_METHOD_POST, 'Save'); + $requestData = ['productWebsiteLink' => ['sku' => 'simple2']]; + $this->expectException(\Exception::class); + $this->expectErrorMessage((string)__('There are not websites for assign to product')); + $this->_webApiCall($serviceInfo, $requestData); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/second_product_simple.php + * + * @return void + */ + public function testSaveWebsiteLinkWithUnexistingWebsiteId(): void + { + $unexistingWebsiteId = 8932568989; + $serviceInfo = $this->fillServiceInfo('/V1/products/:sku/websites', Request::HTTP_METHOD_POST, 'Save'); + $requestData = ['productWebsiteLink' => ['sku' => 'simple2', 'websiteId' => $unexistingWebsiteId]]; + $this->expectException(\Exception::class); + $this->expectExceptionMessageMatches('/Could not assign product \\\"%1\\\" to websites \\\"%2\\\"/'); + $this->_webApiCall($serviceInfo, $requestData); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_with_two_websites.php + * + * @return void + */ + public function testDeleteWebsiteLink(): void + { + $productSku = 'unique-simple-azaza'; + $websiteId = (int)$this->websiteRepository->get('second_website')->getId(); + $resourcePath = sprintf('/V1/products/%s/websites/%u', $productSku, $websiteId); + $serviceInfo = $this->fillServiceInfo($resourcePath, Request::HTTP_METHOD_DELETE, 'Delete'); + $this->_webApiCall($serviceInfo); + $product = $this->productRepository->get($productSku, false, null, true); + $this->assertNotContains($websiteId, $product->getWebsiteIds()); + } + + /** + * Fill service information + * + * @param string $resourcePath + * @param string $httpMethod + * @param string $operation + * @return array + */ + private function fillServiceInfo(string $resourcePath, string $httpMethod, string $operation): array + { + return [ + 'rest' => ['resourcePath' => $resourcePath, 'httpMethod' => $httpMethod], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . $operation, + ], + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductWebsiteLinkRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductWebsiteLinkRepositoryTest.php new file mode 100644 index 0000000000000..a4441c9480b25 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductWebsiteLinkRepositoryTest.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Model; + +use Magento\Catalog\Api\Data\ProductWebsiteLinkInterfaceFactory; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Api\ProductWebsiteLinkRepositoryInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\Store\Api\WebsiteRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Tests to check products to websites assigning. + * + * @see \Magento\Catalog\Model\ProductWebsiteLinkRepository + * + * @magentoAppIsolation enabled + */ +class ProductWebsiteLinkRepositoryTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var ProductWebsiteLinkRepositoryInterface */ + private $productWebsiteLinkRepository; + + /** @var ProductWebsiteLinkInterfaceFactory */ + private $productWebsiteLinkFactory; + + /** @var ProductRepositoryInterface */ + private $productRepository; + + /** @var WebsiteRepositoryInterface */ + private $websiteRepository; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->productWebsiteLinkRepository = $this->objectManager->get(ProductWebsiteLinkRepositoryInterface::class); + $this->productWebsiteLinkFactory = $this->objectManager->get(ProductWebsiteLinkInterfaceFactory::class); + $this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + $this->productRepository->cleanCache(); + $this->websiteRepository = $this->objectManager->get(WebsiteRepositoryInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_with_two_websites.php + * + * @return void + */ + public function testDelete(): void + { + $this->markTestSkipped('Blocked by MC-40250'); + $productWebsiteLink = $this->productWebsiteLinkFactory->create(); + $productWebsiteLink->setSku('unique-simple-azaza'); + $productWebsiteLink->setWebsiteId(1); + $this->productWebsiteLinkRepository->delete($productWebsiteLink); + $product = $this->productRepository->get('unique-simple-azaza', false, null, true); + $this->assertEquals([$this->websiteRepository->get('second_website')->getId()], $product->getWebsiteIds()); + } +} From 0073eb38787d4c52981bcb2981f335a73f6bf3b0 Mon Sep 17 00:00:00 2001 From: rostyslav-hymon <rostyslav.hymon@transoftgroup.com> Date: Tue, 29 Dec 2020 13:48:23 +0200 Subject: [PATCH 137/156] MC-39276: Can not change value for Ship Bundle Item attribute if it was moved to different group --- .../Product/Form/Modifier/BundlePanelTest.php | 166 ++++++++++++++++++ .../Product/Form/Modifier/BundlePanel.php | 17 +- 2 files changed, 176 insertions(+), 7 deletions(-) create mode 100644 app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/Form/Modifier/BundlePanelTest.php diff --git a/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/Form/Modifier/BundlePanelTest.php b/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/Form/Modifier/BundlePanelTest.php new file mode 100644 index 0000000000000..51563d319dfc8 --- /dev/null +++ b/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/Form/Modifier/BundlePanelTest.php @@ -0,0 +1,166 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Bundle\Test\Unit\Ui\DataProvider\Product\Form\Modifier; + +use Magento\Bundle\Model\Product\Attribute\Source\Shipment\Type as ShipmentType; +use Magento\Bundle\Ui\DataProvider\Product\Form\Modifier\BundlePanel; +use Magento\Bundle\Ui\DataProvider\Product\Form\Modifier\BundlePrice; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\Locator\LocatorInterface; +use Magento\Framework\Stdlib\ArrayManager; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\UrlInterface; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +/** + * Test for bundle panel + */ +class BundlePanelTest extends TestCase +{ + /** + * @var UrlInterface|MockObject + */ + private $urlBuilder; + + /** + * @var ShipmentType|MockObject + */ + private $shipmentType; + + /** + * @var LocatorInterface|MockObject + */ + private $locatorMock; + + /** + * @var ProductInterface|MockObject + */ + private $productMock; + + /** + * @var ArrayManager|MockObject + */ + private $arrayManagerMock; + + /** + * @var BundlePanel + */ + private $bundlePanelModel; + + /** + * @return void + */ + protected function setUp(): void + { + $this->objectManager = new ObjectManager($this); + $this->arrayManagerMock = $this->getMockBuilder(ArrayManager::class) + ->disableOriginalConstructor() + ->getMock(); + $this->arrayManagerMock->expects($this->any()) + ->method('get') + ->willReturn([]); + $this->urlBuilder = $this->getMockBuilder(UrlInterface::class) + ->getMockForAbstractClass(); + $this->shipmentType = $this->getMockBuilder(ShipmentType::class) + ->getMockForAbstractClass(); + $this->productMock = $this->getMockBuilder(ProductInterface::class) + ->addMethods(['getStoreId']) + ->getMockForAbstractClass(); + $this->productMock->method('getId') + ->willReturn(true); + $this->productMock->method('getStoreId') + ->willReturn(0); + $this->locatorMock = $this->getMockBuilder(LocatorInterface::class) + ->onlyMethods(['getProduct']) + ->getMockForAbstractClass(); + $this->locatorMock->method('getProduct') + ->willReturn($this->productMock); + + $this->bundlePanelModel = $this->objectManager->getObject( + BundlePanel::class, + [ + 'locator' => $this->locatorMock, + 'urlBuilder' => $this->urlBuilder, + 'shipmentType' => $this->shipmentType, + 'arrayManager' => $this->arrayManagerMock, + ] + ); + } + + /** + * Test for modify meta + * + * @param string $shipmentTypePath + * @param string $dataScope + * + * @return void + * @dataProvider getDataModifyMeta + */ + public function testModifyMeta(string $shipmentTypePath, string $dataScope): void + { + $sourceMeta = [ + 'bundle-items' => [ + 'children' => [ + BundlePrice::CODE_PRICE_TYPE => [] + ] + ] + ]; + $this->arrayManagerMock->method('findPath') + ->willReturnMap( + [ + [ + BundlePanel::CODE_SHIPMENT_TYPE, + [], + null, + 'children', + ArrayManager::DEFAULT_PATH_DELIMITER, + $shipmentTypePath + ], + ] + ); + $this->arrayManagerMock->method('merge') + ->willReturn([]); + $this->arrayManagerMock->method('remove') + ->willReturn([]); + $this->arrayManagerMock->method('set') + ->willReturn([]); + $this->arrayManagerMock->expects($this->at(12)) + ->method('merge') + ->with( + $shipmentTypePath . BundlePanel::META_CONFIG_PATH, + [], + [ + 'dataScope' => $dataScope, + 'validation' => [ + 'required-entry' => false + ] + ] + ); + $this->bundlePanelModel->modifyMeta($sourceMeta); + } + + /** + * Data provider for modify meta test + * + * @return string[][] + */ + public function getDataModifyMeta(): array + { + return [ + [ + 'bundle-items/children', + 'data.product.shipment_type' + ], + [ + 'someAttrGroup/children', + 'shipment_type' + ], + ]; + } +} 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 5ff9e674acad9..01b113def9243 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 @@ -252,16 +252,19 @@ public function modifyData(array $data) */ private function modifyShipmentType(array $meta) { + $actualPath = $this->arrayManager->findPath( + static::CODE_SHIPMENT_TYPE, + $meta, + null, + 'children' + ); + $meta = $this->arrayManager->merge( - $this->arrayManager->findPath( - static::CODE_SHIPMENT_TYPE, - $meta, - null, - 'children' - ) . static::META_CONFIG_PATH, + $actualPath . static::META_CONFIG_PATH, $meta, [ - 'dataScope' => 'data.product.shipment_type', + 'dataScope' => stripos($actualPath, self::CODE_BUNDLE_DATA) === 0 + ? 'data.product.shipment_type' : 'shipment_type', 'validation' => [ 'required-entry' => false ] From 04fd1acd367593c5080075d31602ca7dd68b70ca Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Tue, 29 Dec 2020 14:15:22 +0200 Subject: [PATCH 138/156] MC-39598: Create automated test for: "Assign/Unassign product to websites via API" --- .../Api/ProductWebsiteLinkRepositoryTest.php | 21 ++++--------------- .../ProductWebsiteLinkRepositoryTest.php | 17 ++++++++++++++- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductWebsiteLinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductWebsiteLinkRepositoryTest.php index 13218450e5054..fbca54acc9e0b 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductWebsiteLinkRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductWebsiteLinkRepositoryTest.php @@ -46,20 +46,6 @@ protected function setUp(): void $this->websiteRepository = $this->objectManager->get(WebsiteRepositoryInterface::class); } - /** - * @magentoApiDataFixture Magento/Catalog/_files/second_product_simple.php - * - * @return void - */ - public function testSaveWebsiteLinkWithoutWebsiteId(): void - { - $serviceInfo = $this->fillServiceInfo('/V1/products/:sku/websites', Request::HTTP_METHOD_POST, 'Save'); - $requestData = ['productWebsiteLink' => ['sku' => 'simple2']]; - $this->expectException(\Exception::class); - $this->expectErrorMessage((string)__('There are not websites for assign to product')); - $this->_webApiCall($serviceInfo, $requestData); - } - /** * @magentoApiDataFixture Magento/Catalog/_files/second_product_simple.php * @@ -67,11 +53,12 @@ public function testSaveWebsiteLinkWithoutWebsiteId(): void */ public function testSaveWebsiteLinkWithUnexistingWebsiteId(): void { + $pattern = '/(Could\\snot\\sassign\\sproduct)+([\\s\\S]*)(to\\swebsites)+([\\s\\S]*)/'; $unexistingWebsiteId = 8932568989; $serviceInfo = $this->fillServiceInfo('/V1/products/:sku/websites', Request::HTTP_METHOD_POST, 'Save'); $requestData = ['productWebsiteLink' => ['sku' => 'simple2', 'websiteId' => $unexistingWebsiteId]]; $this->expectException(\Exception::class); - $this->expectExceptionMessageMatches('/Could not assign product \\\"%1\\\" to websites \\\"%2\\\"/'); + $this->expectExceptionMessageMatches($pattern); $this->_webApiCall($serviceInfo, $requestData); } @@ -85,8 +72,8 @@ public function testDeleteWebsiteLink(): void $productSku = 'unique-simple-azaza'; $websiteId = (int)$this->websiteRepository->get('second_website')->getId(); $resourcePath = sprintf('/V1/products/%s/websites/%u', $productSku, $websiteId); - $serviceInfo = $this->fillServiceInfo($resourcePath, Request::HTTP_METHOD_DELETE, 'Delete'); - $this->_webApiCall($serviceInfo); + $serviceInfo = $this->fillServiceInfo($resourcePath, Request::HTTP_METHOD_DELETE, 'DeleteById'); + $this->_webApiCall($serviceInfo, ['sku' => $productSku, 'websiteId' => $websiteId]); $product = $this->productRepository->get($productSku, false, null, true); $this->assertNotContains($websiteId, $product->getWebsiteIds()); } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductWebsiteLinkRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductWebsiteLinkRepositoryTest.php index a4441c9480b25..9ae327036971b 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductWebsiteLinkRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductWebsiteLinkRepositoryTest.php @@ -10,6 +10,7 @@ use Magento\Catalog\Api\Data\ProductWebsiteLinkInterfaceFactory; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Api\ProductWebsiteLinkRepositoryInterface; +use Magento\Framework\Exception\InputException; use Magento\Framework\ObjectManagerInterface; use Magento\Store\Api\WebsiteRepositoryInterface; use Magento\TestFramework\Helper\Bootstrap; @@ -55,7 +56,21 @@ protected function setUp(): void } /** - * @magentoApiDataFixture Magento/Catalog/_files/product_with_two_websites.php + * @magentoDataFixture Magento/Catalog/_files/second_product_simple.php + * + * @return void + */ + public function testSaveWithoutWebsiteId(): void + { + $productWebsiteLink = $this->productWebsiteLinkFactory->create(); + $productWebsiteLink->setSku('unique-simple-azaza'); + $this->expectException(InputException::class); + $this->expectErrorMessage((string)__('There are not websites for assign to product')); + $this->productWebsiteLinkRepository->save($productWebsiteLink); + } + + /** + * @magentoDataFixture Magento/Catalog/_files/product_with_two_websites.php * * @return void */ From 9b0799b75169c7df4e85a647187e15512f71befc Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Tue, 29 Dec 2020 19:07:46 +0200 Subject: [PATCH 139/156] MC-39598: Create automated test for: "Assign/Unassign product to websites via API" --- .../Api/ProductWebsiteLinkRepositoryTest.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductWebsiteLinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductWebsiteLinkRepositoryTest.php index fbca54acc9e0b..0bbed6387ae57 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductWebsiteLinkRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductWebsiteLinkRepositoryTest.php @@ -7,6 +7,7 @@ namespace Magento\Catalog\Api; +use Magento\Catalog\Model\ProductWebsiteLink; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Webapi\Rest\Request; use Magento\Store\Api\WebsiteRepositoryInterface; @@ -56,7 +57,12 @@ public function testSaveWebsiteLinkWithUnexistingWebsiteId(): void $pattern = '/(Could\\snot\\sassign\\sproduct)+([\\s\\S]*)(to\\swebsites)+([\\s\\S]*)/'; $unexistingWebsiteId = 8932568989; $serviceInfo = $this->fillServiceInfo('/V1/products/:sku/websites', Request::HTTP_METHOD_POST, 'Save'); - $requestData = ['productWebsiteLink' => ['sku' => 'simple2', 'websiteId' => $unexistingWebsiteId]]; + $requestData = [ + 'productWebsiteLink' => [ + ProductWebsiteLink::KEY_SKU => 'simple2', + ProductWebsiteLink::WEBSITE_ID => $unexistingWebsiteId, + ], + ]; $this->expectException(\Exception::class); $this->expectExceptionMessageMatches($pattern); $this->_webApiCall($serviceInfo, $requestData); @@ -73,7 +79,10 @@ public function testDeleteWebsiteLink(): void $websiteId = (int)$this->websiteRepository->get('second_website')->getId(); $resourcePath = sprintf('/V1/products/%s/websites/%u', $productSku, $websiteId); $serviceInfo = $this->fillServiceInfo($resourcePath, Request::HTTP_METHOD_DELETE, 'DeleteById'); - $this->_webApiCall($serviceInfo, ['sku' => $productSku, 'websiteId' => $websiteId]); + $this->_webApiCall( + $serviceInfo, + [ProductWebsiteLink::KEY_SKU => $productSku, ProductWebsiteLink::WEBSITE_ID => $websiteId] + ); $product = $this->productRepository->get($productSku, false, null, true); $this->assertNotContains($websiteId, $product->getWebsiteIds()); } From 2740e08869dfc8b0ea69bd20400c693e82c73a1b Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Wed, 30 Dec 2020 13:01:01 +0200 Subject: [PATCH 140/156] MC-40068: Create automated test for: "Try to delete root category by API call" --- .../Catalog/Api/CategoryRepositoryTest.php | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php index 5623edca62b9a..8e0aff81cc3b8 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php @@ -184,22 +184,49 @@ public function testDeleteNoSuchEntityException() /** * @dataProvider deleteSystemOrRootDataProvider + * + * @param int $categoryId + * @param string $exceptionMsg + * @return void */ - public function testDeleteSystemOrRoot() + public function testDeleteSystemOrRoot(int $categoryId, string $exceptionMsg): void { $this->expectException(\Exception::class); + $this->expectExceptionMessage($exceptionMsg); - $this->deleteCategory($this->modelId); + $this->deleteCategory($categoryId); } - public function deleteSystemOrRootDataProvider() + /** + * @return array + */ + public function deleteSystemOrRootDataProvider(): array { return [ - [Category::TREE_ROOT_ID], - [2] //Default root category + 'system_category' => [ + 'category_id' => Category::TREE_ROOT_ID, + 'exception_message' => $this->buildExceptionMessage(Category::TREE_ROOT_ID), + ], + 'root_category' => [ + 'category_id' => 2, + 'exception_message' => $this->buildExceptionMessage(2), + ], ]; } + /** + * Build response error message + * + * @param int $categoryId + * @return string + */ + private function buildExceptionMessage(int $categoryId): string + { + $translatedMsg = (string)__('Cannot delete category with id %1'); + + return sprintf('{"message":"%s","parameters":["%u"]}', $translatedMsg, $categoryId); + } + /** * @magentoApiDataFixture Magento/Catalog/_files/category.php */ From 14f3af27d67db2f807fa413fe013b15ce48857f9 Mon Sep 17 00:00:00 2001 From: SmVladyslav <vlatame.tsg@gmail.com> Date: Wed, 30 Dec 2020 14:12:45 +0200 Subject: [PATCH 141/156] MC-39470: issue with dynamicRows component --- .../base/web/js/dynamic-rows/dynamic-rows.js | 18 +++++++--- .../base/js/dynamic-rows/dynamic-rows.test.js | 33 +++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 0ac35df78e001..45dfaa40f87df 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -620,15 +620,12 @@ define([ * @param {Array} data */ parsePagesData: function (data) { - var pages; - this.relatedData = this.deleteProperty ? _.filter(data, function (elem) { return elem && elem[this.deleteProperty] !== this.deleteValue; }, this) : data; - pages = Math.ceil(this.relatedData.length / this.pageSize) || 1; - this.pages(pages); + this._updatePagesQuantity(); }, /** @@ -885,6 +882,18 @@ define([ this._sort(); }, + /** + * Update number of pages. + * + * @private + * @return void + */ + _updatePagesQuantity: function () { + var pages = Math.ceil(this.relatedData.length / this.pageSize) || 1; + + this.pages(pages); + }, + /** * Reduce the number of pages * @@ -960,6 +969,7 @@ define([ reload: function () { this.clear(); this.initChildren(false, true); + this._updatePagesQuantity(); /* After change page size need to check existing current page */ this._reducePages(); diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/dynamic-rows/dynamic-rows.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/dynamic-rows/dynamic-rows.test.js index fc60fbb0bdccc..1101770b0faa2 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/dynamic-rows/dynamic-rows.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/dynamic-rows/dynamic-rows.test.js @@ -171,5 +171,38 @@ define([ }; expect(JSON.stringify(model.labels())).toEqual(JSON.stringify(result)); }); + + it('Check _updatePagesQuantity method call.', function () { + model._updatePagesQuantity = jasmine.createSpy(); + + model.reload(); + + expect(model._updatePagesQuantity).toHaveBeenCalled(); + }); + + it('Check number of pages is updated after reloading dynamic-rows.', function () { + model.pageSize = 1; + model.relatedData = [ + { + name: 'first' + }, + { + name: 'second' + }, + { + name: 'third' + } + ]; + + model.reload(); + expect(model.pages()).toEqual(3); + + model.currentPage(3); + model.pageSize = 2; + + model.reload(); + expect(model.pages()).toEqual(2); + expect(model.currentPage()).toEqual(2); + }); }); }); From 10fe506d9489296e9c4b27666d3c687c07b8ba57 Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Wed, 30 Dec 2020 14:16:56 +0200 Subject: [PATCH 142/156] MC-39702: Create automated test for: "Visual swatch on the product page" --- .../Product/Renderer/ConfigurableTest.php | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/ConfigurableTest.php index c900d276c7864..111d0aa08f7f5 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/ConfigurableTest.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/ConfigurableTest.php @@ -148,6 +148,32 @@ public function testGetJsonSwatchConfigUsedProductImage(): void ); } + /** + * @magentoDataFixture Magento/Swatches/_files/configurable_product_with_visual_swatch_attribute.php + * @magentoDataFixture Magento/Catalog/_files/product_image.php + * @return void + */ + public function testGetJsonSwatchConfigUsedWithSwatchImageType(): void + { + $this->updateAttributeUseProductImageFlag(); + $this->updateProductImage('simple_option_2', '/m/a/magento_image.jpg'); + $this->setSwatchImage('simple_option_2', '/m/a/magento_image.jpg'); + $expectedOptions = $this->getDefaultOptionsList(); + $expectedOptions['option 2']['value'] = $this->imageUrlBuilder->getUrl( + '/m/a/magento_image.jpg', + 'swatch_image_base' + ); + $expectedOptions['option 2']['thumb'] = $this->imageUrlBuilder->getUrl( + '/m/a/magento_image.jpg', + 'swatch_thumb_base' + ); + $this->assertOptionsData( + $this->serializer->unserialize($this->block->getJsonSwatchConfig()), + $expectedOptions, + ['swatch_input_type' => 'visual', 'use_product_image_for_swatch' => 1] + ); + } + /** * @magentoDataFixture Magento/Swatches/_files/configurable_product_with_visual_swatch_attribute.php * @return void @@ -249,4 +275,18 @@ private function updateProductImage(string $sku, string $imageName): void ->setCanSaveCustomOptions(true); $this->productResource->save($product); } + + /** + * Set swatch image for a Product. + * + * @param string $sku + * @param string $imageName + * @return void + */ + private function setSwatchImage(string $sku, string $imageName): void + { + $product = $this->productRepository->get($sku); + $product->setSwatchImage($imageName)->save($product); + } } + From bd329b681eeab9b667f2fcbe4a1aa67d23d4b3e3 Mon Sep 17 00:00:00 2001 From: Vasya Tsviklinskyi <tsviklinskyi@gmail.com> Date: Wed, 30 Dec 2020 14:46:51 +0200 Subject: [PATCH 143/156] MC-40030: Wrong currency sign in Credit Memo grid with Website scope for Price --- app/code/Magento/Sales/Ui/Component/Listing/Column/Price.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Ui/Component/Listing/Column/Price.php b/app/code/Magento/Sales/Ui/Component/Listing/Column/Price.php index 4ffb6f98447c7..cc323730f14b4 100644 --- a/app/code/Magento/Sales/Ui/Component/Listing/Column/Price.php +++ b/app/code/Magento/Sales/Ui/Component/Listing/Column/Price.php @@ -10,6 +10,7 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\View\Element\UiComponent\ContextInterface; use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Store\Model\Store; use Magento\Store\Model\StoreManagerInterface; use Magento\Ui\Component\Listing\Columns\Column; use Magento\Framework\Pricing\PriceCurrencyInterface; @@ -77,8 +78,10 @@ public function prepareDataSource(array $dataSource) foreach ($dataSource['data']['items'] as & $item) { $currencyCode = isset($item['base_currency_code']) ? $item['base_currency_code'] : null; if (!$currencyCode) { + $storeId = isset($item['store_id']) && (int)$item['store_id'] !== 0 ? $item['store_id'] : + $this->context->getFilterParam('store_id', Store::DEFAULT_STORE_ID); $store = $this->storeManager->getStore( - $this->context->getFilterParam('store_id', \Magento\Store\Model\Store::DEFAULT_STORE_ID) + $storeId ); $currencyCode = $store->getBaseCurrency()->getCurrencyCode(); } From 16826bd19568a4df154f2fc787e2a89d99a2e46a Mon Sep 17 00:00:00 2001 From: Roman Zhupanyn <roma.dj.elf@gmail.com> Date: Wed, 30 Dec 2020 15:01:03 +0200 Subject: [PATCH 144/156] MC-39687: Create automated test for: "Set backorders "Allow Qty Below 0" and check indexers" --- .../Model/Config/Backend/BackordersTest.php | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/BackordersTest.php diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/BackordersTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/BackordersTest.php new file mode 100644 index 0000000000000..279e45fc868cc --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/BackordersTest.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogInventory\Model\Config\Backend; + +use Magento\CatalogInventory\Model\Configuration; +use Magento\CatalogInventory\Model\Indexer\Stock\Processor; +use Magento\CatalogInventory\Model\Stock; +use Magento\Config\Model\Config\BackendFactory; +use Magento\Framework\App\Config\MutableScopeConfigInterface; +use Magento\Framework\Indexer\StateInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Checks that the backorders config backend model is working correctly + */ +class BackordersTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Backorders */ + private $backorders; + + /** @var BackendFactory */ + private $backendFactory; + + /** @var MutableScopeConfigInterface */ + private $mutableConfig; + + /** @var Processor */ + private $stockIndexerProcessor; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->backendFactory = $this->objectManager->create(BackendFactory::class); + $this->backorders = $this->backendFactory->create(Backorders::class, [ + 'data' => [ + 'path' => Configuration::XML_PATH_BACKORDERS, + ] + ]); + $this->mutableConfig = $this->objectManager->get(MutableScopeConfigInterface::class); + $this->stockIndexerProcessor = $this->objectManager->get(Processor::class); + } + + /** + * @dataProvider afterSaveDataProvider + * @param int $value + * @param int $currentValue + * @param string $expectedIndexerStatus + * @magentoDbIsolation disabled + * @return void + */ + public function testAfterSave(int $value, int $currentValue, string $expectedIndexerStatus): void + { + $this->stockIndexerProcessor->reindexAll(); + $this->mutableConfig->setValue(Configuration::XML_PATH_BACKORDERS, $currentValue); + $this->backorders->setValue((string)$value); + $this->backorders->afterSave(); + + $this->assertEquals($expectedIndexerStatus, $this->stockIndexerProcessor->getIndexer()->getStatus()); + } + + /** + * Data provider for testAfterSave + * + * @return array + */ + public function afterSaveDataProvider(): array + { + return [ + 'set_backorders' => [ + 'value' => Stock::BACKORDERS_YES_NONOTIFY, + 'current_value' => Stock::BACKORDERS_NO, + 'expected_indexer_status' => StateInterface::STATUS_INVALID, + ], + 'unset_backorders' => [ + 'value' => Stock::BACKORDERS_NO, + 'current_value' => Stock::BACKORDERS_YES_NONOTIFY, + 'expected_indexer_status' => StateInterface::STATUS_INVALID, + ], + 'same_backorders' => [ + 'value' => Stock::BACKORDERS_YES_NONOTIFY, + 'current_value' => Stock::BACKORDERS_YES_NONOTIFY, + 'expected_indexer_status' => StateInterface::STATUS_VALID, + ], + ]; + } +} From 048ada376695b0df9b5d63ab4a321a8d7302477c Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Wed, 30 Dec 2020 15:24:22 +0200 Subject: [PATCH 145/156] MC-40068: Create automated test for: "Try to delete root category by API call" --- .../testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php index 8e0aff81cc3b8..2e8eedf96b0f8 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php @@ -224,7 +224,9 @@ private function buildExceptionMessage(int $categoryId): string { $translatedMsg = (string)__('Cannot delete category with id %1'); - return sprintf('{"message":"%s","parameters":["%u"]}', $translatedMsg, $categoryId); + return TESTS_WEB_API_ADAPTER === self::ADAPTER_REST + ? sprintf('{"message":"%s","parameters":["%u"]}', $translatedMsg, $categoryId) + : $translatedMsg; } /** From c50560110e4eb940f07566ad66915c5ee58de60b Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Wed, 30 Dec 2020 15:37:34 +0200 Subject: [PATCH 146/156] MC-39702: Create automated test for: "Visual swatch on the category page" --- .../Product/Renderer/ConfigurableTest.php | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/ConfigurableTest.php index 111d0aa08f7f5..5c5b1399caed8 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/ConfigurableTest.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/Block/Product/Renderer/ConfigurableTest.php @@ -156,8 +156,7 @@ public function testGetJsonSwatchConfigUsedProductImage(): void public function testGetJsonSwatchConfigUsedWithSwatchImageType(): void { $this->updateAttributeUseProductImageFlag(); - $this->updateProductImage('simple_option_2', '/m/a/magento_image.jpg'); - $this->setSwatchImage('simple_option_2', '/m/a/magento_image.jpg'); + $this->updateProductImage('simple_option_2', '/m/a/magento_image.jpg', ['swatch_image']); $expectedOptions = $this->getDefaultOptionsList(); $expectedOptions['option 2']['value'] = $this->imageUrlBuilder->getUrl( '/m/a/magento_image.jpg', @@ -249,15 +248,16 @@ private function updateAttributeUseProductImageFlag(): void * * @param string $sku * @param string $imageName + * @param array $imageRoles * @return void */ - private function updateProductImage(string $sku, string $imageName): void - { + private function updateProductImage( + string $sku, + string $imageName, + array $imageRoles = ['image', 'small_image', 'thumbnail'] + ): void { $product = $this->productRepository->get($sku); $product->setStoreId(Store::DEFAULT_STORE_ID) - ->setImage($imageName) - ->setSmallImage($imageName) - ->setThumbnail($imageName) ->setData( 'media_gallery', [ @@ -273,20 +273,10 @@ private function updateProductImage(string $sku, string $imageName): void ] ) ->setCanSaveCustomOptions(true); - $this->productResource->save($product); - } + foreach ($imageRoles as $role) { + $product->setData($role, $imageName); + } - /** - * Set swatch image for a Product. - * - * @param string $sku - * @param string $imageName - * @return void - */ - private function setSwatchImage(string $sku, string $imageName): void - { - $product = $this->productRepository->get($sku); - $product->setSwatchImage($imageName)->save($product); + $this->productResource->save($product); } } - From 10272105edddaca5363e1e16ea033184b33dd009 Mon Sep 17 00:00:00 2001 From: Vasya Tsviklinskyi <tsviklinskyi@gmail.com> Date: Thu, 31 Dec 2020 09:47:11 +0200 Subject: [PATCH 147/156] MC-40030: Wrong currency sign in Credit Memo grid with Website scope for Price --- .../Ui/Component/Listing/Column/PriceTest.php | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Ui/Component/Listing/Column/PriceTest.php b/app/code/Magento/Sales/Test/Unit/Ui/Component/Listing/Column/PriceTest.php index 4a9061c3f3c5c..449ab230b568d 100644 --- a/app/code/Magento/Sales/Test/Unit/Ui/Component/Listing/Column/PriceTest.php +++ b/app/code/Magento/Sales/Test/Unit/Ui/Component/Listing/Column/PriceTest.php @@ -17,6 +17,9 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +/** + * Contains tests for Price class + */ class PriceTest extends TestCase { /** @@ -34,6 +37,9 @@ class PriceTest extends TestCase */ private $storeManagerMock; + /** + * @inheritDoc + */ protected function setUp(): void { $objectManager = new ObjectManager($this); @@ -57,12 +63,20 @@ protected function setUp(): void } /** - * @param $hasCurrency - * @param $dataSource - * @param $currencyCode + * Test for prepareDataSource method + * + * @param bool $hasCurrency + * @param array $dataSource + * @param string $currencyCode + * @param int|null $expectedStoreId * @dataProvider testPrepareDataSourceDataProvider */ - public function testPrepareDataSource($hasCurrency, $dataSource, $currencyCode) + public function testPrepareDataSource( + bool $hasCurrency, + array $dataSource, + string $currencyCode, + ?int $expectedStoreId = null + ): void { $itemName = 'itemName'; $oldItemValue = 'oldItemValue'; @@ -79,6 +93,7 @@ public function testPrepareDataSource($hasCurrency, $dataSource, $currencyCode) ->willReturn($currencyCode); $this->storeManagerMock->expects($hasCurrency ? $this->never() : $this->once()) ->method('getStore') + ->with($expectedStoreId) ->willReturn($store); $store->expects($hasCurrency ? $this->never() : $this->once()) ->method('getBaseCurrency') @@ -98,7 +113,12 @@ public function testPrepareDataSource($hasCurrency, $dataSource, $currencyCode) $this->assertEquals($newItemValue, $dataSource['data']['items'][0][$itemName]); } - public function testPrepareDataSourceDataProvider() + /** + * Provider for testPrepareDataSource + * + * @return array + */ + public function testPrepareDataSourceDataProvider(): array { $dataSource1 = [ 'data' => [ @@ -119,9 +139,31 @@ public function testPrepareDataSourceDataProvider() ] ] ]; + $dataSource3 = [ + 'data' => [ + 'items' => [ + [ + 'itemName' => 'oldItemValue', + 'store_id' => '2' + ] + ] + ] + ]; + $dataSource4 = [ + 'data' => [ + 'items' => [ + [ + 'itemName' => 'oldItemValue', + 'store_id' => 'abc' + ] + ] + ] + ]; return [ [true, $dataSource1, 'US'], [false, $dataSource2, 'SAR'], + [false, $dataSource3, 'SAR', 2], + [false, $dataSource4, 'SAR'], ]; } } From 62bb82c0e93a8085f7a0d5f479ff225896c45385 Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Thu, 31 Dec 2020 11:54:45 +0200 Subject: [PATCH 148/156] MC-30104: When using MysqlMQ messages are always set to complete even if exception occurs --- .../MessageQueue/Model/ResourceModel/Lock.php | 48 ++++---- .../TestModuleMysqlMq/Model/Processor.php | 25 +++- .../TestModuleMysqlMq/etc/communication.xml | 1 + .../Magento/TestModuleMysqlMq/etc/queue.xml | 3 + .../TestModuleMysqlMq/etc/queue_consumer.xml | 1 + .../TestModuleMysqlMq/etc/queue_publisher.xml | 3 + .../TestModuleMysqlMq/etc/queue_topology.xml | 1 + .../MessageQueue/Model/ConsumerTest.php | 109 ++++++++++++++++++ .../Model/ResourceModel/LockTest.php | 28 +++++ 9 files changed, 193 insertions(+), 26 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/MessageQueue/Model/ConsumerTest.php create mode 100644 dev/tests/integration/testsuite/Magento/MessageQueue/Model/ResourceModel/LockTest.php diff --git a/app/code/Magento/MessageQueue/Model/ResourceModel/Lock.php b/app/code/Magento/MessageQueue/Model/ResourceModel/Lock.php index 16c02a7505664..00399e30e8b72 100644 --- a/app/code/Magento/MessageQueue/Model/ResourceModel/Lock.php +++ b/app/code/Magento/MessageQueue/Model/ResourceModel/Lock.php @@ -5,46 +5,52 @@ */ namespace Magento\MessageQueue\Model\ResourceModel; -use \Magento\Framework\MessageQueue\Lock\ReaderInterface; -use \Magento\Framework\MessageQueue\Lock\WriterInterface; +use DateInterval; +use DateTime; +use Magento\Framework\MessageQueue\Lock\ReaderInterface; +use Magento\Framework\MessageQueue\Lock\WriterInterface; +use Magento\Framework\MessageQueue\LockInterface; +use Magento\Framework\Model\ResourceModel\Db\AbstractDb; +use Magento\Framework\Model\ResourceModel\Db\Context; +use Magento\MessageQueue\Model\LockFactory; /** * Class Lock to handle database lock table db transactions. */ -class Lock extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb implements ReaderInterface, WriterInterface +class Lock extends AbstractDb implements ReaderInterface, WriterInterface { /**#@+ * Constants */ - const QUEUE_LOCK_TABLE = 'queue_lock'; + public const QUEUE_LOCK_TABLE = 'queue_lock'; /**#@-*/ /**#@-*/ private $dateTime; /** - * @var \Magento\MessageQueue\Model\LockFactory + * @var LockFactory */ private $lockFactory; /** - * @var integer + * @var int */ private $interval; /** * Initialize dependencies. * - * @param \Magento\Framework\Model\ResourceModel\Db\Context $context + * @param Context $context * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime - * @param \Magento\MessageQueue\Model\LockFactory $lockFactory - * @param null $connectionName - * @param integer $interval + * @param LockFactory $lockFactory + * @param ?string $connectionName + * @param int $interval */ public function __construct( - \Magento\Framework\Model\ResourceModel\Db\Context $context, + Context $context, \Magento\Framework\Stdlib\DateTime\DateTime $dateTime, - \Magento\MessageQueue\Model\LockFactory $lockFactory, + LockFactory $lockFactory, $connectionName = null, $interval = 86400 ) { @@ -55,7 +61,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritdoc */ protected function _construct() { @@ -63,9 +69,9 @@ protected function _construct() } /** - * {@inheritDoc} + * @inheritdoc */ - public function read(\Magento\Framework\MessageQueue\LockInterface $lock, $code) + public function read(LockInterface $lock, $code) { $object = $this->lockFactory->create(); $object->load($code, 'message_code'); @@ -75,23 +81,25 @@ public function read(\Magento\Framework\MessageQueue\LockInterface $lock, $code) } /** - * {@inheritDoc} + * @inheritdoc */ - public function saveLock(\Magento\Framework\MessageQueue\LockInterface $lock) + public function saveLock(LockInterface $lock) { $object = $this->lockFactory->create(); $object->setMessageCode($lock->getMessageCode()); $object->setCreatedAt($this->dateTime->gmtTimestamp()); $object->save(); + $lock->setId($object->getId()); + $lock->setCreatedAt($object->getCreatedAt()); } /** - * {@inheritDoc} + * @inheritdoc */ public function releaseOutdatedLocks() { - $date = (new \DateTime())->setTimestamp($this->dateTime->gmtTimestamp()); - $date->add(new \DateInterval('PT' . $this->interval . 'S')); + $date = (new DateTime())->setTimestamp($this->dateTime->gmtTimestamp()); + $date->add(new DateInterval('PT' . $this->interval . 'S')); $this->getConnection()->delete($this->getTable(self::QUEUE_LOCK_TABLE), ['created_at <= ?' => $date]); } } diff --git a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/Model/Processor.php b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/Model/Processor.php index fb6fd4c5c2802..3d2f722ccb60e 100644 --- a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/Model/Processor.php +++ b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/Model/Processor.php @@ -5,13 +5,16 @@ */ namespace Magento\TestModuleMysqlMq\Model; +use LogicException; +use Magento\Framework\MessageQueue\ConnectionLostException; + /** * Test message processor is used by \Magento\MysqlMq\Model\PublisherConsumerTest */ class Processor { /** - * @param \Magento\TestModuleMysqlMq\Model\DataObject $message + * @param DataObject $message */ public function processMessage($message) { @@ -23,7 +26,7 @@ public function processMessage($message) } /** - * @param \Magento\TestModuleMysqlMq\Model\DataObject $message + * @param DataObject $message */ public function processObjectCreated($message) { @@ -35,7 +38,7 @@ public function processObjectCreated($message) } /** - * @param \Magento\TestModuleMysqlMq\Model\DataObject $message + * @param DataObject $message */ public function processCustomObjectCreated($message) { @@ -47,7 +50,7 @@ public function processCustomObjectCreated($message) } /** - * @param \Magento\TestModuleMysqlMq\Model\DataObject $message + * @param DataObject $message */ public function processObjectUpdated($message) { @@ -59,13 +62,23 @@ public function processObjectUpdated($message) } /** - * @param \Magento\TestModuleMysqlMq\Model\DataObject $message + * @param DataObject $message */ public function processMessageWithException($message) { file_put_contents($message->getOutputPath(), "Exception processing {$message->getEntityId()}"); - throw new \LogicException( + throw new LogicException( "Exception during message processing happened. Entity: {{$message->getEntityId()}}" ); } + + /** + * @throws ConnectionLostException + */ + public function processMessageWithConnectionException() + { + throw new ConnectionLostException( + "Connection exception during message processing happened." + ); + } } diff --git a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/communication.xml b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/communication.xml index 4d6269dbb7920..1a5a5feb11324 100644 --- a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/communication.xml +++ b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/communication.xml @@ -7,6 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Communication/etc/communication.xsd"> <topic name="demo.exception" request="Magento\TestModuleMysqlMq\Model\DataObject"/> + <topic name="demo.connection.exception" request="Magento\TestModuleMysqlMq\Model\DataObject"/> <topic name="test.schema.defined.by.method" schema="Magento\TestModuleMysqlMq\Model\DataObjectRepository::delayedOperation" is_synchronous="false"/> <topic name="demo.object.created" request="Magento\TestModuleMysqlMq\Model\DataObject"/> <topic name="demo.object.updated" request="Magento\TestModuleMysqlMq\Model\DataObject"/> diff --git a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue.xml b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue.xml index 362237c0c5e62..c879b271c6651 100644 --- a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue.xml +++ b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue.xml @@ -9,6 +9,9 @@ <broker topic="demo.exception" type="db" exchange="magento"> <queue consumer="demoConsumerWithException" name="queue-exception" handler="Magento\TestModuleMysqlMq\Model\Processor::processMessageWithException"/> </broker> + <broker topic="demo.connection.exception" type="db" exchange="magento"> + <queue consumer="demoConsumerWithConnectionException" name="queue-connection-exception" handler="Magento\TestModuleMysqlMq\Model\Processor::processMessageWithConnectionException"/> + </broker> <broker topic="test.schema.defined.by.method" type="db" exchange="magento"> <queue consumer="delayedOperationConsumer" name="demo-queue-6" handler="Magento\TestModuleMysqlMq\Model\DataObjectRepository::delayedOperation"/> </broker> diff --git a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_consumer.xml b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_consumer.xml index bb495a123a05d..6a3916a23b43b 100644 --- a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_consumer.xml +++ b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_consumer.xml @@ -10,5 +10,6 @@ <consumer name="demoConsumerQueueTwo" queue="queue-updated" connection="db" handler="Magento\TestModuleMysqlMq\Model\Processor::processObjectUpdated"/> <consumer name="demoConsumerQueueThree" queue="queue-custom-created" connection="db" handler="Magento\TestModuleMysqlMq\Model\Processor::processCustomObjectCreated"/> <consumer name="demoConsumerWithException" queue="queue-exception" connection="db" handler="Magento\TestModuleMysqlMq\Model\Processor::processMessageWithException"/> + <consumer name="demoConsumerWithConnectionException" queue="queue-connection-exception" connection="db" handler="Magento\TestModuleMysqlMq\Model\Processor::processMessageWithConnectionException"/> <consumer name="delayedOperationConsumer" queue="demo-queue-6" connection="db" handler="Magento\TestModuleMysqlMq\Model\DataObjectRepository::delayedOperation"/> </config> diff --git a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_publisher.xml b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_publisher.xml index a665e10ef5f14..639503a936cb5 100644 --- a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_publisher.xml +++ b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_publisher.xml @@ -9,6 +9,9 @@ <publisher topic="demo.exception"> <connection name="db" exchange="magento"/> </publisher> + <publisher topic="demo.connection.exception"> + <connection name="db" exchange="magento"/> + </publisher> <publisher topic="test.schema.defined.by.method"> <connection name="db" exchange="magento"/> </publisher> diff --git a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_topology.xml b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_topology.xml index 2df5485ee3447..3612438c37f4a 100644 --- a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_topology.xml +++ b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_topology.xml @@ -9,6 +9,7 @@ <exchange name="magento" type="topic" connection="db"> <binding id="demo.exception.consumer" topic="demo.exception" destination="queue-exception" destinationType="queue"/> + <binding id="demo.connection.exception.consumer" topic="demo.connection.exception" destination="queue-connection-exception" destinationType="queue"/> <binding id="test.schema.defined.by.method" topic="test.schema.defined.by.method" destination="demo-queue-6" destinationType="queue"/> <binding id="demo.object.created" topic="demo.object.created" destination="queue-created" destinationType="queue"/> <binding id="demo.object.updated" topic="demo.object.updated" destination="queue-updated" destinationType="queue"/> diff --git a/dev/tests/integration/testsuite/Magento/MessageQueue/Model/ConsumerTest.php b/dev/tests/integration/testsuite/Magento/MessageQueue/Model/ConsumerTest.php new file mode 100644 index 0000000000000..a3515b07f1e0b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MessageQueue/Model/ConsumerTest.php @@ -0,0 +1,109 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MessageQueue\Model; + +use Magento\Framework\MessageQueue\Consumer; +use Magento\Framework\MessageQueue\ConsumerFactory; +use Magento\Framework\MessageQueue\EnvelopeFactory; +use Magento\Framework\MessageQueue\QueueInterface; +use Magento\MysqlMq\Model\QueueManagement; +use Magento\MysqlMq\Model\ResourceModel\Queue; +use Magento\TestFramework\ObjectManager; +use PHPUnit\Framework\TestCase; + +/** + * Tests the different cases of consumers running by Consumer processor + */ +class ConsumerTest extends TestCase +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var Consumer + */ + private $model; + + /** + * @var Queue + */ + private $queueResource; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + $this->objectManager = ObjectManager::getInstance(); + /** @var ConsumerFactory $factory */ + $factory = $this->objectManager->get(ConsumerFactory::class); + $this->model = $factory->get('demoConsumerWithConnectionException'); + $this->queueResource = $this->objectManager->get(Queue::class); + } + + /** + * Test if after connection exception and retry + * message doesn't have success status but still has status in progress + * + * @return void + */ + public function testRunWithException(): void + { + /** @var EnvelopeFactory $envelopFactory */ + $envelopFactory = $this->objectManager->get(EnvelopeFactory::class); + $messageBody = '{"name":"test"}'; + $topicName = 'demo.connection.exception'; + $queueName = 'queue-connection-exception'; + $envelope = $envelopFactory->create(['body' => $messageBody, 'properties' => ['topic_name' => $topicName]]); + /** @var QueueInterface $queue */ + $queue = $this->objectManager->create( + \Magento\MysqlMq\Model\Driver\Queue::class, + ['queueName' => $queueName] + ); + $queue->push($envelope); + $messages = $this->queueResource->getMessages($queueName, 1); + $envelope = $envelopFactory->create(['body' => $messageBody, 'properties' => $messages[0]]); + $this->model->process(1); + $queue->reject($envelope); + $this->model->process(1); + $message = $this->getLastMessage($queueName); + $this->assertEquals(QueueManagement::MESSAGE_STATUS_IN_PROGRESS, $message['status']); + } + + /** + * Return last message by queue name + * + * @param string $queueName + * @return array + */ + private function getLastMessage(string $queueName) + { + $connection = $this->queueResource->getConnection(); + $select = $connection->select() + ->from( + ['queue_message' => $this->queueResource->getTable('queue_message')], + [] + )->join( + ['queue_message_status' => $this->queueResource->getTable('queue_message_status')], + 'queue_message.id = queue_message_status.message_id', + [ + QueueManagement::MESSAGE_QUEUE_RELATION_ID => 'id', + QueueManagement::MESSAGE_STATUS => 'status', + ] + )->join( + ['queue' => $this->queueResource->getTable('queue')], + 'queue.id = queue_message_status.queue_id', + [QueueManagement::MESSAGE_QUEUE_NAME => 'name'] + )->where('queue.name = ?', $queueName) + ->order(['queue_message_status.id DESC']); + + return $connection->fetchRow($select); + } +} diff --git a/dev/tests/integration/testsuite/Magento/MessageQueue/Model/ResourceModel/LockTest.php b/dev/tests/integration/testsuite/Magento/MessageQueue/Model/ResourceModel/LockTest.php new file mode 100644 index 0000000000000..bede370db29c4 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MessageQueue/Model/ResourceModel/LockTest.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MessageQueue\Model\ResourceModel; + +use Magento\Framework\MessageQueue\LockInterface; +use Magento\TestFramework\ObjectManager; +use PHPUnit\Framework\TestCase; + +/** + * Covers Lock resource model test cases + */ +class LockTest extends TestCase +{ + public function testSaveLock() + { + $objectManager = ObjectManager::getInstance(); + /** @var Lock $resourceModel */ + $resourceModel = $objectManager->get(Lock::class); + $lock = $objectManager->create(LockInterface::class); + $resourceModel->saveLock($lock); + self::assertNotEquals(null, $lock->getId()); + } +} From 79887430a29094e13dbdbc084a4ed8c06f19474e Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Wed, 30 Dec 2020 13:33:06 +0200 Subject: [PATCH 149/156] MC-30127: Product Price is mismatch in invoice and invoice PDF magento for Bundle Product 2.2.1 --- .../Model/Sales/Order/Pdf/Items/Invoice.php | 152 +++++--- .../Sales/Order/Pdf/Items/InvoiceTest.php | 352 ++++++++++++++++++ 2 files changed, 460 insertions(+), 44 deletions(-) create mode 100644 app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTest.php diff --git a/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php b/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php index 64e9f56dd65bc..26d0fd274014c 100644 --- a/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php +++ b/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php @@ -8,6 +8,7 @@ namespace Magento\Bundle\Model\Sales\Order\Pdf\Items; use Magento\Framework\Data\Collection\AbstractDb; +use Magento\Framework\DataObject; use Magento\Framework\Filesystem; use Magento\Framework\Filter\FilterManager; use Magento\Framework\Model\Context; @@ -69,34 +70,38 @@ public function __construct( } /** - * Draw item line + * Draw bundle product item line * * @return void - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function draw() { - $order = $this->getOrder(); - $item = $this->getItem(); - $pdf = $this->getPdf(); - $page = $this->getPage(); + $draw = $this->drawChildrenItems(); + $draw = $this->drawCustomOptions($draw); + $page = $this->getPdf()->drawLineBlocks($this->getPage(), $draw, ['table_header' => true]); + + $this->setPage($page); + } + + /** + * Draw bundle product children items + * + * @return array + */ + private function drawChildrenItems(): array + { $this->_setFontRegular(); - $items = $this->getChildren($item); $prevOptionId = ''; $drawItems = []; - - foreach ($items as $childItem) { - $line = []; - + $optionId = 0; + foreach ($this->getChildren($this->getItem()) as $childItem) { + $lines = []; + $index = array_key_last($lines) !== null ? array_key_last($lines) + 1 : 0; $attributes = $this->getSelectionAttributes($childItem); if (is_array($attributes)) { $optionId = $attributes['option_id']; - } else { - $optionId = 0; } if (!isset($drawItems[$optionId])) { @@ -104,15 +109,14 @@ public function draw() } if ($childItem->getOrderItem()->getParentItem() && $prevOptionId != $attributes['option_id']) { - $line[0] = [ + $lines[$index][] = [ 'font' => 'italic', 'text' => $this->string->split($attributes['option_label'], 45, true, true), 'feed' => 35, ]; - $drawItems[$optionId] = ['lines' => [$line], 'height' => 15]; - - $line = []; + $drawItems[$optionId] = ['height' => 15]; + $index++; $prevOptionId = $attributes['option_id']; } @@ -124,35 +128,97 @@ public function draw() $feed = 35; $name = $childItem->getName(); } - $line[] = ['text' => $this->string->split($name, 35, true, true), 'feed' => $feed]; + $lines[$index][] = ['text' => $this->string->split($name, 35, true, true), 'feed' => $feed]; - // draw SKUs - if (!$childItem->getOrderItem()->getParentItem()) { - $text = []; - foreach ($this->string->split($item->getSku(), 17) as $part) { - $text[] = $part; - } - $line[] = ['text' => $text, 'feed' => 255]; - } + $lines = $this->drawSkus($childItem, $lines); - // draw prices - if ($this->canShowPriceInfo($childItem)) { - $price = $order->formatPriceTxt($childItem->getPrice()); - $line[] = ['text' => $price, 'feed' => 395, 'font' => 'bold', 'align' => 'right']; - $line[] = ['text' => $childItem->getQty() * 1, 'feed' => 435, 'font' => 'bold']; + $lines = $this->drawPrices($childItem, $lines); + $drawItems[$optionId]['lines'] = $lines; + } - $tax = $order->formatPriceTxt($childItem->getTaxAmount()); - $line[] = ['text' => $tax, 'feed' => 495, 'font' => 'bold', 'align' => 'right']; + return $drawItems; + } - $row_total = $order->formatPriceTxt($childItem->getRowTotal()); - $line[] = ['text' => $row_total, 'feed' => 565, 'font' => 'bold', 'align' => 'right']; + /** + * Draw sku parts + * + * @param DataObject $childItem + * @param array $lines + * @return array + */ + private function drawSkus(DataObject $childItem, array $lines): array + { + $index = array_key_last($lines); + if (!$childItem->getOrderItem()->getParentItem()) { + $text = []; + foreach ($this->string->split($this->getItem()->getSku(), 17) as $part) { + $text[] = $part; } + $lines[$index][] = ['text' => $text, 'feed' => 255]; + } + + return $lines; + } - $drawItems[$optionId]['lines'][] = $line; + /** + * Draw prices for bundle product children items + * + * @param DataObject $childItem + * @param array $lines + * @return array + */ + private function drawPrices(DataObject $childItem, array $lines): array + { + $index = array_key_last($lines); + if ($this->canShowPriceInfo($childItem)) { + $lines[$index][] = ['text' => $childItem->getQty() * 1, 'feed' => 435, 'align' => 'right']; + + $tax = $this->getOrder()->formatPriceTxt($childItem->getTaxAmount()); + $lines[$index][] = ['text' => $tax, 'feed' => 495, 'font' => 'bold', 'align' => 'right']; + + $item = $this->getItem(); + $this->_item = $childItem; + $feedPrice = 380; + $feedSubtotal = $feedPrice + 185; + foreach ($this->getItemPricesForDisplay() as $priceData) { + if (isset($priceData['label'])) { + // draw Price label + $lines[$index][] = ['text' => $priceData['label'], 'feed' => $feedPrice, 'align' => 'right']; + // draw Subtotal label + $lines[$index][] = ['text' => $priceData['label'], 'feed' => $feedSubtotal, 'align' => 'right']; + $index++; + } + // draw Price + $lines[$index][] = [ + 'text' => $priceData['price'], + 'feed' => $feedPrice, + 'font' => 'bold', + 'align' => 'right', + ]; + // draw Subtotal + $lines[$index][] = [ + 'text' => $priceData['subtotal'], + 'feed' => $feedSubtotal, + 'font' => 'bold', + 'align' => 'right', + ]; + $index++; + } + $this->_item = $item; } - // custom options - $options = $item->getOrderItem()->getProductOptions(); + return $lines; + } + + /** + * Draw bundle product custom options + * + * @param array $draw + * @return array + */ + private function drawCustomOptions(array $draw): array + { + $options = $this->getItem()->getOrderItem()->getProductOptions(); if ($options && isset($options['options'])) { foreach ($options['options'] as $option) { $lines = []; @@ -180,12 +246,10 @@ public function draw() $lines[][] = ['text' => $text, 'feed' => 40]; } - $drawItems[] = ['lines' => $lines, 'height' => 15]; + $draw[] = ['lines' => $lines, 'height' => 15]; } } - $page = $pdf->drawLineBlocks($page, $drawItems, ['table_header' => true]); - - $this->setPage($page); + return $draw; } } diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTest.php new file mode 100644 index 0000000000000..e93d231383820 --- /dev/null +++ b/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTest.php @@ -0,0 +1,352 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Bundle\Test\Unit\Model\Sales\Order\Pdf\Items; + +use Magento\Bundle\Model\Sales\Order\Pdf\Items\Invoice; +use Magento\Framework\Data\Collection\AbstractDb; +use Magento\Framework\DataObject; +use Magento\Framework\Filesystem; +use Magento\Framework\Filter\FilterManager; +use Magento\Framework\Model\Context; +use Magento\Framework\Model\ResourceModel\AbstractResource; +use Magento\Framework\Registry; +use Magento\Framework\Serialize\Serializer\Json; +use Magento\Framework\Stdlib\StringUtils; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Pdf\Invoice as InvoicePdf; +use Magento\Tax\Helper\Data; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use Zend_Pdf_Page; + +/** + * Covers bundle order item invoice print logic + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class InvoiceTest extends TestCase +{ + /** + * @var Invoice|MockObject + */ + private $model; + + /** + * @var Data|MockObject + */ + private $taxDataMock; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + $contextMock = $this->createMock(Context::class); + $registryMock = $this->createMock(Registry::class); + $this->taxDataMock = $this->createMock(Data::class); + $directoryMock = $this->createMock(Filesystem\Directory\Read::class); + $directoryMock->expects($this->any())->method('getAbsolutePath')->willReturn(''); + $filesystemMock = $this->createMock(Filesystem::class); + $filesystemMock->expects($this->any())->method('getDirectoryRead')->willReturn($directoryMock); + $filterManagerMock = $this->createMock(FilterManager::class); + $stringUtilsMock = $this->createMock(StringUtils::class); + $stringUtilsMock->expects($this->any())->method('split')->willReturnArgument(0); + $resourceMock = $this->createMock(AbstractResource::class); + $collectionMock = $this->createMock(AbstractDb::class); + $serializerMock = $this->createMock(Json::class); + + $this->model = $this->getMockBuilder(Invoice::class) + ->setConstructorArgs( + [ + $contextMock, + $registryMock, + $this->taxDataMock, + $filesystemMock, + $filterManagerMock, + $stringUtilsMock, + $serializerMock, + $resourceMock, + $collectionMock, + [], + ] + ) + ->onlyMethods( + [ + '_setFontRegular', + 'getChildren', + 'isShipmentSeparately', + 'isChildCalculated', + 'getValueHtml', + 'getSelectionAttributes', + ] + ) + ->getMock(); + } + + /** + * @dataProvider invoiceDataProvider + * @param array $expected + * @param string $method + */ + public function testDrawPrice(array $expected, string $method): void + { + $this->taxDataMock->expects($this->any())->method($method)->willReturn(true); + $pageMock = $this->createMock(Zend_Pdf_Page::class); + $this->model->setPage($pageMock); + $pdfMock = $this->createMock(InvoicePdf::class); + $pdfMock->expects($this->any())->method('drawLineBlocks')->with( + $pageMock, + $expected, + ['table_header' => true] + )->willReturn($pageMock); + $this->model->setPdf($pdfMock); + + $this->prepareModel(); + $this->model->draw(); + } + + /** + * @return array[] + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function invoiceDataProvider(): array + { + return [ + 'display_both' => [ + 'expected' => [ + 1 => [ + 'height' => 15, + 'lines' => [ + [ + [ + 'text' => 'test option', + 'feed' => 35, + 'font' => 'italic', + + ], + ], + [ + [ + 'text' => 'Simple1', + 'feed' => 40, + ], + [ + 'text' => 2, + 'feed' => 435, + 'align' => 'right', + ], + [ + 'text' => 1.66, + 'feed' => 495, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => 'Excl. Tax:', + 'feed' => 380, + 'align' => 'right', + ], + [ + 'text' => 'Excl. Tax:', + 'feed' => 565, + 'align' => 'right', + ], + ], + [ + [ + 'text' => '10.00', + 'feed' => 380, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '20.00', + 'feed' => 565, + 'font' => 'bold', + 'align' => 'right', + ], + ], + [ + [ + 'text' => 'Incl. Tax:', + 'feed' => 380, + 'align' => 'right', + ], + [ + 'text' => 'Incl. Tax:', + 'feed' => 565, + 'align' => 'right', + ], + ], + [ + [ + 'text' => '10.83', + 'feed' => 380, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '21.66', + 'feed' => 565, + 'font' => 'bold', + 'align' => 'right', + ], + ], + ], + ], + ], + 'tax_mock_method' => 'displaySalesBothPrices', + ], + 'including_tax' => [ + 'expected' => [ + 1 => [ + 'height' => 15, + 'lines' => [ + [ + [ + 'text' => 'test option', + 'feed' => 35, + 'font' => 'italic', + + ], + ], + [ + [ + 'text' => 'Simple1', + 'feed' => 40, + ], + [ + 'text' => 2, + 'feed' => 435, + 'align' => 'right', + ], + [ + 'text' => 1.66, + 'feed' => 495, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '10.83', + 'feed' => 380, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '21.66', + 'feed' => 565, + 'font' => 'bold', + 'align' => 'right', + ], + ], + ], + ], + ], + 'tax_mock_method' => 'displaySalesPriceInclTax', + ], + 'excluding_tax' => [ + 'expected' => [ + 1 => [ + 'height' => 15, + 'lines' => [ + [ + [ + 'text' => 'test option', + 'feed' => 35, + 'font' => 'italic', + + ], + ], + [ + [ + 'text' => 'Simple1', + 'feed' => 40, + ], + [ + 'text' => 2, + 'feed' => 435, + 'align' => 'right', + ], + [ + 'text' => 1.66, + 'feed' => 495, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '10.00', + 'feed' => 380, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '20.00', + 'feed' => 565, + 'font' => 'bold', + 'align' => 'right', + ], + ], + ], + ], + ], + 'tax_mock_method' => 'displaySalesPriceExclTax', + ], + ]; + } + + /** + * Prepare invoice draw model for test execution + * + * @return void + */ + private function prepareModel(): void + { + $parentItem = new DataObject( + [ + 'sku' => 'bundle-simple', + 'name' => 'Bundle', + 'order_item' => new DataObject( + [ + 'product_options' => [], + ] + ), + ] + ); + $items = [ + new DataObject( + [ + 'name' => 'Simple1', + 'sku' => 'simple1', + 'price' => '10.00', + 'price_incl_tax' => '10.83', + 'row_total' => '20.00', + 'row_total_incl_tax' => '21.66', + 'qty' => '2', + 'tax_amount' => '1.66', + 'order_item' => new DataObject( + [ + 'parent_item' => $parentItem, + ] + ), + ] + ), + ]; + $orderMock = $this->createMock(Order::class); + + $this->model->expects($this->any())->method('getChildren')->willReturn($items); + $this->model->expects($this->any())->method('isShipmentSeparately')->willReturn(false); + $this->model->expects($this->any())->method('isChildCalculated')->willReturn(true); + $this->model->expects($this->any())->method('getValueHtml')->willReturn($items[0]->getName()); + $this->model->expects($this->any())->method('getSelectionAttributes')->willReturn( + ['option_id' => 1, 'option_label' => 'test option'] + ); + + $orderMock->expects($this->any())->method('formatPriceTxt')->willReturnArgument(0); + $this->model->setOrder($orderMock); + $this->model->setItem($parentItem); + } +} From 1ce3e1fe70b5c549ff519560dd7ada48f7a2034c Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Thu, 31 Dec 2020 16:36:31 +0200 Subject: [PATCH 150/156] MC-30127: Product Price is mismatch in invoice and invoice PDF magento for Bundle Product 2.2.1 --- .../Model/Sales/Order/Pdf/Items/Invoice.php | 5 +- .../Sales/Order/Pdf/Items/InvoiceTest.php | 216 ++---------- .../Order/Pdf/Items/InvoiceTestProvider.php | 329 ++++++++++++++++++ 3 files changed, 355 insertions(+), 195 deletions(-) create mode 100644 app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTestProvider.php diff --git a/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php b/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php index 26d0fd274014c..a7f0a70b45219 100644 --- a/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php +++ b/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php @@ -96,8 +96,8 @@ private function drawChildrenItems(): array $prevOptionId = ''; $drawItems = []; $optionId = 0; + $lines = []; foreach ($this->getChildren($this->getItem()) as $childItem) { - $lines = []; $index = array_key_last($lines) !== null ? array_key_last($lines) + 1 : 0; $attributes = $this->getSelectionAttributes($childItem); if (is_array($attributes)) { @@ -115,7 +115,6 @@ private function drawChildrenItems(): array 'feed' => 35, ]; - $drawItems[$optionId] = ['height' => 15]; $index++; $prevOptionId = $attributes['option_id']; } @@ -133,8 +132,8 @@ private function drawChildrenItems(): array $lines = $this->drawSkus($childItem, $lines); $lines = $this->drawPrices($childItem, $lines); - $drawItems[$optionId]['lines'] = $lines; } + $drawItems[$optionId]['lines'] = $lines; return $drawItems; } diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTest.php index e93d231383820..e5bf94241dbd9 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTest.php @@ -88,7 +88,7 @@ protected function setUp(): void } /** - * @dataProvider invoiceDataProvider + * @dataProvider \Magento\Bundle\Test\Unit\Model\Sales\Order\Pdf\Items\InvoiceTestProvider::getData * @param array $expected * @param string $method */ @@ -109,195 +109,6 @@ public function testDrawPrice(array $expected, string $method): void $this->model->draw(); } - /** - * @return array[] - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function invoiceDataProvider(): array - { - return [ - 'display_both' => [ - 'expected' => [ - 1 => [ - 'height' => 15, - 'lines' => [ - [ - [ - 'text' => 'test option', - 'feed' => 35, - 'font' => 'italic', - - ], - ], - [ - [ - 'text' => 'Simple1', - 'feed' => 40, - ], - [ - 'text' => 2, - 'feed' => 435, - 'align' => 'right', - ], - [ - 'text' => 1.66, - 'feed' => 495, - 'font' => 'bold', - 'align' => 'right', - ], - [ - 'text' => 'Excl. Tax:', - 'feed' => 380, - 'align' => 'right', - ], - [ - 'text' => 'Excl. Tax:', - 'feed' => 565, - 'align' => 'right', - ], - ], - [ - [ - 'text' => '10.00', - 'feed' => 380, - 'font' => 'bold', - 'align' => 'right', - ], - [ - 'text' => '20.00', - 'feed' => 565, - 'font' => 'bold', - 'align' => 'right', - ], - ], - [ - [ - 'text' => 'Incl. Tax:', - 'feed' => 380, - 'align' => 'right', - ], - [ - 'text' => 'Incl. Tax:', - 'feed' => 565, - 'align' => 'right', - ], - ], - [ - [ - 'text' => '10.83', - 'feed' => 380, - 'font' => 'bold', - 'align' => 'right', - ], - [ - 'text' => '21.66', - 'feed' => 565, - 'font' => 'bold', - 'align' => 'right', - ], - ], - ], - ], - ], - 'tax_mock_method' => 'displaySalesBothPrices', - ], - 'including_tax' => [ - 'expected' => [ - 1 => [ - 'height' => 15, - 'lines' => [ - [ - [ - 'text' => 'test option', - 'feed' => 35, - 'font' => 'italic', - - ], - ], - [ - [ - 'text' => 'Simple1', - 'feed' => 40, - ], - [ - 'text' => 2, - 'feed' => 435, - 'align' => 'right', - ], - [ - 'text' => 1.66, - 'feed' => 495, - 'font' => 'bold', - 'align' => 'right', - ], - [ - 'text' => '10.83', - 'feed' => 380, - 'font' => 'bold', - 'align' => 'right', - ], - [ - 'text' => '21.66', - 'feed' => 565, - 'font' => 'bold', - 'align' => 'right', - ], - ], - ], - ], - ], - 'tax_mock_method' => 'displaySalesPriceInclTax', - ], - 'excluding_tax' => [ - 'expected' => [ - 1 => [ - 'height' => 15, - 'lines' => [ - [ - [ - 'text' => 'test option', - 'feed' => 35, - 'font' => 'italic', - - ], - ], - [ - [ - 'text' => 'Simple1', - 'feed' => 40, - ], - [ - 'text' => 2, - 'feed' => 435, - 'align' => 'right', - ], - [ - 'text' => 1.66, - 'feed' => 495, - 'font' => 'bold', - 'align' => 'right', - ], - [ - 'text' => '10.00', - 'feed' => 380, - 'font' => 'bold', - 'align' => 'right', - ], - [ - 'text' => '20.00', - 'feed' => 565, - 'font' => 'bold', - 'align' => 'right', - ], - ], - ], - ], - ], - 'tax_mock_method' => 'displaySalesPriceExclTax', - ], - ]; - } - /** * Prepare invoice draw model for test execution * @@ -334,16 +145,37 @@ private function prepareModel(): void ), ] ), + new DataObject( + [ + 'name' => 'Simple2', + 'sku' => 'simple2', + 'price' => '5.00', + 'price_incl_tax' => '5.41', + 'row_total' => '10.00', + 'row_total_incl_tax' => '10.83', + 'qty' => '2', + 'tax_amount' => '0.83', + 'order_item' => new DataObject( + [ + 'parent_item' => $parentItem, + ] + ), + ] + ), ]; $orderMock = $this->createMock(Order::class); $this->model->expects($this->any())->method('getChildren')->willReturn($items); $this->model->expects($this->any())->method('isShipmentSeparately')->willReturn(false); $this->model->expects($this->any())->method('isChildCalculated')->willReturn(true); - $this->model->expects($this->any())->method('getValueHtml')->willReturn($items[0]->getName()); - $this->model->expects($this->any())->method('getSelectionAttributes')->willReturn( + $this->model->expects($this->at(2))->method('getSelectionAttributes')->willReturn( ['option_id' => 1, 'option_label' => 'test option'] ); + $this->model->expects($this->at(3))->method('getValueHtml')->willReturn($items[0]->getName()); + $this->model->expects($this->at(5))->method('getSelectionAttributes')->willReturn( + ['option_id' => 1, 'option_label' => 'second option'] + ); + $this->model->expects($this->at(6))->method('getValueHtml')->willReturn($items[1]->getName()); $orderMock->expects($this->any())->method('formatPriceTxt')->willReturnArgument(0); $this->model->setOrder($orderMock); diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTestProvider.php b/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTestProvider.php new file mode 100644 index 0000000000000..7de3d383d006e --- /dev/null +++ b/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTestProvider.php @@ -0,0 +1,329 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Bundle\Test\Unit\Model\Sales\Order\Pdf\Items; + +/** + * Data provider class for InvoiceTest class + */ +class InvoiceTestProvider +{ + /** + * Returns invoice test variations data + * + * @return array[] + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function getData(): array + { + return [ + 'display_both' => [ + 'expected' => [ + 1 => [ + 'height' => 15, + 'lines' => [ + [ + [ + 'text' => 'test option', + 'feed' => 35, + 'font' => 'italic', + + ], + ], + [ + [ + 'text' => 'Simple1', + 'feed' => 40, + ], + [ + 'text' => 2, + 'feed' => 435, + 'align' => 'right', + ], + [ + 'text' => 1.66, + 'feed' => 495, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => 'Excl. Tax:', + 'feed' => 380, + 'align' => 'right', + ], + [ + 'text' => 'Excl. Tax:', + 'feed' => 565, + 'align' => 'right', + ], + ], + [ + [ + 'text' => '10.00', + 'feed' => 380, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '20.00', + 'feed' => 565, + 'font' => 'bold', + 'align' => 'right', + ], + ], + [ + [ + 'text' => 'Incl. Tax:', + 'feed' => 380, + 'align' => 'right', + ], + [ + 'text' => 'Incl. Tax:', + 'feed' => 565, + 'align' => 'right', + ], + ], + [ + [ + 'text' => '10.83', + 'feed' => 380, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '21.66', + 'feed' => 565, + 'font' => 'bold', + 'align' => 'right', + ], + ], + [ + [ + 'text' => 'Simple2', + 'feed' => 40, + ], + [ + 'text' => 2, + 'feed' => 435, + 'align' => 'right', + ], + [ + 'text' => 0.83, + 'feed' => 495, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => 'Excl. Tax:', + 'feed' => 380, + 'align' => 'right', + ], + [ + 'text' => 'Excl. Tax:', + 'feed' => 565, + 'align' => 'right', + ], + ], + [ + [ + 'text' => '5.00', + 'feed' => 380, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '10.00', + 'feed' => 565, + 'font' => 'bold', + 'align' => 'right', + ], + ], + [ + [ + 'text' => 'Incl. Tax:', + 'feed' => 380, + 'align' => 'right', + ], + [ + 'text' => 'Incl. Tax:', + 'feed' => 565, + 'align' => 'right', + ], + ], + [ + [ + 'text' => '5.41', + 'feed' => 380, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '10.83', + 'feed' => 565, + 'font' => 'bold', + 'align' => 'right', + ], + ], + ], + ], + ], + 'tax_mock_method' => 'displaySalesBothPrices', + ], + 'including_tax' => [ + 'expected' => [ + 1 => [ + 'height' => 15, + 'lines' => [ + [ + [ + 'text' => 'test option', + 'feed' => 35, + 'font' => 'italic', + ], + ], + [ + [ + 'text' => 'Simple1', + 'feed' => 40, + ], + [ + 'text' => 2, + 'feed' => 435, + 'align' => 'right', + ], + [ + 'text' => 1.66, + 'feed' => 495, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '10.83', + 'feed' => 380, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '21.66', + 'feed' => 565, + 'font' => 'bold', + 'align' => 'right', + ], + ], + [ + [ + 'text' => 'Simple2', + 'feed' => 40, + ], + [ + 'text' => 2, + 'feed' => 435, + 'align' => 'right', + ], + [ + 'text' => 0.83, + 'feed' => 495, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '5.41', + 'feed' => 380, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '10.83', + 'feed' => 565, + 'font' => 'bold', + 'align' => 'right', + ], + ], + ], + ], + ], + 'tax_mock_method' => 'displaySalesPriceInclTax', + ], + 'excluding_tax' => [ + 'expected' => [ + 1 => [ + 'height' => 15, + 'lines' => [ + [ + [ + 'text' => 'test option', + 'feed' => 35, + 'font' => 'italic', + + ], + ], + [ + [ + 'text' => 'Simple1', + 'feed' => 40, + ], + [ + 'text' => 2, + 'feed' => 435, + 'align' => 'right', + ], + [ + 'text' => 1.66, + 'feed' => 495, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '10.00', + 'feed' => 380, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '20.00', + 'feed' => 565, + 'font' => 'bold', + 'align' => 'right', + ], + ], + [ + [ + 'text' => 'Simple2', + 'feed' => 40, + ], + [ + 'text' => 2, + 'feed' => 435, + 'align' => 'right', + ], + [ + 'text' => 0.83, + 'feed' => 495, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '5.00', + 'feed' => 380, + 'font' => 'bold', + 'align' => 'right', + ], + [ + 'text' => '10.00', + 'feed' => 565, + 'font' => 'bold', + 'align' => 'right', + ], + ], + ], + ], + ], + 'tax_mock_method' => 'displaySalesPriceExclTax', + ], + ]; + } +} From 245fc040700e534181cff1956688c77c17eb33d1 Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Mon, 4 Jan 2021 17:06:37 +0200 Subject: [PATCH 151/156] MC-40061: Create automated test for: "Subscribe to stock price alert" --- .../Product/Edit/Tab/Alerts/StockTest.php | 90 +++++++++++++++++++ .../Product/Form/Modifier/AlertsTest.php | 56 ++++++++++++ .../_files/product_alert_rollback.php | 33 +++++++ .../_files/stock_alert_on_second_website.php | 66 ++++++++++++++ ...stock_alert_on_second_website_rollback.php | 52 +++++++++++ 5 files changed, 297 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/StockTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AlertsTest.php create mode 100644 dev/tests/integration/testsuite/Magento/ProductAlert/_files/product_alert_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/ProductAlert/_files/stock_alert_on_second_website.php create mode 100644 dev/tests/integration/testsuite/Magento/ProductAlert/_files/stock_alert_on_second_website_rollback.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/StockTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/StockTest.php new file mode 100644 index 0000000000000..d03bc935bcd72 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/StockTest.php @@ -0,0 +1,90 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Alerts; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\View\LayoutInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Check stock alert grid + * + * @see \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Alerts\Stock + * + * @magentoAppArea adminhtml + */ +class StockTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Stock */ + private $block; + + /** @var StoreManagerInterface */ + private $storeManager; + + /** @var ProductRepositoryInterface */ + private $productRepository; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->block = $this->objectManager->get(LayoutInterface::class)->createBlock(Stock::class); + $this->storeManager = $this->objectManager->get(StoreManagerInterface::class); + $this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + } + + /** + * @dataProvider alertsDataProvider + * + * @magentoDbIsolation disabled + * @magentoDataFixture Magento/ProductAlert/_files/product_alert.php + * @magentoDataFixture Magento/ProductAlert/_files/stock_alert_on_second_website.php + * + * @param string $sku + * @param string $expectedEmail + * @param string|null $storeCode + * @return void + */ + public function testGridCollectionWIthStoreId(string $sku, string $expectedEmail, ?string $storeCode = null): void + { + $productId = (int)$this->productRepository->get($sku)->getId(); + $storeId = $storeCode ? (int)$this->storeManager->getStore($storeCode)->getId() : null; + $this->block->getRequest()->setParams(['id' => $productId, 'store' => $storeId]); + $collection = $this->block->getPreparedCollection(); + $this->assertCount(1, $collection); + $this->assertEquals($expectedEmail, $collection->getFirstItem()->getEmail()); + } + + /** + * @return array + */ + public function alertsDataProvider(): array + { + return [ + 'without_store_id_filter' => [ + 'product_sku' => 'simple', + 'expected_customer_emails' => 'customer@example.com', + ], + 'with_store_id_filter' => [ + 'product_sku' => 'simple_on_second_website', + 'expected_customer_emails' => 'customer_second_ws_with_addr@example.com', + 'store_code' => 'fixture_third_store', + ], + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AlertsTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AlertsTest.php new file mode 100644 index 0000000000000..96ddc66c875b7 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AlertsTest.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Ui\DataProvider\Product\Form\Modifier; + +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\Xpath; +use PHPUnit\Framework\TestCase; + +/** + * Alerts modifier test + * + * @see \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Alerts + * + * @magentoAppArea adminhtml + */ +class AlertsTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Alerts */ + private $stockAlertsModifier; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->stockAlertsModifier = $this->objectManager->get(Alerts::class); + } + + /** + * @magentoConfigFixture current_store catalog/productalert/allow_stock 1 + * + * @return void + */ + public function testModifyMeta(): void + { + $meta = $this->stockAlertsModifier->modifyMeta([]); + $this->assertArrayHasKey('alerts', $meta); + $content = $meta['alerts']['children'][Alerts::DATA_SCOPE_STOCK]['arguments']['data']['config']['content']; + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath("//div[@data-grid-id='alertStock']", $content) + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/ProductAlert/_files/product_alert_rollback.php b/dev/tests/integration/testsuite/Magento/ProductAlert/_files/product_alert_rollback.php new file mode 100644 index 0000000000000..e9c4900ded341 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ProductAlert/_files/product_alert_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\Customer\Api\CustomerRepositoryInterface; +use Magento\Framework\Registry; +use Magento\ProductAlert\Model\StockFactory; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +$objectManager = Bootstrap::getObjectManager(); +/** @var StockFactory $stockFactory */ +$stockFactory = $objectManager->get(StockFactory::class); +/** @var CustomerRepositoryInterface $customerRepository */ +$customerRepository = $objectManager->get(CustomerRepositoryInterface::class); +$customer = $customerRepository->get('customer@example.com'); +/** @var Registry $registry */ +$registry = $objectManager->get(Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +$stockAlert = $stockFactory->create(); +$stockAlert->deleteCustomer((int)$customer->getId()); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); + +Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer_rollback.php'); +Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_simple_rollback.php'); diff --git a/dev/tests/integration/testsuite/Magento/ProductAlert/_files/stock_alert_on_second_website.php b/dev/tests/integration/testsuite/Magento/ProductAlert/_files/stock_alert_on_second_website.php new file mode 100644 index 0000000000000..b9d4c4b81f69b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ProductAlert/_files/stock_alert_on_second_website.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\Data\ProductInterfaceFactory; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Catalog\Model\Product\Visibility; +use Magento\CatalogInventory\Api\Data\StockStatusInterface; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\ProductAlert\Model\ResourceModel\Stock as StockResource; +use Magento\ProductAlert\Model\StockFactory; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer_for_second_website_with_address.php'); + +$objectManager = Bootstrap::getObjectManager(); +/** @var StoreManagerInterface $storeManager */ +$storeManager = $objectManager->get(StoreManagerInterface::class); +$secondWebsite = $storeManager->getWebsite('test'); +/** @var ProductInterfaceFactory $productFactory */ +$productFactory = $objectManager->get(ProductInterfaceFactory::class); +/** @var ProductRepositoryInterface $peoductRepository */ +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +/** @var StockFactory $stockFactory */ +$stockFactory = $objectManager->get(StockFactory::class); +/** @var StockResource $stockResource */ +$stockResource = $objectManager->get(StockResource::class); +/** @var CustomerRepositoryInterface $customerRepository */ +$customerRepository = $objectManager->get(CustomerRepositoryInterface::class); +$customer = $customerRepository->get('customer_second_ws_with_addr@example.com', (int)$secondWebsite->getId()); + + +$product = $productFactory->create(); +$product + ->setTypeId('simple') + ->setAttributeSetId(4) + ->setWebsiteIds([(int)$secondWebsite->getId()]) + ->setName('Simple Product2') + ->setSku('simple_on_second_website') + ->setPrice(10) + ->setMetaTitle('meta title2') + ->setMetaKeyword('meta keyword2') + ->setMetaDescription('meta description2') + ->setVisibility(Visibility::VISIBILITY_BOTH) + ->setStatus(Status::STATUS_ENABLED) + ->setStockData(['is_in_stock' => StockStatusInterface::STATUS_OUT_OF_STOCK]); + +$productRepository->save($product); + +$stockAlert = $stockFactory->create(); +$stockAlert->setCustomerId( + $customer->getId() +)->setProductId( + (int)$productRepository->get($product->getSku())->getId() +)->setWebsiteId( + (int)$secondWebsite->getId() +)->setStoreId( + (int)$storeManager->getStore('fixture_third_store')->getId() +); +$stockResource->save($stockAlert); diff --git a/dev/tests/integration/testsuite/Magento/ProductAlert/_files/stock_alert_on_second_website_rollback.php b/dev/tests/integration/testsuite/Magento/ProductAlert/_files/stock_alert_on_second_website_rollback.php new file mode 100644 index 0000000000000..0fa5f73a7927c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ProductAlert/_files/stock_alert_on_second_website_rollback.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Registry; +use Magento\ProductAlert\Model\ResourceModel\Stock as StockResource; +use Magento\ProductAlert\Model\StockFactory; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + + +$objectManager = Bootstrap::getObjectManager(); +/** @var ProductRepositoryInterface $peoductRepository */ +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +/** @var StockFactory $stockFactory */ +$stockFactory = $objectManager->get(StockFactory::class); +/** @var StockResource $stockResource */ +$stockResource = $objectManager->get(StockResource::class); +/** @var StoreManagerInterface $storeManager */ +$storeManager = $objectManager->get(StoreManagerInterface::class); +$secondWebsite = $storeManager->getWebsite('test'); +/** @var CustomerRepositoryInterface $customerRepository */ +$customerRepository = $objectManager->get(CustomerRepositoryInterface::class); +$customer = $customerRepository->get('customer_second_ws_with_addr@example.com', (int)$secondWebsite->getId()); +/** @var Registry $registry */ +$registry = $objectManager->get(Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +try { + $productRepository->deleteById('simple_on_second_website'); +} catch (NoSuchEntityException $e) { + //already removed +} + + +$stockAlert = $stockFactory->create(); +$stockAlert->deleteCustomer((int)$customer->getId(), (int)$secondWebsite->getId()); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); + +Resolver::getInstance() + ->requireDataFixture('Magento/Customer/_files/customer_for_second_website_with_address_rollback.php'); From d866a0b69b35f7207f743d48ad9bcc2c3280f85c Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Mon, 4 Jan 2021 18:17:41 +0200 Subject: [PATCH 152/156] MC-40070: Create automated test for: "Try to save product with string type qty value" --- .../Product/Attribute/Backend/StockTest.php | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/StockTest.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/StockTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/StockTest.php new file mode 100644 index 0000000000000..24d5b668ac09c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/StockTest.php @@ -0,0 +1,62 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Model\Product\Attribute\Backend; + +use Magento\Catalog\Api\Data\ProductInterfaceFactory; +use Magento\Catalog\Model\Product; +use Magento\Eav\Model\Config; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Test class for backend stock attribute model. + * + * @see \Magento\Catalog\Model\Product\Attribute\Backend\Stock + * + * @magentoAppArea adminhtml + */ +class StockTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var ProductInterfaceFactory */ + private $productFactory; + + /** @var Stock */ + private $model; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->productFactory = $this->objectManager->get(ProductInterfaceFactory::class); + $this->model = $this->objectManager->get(Stock::class); + $this->model->setAttribute( + $this->objectManager->get(Config::class)->getAttribute(Product::ENTITY, 'quantity_and_stock_status') + ); + } + + /** + * @return void + */ + public function testValidate(): void + { + $this->expectException(LocalizedException::class); + $this->expectErrorMessage((string)__('Please enter a valid number in this field.')); + $product = $this->productFactory->create(); + $product->setQuantityAndStockStatus(['qty' => 'string']); + $this->model->validate($product); + } +} From f5932e2fe2abbd8d011c53cc886d57f5d6464f20 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 5 Jan 2021 08:30:55 +0200 Subject: [PATCH 153/156] MC-40277: Integration test failed \Magento\Catalog\Block\Product\View\Options\Type\DateTest::testToHtmlWithDropDown --- .../Catalog/Block/Product/View/Options/Type/DateTest.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/View/Options/Type/DateTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/View/Options/Type/DateTest.php index 91a54d8fc13fa..d21fdf190c0b8 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/View/Options/Type/DateTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/View/Options/Type/DateTest.php @@ -20,6 +20,7 @@ /** * @magentoDataFixture Magento/Catalog/_files/product_simple.php + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class DateTest extends TestCase { @@ -96,9 +97,10 @@ protected function tearDown(): void } /** - * @magentoAppArea frontend * @param array $data * @param array $expected + * @magentoAppArea frontend + * @magentoConfigFixture current_store catalog/custom_options/year_range 2020,2030 * @dataProvider toHtmlWithDropDownDataProvider */ public function testToHtmlWithDropDown(array $data, array $expected): void @@ -108,11 +110,12 @@ public function testToHtmlWithDropDown(array $data, array $expected): void } /** - * @magentoAppArea frontend - * @magentoConfigFixture current_store catalog/custom_options/use_calendar 1 * @param array $data * @param array $expected * @param string|null $locale + * @magentoAppArea frontend + * @magentoConfigFixture current_store catalog/custom_options/use_calendar 1 + * @magentoConfigFixture current_store catalog/custom_options/year_range 2020,2030 * @dataProvider toHtmlWithCalendarDataProvider */ public function testToHtmlWithCalendar(array $data, array $expected, ?string $locale = null): void From 0292cb250ec6c9a436486b7e6d1e11c4e3a95286 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 5 Jan 2021 08:54:49 +0200 Subject: [PATCH 154/156] MC-40277: Integration test failed \Magento\Catalog\Block\Product\View\Options\Type\DateTest::testToHtmlWithDropDown --- .../CreateProductAttributeEntityDateTest.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml index d1f7adb8a902c..9d805b2cf7930 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml @@ -14,8 +14,8 @@ <title value="Admin should be able to create a Date product attribute"/> <description value="Admin should be able to create a Date product attribute"/> <severity value="BLOCKER"/> - <testCaseId value="MC-10895"/> - <group value="Catalog"/> + <testCaseId value="MC-26021"/> + <group value="catalog"/> <group value="mtf_migrated"/> </annotations> @@ -34,7 +34,7 @@ <!--Generate date for use as default value, needs to be MM/d/YYYY and mm/d/yy--> <generateDate date="now" format="m/j/Y" stepKey="generateDefaultDate"/> - <generateDate date="now" format="m/j/y" stepKey="generateDateCompressedFormat"/> + <generateDate date="now" format="n/j/y" stepKey="generateDateCompressedFormat"/> <!--Navigate to Stores > Attributes > Product.--> <actionGroup ref="AdminOpenProductAttributePageActionGroup" stepKey="goToProductAttributes"/> From 7a1e8a88f00ceb4ff689e591eeaaa06e62fb336b Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Tue, 5 Jan 2021 12:35:05 +0200 Subject: [PATCH 155/156] MC-40061: Create automated test for: "Subscribe to stock price alert" --- .../Block/Adminhtml/Product/Edit/Tab/Alerts/StockTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/StockTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/StockTest.php index d03bc935bcd72..b9ccfd6d52458 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/StockTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/StockTest.php @@ -60,7 +60,7 @@ protected function setUp(): void * @param string|null $storeCode * @return void */ - public function testGridCollectionWIthStoreId(string $sku, string $expectedEmail, ?string $storeCode = null): void + public function testGridCollectionWithStoreId(string $sku, string $expectedEmail, ?string $storeCode = null): void { $productId = (int)$this->productRepository->get($sku)->getId(); $storeId = $storeCode ? (int)$this->storeManager->getStore($storeCode)->getId() : null; From 6db8da7e8d8e5d0df516b501cf2473b43fcc4c8b Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh <nikita.shcherbatykh@transoftgroup.com> Date: Wed, 6 Jan 2021 10:18:37 +0200 Subject: [PATCH 156/156] MC-39891: Arabic text in invoice is not displayed correctly --- app/code/Magento/Sales/Model/RtlTextHandler.php | 2 +- app/code/Magento/Sales/Test/Unit/Model/RtlTextHandlerTest.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/RtlTextHandler.php b/app/code/Magento/Sales/Model/RtlTextHandler.php index cfb88dc63f58b..b943320e0f897 100644 --- a/app/code/Magento/Sales/Model/RtlTextHandler.php +++ b/app/code/Magento/Sales/Model/RtlTextHandler.php @@ -48,7 +48,7 @@ public function reverseRtlText(string $string): string for ($i = 0; $i < $splitTextAmount; $i++) { if ($this->isRtlText($splitText[$i])) { - for ($j = $i + 1; $j < $splitTextAmount; $j++) { + for ($j = $i; $j < $splitTextAmount; $j++) { $tmp = $this->isRtlText($splitText[$j]) ? $this->stringUtils->strrev($splitText[$j]) : $splitText[$j]; $splitText[$j] = $this->isRtlText($splitText[$i]) diff --git a/app/code/Magento/Sales/Test/Unit/Model/RtlTextHandlerTest.php b/app/code/Magento/Sales/Test/Unit/Model/RtlTextHandlerTest.php index 2faeb17dc2395..1a8159dbf4cbb 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/RtlTextHandlerTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/RtlTextHandlerTest.php @@ -62,6 +62,7 @@ public function provideRtlTexts(): array ['Herr Prof. Dr. Gerald Schüler B.A.', false],//German ['نديم مقداد نعمان القحطاني', true],//Arabic ['شهاب الفرحان', true],//Arabic + ['مرحبا ماجنت اثنان', true],//Arabic ['צבר קרליבך', true],//Hebrew ['גורי מייזליש', true],//Hebrew ['اتابک بهشتی', true],//Persian