From 9a7daab839a99142bec2251faad25851de706533 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher Date: Tue, 31 Jan 2017 12:55:12 +0200 Subject: [PATCH 01/44] MAGETWO-56014: [GitHub] Dashboard Most Viewed Products Tab in admin - prices issue #5660 --- .../Backend/Block/Dashboard/Tab/Products/Viewed.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php b/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php index af9dded435a7f..f4a0d0caa79f8 100644 --- a/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php +++ b/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php @@ -5,6 +5,8 @@ */ namespace Magento\Backend\Block\Dashboard\Tab\Products; +use Magento\Catalog\Model\Product; + /** * Adminhtml dashboard most viewed products grid * @@ -67,7 +69,14 @@ protected function _prepareCollection() $this->setCollection($collection); - return parent::_prepareCollection(); + parent::_prepareCollection(); + + /** @var Product $product */ + foreach ($collection as $product) { + $product->setPrice($product->getFinalPrice()); + } + + return $this; } /** From 0ee7d38dafbc5f3dc3a2f71053e1ada4cccf3beb Mon Sep 17 00:00:00 2001 From: Yuri Kovsher Date: Tue, 31 Jan 2017 13:20:19 +0200 Subject: [PATCH 02/44] MAGETWO-56014: [GitHub] Dashboard Most Viewed Products Tab in admin - prices issue #5660 --- app/code/Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php b/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php index f4a0d0caa79f8..65d17ce2a6ee9 100644 --- a/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php +++ b/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php @@ -68,7 +68,6 @@ protected function _prepareCollection() ); $this->setCollection($collection); - parent::_prepareCollection(); /** @var Product $product */ From ce66d856f8e2056412249266ce9fd33fbaad1b00 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher Date: Tue, 31 Jan 2017 16:04:42 +0200 Subject: [PATCH 03/44] MAGETWO-56014: [GitHub] Dashboard Most Viewed Products Tab in admin - prices issue #5660 --- .../Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php b/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php index 65d17ce2a6ee9..5247105a1cf6e 100644 --- a/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php +++ b/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Viewed.php @@ -6,6 +6,7 @@ namespace Magento\Backend\Block\Dashboard\Tab\Products; use Magento\Catalog\Model\Product; +use Magento\Catalog\Pricing\Price\FinalPrice; /** * Adminhtml dashboard most viewed products grid @@ -72,7 +73,7 @@ protected function _prepareCollection() /** @var Product $product */ foreach ($collection as $product) { - $product->setPrice($product->getFinalPrice()); + $product->setPrice($product->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getValue()); } return $this; From ea95fc5be719617c1029edac0ad5c1c54622d62a Mon Sep 17 00:00:00 2001 From: Yuri Kovsher Date: Fri, 3 Feb 2017 13:01:37 +0200 Subject: [PATCH 04/44] MAGETWO-62044: Not possible to update or delete products in cart or checkout after deleting address --- .../ShippingAssignment/ShippingProcessor.php | 40 ++++++++++++++++++- .../Model/QuoteRepository/SaveHandler.php | 3 +- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingProcessor.php b/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingProcessor.php index 4d18ae7a58193..715a6b9ffb895 100644 --- a/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingProcessor.php +++ b/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingProcessor.php @@ -10,6 +10,9 @@ use Magento\Quote\Model\ShippingFactory; use Magento\Quote\Model\ShippingAddressManagement; use Magento\Quote\Model\ShippingMethodManagement; +use Magento\Framework\App\ObjectManager; +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; class ShippingProcessor { @@ -28,6 +31,11 @@ class ShippingProcessor */ private $shippingMethodManagement; + /** + * @var AddressRepositoryInterface + */ + private $addressRepository; + /** * @param ShippingFactory $shippingFactory * @param ShippingAddressManagement $shippingAddressManagement @@ -63,7 +71,22 @@ public function create(\Magento\Quote\Api\Data\AddressInterface $shippingAddress */ public function save(ShippingInterface $shipping, CartInterface $quote) { - $this->shippingAddressManagement->assign($quote->getId(), $shipping->getAddress()); + $assignAddress = true; + $shippingAddress = $shipping->getAddress(); + + if ($shippingAddress->getCustomerAddressId()) { + try { + $this->getAddressRepository()->getById($shippingAddress->getCustomerAddressId()); + } catch (NoSuchEntityException $e) { + //do not re-assign address if the original customer address does not exist + $assignAddress = false; + } + } + + if ($assignAddress) { + $this->shippingAddressManagement->assign($quote->getId(), $shippingAddress); + } + if (!empty($shipping->getMethod()) && $quote->getItemsCount() > 0) { $nameComponents = explode('_', $shipping->getMethod()); $carrierCode = array_shift($nameComponents); @@ -72,4 +95,19 @@ public function save(ShippingInterface $shipping, CartInterface $quote) $this->shippingMethodManagement->apply($quote->getId(), $carrierCode, $methodCode); } } + + /** + * Get Magento\Customer\Api\AddressRepositoryInterface instance + * + * @return AddressRepositoryInterface + * @deprecated + */ + private function getAddressRepository() + { + if ($this->addressRepository === null) { + $this->addressRepository = ObjectManager::getInstance()->get(AddressRepositoryInterface::class); + } + + return $this->addressRepository; + } } diff --git a/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php b/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php index 647946e141a63..6a658bb4e0488 100644 --- a/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php +++ b/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php @@ -73,7 +73,8 @@ public function save(CartInterface $quote) // Billing Address processing $billingAddress = $quote->getBillingAddress(); - if ($billingAddress) { + + if ($billingAddress && (!$billingAddress->getCustomerAddressId() || $billingAddress->getCustomerAddress())) { $this->billingAddressPersister->save($quote, $billingAddress); } From f298ef5f4f802e0f91b64b3123052c2940f3f87a Mon Sep 17 00:00:00 2001 From: thomasvillagers Date: Sat, 4 Feb 2017 12:02:12 +0100 Subject: [PATCH 05/44] add anonymize ip option for google analytics --- app/code/Magento/GoogleAnalytics/Block/Ga.php | 10 ++++++++-- app/code/Magento/GoogleAnalytics/Helper/Data.php | 14 ++++++++++++++ .../GoogleAnalytics/etc/adminhtml/system.xml | 8 ++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/GoogleAnalytics/Block/Ga.php b/app/code/Magento/GoogleAnalytics/Block/Ga.php index cb1cb1c3bdd24..2d9472c98689e 100644 --- a/app/code/Magento/GoogleAnalytics/Block/Ga.php +++ b/app/code/Magento/GoogleAnalytics/Block/Ga.php @@ -80,8 +80,14 @@ public function getPageTrackingCode($accountId) $optPageURL = ", '" . $this->escapeHtmlAttr($pageName, false) . "'"; } - return "\nga('create', '" . $this->escapeHtmlAttr($accountId, false) - . ", 'auto');\nga('send', 'pageview'{$optPageURL});\n"; + $anonymizeIp = "false"; + if ($this->_googleAnalyticsData->isAnonymizedIpActive()) { + $anonymizeIp = "true"; + } + + return "\nga('create', '{$this->escapeJsQuote( + $accountId + )}', 'auto');\nga('send', 'pageview'{$optPageURL}, {'anonymizeIp' : {$anonymizeIp}});\n"; } /** diff --git a/app/code/Magento/GoogleAnalytics/Helper/Data.php b/app/code/Magento/GoogleAnalytics/Helper/Data.php index fcf1f4c3f0615..df3a53f4aa003 100644 --- a/app/code/Magento/GoogleAnalytics/Helper/Data.php +++ b/app/code/Magento/GoogleAnalytics/Helper/Data.php @@ -23,6 +23,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper const XML_PATH_ACCOUNT = 'google/analytics/account'; + const XML_PATH_ANONYMIZE = 'google/analytics/anonymize'; + /** * Whether GA is ready to use * @@ -34,4 +36,16 @@ public function isGoogleAnalyticsAvailable($store = null) $accountId = $this->scopeConfig->getValue(self::XML_PATH_ACCOUNT, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store); return $accountId && $this->scopeConfig->isSetFlag(self::XML_PATH_ACTIVE, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store); } + + /** + * Whether anonymized IPs are active + * + * @param null|string|bool|int|Store $store + * @return bool + */ + public function isAnonymizedIpActive($store = null) { + $anonymize = $this->scopeConfig->getValue(self::XML_PATH_ANONYMIZE, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store); + return $anonymize; + } + } diff --git a/app/code/Magento/GoogleAnalytics/etc/adminhtml/system.xml b/app/code/Magento/GoogleAnalytics/etc/adminhtml/system.xml index 1238ab525e1a4..97cfc4f80c781 100644 --- a/app/code/Magento/GoogleAnalytics/etc/adminhtml/system.xml +++ b/app/code/Magento/GoogleAnalytics/etc/adminhtml/system.xml @@ -23,6 +23,14 @@ 1 + + + + Magento\Config\Model\Config\Source\Yesno + + 1 + + From ed86a7576c4d1d292a752ba1e82df857a902c4c2 Mon Sep 17 00:00:00 2001 From: thomasvillagers Date: Sat, 4 Feb 2017 18:56:54 +0100 Subject: [PATCH 06/44] refactoring; add anonymize flag to Magento\GoogleAnalytics\Block\Ga.php->getOrdersTrackingCode --- app/code/Magento/GoogleAnalytics/Block/Ga.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/GoogleAnalytics/Block/Ga.php b/app/code/Magento/GoogleAnalytics/Block/Ga.php index 2d9472c98689e..a88e35ccec479 100644 --- a/app/code/Magento/GoogleAnalytics/Block/Ga.php +++ b/app/code/Magento/GoogleAnalytics/Block/Ga.php @@ -80,14 +80,13 @@ public function getPageTrackingCode($accountId) $optPageURL = ", '" . $this->escapeHtmlAttr($pageName, false) . "'"; } - $anonymizeIp = "false"; + $anonymizeIp = ""; if ($this->_googleAnalyticsData->isAnonymizedIpActive()) { - $anonymizeIp = "true"; + $anonymizeIp = ", {'anonymizeIp': true}"; } - return "\nga('create', '{$this->escapeJsQuote( - $accountId - )}', 'auto');\nga('send', 'pageview'{$optPageURL}, {'anonymizeIp' : {$anonymizeIp}});\n"; + return "\nga('create', '" . $this->escapeHtmlAttr($accountId, false) + . ", 'auto');\nga('send', 'pageview'{$optPageURL}{$anonymizeIp});\n"; } /** @@ -111,6 +110,12 @@ public function getOrdersTrackingCode() $result = []; $result[] = "ga('require', 'ec', 'ec.js');"; + + $anonymizeIp = ""; + if ($this->_googleAnalyticsData->isAnonymizedIpActive()) { + $anonymizeIp = ", {'anonymizeIp': true}"; + } + foreach ($collection as $order) { if ($order->getIsVirtual()) { $address = $order->getBillingAddress(); @@ -148,7 +153,7 @@ public function getOrdersTrackingCode() $order->getBaseShippingAmount() ); - $result[] = "ga('send', 'pageview');"; + $result[] = "ga('send', 'pageview'{$anonymizeIp});"; } return implode("\n", $result); } From feaaa277c08f173c889263b81370a553d70496e3 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher Date: Mon, 6 Feb 2017 11:55:30 +0200 Subject: [PATCH 07/44] MAGETWO-62044: Not possible to update or delete products in cart or checkout after deleting address --- .../ShippingAssignmentProcessor.php | 26 +++++++++++- .../ShippingAssignment/ShippingProcessor.php | 40 +------------------ 2 files changed, 26 insertions(+), 40 deletions(-) diff --git a/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingAssignmentProcessor.php b/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingAssignmentProcessor.php index fdf819c8d864c..5c3afacf6d1ea 100644 --- a/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingAssignmentProcessor.php +++ b/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingAssignmentProcessor.php @@ -10,6 +10,9 @@ use Magento\Framework\Exception\InputException; use Magento\Quote\Model\ShippingAssignmentFactory; use Magento\Quote\Model\Quote\Item\CartItemPersister; +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\NoSuchEntityException; class ShippingAssignmentProcessor { @@ -28,22 +31,33 @@ class ShippingAssignmentProcessor */ protected $cartItemPersister; + /** + * @var AddressRepositoryInterface + */ + private $addressRepository; + /** * @param ShippingAssignmentFactory $shippingAssignmentFactory * @param ShippingProcessor $shippingProcessor * @param CartItemPersister $cartItemPersister + * @param AddressRepositoryInterface $addressRepository */ public function __construct( ShippingAssignmentFactory $shippingAssignmentFactory, ShippingProcessor $shippingProcessor, - CartItemPersister $cartItemPersister + CartItemPersister $cartItemPersister, + AddressRepositoryInterface $addressRepository = null ) { $this->shippingAssignmentFactory = $shippingAssignmentFactory; $this->shippingProcessor = $shippingProcessor; $this->cartItemPersister = $cartItemPersister; + $this->addressRepository = $addressRepository + ?: ObjectManager::getInstance()->get(AddressRepositoryInterface::class); } /** + * Create shipping assignment + * * @param CartInterface $quote * @return \Magento\Quote\Api\Data\ShippingAssignmentInterface */ @@ -51,10 +65,20 @@ public function create(CartInterface $quote) { /** @var \Magento\Quote\Model\Quote $quote */ $shippingAddress = $quote->getShippingAddress(); + + if ($shippingAddress->getCustomerAddressId()) { + try { + $this->addressRepository->getById($shippingAddress->getCustomerAddressId()); + } catch (NoSuchEntityException $e) { + $shippingAddress->setCustomerAddressId(null); + } + } + /** @var \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment */ $shippingAssignment = $this->shippingAssignmentFactory->create(); $shippingAssignment->setItems($quote->getItems()); $shippingAssignment->setShipping($this->shippingProcessor->create($shippingAddress)); + return $shippingAssignment; } diff --git a/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingProcessor.php b/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingProcessor.php index 715a6b9ffb895..4d18ae7a58193 100644 --- a/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingProcessor.php +++ b/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingProcessor.php @@ -10,9 +10,6 @@ use Magento\Quote\Model\ShippingFactory; use Magento\Quote\Model\ShippingAddressManagement; use Magento\Quote\Model\ShippingMethodManagement; -use Magento\Framework\App\ObjectManager; -use Magento\Customer\Api\AddressRepositoryInterface; -use Magento\Framework\Exception\NoSuchEntityException; class ShippingProcessor { @@ -31,11 +28,6 @@ class ShippingProcessor */ private $shippingMethodManagement; - /** - * @var AddressRepositoryInterface - */ - private $addressRepository; - /** * @param ShippingFactory $shippingFactory * @param ShippingAddressManagement $shippingAddressManagement @@ -71,22 +63,7 @@ public function create(\Magento\Quote\Api\Data\AddressInterface $shippingAddress */ public function save(ShippingInterface $shipping, CartInterface $quote) { - $assignAddress = true; - $shippingAddress = $shipping->getAddress(); - - if ($shippingAddress->getCustomerAddressId()) { - try { - $this->getAddressRepository()->getById($shippingAddress->getCustomerAddressId()); - } catch (NoSuchEntityException $e) { - //do not re-assign address if the original customer address does not exist - $assignAddress = false; - } - } - - if ($assignAddress) { - $this->shippingAddressManagement->assign($quote->getId(), $shippingAddress); - } - + $this->shippingAddressManagement->assign($quote->getId(), $shipping->getAddress()); if (!empty($shipping->getMethod()) && $quote->getItemsCount() > 0) { $nameComponents = explode('_', $shipping->getMethod()); $carrierCode = array_shift($nameComponents); @@ -95,19 +72,4 @@ public function save(ShippingInterface $shipping, CartInterface $quote) $this->shippingMethodManagement->apply($quote->getId(), $carrierCode, $methodCode); } } - - /** - * Get Magento\Customer\Api\AddressRepositoryInterface instance - * - * @return AddressRepositoryInterface - * @deprecated - */ - private function getAddressRepository() - { - if ($this->addressRepository === null) { - $this->addressRepository = ObjectManager::getInstance()->get(AddressRepositoryInterface::class); - } - - return $this->addressRepository; - } } From 22aa3899e3a5d9fe9eb4c8b4efc1d699a33ee3d9 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher Date: Mon, 6 Feb 2017 12:14:53 +0200 Subject: [PATCH 08/44] MAGETWO-62044: Not possible to update or delete products in cart or checkout after deleting address --- .../ShippingAssignmentProcessor.php | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingAssignmentProcessor.php b/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingAssignmentProcessor.php index 5c3afacf6d1ea..457b23f0b7d79 100644 --- a/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingAssignmentProcessor.php +++ b/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingAssignmentProcessor.php @@ -5,6 +5,7 @@ */ namespace Magento\Quote\Model\Quote\ShippingAssignment; +use Magento\Framework\Exception\LocalizedException; use Magento\Quote\Api\Data\CartInterface; use Magento\Quote\Api\Data\ShippingAssignmentInterface; use Magento\Framework\Exception\InputException; @@ -66,14 +67,6 @@ public function create(CartInterface $quote) /** @var \Magento\Quote\Model\Quote $quote */ $shippingAddress = $quote->getShippingAddress(); - if ($shippingAddress->getCustomerAddressId()) { - try { - $this->addressRepository->getById($shippingAddress->getCustomerAddressId()); - } catch (NoSuchEntityException $e) { - $shippingAddress->setCustomerAddressId(null); - } - } - /** @var \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment */ $shippingAssignment = $this->shippingAssignmentFactory->create(); $shippingAssignment->setItems($quote->getItems()); @@ -83,10 +76,12 @@ public function create(CartInterface $quote) } /** + * Save shipping assignment + * * @param ShippingAssignmentInterface $shippingAssignment * @param CartInterface $quote * @return void - * @throws InputException + * @throws InputException|LocalizedException */ public function save(CartInterface $quote, ShippingAssignmentInterface $shippingAssignment) { @@ -97,6 +92,17 @@ public function save(CartInterface $quote, ShippingAssignmentInterface $shipping $this->cartItemPersister->save($quote, $item); } } + + $shippingAddress = $quote->getShippingAddress(); + + if ($shippingAddress->getCustomerAddressId()) { + try { + $this->addressRepository->getById($shippingAddress->getCustomerAddressId()); + } catch (NoSuchEntityException $e) { + $shippingAddress->setCustomerAddressId(null); + } + } + $this->shippingProcessor->save($shippingAssignment->getShipping(), $quote); } } From 1a991ae380239a1656e0bf75a43980d98e5ea5dc Mon Sep 17 00:00:00 2001 From: Yuri Kovsher Date: Mon, 6 Feb 2017 13:15:55 +0200 Subject: [PATCH 09/44] MAGETWO-62044: Not possible to update or delete products in cart or checkout after deleting address --- .../ShippingAssignmentProcessorTest.php | 193 ++++++++++++------ 1 file changed, 132 insertions(+), 61 deletions(-) diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/ShippingAssignment/ShippingAssignmentProcessorTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/ShippingAssignment/ShippingAssignmentProcessorTest.php index e74070c3eaee7..b55b66b07e6b3 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/Quote/ShippingAssignment/ShippingAssignmentProcessorTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/ShippingAssignment/ShippingAssignmentProcessorTest.php @@ -5,107 +5,178 @@ */ namespace Magento\Quote\Test\Unit\Model\Quote\ShippingAssignment; -use Magento\Quote\Api\Data\ShippingAssignmentInterface; -use Magento\Quote\Api\Data\ShippingInterface; -use Magento\Quote\Model\Quote; -use Magento\Quote\Model\ShippingAssignmentFactory; -use Magento\Quote\Model\Quote\Item\CartItemPersister; use Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentProcessor; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Quote\Model\ShippingAssignmentFactory; use Magento\Quote\Model\Quote\ShippingAssignment\ShippingProcessor; -use PHPUnit_Framework_MockObject_MockObject as MockObject; +use Magento\Quote\Model\Quote\Item\CartItemPersister; +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Quote\Model\Quote; +use Magento\Quote\Api\Data\ShippingAssignmentInterface; +use Magento\Quote\Model\Quote\Address as QuoteAddress; +use Magento\Quote\Api\Data\ShippingInterface; +use Magento\Quote\Model\Quote\Item as QuoteItem; +use Magento\Framework\Exception\NoSuchEntityException; -/** - * Class ShippingAssignmentProcessorTest - */ class ShippingAssignmentProcessorTest extends \PHPUnit_Framework_TestCase { /** - * @var ShippingAssignmentFactory|MockObject + * @var ShippingAssignmentProcessor */ - private $shippingAssignmentFactory; + private $shippingAssignmentProcessor; /** - * @var ShippingProcessor|MockObject + * @var ObjectManagerHelper */ - private $shippingProcessor; + private $objectManagerHelper; /** - * @var CartItemPersister|MockObject + * @var ShippingAssignmentFactory|\PHPUnit_Framework_MockObject_MockObject */ - private $cartItemPersister; + private $shippingAssignmentFactoryMock; /** - * @var ShippingAssignmentProcessor + * @var ShippingProcessor|\PHPUnit_Framework_MockObject_MockObject */ - private $shippingAssignmentProcessor; + private $shippingProcessorMock; + + /** + * @var CartItemPersister|\PHPUnit_Framework_MockObject_MockObject + */ + private $cartItemPersisterMock; + + /** + * @var AddressRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $addressRepositoryMock; + + /** + * @var Quote|\PHPUnit_Framework_MockObject_MockObject + */ + private $quoteMock; + + /** + * @var ShippingAssignmentInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shippingAssignmentMock; + + /** + * @var QuoteAddress|\PHPUnit_Framework_MockObject_MockObject + */ + private $shippingAddressMock; + + /** + * @var ShippingInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shippingMock; protected function setUp() { - $this->shippingAssignmentFactory = $this->getMockBuilder(ShippingAssignmentFactory::class) + $this->shippingAssignmentFactoryMock = $this->getMockBuilder(ShippingAssignmentFactory::class) ->disableOriginalConstructor() ->getMock(); - - $this->shippingProcessor = $this->getMockBuilder(ShippingProcessor::class) + $this->shippingProcessorMock = $this->getMockBuilder(ShippingProcessor::class) ->disableOriginalConstructor() ->getMock(); - - $this->cartItemPersister = $this->getMockBuilder(CartItemPersister::class) + $this->cartItemPersisterMock = $this->getMockBuilder(CartItemPersister::class) + ->disableOriginalConstructor() + ->getMock(); + $this->addressRepositoryMock = $this->getMockBuilder(AddressRepositoryInterface::class) + ->getMockForAbstractClass(); + $this->quoteMock = $this->getMockBuilder(Quote::class) ->disableOriginalConstructor() ->getMock(); + $this->shippingAssignmentMock = $this->getMockBuilder(ShippingAssignmentInterface::class) + ->getMockForAbstractClass(); + $this->shippingAddressMock = $this->getMockBuilder(QuoteAddress::class) + ->disableOriginalConstructor() + ->getMock(); + $this->shippingMock = $this->getMockBuilder(ShippingInterface::class) + ->getMockForAbstractClass(); - $this->shippingAssignmentProcessor = new ShippingAssignmentProcessor( - $this->shippingAssignmentFactory, - $this->shippingProcessor, - $this->cartItemPersister + $this->quoteMock->expects(static::any()) + ->method('getShippingAddress') + ->willReturn($this->shippingAddressMock); + $this->shippingAssignmentMock->expects(static::any()) + ->method('getShipping') + ->willReturn($this->shippingMock); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->shippingAssignmentProcessor = $this->objectManagerHelper->getObject( + ShippingAssignmentProcessor::class, + [ + 'shippingAssignmentFactory' => $this->shippingAssignmentFactoryMock, + 'shippingProcessor' => $this->shippingProcessorMock, + 'cartItemPersister' => $this->cartItemPersisterMock, + 'addressRepository' => $this->addressRepositoryMock + ] ); } - /** - * Test saving shipping assignments with deleted cart items - * - * @covers \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentProcessor::save - */ public function testSaveWithDeletedCartItems() { - $shippingAssignment = $this->getMockForAbstractClass(ShippingAssignmentInterface::class); - $shipping = $this->getMockForAbstractClass(ShippingInterface::class); $quoteId = 1; + $quoteItemMock = $this->createQuoteItemMock(); - $quote = $this->getMockBuilder(Quote::class) - ->disableOriginalConstructor() - ->getMock(); - $quoteItem = $this->getMockBuilder(\Magento\Quote\Model\Quote\Item::class) - ->disableOriginalConstructor() - ->getMock(); - $quoteItem->expects(static::once()) - ->method('isDeleted') - ->willReturn(true); - $quoteItem->expects(static::once()) - ->method('getItemId') - ->willReturn($quoteId); - - $quote->expects(static::once()) + $this->shippingAssignmentMock->expects(static::once()) + ->method('getItems') + ->willReturn([$quoteItemMock]); + $this->quoteMock->expects(static::atLeastOnce()) ->method('getItemById') ->with($quoteId) ->willReturn(null); + $quoteItemMock->expects(static::atLeastOnce()) + ->method('getItemId') + ->willReturn($quoteId); + $quoteItemMock->expects(static::atLeastOnce()) + ->method('isDeleted') + ->willReturn(true); + $this->cartItemPersisterMock->expects(static::never()) + ->method('save'); + $this->shippingAddressMock->expects(static::atLeastOnce()) + ->method('getCustomerAddressId') + ->willReturn(null); + $this->addressRepositoryMock->expects(static::never()) + ->method('getById'); + $this->shippingProcessorMock->expects(static::once()) + ->method('save') + ->with($this->shippingMock, $this->quoteMock); - $shippingAssignment->expects(static::once()) - ->method('getItems') - ->willReturn([$quoteItem]); - $shippingAssignment->expects(static::once()) - ->method('getShipping') - ->willReturn($shipping); + $this->shippingAssignmentProcessor->save($this->quoteMock, $this->shippingAssignmentMock); + } - $this->cartItemPersister->expects(static::never()) - ->method('save'); + public function testSaveWithNotExistingCustomerAddress() + { + $customerAddressId = 11; - $this->shippingProcessor->expects(static::once()) + $this->shippingAssignmentMock->expects(static::atLeastOnce()) + ->method('getItems') + ->willReturn([]); + $this->shippingAddressMock->expects(static::atLeastOnce()) + ->method('getCustomerAddressId') + ->willReturn($customerAddressId); + $this->addressRepositoryMock->expects(static::once()) + ->method('getById') + ->with($customerAddressId) + ->willThrowException(new NoSuchEntityException()); + $this->shippingAddressMock->expects(static::once()) + ->method('setCustomerAddressId') + ->with(null) + ->willReturn($this->shippingAddressMock); + $this->shippingProcessorMock->expects(static::once()) ->method('save') - ->with($shipping, $quote); + ->with($this->shippingMock, $this->quoteMock); - $this->shippingAssignmentProcessor->save( - $quote, - $shippingAssignment - ); + $this->shippingAssignmentProcessor->save($this->quoteMock, $this->shippingAssignmentMock); + } + + /** + * @return QuoteItem|\PHPUnit_Framework_MockObject_MockObject + */ + private function createQuoteItemMock() + { + return $this->getMockBuilder(QuoteItem::class) + ->disableOriginalConstructor() + ->getMock(); } } From 347a26542c4940626b95033312b3832d823533b9 Mon Sep 17 00:00:00 2001 From: Dennis van Schaik Date: Mon, 6 Feb 2017 13:07:31 +0100 Subject: [PATCH 10/44] [2.1.0] Problem on mobile when catalog gallery allowfullscreen is false #5808 --- lib/web/mage/gallery/gallery.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/mage/gallery/gallery.js b/lib/web/mage/gallery/gallery.js index b3cc06fcc6a8f..c81f9a0444ea8 100644 --- a/lib/web/mage/gallery/gallery.js +++ b/lib/web/mage/gallery/gallery.js @@ -143,7 +143,7 @@ define([ } }); - if (this.isTouchEnabled) { + if (this.isTouchEnabled && this.settings.isFullscreen) { this.settings.$element.on('tap', '.fotorama__stage__frame', function () { var translate = getTranslate($(this).parents('.fotorama__stage__shaft')); From 93dc2fa370c89a9fa564316ea66459945d89955a Mon Sep 17 00:00:00 2001 From: Yuri Kovsher Date: Mon, 6 Feb 2017 15:01:51 +0200 Subject: [PATCH 11/44] MAGETWO-62044: Not possible to update or delete products in cart or checkout after deleting address --- .../Model/QuoteRepository/SaveHandler.php | 20 +- .../ShippingAssignmentProcessorTest.php | 30 ++- .../Model/QuoteRepository/SaveHandlerTest.php | 250 ++++++++++++------ 3 files changed, 198 insertions(+), 102 deletions(-) diff --git a/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php b/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php index 6a658bb4e0488..25dfe7a3f20c5 100644 --- a/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php +++ b/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php @@ -49,19 +49,20 @@ public function __construct( } /** + * Process and save quote data + * * @param CartInterface $quote * @return CartInterface - * * @throws InputException * @throws \Magento\Framework\Exception\CouldNotSaveException * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Magento\Framework\Exception\NoSuchEntityException */ public function save(CartInterface $quote) { /** @var \Magento\Quote\Model\Quote $quote */ // Quote Item processing $items = $quote->getItems(); + if ($items) { foreach ($items as $item) { /** @var \Magento\Quote\Model\Quote\Item $item */ @@ -74,17 +75,23 @@ public function save(CartInterface $quote) // Billing Address processing $billingAddress = $quote->getBillingAddress(); - if ($billingAddress && (!$billingAddress->getCustomerAddressId() || $billingAddress->getCustomerAddress())) { + if ($billingAddress) { + if ($billingAddress->getCustomerAddressId() && !$billingAddress->getCustomerAddress()) { + $billingAddress->setCustomerAddressId(null); + } + $this->billingAddressPersister->save($quote, $billingAddress); } $this->processShippingAssignment($quote); - $this->quoteResourceModel->save($quote->collectTotals()); + return $quote; } /** + * Process shipping assignment + * * @param \Magento\Quote\Model\Quote $quote * @return void * @throws InputException @@ -93,11 +100,14 @@ private function processShippingAssignment($quote) { // Shipping Assignments processing $extensionAttributes = $quote->getExtensionAttributes(); + if (!$quote->isVirtual() && $extensionAttributes && $extensionAttributes->getShippingAssignments()) { $shippingAssignments = $extensionAttributes->getShippingAssignments(); + if (count($shippingAssignments) > 1) { - throw new InputException(__("Only 1 shipping assignment can be set")); + throw new InputException(__('Only 1 shipping assignment can be set')); } + $this->shippingAssignmentPersister->save($quote, $shippingAssignments[0]); } } diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/ShippingAssignment/ShippingAssignmentProcessorTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/ShippingAssignment/ShippingAssignmentProcessorTest.php index b55b66b07e6b3..985afa8b6829f 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/Quote/ShippingAssignment/ShippingAssignmentProcessorTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/ShippingAssignment/ShippingAssignmentProcessorTest.php @@ -115,22 +115,15 @@ protected function setUp() public function testSaveWithDeletedCartItems() { - $quoteId = 1; - $quoteItemMock = $this->createQuoteItemMock(); + $quoteItemId = 1; $this->shippingAssignmentMock->expects(static::once()) ->method('getItems') - ->willReturn([$quoteItemMock]); + ->willReturn([$this->createQuoteItemMock($quoteItemId, true)]); $this->quoteMock->expects(static::atLeastOnce()) ->method('getItemById') - ->with($quoteId) + ->with($quoteItemId) ->willReturn(null); - $quoteItemMock->expects(static::atLeastOnce()) - ->method('getItemId') - ->willReturn($quoteId); - $quoteItemMock->expects(static::atLeastOnce()) - ->method('isDeleted') - ->willReturn(true); $this->cartItemPersisterMock->expects(static::never()) ->method('save'); $this->shippingAddressMock->expects(static::atLeastOnce()) @@ -171,12 +164,25 @@ public function testSaveWithNotExistingCustomerAddress() } /** + * Create quote item mock + * + * @param int|string $id + * @param bool $isDeleted * @return QuoteItem|\PHPUnit_Framework_MockObject_MockObject */ - private function createQuoteItemMock() + private function createQuoteItemMock($id, $isDeleted) { - return $this->getMockBuilder(QuoteItem::class) + $quoteItemMock = $this->getMockBuilder(QuoteItem::class) ->disableOriginalConstructor() ->getMock(); + + $quoteItemMock->expects(static::any()) + ->method('getItemId') + ->willReturn($id); + $quoteItemMock->expects(static::any()) + ->method('isDeleted') + ->willReturn($isDeleted); + + return $quoteItemMock; } } diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php index 633beb6c1853a..51d025e4043ef 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php @@ -3,10 +3,19 @@ * Copyright © 2013-2017 Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Quote\Test\Unit\Model\QuoteRepository; use Magento\Quote\Model\QuoteRepository\SaveHandler; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Quote\Model\ResourceModel\Quote as QuoteResourceModel; +use Magento\Quote\Model\Quote\Item\CartItemPersister; +use Magento\Quote\Model\Quote\Address\BillingAddressPersister; +use Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\Quote\Address as QuoteAddress; +use Magento\Quote\Api\Data\CartExtensionInterface; +use Magento\Quote\Api\Data\ShippingAssignmentInterface; +use Magento\Quote\Model\Quote\Item as QuoteItem; class SaveHandlerTest extends \PHPUnit_Framework_TestCase { @@ -16,124 +25,195 @@ class SaveHandlerTest extends \PHPUnit_Framework_TestCase private $saveHandler; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var ObjectManagerHelper */ - private $cartItemPersister; + private $objectManagerHelper; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var QuoteResourceModel|\PHPUnit_Framework_MockObject_MockObject */ - private $billingAddressPersister; + private $quoteResourceModelMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var CartItemPersister|\PHPUnit_Framework_MockObject_MockObject */ - private $quoteResourceModel; + private $cartItemPersisterMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var BillingAddressPersister|\PHPUnit_Framework_MockObject_MockObject */ - private $shippingAssignmentPersister; + private $billingAddressPersisterMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var ShippingAssignmentPersister|\PHPUnit_Framework_MockObject_MockObject */ - private $quoteMock; + private $shippingAssignmentPersisterMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var Quote|\PHPUnit_Framework_MockObject_MockObject */ - private $itemMock; + private $quoteMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var QuoteAddress|\PHPUnit_Framework_MockObject_MockObject */ private $billingAddressMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var CartExtensionInterface|\PHPUnit_Framework_MockObject_MockObject */ - private $extensionAttributeMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $shippingAssignmentMock; + private $extensionAttributesMock; protected function setUp() { - $this->quoteResourceModel = $this->getMock(\Magento\Quote\Model\ResourceModel\Quote::class, [], [], '', false); - $this->cartItemPersister = $this->getMock( - \Magento\Quote\Model\Quote\Item\CartItemPersister::class, - [], - [], - '', - false - ); - $this->billingAddressPersister = $this->getMock( - \Magento\Quote\Model\Quote\Address\BillingAddressPersister::class, - [], - [], - '', - false - ); - $this->shippingAssignmentPersister = $this->getMock( - \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister::class, - [], - [], - '', - false - ); - $methods = [ - 'getItems', 'setLastAddedItem', 'getBillingAddress', 'getIsActive', - 'getExtensionAttributes', 'isVirtual', 'collectTotals' - ]; - $this->quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, $methods, [], '', false); - $this->itemMock = $this->getMock(\Magento\Quote\Model\Quote\Item::class, [], [], '', false); - $this->billingAddressMock = $this->getMock(\Magento\Quote\Model\Quote\Address::class, [], [], '', false); - $this->extensionAttributeMock = $this->getMock(\Magento\Quote\Api\Data\CartExtensionInterface::class); - $this->shippingAssignmentMock = - $this->getMock( - \Magento\Quote\Api\Data\CartExtension::class, - ['getShippingAssignments', 'setShippingAssignments'], - [], - '', - false - ); - $this->saveHandler = new SaveHandler( - $this->quoteResourceModel, - $this->cartItemPersister, - $this->billingAddressPersister, - $this->shippingAssignmentPersister - ); + $this->quoteResourceModelMock = $this->getMockBuilder(QuoteResourceModel::class) + ->disableOriginalConstructor() + ->getMock(); + $this->cartItemPersisterMock = $this->getMockBuilder(CartItemPersister::class) + ->disableOriginalConstructor() + ->getMock(); + $this->billingAddressPersisterMock = $this->getMockBuilder(BillingAddressPersister::class) + ->disableOriginalConstructor() + ->getMock(); + $this->shippingAssignmentPersisterMock = $this->getMockBuilder(ShippingAssignmentPersister::class) + ->disableOriginalConstructor() + ->getMock(); + $this->quoteMock = $this->getMockBuilder(Quote::class) + ->disableOriginalConstructor() + ->setMethods( + [ + 'getItems', 'setLastAddedItem', 'getBillingAddress', 'getExtensionAttributes', 'isVirtual', + 'collectTotals' + ] + ) + ->getMock(); + $this->billingAddressMock = $this->getMockBuilder(QuoteAddress::class) + ->disableOriginalConstructor() + ->setMethods(['getCustomerAddressId', 'getCustomerAddress', 'setCustomerAddressId']) + ->getMock(); + $this->extensionAttributesMock = $this->getMockBuilder(CartExtensionInterface::class) + ->getMockForAbstractClass(); + + $this->quoteMock->expects(static::any()) + ->method('getBillingAddress') + ->willReturn($this->billingAddressMock); + $this->quoteMock->expects(static::any()) + ->method('getExtensionAttributes') + ->willReturn($this->extensionAttributesMock); + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->saveHandler = $this->objectManagerHelper->getObject( + SaveHandler::class, + [ + 'quoteResource' => $this->quoteResourceModelMock, + 'cartItemPersister' => $this->cartItemPersisterMock, + 'billingAddressPersister' => $this->billingAddressPersisterMock, + 'ShippingAssignmentPersister' => $this->shippingAssignmentPersisterMock + ] + ); } public function testSaveForVirtualQuote() { - $this->quoteMock->expects($this->once())->method('getItems')->willReturn([$this->itemMock]); - $this->itemMock->expects($this->once())->method('isDeleted')->willReturn(false); - $this->cartItemPersister - ->expects($this->once()) + $quoteItemMock = $this->createQuoteItemMock(false); + + $this->quoteMock->expects(static::atLeastOnce()) + ->method('getItems') + ->willReturn([$quoteItemMock]); + $this->cartItemPersisterMock->expects(static::once()) ->method('save') - ->with($this->quoteMock, $this->itemMock) - ->willReturn($this->itemMock); - $this->quoteMock->expects($this->once())->method('setLastAddedItem')->with($this->itemMock); - $this->quoteMock->expects($this->once())->method('getBillingAddress')->willReturn($this->billingAddressMock); - $this->billingAddressPersister - ->expects($this->once()) + ->with($this->quoteMock, $quoteItemMock) + ->willReturn($quoteItemMock); + $this->quoteMock->expects(static::once()) + ->method('setLastAddedItem') + ->with($quoteItemMock) + ->willReturnSelf(); + $this->billingAddressMock->expects(static::atLeastOnce()) + ->method('getCustomerAddressId') + ->willReturn(null); + $this->billingAddressMock->expects(static::never()) + ->method('getCustomerAddress'); + $this->billingAddressPersisterMock->expects(static::once()) ->method('save') ->with($this->quoteMock, $this->billingAddressMock); - $this->quoteMock - ->expects($this->once()) - ->method('getExtensionAttributes') - ->willReturn($this->extensionAttributeMock); - $this->extensionAttributeMock - ->expects($this->never()) + $this->quoteMock->expects(static::atLeastOnce()) + ->method('isVirtual') + ->willReturn(true); + $this->extensionAttributesMock->expects(static::never()) ->method('getShippingAssignments'); - $this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(true); - $this->quoteMock->expects($this->once())->method('collectTotals')->willReturn($this->quoteMock); - $this->quoteResourceModel->expects($this->once())->method('save')->with($this->quoteMock); - $this->assertEquals($this->quoteMock, $this->saveHandler->save($this->quoteMock)); + $this->quoteMock->expects(static::atLeastOnce()) + ->method('collectTotals') + ->willReturnSelf(); + $this->quoteResourceModelMock->expects(static::once()) + ->method('save') + ->with($this->quoteMock) + ->willReturnSelf(); + + $this->assertSame($this->quoteMock, $this->saveHandler->save($this->quoteMock)); + } + + public function testSaveWithNotExistingCustomerAddress() + { + $this->quoteMock->expects(static::atLeastOnce()) + ->method('getItems') + ->willReturn([]); + $this->quoteMock->expects(static::never()) + ->method('setLastAddedItem'); + $this->billingAddressMock->expects(static::atLeastOnce()) + ->method('getCustomerAddressId') + ->willReturn(5); + $this->billingAddressMock->expects(static::atLeastOnce()) + ->method('getCustomerAddress') + ->willReturn(null); + $this->billingAddressMock->expects(static::atLeastOnce()) + ->method('setCustomerAddressId') + ->willReturn(null); + $this->billingAddressPersisterMock->expects(static::once()) + ->method('save') + ->with($this->quoteMock, $this->billingAddressMock); + $this->quoteMock->expects(static::atLeastOnce()) + ->method('isVirtual') + ->willReturn(true); + $this->extensionAttributesMock->expects(static::never()) + ->method('getShippingAssignments'); + $this->quoteMock->expects(static::atLeastOnce()) + ->method('collectTotals') + ->willReturnSelf(); + $this->quoteResourceModelMock->expects(static::once()) + ->method('save') + ->with($this->quoteMock) + ->willReturnSelf(); + + $this->assertSame($this->quoteMock, $this->saveHandler->save($this->quoteMock)); + } + + /** + * Create quote item mock + * + * @param bool $isDeleted + * @return QuoteItem|\PHPUnit_Framework_MockObject_MockObject + */ + private function createQuoteItemMock($isDeleted) + { + $quoteItemMock = $this->getMockBuilder(QuoteItem::class) + ->disableOriginalConstructor() + ->getMock(); + + $quoteItemMock->expects(static::any()) + ->method('isDeleted') + ->willReturn($isDeleted); + + return $quoteItemMock; + } + + /** + * Create shipping assignment mock + * + * @return ShippingAssignmentInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private function createShippingAssignmentMock() + { + return $this->getMockBuilder(ShippingAssignmentInterface::class) + ->getMockForAbstractClass(); } } From 08ccbacb598909c41acf4b8b9a73bf2653075f10 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher Date: Mon, 6 Feb 2017 16:42:06 +0200 Subject: [PATCH 12/44] MAGETWO-62044: Not possible to update or delete products in cart or checkout after deleting address --- .../Unit/Model/QuoteRepository/SaveHandlerTest.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php index 51d025e4043ef..244ccd3cf779b 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php @@ -205,15 +205,4 @@ private function createQuoteItemMock($isDeleted) return $quoteItemMock; } - - /** - * Create shipping assignment mock - * - * @return ShippingAssignmentInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private function createShippingAssignmentMock() - { - return $this->getMockBuilder(ShippingAssignmentInterface::class) - ->getMockForAbstractClass(); - } } From c37d705a67525d93020714251e695ed1848ad266 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher Date: Tue, 7 Feb 2017 15:04:29 +0200 Subject: [PATCH 13/44] MAGETWO-62044: Not possible to update or delete products in cart or checkout after deleting address --- .../ShippingAssignmentProcessor.php | 1 + .../Model/QuoteRepository/SaveHandlerTest.php | 1 - .../Quote/Model/QuoteRepositoryTest.php | 122 ++++++++++++++---- 3 files changed, 97 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingAssignmentProcessor.php b/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingAssignmentProcessor.php index 457b23f0b7d79..031f2435881f9 100644 --- a/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingAssignmentProcessor.php +++ b/app/code/Magento/Quote/Model/Quote/ShippingAssignment/ShippingAssignmentProcessor.php @@ -100,6 +100,7 @@ public function save(CartInterface $quote, ShippingAssignmentInterface $shipping $this->addressRepository->getById($shippingAddress->getCustomerAddressId()); } catch (NoSuchEntityException $e) { $shippingAddress->setCustomerAddressId(null); + $shippingAssignment->getShipping()->getAddress()->setCustomerAddressId(null); } } diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php index 244ccd3cf779b..9af461611853f 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php @@ -14,7 +14,6 @@ use Magento\Quote\Model\Quote; use Magento\Quote\Model\Quote\Address as QuoteAddress; use Magento\Quote\Api\Data\CartExtensionInterface; -use Magento\Quote\Api\Data\ShippingAssignmentInterface; use Magento\Quote\Model\Quote\Item as QuoteItem; class SaveHandlerTest extends \PHPUnit_Framework_TestCase diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteRepositoryTest.php index 3a25f419e38ba..cf2597e43d525 100644 --- a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteRepositoryTest.php @@ -5,23 +5,54 @@ */ namespace Magento\Quote\Model; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\Framework\Api\FilterBuilder; -use Magento\Quote\Api\CartRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap as BootstrapHelper; +use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SearchCriteria; +use Magento\Framework\Api\FilterBuilder; use Magento\Quote\Api\Data\CartInterface; +use Magento\Quote\Api\Data\CartSearchResultsInterface; +use Magento\Quote\Api\Data\CartExtension; +use Magento\User\Api\Data\UserInterface; +use Magento\Quote\Model\Quote\Address as QuoteAddress; class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase { + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @var QuoteRepository + */ + private $quoteRepository; + + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @var FilterBuilder + */ + private $filterBuilder; + + protected function setUp() + { + $this->objectManager = BootstrapHelper::getObjectManager(); + $this->quoteRepository = $this->objectManager->create(QuoteRepository::class); + $this->searchCriteriaBuilder = $this->objectManager->create(SearchCriteriaBuilder::class); + $this->filterBuilder = $this->objectManager->create(FilterBuilder::class); + } + /** * @magentoDataFixture Magento/Sales/_files/quote.php */ public function testGetList() { $searchCriteria = $this->getSearchCriteria('test01'); - /** @var \Magento\Quote\Api\CartRepositoryInterface $quoteRepository */ - $quoteRepository = Bootstrap::getObjectManager()->create(CartRepositoryInterface::class); - $searchResult = $quoteRepository->getList($searchCriteria); + $searchResult = $this->quoteRepository->getList($searchCriteria); $this->performAssertions($searchResult); } @@ -32,40 +63,76 @@ public function testGetListDoubleCall() { $searchCriteria1 = $this->getSearchCriteria('test01'); $searchCriteria2 = $this->getSearchCriteria('test02'); - - /** @var \Magento\Quote\Api\CartRepositoryInterface $quoteRepository */ - $quoteRepository = Bootstrap::getObjectManager()->create(CartRepositoryInterface::class); - $searchResult = $quoteRepository->getList($searchCriteria1); + $searchResult = $this->quoteRepository->getList($searchCriteria1); $this->performAssertions($searchResult); - $searchResult = $quoteRepository->getList($searchCriteria2); - $items = $searchResult->getItems(); - $this->assertEmpty($items); + $searchResult = $this->quoteRepository->getList($searchCriteria2); + + $this->assertEmpty($searchResult->getItems()); + } + + public function testSaveWithNotExistingCustomerAddress() + { + $addressData = include __DIR__ . '/../../Sales/_files/address_data.php'; + + /** @var QuoteAddress $billingAddress */ + $billingAddress = $this->objectManager->create(QuoteAddress::class, ['data' => $addressData]); + $billingAddress->setAddressType(QuoteAddress::ADDRESS_TYPE_BILLING) + ->setCustomerAddressId('not_existing'); + + /** @var QuoteAddress $shippingAddress */ + $shippingAddress = $this->objectManager->create(QuoteAddress::class, ['data' => $addressData]); + $shippingAddress->setAddressType(QuoteAddress::ADDRESS_TYPE_SHIPPING) + ->setCustomerAddressId('not_existing'); + + /** @var Shipping $shipping */ + $shipping = $this->objectManager->create(Shipping::class); + $shipping->setAddress($shippingAddress); + + /** @var ShippingAssignment $shippingAssignment */ + $shippingAssignment = $this->objectManager->create(ShippingAssignment::class); + $shippingAssignment->setItems([]); + $shippingAssignment->setShipping($shipping); + + /** @var CartExtension $extensionAttributes */ + $extensionAttributes = $this->objectManager->create(CartExtension::class); + $extensionAttributes->setShippingAssignments([$shippingAssignment]); + + /** @var Quote $quote */ + $quote = $this->objectManager->create(Quote::class); + $quote->setStoreId(1) + ->setIsActive(true) + ->setIsMultiShipping(false) + ->setBillingAddress($billingAddress) + ->setShippingAddress($shippingAddress) + ->setExtensionAttributes($extensionAttributes) + ->save(); + $this->quoteRepository->save($quote); } /** + * Get search criteria + * * @param string $filterValue - * @return \Magento\Framework\Api\SearchCriteria + * @return SearchCriteria */ private function getSearchCriteria($filterValue) { - /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder */ - $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); - $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); $filters = []; - $filters[] = $filterBuilder - ->setField('reserved_order_id') + $filters[] = $this->filterBuilder->setField('reserved_order_id') ->setConditionType('=') ->setValue($filterValue) ->create(); - $searchCriteriaBuilder->addFilters($filters); + $this->searchCriteriaBuilder->addFilters($filters); - return $searchCriteriaBuilder->create(); + return $this->searchCriteriaBuilder->create(); } /** - * @param object $searchResult + * Perform assertions + * + * @param CartSearchResultsInterface $searchResult */ - protected function performAssertions($searchResult) + private function performAssertions(CartSearchResultsInterface $searchResult) { $expectedExtensionAttributes = [ 'firstname' => 'firstname', @@ -74,12 +141,15 @@ protected function performAssertions($searchResult) ]; $items = $searchResult->getItems(); - /** @var \Magento\Quote\Api\Data\CartInterface $actualQuote */ + + /** @var CartInterface $actualQuote */ $actualQuote = array_pop($items); + + /** @var UserInterface $testAttribute */ + $testAttribute = $actualQuote->getExtensionAttributes()->getQuoteTestAttribute(); + $this->assertInstanceOf(CartInterface::class, $actualQuote); $this->assertEquals('test01', $actualQuote->getReservedOrderId()); - /** @var \Magento\User\Api\Data\UserInterface $testAttribute */ - $testAttribute = $actualQuote->getExtensionAttributes()->getQuoteTestAttribute(); $this->assertEquals($expectedExtensionAttributes['firstname'], $testAttribute->getFirstName()); $this->assertEquals($expectedExtensionAttributes['lastname'], $testAttribute->getLastName()); $this->assertEquals($expectedExtensionAttributes['email'], $testAttribute->getEmail()); From 8aeba8f8ef4481b62a51d52be0f6aff6e6a409f4 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher Date: Tue, 7 Feb 2017 17:37:19 +0200 Subject: [PATCH 14/44] MAGETWO-62044: Not possible to update or delete products in cart or checkout after deleting address --- .../Model/QuoteRepository/SaveHandler.php | 22 +++++++++++++--- .../ShippingAssignmentProcessorTest.php | 5 +++- .../Model/QuoteRepository/SaveHandlerTest.php | 26 ++++++++++++++----- .../Quote/Model/QuoteRepositoryTest.php | 19 ++++++++++++-- 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php b/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php index 25dfe7a3f20c5..454da7002941c 100644 --- a/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php +++ b/app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php @@ -6,6 +6,9 @@ namespace Magento\Quote\Model\QuoteRepository; use Magento\Quote\Api\Data\CartInterface; +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\InputException; class SaveHandler @@ -30,22 +33,31 @@ class SaveHandler */ private $shippingAssignmentPersister; + /** + * @var AddressRepositoryInterface + */ + private $addressRepository; + /** * @param \Magento\Quote\Model\ResourceModel\Quote $quoteResource * @param \Magento\Quote\Model\Quote\Item\CartItemPersister $cartItemPersister * @param \Magento\Quote\Model\Quote\Address\BillingAddressPersister $billingAddressPersister * @param \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister $shippingAssignmentPersister + * @param AddressRepositoryInterface $addressRepository */ public function __construct( \Magento\Quote\Model\ResourceModel\Quote $quoteResource, \Magento\Quote\Model\Quote\Item\CartItemPersister $cartItemPersister, \Magento\Quote\Model\Quote\Address\BillingAddressPersister $billingAddressPersister, - \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister $shippingAssignmentPersister + \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister $shippingAssignmentPersister, + AddressRepositoryInterface $addressRepository = null ) { $this->quoteResourceModel = $quoteResource; $this->cartItemPersister = $cartItemPersister; $this->billingAddressPersister = $billingAddressPersister; $this->shippingAssignmentPersister = $shippingAssignmentPersister; + $this->addressRepository = $addressRepository + ?: ObjectManager::getInstance()->get(AddressRepositoryInterface::class); } /** @@ -76,8 +88,12 @@ public function save(CartInterface $quote) $billingAddress = $quote->getBillingAddress(); if ($billingAddress) { - if ($billingAddress->getCustomerAddressId() && !$billingAddress->getCustomerAddress()) { - $billingAddress->setCustomerAddressId(null); + if ($billingAddress->getCustomerAddressId()) { + try { + $this->addressRepository->getById($billingAddress->getCustomerAddressId()); + } catch (NoSuchEntityException $e) { + $billingAddress->setCustomerAddressId(null); + } } $this->billingAddressPersister->save($quote, $billingAddress); diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/ShippingAssignment/ShippingAssignmentProcessorTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/ShippingAssignment/ShippingAssignmentProcessorTest.php index 985afa8b6829f..efdaa0a52f862 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/Quote/ShippingAssignment/ShippingAssignmentProcessorTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/ShippingAssignment/ShippingAssignmentProcessorTest.php @@ -100,6 +100,9 @@ protected function setUp() $this->shippingAssignmentMock->expects(static::any()) ->method('getShipping') ->willReturn($this->shippingMock); + $this->shippingMock->expects(static::any()) + ->method('getAddress') + ->willReturn($this->shippingAddressMock); $this->objectManagerHelper = new ObjectManagerHelper($this); $this->shippingAssignmentProcessor = $this->objectManagerHelper->getObject( @@ -152,7 +155,7 @@ public function testSaveWithNotExistingCustomerAddress() ->method('getById') ->with($customerAddressId) ->willThrowException(new NoSuchEntityException()); - $this->shippingAddressMock->expects(static::once()) + $this->shippingAddressMock->expects(static::exactly(2)) ->method('setCustomerAddressId') ->with(null) ->willReturn($this->shippingAddressMock); diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php index 9af461611853f..b3b12ce5c6e04 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/SaveHandlerTest.php @@ -11,10 +11,12 @@ use Magento\Quote\Model\Quote\Item\CartItemPersister; use Magento\Quote\Model\Quote\Address\BillingAddressPersister; use Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister; +use Magento\Customer\Api\AddressRepositoryInterface; use Magento\Quote\Model\Quote; use Magento\Quote\Model\Quote\Address as QuoteAddress; use Magento\Quote\Api\Data\CartExtensionInterface; use Magento\Quote\Model\Quote\Item as QuoteItem; +use Magento\Framework\Exception\NoSuchEntityException; class SaveHandlerTest extends \PHPUnit_Framework_TestCase { @@ -48,6 +50,11 @@ class SaveHandlerTest extends \PHPUnit_Framework_TestCase */ private $shippingAssignmentPersisterMock; + /** + * @var AddressRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $addressRepositoryMock; + /** * @var Quote|\PHPUnit_Framework_MockObject_MockObject */ @@ -77,6 +84,8 @@ protected function setUp() $this->shippingAssignmentPersisterMock = $this->getMockBuilder(ShippingAssignmentPersister::class) ->disableOriginalConstructor() ->getMock(); + $this->addressRepositoryMock = $this->getMockBuilder(AddressRepositoryInterface::class) + ->getMockForAbstractClass(); $this->quoteMock = $this->getMockBuilder(Quote::class) ->disableOriginalConstructor() ->setMethods( @@ -88,7 +97,6 @@ protected function setUp() ->getMock(); $this->billingAddressMock = $this->getMockBuilder(QuoteAddress::class) ->disableOriginalConstructor() - ->setMethods(['getCustomerAddressId', 'getCustomerAddress', 'setCustomerAddressId']) ->getMock(); $this->extensionAttributesMock = $this->getMockBuilder(CartExtensionInterface::class) ->getMockForAbstractClass(); @@ -107,7 +115,8 @@ protected function setUp() 'quoteResource' => $this->quoteResourceModelMock, 'cartItemPersister' => $this->cartItemPersisterMock, 'billingAddressPersister' => $this->billingAddressPersisterMock, - 'ShippingAssignmentPersister' => $this->shippingAssignmentPersisterMock + 'shippingAssignmentPersister' => $this->shippingAssignmentPersisterMock, + 'addressRepository' => $this->addressRepositoryMock ] ); } @@ -153,6 +162,8 @@ public function testSaveForVirtualQuote() public function testSaveWithNotExistingCustomerAddress() { + $customerAddressId = 5; + $this->quoteMock->expects(static::atLeastOnce()) ->method('getItems') ->willReturn([]); @@ -160,11 +171,12 @@ public function testSaveWithNotExistingCustomerAddress() ->method('setLastAddedItem'); $this->billingAddressMock->expects(static::atLeastOnce()) ->method('getCustomerAddressId') - ->willReturn(5); - $this->billingAddressMock->expects(static::atLeastOnce()) - ->method('getCustomerAddress') - ->willReturn(null); - $this->billingAddressMock->expects(static::atLeastOnce()) + ->willReturn($customerAddressId); + $this->addressRepositoryMock->expects(static::once()) + ->method('getById') + ->with($customerAddressId) + ->willThrowException(new NoSuchEntityException()); + $this->billingAddressMock->expects(static::once()) ->method('setCustomerAddressId') ->willReturn(null); $this->billingAddressPersisterMock->expects(static::once()) diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteRepositoryTest.php index cf2597e43d525..caa10172de7d8 100644 --- a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteRepositoryTest.php @@ -9,6 +9,7 @@ use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Api\SearchCriteria; +use Magento\Framework\Api\SearchResults; use Magento\Framework\Api\FilterBuilder; use Magento\Quote\Api\Data\CartInterface; use Magento\Quote\Api\Data\CartSearchResultsInterface; @@ -70,6 +71,10 @@ public function testGetListDoubleCall() $this->assertEmpty($searchResult->getItems()); } + /** + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled + */ public function testSaveWithNotExistingCustomerAddress() { $addressData = include __DIR__ . '/../../Sales/_files/address_data.php'; @@ -107,6 +112,16 @@ public function testSaveWithNotExistingCustomerAddress() ->setExtensionAttributes($extensionAttributes) ->save(); $this->quoteRepository->save($quote); + + $this->assertNull($quote->getBillingAddress()->getCustomerAddressId()); + $this->assertNull($quote->getShippingAddress()->getCustomerAddressId()); + $this->assertNull( + $quote->getExtensionAttributes() + ->getShippingAssignments()[0] + ->getShipping() + ->getAddress() + ->getCustomerAddressId() + ); } /** @@ -130,9 +145,9 @@ private function getSearchCriteria($filterValue) /** * Perform assertions * - * @param CartSearchResultsInterface $searchResult + * @param SearchResults|CartSearchResultsInterface $searchResult */ - private function performAssertions(CartSearchResultsInterface $searchResult) + private function performAssertions($searchResult) { $expectedExtensionAttributes = [ 'firstname' => 'firstname', From d92845a648efc9fee1e79f2179d93664c8c6bc68 Mon Sep 17 00:00:00 2001 From: dmanners Date: Fri, 3 Feb 2017 14:11:02 +0000 Subject: [PATCH 15/44] Remove the use of Zend_Json from the Onepage checkout block --- app/code/Magento/Checkout/Block/Onepage.php | 13 +++++++++++-- .../Checkout/Test/Unit/Block/OnepageTest.php | 11 ++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/Block/Onepage.php b/app/code/Magento/Checkout/Block/Onepage.php index 15e913d9338d0..d5fbb04155b5e 100644 --- a/app/code/Magento/Checkout/Block/Onepage.php +++ b/app/code/Magento/Checkout/Block/Onepage.php @@ -36,19 +36,26 @@ class Onepage extends \Magento\Framework\View\Element\Template */ protected $layoutProcessors; + /** + * @var \Magento\Framework\Serialize\SerializerInterface + */ + private $serializer; + /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Framework\Data\Form\FormKey $formKey * @param \Magento\Checkout\Model\CompositeConfigProvider $configProvider * @param array $layoutProcessors * @param array $data + * @param \Magento\Framework\Serialize\SerializerInterface|null $serializer */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Magento\Framework\Data\Form\FormKey $formKey, \Magento\Checkout\Model\CompositeConfigProvider $configProvider, array $layoutProcessors = [], - array $data = [] + array $data = [], + \Magento\Framework\Serialize\SerializerInterface $serializer = null ) { parent::__construct($context, $data); $this->formKey = $formKey; @@ -56,6 +63,8 @@ public function __construct( $this->jsLayout = isset($data['jsLayout']) && is_array($data['jsLayout']) ? $data['jsLayout'] : []; $this->configProvider = $configProvider; $this->layoutProcessors = $layoutProcessors; + $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\Serialize\SerializerInterface::class); } /** @@ -66,7 +75,7 @@ public function getJsLayout() foreach ($this->layoutProcessors as $processor) { $this->jsLayout = $processor->process($this->jsLayout); } - return \Zend_Json::encode($this->jsLayout); + return $this->serializer->serialize($this->jsLayout); } /** diff --git a/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php b/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php index 47fddfeb4a827..9936dc5157af7 100644 --- a/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php @@ -32,6 +32,11 @@ class OnepageTest extends \PHPUnit_Framework_TestCase */ protected $layoutProcessorMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $serializer; + protected function setUp() { $contextMock = $this->getMock(\Magento\Framework\View\Element\Template\Context::class, [], [], '', false); @@ -54,11 +59,15 @@ protected function setUp() false ); + $this->serializer = new \Magento\Framework\Serialize\Serializer\Json(); + $this->model = new \Magento\Checkout\Block\Onepage( $contextMock, $this->formKeyMock, $this->configProviderMock, - [$this->layoutProcessorMock] + [$this->layoutProcessorMock], + [], + $this->serializer ); } From 248cd85617e857e5dcae35531a33e9806d63fc07 Mon Sep 17 00:00:00 2001 From: dmanners Date: Fri, 3 Feb 2017 14:15:50 +0000 Subject: [PATCH 16/44] Mock the serialize method return value --- app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php b/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php index 9936dc5157af7..25b00379e5c44 100644 --- a/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php @@ -59,7 +59,7 @@ protected function setUp() false ); - $this->serializer = new \Magento\Framework\Serialize\Serializer\Json(); + $this->serializer = $this->getMock(\Magento\Framework\Serialize\SerializerInterface::class,[],[],'',false); $this->model = new \Magento\Checkout\Block\Onepage( $contextMock, @@ -103,6 +103,9 @@ public function testGetJsLayout() $processedLayout = ['layout' => ['processed' => true]]; $jsonLayout = '{"layout":{"processed":true}}'; $this->layoutProcessorMock->expects($this->once())->method('process')->with([])->willReturn($processedLayout); + $this->serializer->expects($this->once())->method('serialize')->will( + $this->returnValue(json_encode($processedLayout)) + ); $this->assertEquals($jsonLayout, $this->model->getJsLayout()); } From 072dde798832c708359c33c578f7990040e97f64 Mon Sep 17 00:00:00 2001 From: dmanners Date: Fri, 3 Feb 2017 14:27:31 +0000 Subject: [PATCH 17/44] Remove Zend_Json usage from the cart shipping block --- app/code/Magento/Checkout/Block/Cart/Shipping.php | 13 +++++++++++-- app/code/Magento/Checkout/Block/Onepage.php | 7 ++++--- .../Checkout/Test/Unit/Block/Cart/ShippingTest.php | 14 +++++++++++++- .../Checkout/Test/Unit/Block/OnepageTest.php | 4 ++-- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Checkout/Block/Cart/Shipping.php b/app/code/Magento/Checkout/Block/Cart/Shipping.php index a7f808b9ccb5e..5b0d231bbdfbe 100644 --- a/app/code/Magento/Checkout/Block/Cart/Shipping.php +++ b/app/code/Magento/Checkout/Block/Cart/Shipping.php @@ -20,14 +20,20 @@ class Shipping extends \Magento\Checkout\Block\Cart\AbstractCart */ protected $layoutProcessors; + /** + * @var \Magento\Framework\Serialize\SerializerInterface + */ + private $serializer; + /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Checkout\Model\Session $checkoutSession * @param \Magento\Checkout\Model\CompositeConfigProvider $configProvider * @param array $layoutProcessors + * @param \Magento\Framework\Serialize\SerializerInterface|null $serializer * @param array $data - * @codeCoverageIgnore + * @throws \RuntimeException */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, @@ -35,12 +41,15 @@ public function __construct( \Magento\Checkout\Model\Session $checkoutSession, \Magento\Checkout\Model\CompositeConfigProvider $configProvider, array $layoutProcessors = [], + \Magento\Framework\Serialize\SerializerInterface $serializer = null, array $data = [] ) { $this->configProvider = $configProvider; $this->layoutProcessors = $layoutProcessors; parent::__construct($context, $customerSession, $checkoutSession, $data); $this->_isScopePrivate = true; + $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\Serialize\SerializerInterface::class); } /** @@ -64,7 +73,7 @@ public function getJsLayout() foreach ($this->layoutProcessors as $processor) { $this->jsLayout = $processor->process($this->jsLayout); } - return \Zend_Json::encode($this->jsLayout); + return $this->serializer->serialize($this->jsLayout); } /** diff --git a/app/code/Magento/Checkout/Block/Onepage.php b/app/code/Magento/Checkout/Block/Onepage.php index d5fbb04155b5e..61001abcc70d7 100644 --- a/app/code/Magento/Checkout/Block/Onepage.php +++ b/app/code/Magento/Checkout/Block/Onepage.php @@ -46,16 +46,17 @@ class Onepage extends \Magento\Framework\View\Element\Template * @param \Magento\Framework\Data\Form\FormKey $formKey * @param \Magento\Checkout\Model\CompositeConfigProvider $configProvider * @param array $layoutProcessors - * @param array $data * @param \Magento\Framework\Serialize\SerializerInterface|null $serializer + * @param array $data + * @throws \RuntimeException */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Magento\Framework\Data\Form\FormKey $formKey, \Magento\Checkout\Model\CompositeConfigProvider $configProvider, array $layoutProcessors = [], - array $data = [], - \Magento\Framework\Serialize\SerializerInterface $serializer = null + \Magento\Framework\Serialize\SerializerInterface $serializer = null, + array $data = [] ) { parent::__construct($context, $data); $this->formKey = $formKey; diff --git a/app/code/Magento/Checkout/Test/Unit/Block/Cart/ShippingTest.php b/app/code/Magento/Checkout/Test/Unit/Block/Cart/ShippingTest.php index 8313695ff8e76..f30ea4a9c578a 100644 --- a/app/code/Magento/Checkout/Test/Unit/Block/Cart/ShippingTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Block/Cart/ShippingTest.php @@ -47,6 +47,11 @@ class ShippingTest extends \PHPUnit_Framework_TestCase */ protected $layout; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $serializer; + protected function setUp() { $this->context = $this->getMock(\Magento\Framework\View\Element\Template\Context::class, [], [], '', false); @@ -69,6 +74,7 @@ protected function setUp() $this->storeManager = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class); $this->context->expects($this->once())->method('getStoreManager')->willReturn($this->storeManager); + $this->serializer = $this->getMock(\Magento\Framework\Serialize\SerializerInterface::class,[],[],'',false); $this->model = new \Magento\Checkout\Block\Cart\Shipping( $this->context, @@ -76,6 +82,7 @@ protected function setUp() $this->checkoutSession, $this->configProvider, [$this->layoutProcessor], + $this->serializer, ['jsLayout' => $this->layout] ); } @@ -91,13 +98,18 @@ public function testGetJsLayout() { $layoutProcessed = $this->layout; $layoutProcessed['components']['thirdComponent'] = ['param' => 'value']; + $jsonLayoutProcessed = json_encode($layoutProcessed); $this->layoutProcessor->expects($this->once()) ->method('process') ->with($this->layout) ->willReturn($layoutProcessed); + + $this->serializer->expects($this->once())->method('serialize')->will( + $this->returnValue($jsonLayoutProcessed) + ); $this->assertEquals( - \Zend_Json::encode($layoutProcessed), + $jsonLayoutProcessed, $this->model->getJsLayout() ); } diff --git a/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php b/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php index 25b00379e5c44..0ef5e89669dad 100644 --- a/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php @@ -66,8 +66,8 @@ protected function setUp() $this->formKeyMock, $this->configProviderMock, [$this->layoutProcessorMock], - [], - $this->serializer + $this->serializer, + [] ); } From 287c3150bd793cc1bc3e94512f0423e8e64b470f Mon Sep 17 00:00:00 2001 From: dmanners Date: Fri, 3 Feb 2017 14:32:16 +0000 Subject: [PATCH 18/44] Remove Zend_Json usage from the onepage.phtml template --- app/code/Magento/Checkout/Block/Onepage.php | 8 ++++++++ .../Magento/Checkout/Test/Unit/Block/OnepageTest.php | 11 +++++++++++ .../Checkout/view/frontend/templates/onepage.phtml | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Block/Onepage.php b/app/code/Magento/Checkout/Block/Onepage.php index 61001abcc70d7..d9b1e9d08ad6c 100644 --- a/app/code/Magento/Checkout/Block/Onepage.php +++ b/app/code/Magento/Checkout/Block/Onepage.php @@ -111,4 +111,12 @@ public function getBaseUrl() { return $this->_storeManager->getStore()->getBaseUrl(); } + + /** + * @return bool|string + */ + public function getSerializedCheckoutConfig() + { + return $this->serializer->serialize($this->getCheckoutConfig()); + } } diff --git a/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php b/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php index 0ef5e89669dad..ac50ce76c45ad 100644 --- a/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Block/OnepageTest.php @@ -109,4 +109,15 @@ public function testGetJsLayout() $this->assertEquals($jsonLayout, $this->model->getJsLayout()); } + + public function testGetSerializedCheckoutConfig() + { + $checkoutConfig = ['checkout', 'config']; + $this->configProviderMock->expects($this->once())->method('getConfig')->willReturn($checkoutConfig); + $this->serializer->expects($this->once())->method('serialize')->will( + $this->returnValue(json_encode($checkoutConfig)) + ); + + $this->assertEquals(json_encode($checkoutConfig), $this->model->getSerializedCheckoutConfig()); + } } diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage.phtml index bf9bcb15c3ec8..6f1931583fb57 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/onepage.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/onepage.phtml @@ -23,7 +23,7 @@ }