diff --git a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php index 79e76feb4366190cb1d81389e7c54ac4f97cca9e..4a0f502da20dfdc94545a81c20dfa061ffef0008 100644 --- a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php +++ b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php @@ -14,6 +14,7 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor { /** * @var \Magento\Quote\Api\BillingAddressManagementInterface + * @deprecated This call was substituted to eliminate extra quote::save call */ protected $billingAddressManagement; @@ -42,6 +43,11 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor */ private $logger; + /** + * @var \Magento\Quote\Api\CartRepositoryInterface + */ + private $cartRepository; + /** * @param \Magento\Quote\Api\BillingAddressManagementInterface $billingAddressManagement * @param \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement @@ -99,7 +105,19 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor \Magento\Quote\Api\Data\AddressInterface $billingAddress = null ) { if ($billingAddress) { - $this->billingAddressManagement->assign($cartId, $billingAddress); + /** @var \Magento\Quote\Api\CartRepositoryInterface $quoteRepository */ + $quoteRepository = $this->getCartRepository(); + /** @var \Magento\Quote\Model\Quote $quote */ + $quote = $quoteRepository->getActive($cartId); + $quote->removeAddress($quote->getBillingAddress()->getId()); + $quote->setBillingAddress($billingAddress); + $quote->setDataChanges(true); + $shippingAddress = $quote->getShippingAddress(); + if ($shippingAddress && $shippingAddress->getShippingMethod()) { + $shippingDataArray = explode('_', $shippingAddress->getShippingMethod()); + $shippingCarrier = array_shift($shippingDataArray); + $shippingAddress->setLimitCarrier($shippingCarrier); + } } $this->paymentMethodManagement->set($cartId, $paymentMethod); return true; @@ -130,4 +148,19 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor } return $this->logger; } + + /** + * Get Cart repository + * + * @return \Magento\Quote\Api\CartRepositoryInterface + * @deprecated + */ + private function getCartRepository() + { + if (!$this->cartRepository) { + $this->cartRepository = \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Quote\Api\CartRepositoryInterface::class); + } + return $this->cartRepository; + } } diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php index 237d28e2845e430493d1ba7f73b15160995c7c9c..1b4f8b8c64a864efefb03e56cd52aa8dbb41e304 100644 --- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php +++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php @@ -144,6 +144,7 @@ class ShippingInformationManagement implements \Magento\Checkout\Api\ShippingInf /** @var \Magento\Quote\Model\Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); + $address->setLimitCarrier($carrierCode); $quote = $this->prepareShippingAssignment($quote, $address, $carrierCode . '_' . $methodCode); $this->validateQuote($quote); $quote->setIsMultiShipping(false); diff --git a/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php index 8da67a1fcb71512dd218a2c62d51b7922bb36c25..f256d8edefd1c9b2bd0dc41c838293cf4b9dfa32 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php @@ -5,8 +5,9 @@ */ namespace Magento\Checkout\Test\Unit\Model; -use Magento\Framework\Exception\CouldNotSaveException; - +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase { /** @@ -34,6 +35,11 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase */ private $loggerMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $cartRepositoryMock; + protected function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -46,7 +52,7 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase $this->cartManagementMock = $this->getMock(\Magento\Quote\Api\CartManagementInterface::class); $this->loggerMock = $this->getMock(\Psr\Log\LoggerInterface::class); - + $this->cartRepositoryMock = $this->getMockBuilder(\Magento\Quote\Api\CartRepositoryInterface::class)->getMock(); $this->model = $objectManager->getObject( \Magento\Checkout\Model\PaymentInformationManagement::class, [ @@ -56,6 +62,7 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase ] ); $objectManager->setBackwardCompatibleProperty($this->model, 'logger', $this->loggerMock); + $objectManager->setBackwardCompatibleProperty($this->model, 'cartRepository', $this->cartRepositoryMock); } public function testSavePaymentInformationAndPlaceOrder() @@ -65,9 +72,7 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase $paymentMock = $this->getMock(\Magento\Quote\Api\Data\PaymentInterface::class); $billingAddressMock = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class); - $this->billingAddressManagementMock->expects($this->once()) - ->method('assign') - ->with($cartId, $billingAddressMock); + $this->getMockForAssignBillingAddress($cartId, $billingAddressMock); $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock); $this->cartManagementMock->expects($this->once())->method('placeOrder')->with($cartId)->willReturn($orderId); @@ -87,9 +92,7 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase $paymentMock = $this->getMock(\Magento\Quote\Api\Data\PaymentInterface::class); $billingAddressMock = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class); - $this->billingAddressManagementMock->expects($this->once()) - ->method('assign') - ->with($cartId, $billingAddressMock); + $this->getMockForAssignBillingAddress($cartId, $billingAddressMock); $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock); $exception = new \Exception(__('DB exception')); $this->loggerMock->expects($this->once())->method('critical'); @@ -104,7 +107,6 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase $orderId = 200; $paymentMock = $this->getMock(\Magento\Quote\Api\Data\PaymentInterface::class); - $this->billingAddressManagementMock->expects($this->never())->method('assign'); $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock); $this->cartManagementMock->expects($this->once())->method('placeOrder')->with($cartId)->willReturn($orderId); @@ -120,9 +122,7 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase $paymentMock = $this->getMock(\Magento\Quote\Api\Data\PaymentInterface::class); $billingAddressMock = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class); - $this->billingAddressManagementMock->expects($this->once()) - ->method('assign') - ->with($cartId, $billingAddressMock); + $this->getMockForAssignBillingAddress($cartId, $billingAddressMock); $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock); $this->assertTrue($this->model->savePaymentInformation($cartId, $paymentMock, $billingAddressMock)); @@ -133,7 +133,6 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase $cartId = 100; $paymentMock = $this->getMock(\Magento\Quote\Api\Data\PaymentInterface::class); - $this->billingAddressManagementMock->expects($this->never())->method('assign'); $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock); $this->assertTrue($this->model->savePaymentInformation($cartId, $paymentMock)); @@ -149,9 +148,8 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase $paymentMock = $this->getMock(\Magento\Quote\Api\Data\PaymentInterface::class); $billingAddressMock = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class); - $this->billingAddressManagementMock->expects($this->once()) - ->method('assign') - ->with($cartId, $billingAddressMock); + $this->getMockForAssignBillingAddress($cartId, $billingAddressMock); + $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock); $phrase = new \Magento\Framework\Phrase(__('DB exception')); $exception = new \Magento\Framework\Exception\LocalizedException($phrase); @@ -160,4 +158,31 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase $this->model->savePaymentInformationAndPlaceOrder($cartId, $paymentMock, $billingAddressMock); } + + /** + * @param int $cartId + * @param \PHPUnit_Framework_MockObject_MockObject $billingAddressMock + */ + private function getMockForAssignBillingAddress($cartId, $billingAddressMock) + { + $billingAddressId = 1; + $quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false); + $quoteBillingAddress = $this->getMock(\Magento\Quote\Model\Quote\Address::class, [], [], '', false); + $quoteShippingAddress = $this->getMock( + \Magento\Quote\Model\Quote\Address::class, + ['setLimitCarrier', 'getShippingMethod'], + [], + '', + false + ); + $this->cartRepositoryMock->expects($this->any())->method('getActive')->with($cartId)->willReturn($quoteMock); + $quoteMock->expects($this->once())->method('getBillingAddress')->willReturn($quoteBillingAddress); + $quoteMock->expects($this->once())->method('getShippingAddress')->willReturn($quoteShippingAddress); + $quoteBillingAddress->expects($this->once())->method('getId')->willReturn($billingAddressId); + $quoteMock->expects($this->once())->method('removeAddress')->with($billingAddressId); + $quoteMock->expects($this->once())->method('setBillingAddress')->with($billingAddressMock); + $quoteMock->expects($this->once())->method('setDataChanges')->willReturnSelf(); + $quoteShippingAddress->expects($this->any())->method('getShippingMethod')->willReturn('flatrate_flatrate'); + $quoteShippingAddress->expects($this->once())->method('setLimitCarrier')->with('flatrate')->willReturnSelf(); + } } diff --git a/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php index 402a0c8228356a7ae8a148d7626e06bb5dc15a27..751bcee6db2a9fd6e2d15405c57f899a2d7ad972 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php @@ -109,7 +109,8 @@ class ShippingInformationManagementTest extends \PHPUnit_Framework_TestCase 'importCustomerAddressData', 'save', 'getShippingRateByCode', - 'getShippingMethod' + 'getShippingMethod', + 'setLimitCarrier' ], [], '', @@ -208,7 +209,7 @@ class ShippingInformationManagementTest extends \PHPUnit_Framework_TestCase private function setShippingAssignmentsMocks($shippingMethod) { $this->quoteMock->expects($this->once())->method('getExtensionAttributes')->willReturn(null); - + $this->shippingAddressMock->expects($this->once())->method('setLimitCarrier'); $this->cartExtensionMock = $this->getMock( \Magento\Quote\Api\Data\CartExtension::class, ['getShippingAssignments', 'setShippingAssignments'], diff --git a/app/code/Magento/Quote/Model/CustomerManagement.php b/app/code/Magento/Quote/Model/CustomerManagement.php index b796ebe9d0db4c0305c9e1d9c8e09838540ba820..04707e152674808b45c72c695861bd11b42cf13a 100644 --- a/app/code/Magento/Quote/Model/CustomerManagement.php +++ b/app/code/Magento/Quote/Model/CustomerManagement.php @@ -62,8 +62,6 @@ class CustomerManagement $quote->getPasswordHash() ); $quote->setCustomer($customer); - } else { - $this->customerRepository->save($customer); } if (!$quote->getBillingAddress()->getId() && $customer->getDefaultBilling()) { $quote->getBillingAddress()->importCustomerAddressData( diff --git a/app/code/Magento/Quote/Test/Unit/Model/CustomerManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/CustomerManagementTest.php index 600bf1723a5c091a7879c3c1eb706c261f197c18..a1caac3473ccb3a352af6be8e64e36c4c6061cf3 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/CustomerManagementTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/CustomerManagementTest.php @@ -158,4 +158,34 @@ class CustomerManagementTest extends \PHPUnit_Framework_TestCase ->willReturn($this->customerMock); $this->customerManagement->populateCustomerInfo($this->quoteMock); } + + public function testPopulateCustomerInfoForExistingCustomer() + { + $this->quoteMock->expects($this->once()) + ->method('getCustomer') + ->willReturn($this->customerMock); + $this->customerMock->expects($this->atLeastOnce()) + ->method('getId') + ->willReturn(1); + $this->customerMock->expects($this->atLeastOnce()) + ->method('getDefaultBilling') + ->willReturn(100500); + $this->quoteMock->expects($this->atLeastOnce()) + ->method('getBillingAddress') + ->willReturn($this->quoteAddressMock); + $this->quoteMock->expects($this->atLeastOnce()) + ->method('getShippingAddress') + ->willReturn($this->quoteAddressMock); + $this->quoteAddressMock->expects($this->atLeastOnce()) + ->method('getId') + ->willReturn(null); + $this->customerAddressRepositoryMock->expects($this->atLeastOnce()) + ->method('getById') + ->with(100500) + ->willReturn($this->customerAddressMock); + $this->quoteAddressMock->expects($this->atLeastOnce()) + ->method('importCustomerAddressData') + ->willReturnSelf(); + $this->customerManagement->populateCustomerInfo($this->quoteMock); + } } diff --git a/app/code/Magento/SalesInventory/composer.json b/app/code/Magento/SalesInventory/composer.json index fa06db402a286f5f37b2b1991d2c8c49665bd1d8..07bbc9aeba4827a9fa0f78025c647932d0ca6910 100644 --- a/app/code/Magento/SalesInventory/composer.json +++ b/app/code/Magento/SalesInventory/composer.json @@ -10,7 +10,7 @@ "magento/framework": "100.2.*" }, "type": "magento2-module", - "version": "100.0.0-dev", + "version": "100.2.0-dev", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Ui/Model/Manager.php b/app/code/Magento/Ui/Model/Manager.php index 348b7d398800d71bc763eecb719313b89f44252e..a2a4f05eb8bad7b2a4e379b552e245df9c00e13c 100644 --- a/app/code/Magento/Ui/Model/Manager.php +++ b/app/code/Magento/Ui/Model/Manager.php @@ -1,6 +1,6 @@ <?php /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © 2017 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Ui\Model; @@ -17,6 +17,8 @@ use Magento\Framework\View\Element\UiComponent\Config\ManagerInterface; use Magento\Framework\View\Element\UiComponent\Config\Provider\Component\Definition as ComponentDefinition; use Magento\Framework\View\Element\UiComponent\Config\ReaderFactory; use Magento\Framework\View\Element\UiComponent\Config\UiReaderInterface; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Framework\App\ObjectManager; /** * Class Manager @@ -94,6 +96,11 @@ class Manager implements ManagerInterface */ protected $uiReader; + /** + * @var SerializerInterface + */ + private $serializer; + /** * @param ComponentDefinition $componentConfigProvider * @param DomMergerInterface $domMerger @@ -102,6 +109,7 @@ class Manager implements ManagerInterface * @param AggregatedFileCollectorFactory $aggregatedFileCollectorFactory * @param CacheInterface $cache * @param InterpreterInterface $argumentInterpreter + * @param SerializerInterface|null $serializer */ public function __construct( ComponentDefinition $componentConfigProvider, @@ -110,7 +118,8 @@ class Manager implements ManagerInterface ArrayObjectFactory $arrayObjectFactory, AggregatedFileCollectorFactory $aggregatedFileCollectorFactory, CacheInterface $cache, - InterpreterInterface $argumentInterpreter + InterpreterInterface $argumentInterpreter, + SerializerInterface $serializer = null ) { $this->componentConfigProvider = $componentConfigProvider; $this->domMerger = $domMerger; @@ -120,6 +129,7 @@ class Manager implements ManagerInterface $this->aggregatedFileCollectorFactory = $aggregatedFileCollectorFactory; $this->cache = $cache; $this->argumentInterpreter = $argumentInterpreter; + $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); } /** @@ -164,9 +174,14 @@ class Manager implements ManagerInterface $cachedPool = $this->cache->load($cacheID); if ($cachedPool === false) { $this->prepare($name); - $this->cache->save($this->componentsPool->serialize(), $cacheID); + $this->cache->save( + $this->serializer->serialize($this->componentsPool->getArrayCopy()), + $cacheID + ); } else { - $this->componentsPool->unserialize($cachedPool); + $this->componentsPool->exchangeArray( + $this->serializer->unserialize($cachedPool) + ); } $this->componentsData->offsetSet($name, $this->componentsPool); $this->componentsData->offsetSet($name, $this->evaluateComponentArguments($this->getData($name))); diff --git a/app/code/Magento/Ui/Test/Unit/Model/ManagerTest.php b/app/code/Magento/Ui/Test/Unit/Model/ManagerTest.php index 37f97af4597ac069312dbb1e1fb404e36cbdf12f..0e50950cc953eb4a24a2b36ff114a588b700d573 100644 --- a/app/code/Magento/Ui/Test/Unit/Model/ManagerTest.php +++ b/app/code/Magento/Ui/Test/Unit/Model/ManagerTest.php @@ -1,6 +1,6 @@ <?php /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © 2017 Magento. All rights reserved. * See COPYING.txt for license details. */ @@ -75,6 +75,9 @@ class ManagerTest extends \PHPUnit_Framework_TestCase */ protected $aggregatedFileCollectorFactory; + /** @var \Magento\Framework\Serialize\SerializerInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $serializer; + protected function setUp() { $this->componentConfigProvider = $this->getMockBuilder( @@ -105,6 +108,24 @@ class ManagerTest extends \PHPUnit_Framework_TestCase ->getMockForAbstractClass(); $this->argumentInterpreter = $this->getMockBuilder(\Magento\Framework\Data\Argument\InterpreterInterface::class) ->getMockForAbstractClass(); + $this->serializer = $this->getMockBuilder( + \Magento\Framework\Serialize\SerializerInterface::class + )->getMockForAbstractClass(); + $this->serializer->expects($this->any()) + ->method('serialize') + ->willReturnCallback( + function ($value) { + return json_encode($value); + } + ); + $this->serializer->expects($this->any()) + ->method('unserialize') + ->willReturnCallback( + function ($value) { + return json_decode($value, true); + } + ); + $this->manager = new Manager( $this->componentConfigProvider, $this->domMerger, @@ -112,7 +133,8 @@ class ManagerTest extends \PHPUnit_Framework_TestCase $this->arrayObjectFactory, $this->aggregatedFileCollectorFactory, $this->cacheConfig, - $this->argumentInterpreter + $this->argumentInterpreter, + $this->serializer ); } @@ -192,7 +214,7 @@ class ManagerTest extends \PHPUnit_Framework_TestCase [ 'test_component1', new \ArrayObject(), - $cachedData->serialize(), + json_encode($cachedData->getArrayCopy()), [], [ 'test_component1' => [ diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/date.js b/app/code/Magento/Ui/view/base/web/js/form/element/date.js index 202cfe93069b02bad6ff888a51b9661a54109e54..eb8dfb4b4057e8c7d8cf274062788a5849114d09 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/date.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/date.js @@ -53,13 +53,12 @@ define([ pickerDefaultDateFormat: 'MM/dd/y', // ICU Date Format pickerDefaultTimeFormat: 'h:mm a', // ICU Time Format + elementTmpl: 'ui/form/element/date', + /** - * Moment compatible format used for moment conversion - * of date from datePicker + * Format needed by moment timezone for conversion */ - momentFormat: 'MM/DD/YYYY', - - elementTmpl: 'ui/form/element/date', + timezoneFormat: 'YYYY-MM-DD HH:mm', listens: { 'value': 'onValueChange', @@ -141,15 +140,17 @@ define([ */ onShiftedValueChange: function (shiftedValue) { var value, - formattedValue; + formattedValue, + momentValue; if (shiftedValue) { + momentValue = moment(shiftedValue, this.pickerDateTimeFormat); + if (this.options.showsTime) { - formattedValue = moment(shiftedValue).format('YYYY-MM-DD HH:mm'); + formattedValue = moment(momentValue).format(this.timezoneFormat); value = moment.tz(formattedValue, this.storeTimeZone).tz('UTC').toISOString(); } else { - value = moment(shiftedValue, this.momentFormat); - value = value.format(this.outputDateFormat); + value = momentValue.format(this.outputDateFormat); } } else { value = ''; @@ -166,8 +167,6 @@ define([ */ prepareDateTimeFormats: function () { this.pickerDateTimeFormat = this.options.dateFormat; - this.momentFormat = this.options.dateFormat ? - utils.convertToMomentFormat(this.options.dateFormat) : this.momentFormat; if (this.options.showsTime) { this.pickerDateTimeFormat += ' ' + this.options.timeFormat; diff --git a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_toolbar.less b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_toolbar.less index 00b2c23450ff7881c5a9acca30df491b7001187c..782b78672f7aebd3d7038544dbb56884e680dd6d 100644 --- a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_toolbar.less +++ b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_toolbar.less @@ -81,9 +81,11 @@ ); } - .sorter.sort-desc { - &:before { - content: @icon-arrow-down; + .sorter { + .sort-desc { + &:before { + content: @icon-arrow-down; + } } } diff --git a/composer.json b/composer.json index 7840f84720b6cac97073647c90c184315a80eb4b..11fe00b7ed45add98a8996bea8a480403d44a53c 100644 --- a/composer.json +++ b/composer.json @@ -151,7 +151,7 @@ "magento/module-rss": "100.2.0-dev", "magento/module-rule": "100.2.0-dev", "magento/module-sales": "100.2.0-dev", - "magento/module-sales-inventory": "100.0.0-dev", + "magento/module-sales-inventory": "100.2.0-dev", "magento/module-sales-rule": "100.2.0-dev", "magento/module-sales-sequence": "100.2.0-dev", "magento/module-sample-data": "100.2.0-dev", diff --git a/composer.lock b/composer.lock index 7b3c6ccc9928df82fc72f6e397d1b98d3f2823d0..e69e12953fea2c150e1e063ddb9502148aad38ec 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "8c0f23eee8426e8aeba5a897f6f2ccbd", - "content-hash": "600aca1692cf3fe5c2ea1cbf66de09ab", + "hash": "01335ef9c76fd6d77bf6bd9236b84d03", + "content-hash": "07be52ec4880d0390acff2dd605a194d", "packages": [ { "name": "braintree/braintree_php", @@ -56,7 +56,7 @@ }, { "name": "colinmollenhour/cache-backend-file", - "version": "1.4.0", + "version": "1.4", "source": { "type": "git", "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_File.git", @@ -818,16 +818,16 @@ }, { "name": "paragonie/random_compat", - "version": "v2.0.3", + "version": "v2.0.4", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", - "reference": "c0125896dbb151380ab47e96c621741e79623beb" + "reference": "a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/c0125896dbb151380ab47e96c621741e79623beb", - "reference": "c0125896dbb151380ab47e96c621741e79623beb", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e", + "reference": "a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e", "shasum": "" }, "require": { @@ -862,7 +862,7 @@ "pseudorandom", "random" ], - "time": "2016-10-17 15:23:22" + "time": "2016-11-07 23:38:38" }, { "name": "pelago/emogrifier", @@ -1189,16 +1189,16 @@ }, { "name": "seld/jsonlint", - "version": "1.4.1", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "e827b5254d3e58c736ea2c5616710983d80b0b70" + "reference": "19495c181d6d53a0a13414154e52817e3b504189" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/e827b5254d3e58c736ea2c5616710983d80b0b70", - "reference": "e827b5254d3e58c736ea2c5616710983d80b0b70", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/19495c181d6d53a0a13414154e52817e3b504189", + "reference": "19495c181d6d53a0a13414154e52817e3b504189", "shasum": "" }, "require": { @@ -1231,7 +1231,7 @@ "parser", "validator" ], - "time": "2016-09-14 15:17:56" + "time": "2016-11-14 17:59:58" }, { "name": "seld/phar-utils", @@ -1390,16 +1390,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.8.12", + "version": "v2.8.15", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "889983a79a043dfda68f38c38b6dba092dd49cd8" + "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/889983a79a043dfda68f38c38b6dba092dd49cd8", - "reference": "889983a79a043dfda68f38c38b6dba092dd49cd8", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/25c576abd4e0f212e678fe8b2bd9a9a98c7ea934", + "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934", "shasum": "" }, "require": { @@ -1446,20 +1446,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-07-28 16:56:28" + "time": "2016-10-13 01:43:15" }, { "name": "symfony/filesystem", - "version": "v2.8.12", + "version": "v2.8.15", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "44b499521defddf2eae17a18c811bbdae4f98bdf" + "reference": "a3784111af9f95f102b6411548376e1ae7c93898" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/44b499521defddf2eae17a18c811bbdae4f98bdf", - "reference": "44b499521defddf2eae17a18c811bbdae4f98bdf", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/a3784111af9f95f102b6411548376e1ae7c93898", + "reference": "a3784111af9f95f102b6411548376e1ae7c93898", "shasum": "" }, "require": { @@ -1495,20 +1495,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2016-09-06 10:55:00" + "time": "2016-10-18 04:28:30" }, { "name": "symfony/finder", - "version": "v3.1.5", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f" + "reference": "a69cb5d455b4885ca376dc5bb3e1155cc8c08c4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", - "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", + "url": "https://api.github.com/repos/symfony/finder/zipball/a69cb5d455b4885ca376dc5bb3e1155cc8c08c4b", + "reference": "a69cb5d455b4885ca376dc5bb3e1155cc8c08c4b", "shasum": "" }, "require": { @@ -1517,7 +1517,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -1544,20 +1544,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-09-28 00:11:12" + "time": "2016-12-13 09:39:43" }, { "name": "symfony/process", - "version": "v2.8.12", + "version": "v2.8.15", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f" + "reference": "1a1bd056395540d0bc549d39818316513565d278" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f", - "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f", + "url": "https://api.github.com/repos/symfony/process/zipball/1a1bd056395540d0bc549d39818316513565d278", + "reference": "1a1bd056395540d0bc549d39818316513565d278", "shasum": "" }, "require": { @@ -1593,7 +1593,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-09-29 14:03:54" + "time": "2016-11-24 00:43:03" }, { "name": "tedivm/jshrink", @@ -3242,16 +3242,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v1.12.2", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "baa7112bef3b86c65fcfaae9a7a50436e3902b41" + "reference": "0ea4f7ed06ca55da1d8fc45da26ff87f261c4088" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/baa7112bef3b86c65fcfaae9a7a50436e3902b41", - "reference": "baa7112bef3b86c65fcfaae9a7a50436e3902b41", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/0ea4f7ed06ca55da1d8fc45da26ff87f261c4088", + "reference": "0ea4f7ed06ca55da1d8fc45da26ff87f261c4088", "shasum": "" }, "require": { @@ -3296,7 +3296,7 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2016-09-27 07:57:59" + "time": "2016-12-01 00:05:05" }, { "name": "lusitanian/oauth", @@ -3407,21 +3407,21 @@ }, { "name": "phpmd/phpmd", - "version": "2.4.3", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/phpmd/phpmd.git", - "reference": "2b9c2417a18696dfb578b38c116cd0ddc19b256e" + "reference": "9298602a922cd8c46666df8d540a60bc5925ce55" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmd/phpmd/zipball/2b9c2417a18696dfb578b38c116cd0ddc19b256e", - "reference": "2b9c2417a18696dfb578b38c116cd0ddc19b256e", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/9298602a922cd8c46666df8d540a60bc5925ce55", + "reference": "9298602a922cd8c46666df8d540a60bc5925ce55", "shasum": "" }, "require": { "pdepend/pdepend": "^2.0.4", - "php": ">=5.3.0" + "php": ">=5.3.9" }, "require-dev": { "phpunit/phpunit": "^4.0", @@ -3468,7 +3468,7 @@ "phpmd", "pmd" ], - "time": "2016-04-04 11:52:04" + "time": "2016-11-23 20:33:32" }, { "name": "phpunit/php-code-coverage", @@ -3664,16 +3664,16 @@ }, { "name": "phpunit/php-token-stream", - "version": "1.4.8", + "version": "1.4.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b", + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b", "shasum": "" }, "require": { @@ -3709,7 +3709,7 @@ "keywords": [ "tokenizer" ], - "time": "2015-09-15 10:49:45" + "time": "2016-11-15 14:06:22" }, { "name": "phpunit/phpunit", @@ -3843,22 +3843,22 @@ }, { "name": "sebastian/comparator", - "version": "1.2.0", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f", + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f", "shasum": "" }, "require": { "php": ">=5.3.3", "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" + "sebastian/exporter": "~1.2 || ~2.0" }, "require-dev": { "phpunit/phpunit": "~4.4" @@ -3903,7 +3903,7 @@ "compare", "equality" ], - "time": "2015-07-26 15:48:44" + "time": "2016-11-19 09:18:40" }, { "name": "sebastian/diff", @@ -4329,22 +4329,25 @@ }, { "name": "symfony/config", - "version": "v2.8.12", + "version": "v2.8.15", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "f8b1922bbda9d2ac86aecd649399040bce849fde" + "reference": "b522856007b258f46d5ee35d3b7b235c11e76e86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/f8b1922bbda9d2ac86aecd649399040bce849fde", - "reference": "f8b1922bbda9d2ac86aecd649399040bce849fde", + "url": "https://api.github.com/repos/symfony/config/zipball/b522856007b258f46d5ee35d3b7b235c11e76e86", + "reference": "b522856007b258f46d5ee35d3b7b235c11e76e86", "shasum": "" }, "require": { "php": ">=5.3.9", "symfony/filesystem": "~2.3|~3.0.0" }, + "require-dev": { + "symfony/yaml": "~2.7|~3.0.0" + }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" }, @@ -4378,20 +4381,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2016-09-14 20:31:12" + "time": "2016-12-10 08:21:45" }, { "name": "symfony/dependency-injection", - "version": "v2.8.12", + "version": "v2.8.15", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "ee9ec9ac2b046462d341e9de7c4346142d335e75" + "reference": "51a7b5385fb0f42e5edbdb2cfbad1a011ecdaee7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ee9ec9ac2b046462d341e9de7c4346142d335e75", - "reference": "ee9ec9ac2b046462d341e9de7c4346142d335e75", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/51a7b5385fb0f42e5edbdb2cfbad1a011ecdaee7", + "reference": "51a7b5385fb0f42e5edbdb2cfbad1a011ecdaee7", "shasum": "" }, "require": { @@ -4441,20 +4444,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2016-09-24 09:47:20" + "time": "2016-12-08 14:41:31" }, { "name": "symfony/stopwatch", - "version": "v3.1.5", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1" + "reference": "5b139e1c4290e6c7640ba80d9c9b5e49ef22b841" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/bb42806b12c5f89db4ebf64af6741afe6d8457e1", - "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5b139e1c4290e6c7640ba80d9c9b5e49ef22b841", + "reference": "5b139e1c4290e6c7640ba80d9c9b5e49ef22b841", "shasum": "" }, "require": { @@ -4463,7 +4466,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -4490,20 +4493,20 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:41:56" + "time": "2016-06-29 05:43:10" }, { "name": "symfony/yaml", - "version": "v2.8.12", + "version": "v2.8.15", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e7540734bad981fe59f8ef14b6fc194ae9df8d9c" + "reference": "befb26a3713c97af90d25dd12e75621ef14d91ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e7540734bad981fe59f8ef14b6fc194ae9df8d9c", - "reference": "e7540734bad981fe59f8ef14b6fc194ae9df8d9c", + "url": "https://api.github.com/repos/symfony/yaml/zipball/befb26a3713c97af90d25dd12e75621ef14d91ff", + "reference": "befb26a3713c97af90d25dd12e75621ef14d91ff", "shasum": "" }, "require": { @@ -4539,7 +4542,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-09-02 01:57:56" + "time": "2016-11-14 16:15:57" }, { "name": "theseer/fdomdocument", diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php index db43cc535ca01c4bbac96e425a435bd71ef3fcef..ddf036fd18abb1cc0c964abf7685eeaed6208a0c 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php @@ -17,6 +17,20 @@ use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator; */ class Curl extends AbstractCurl implements CatalogProductAttributeInterface { + /** + * Relative action path with parameters. + * + * @var string + */ + protected $urlActionPath = 'catalog/product_attribute/save/back/edit'; + + /** + * Message for Exception when was received not successful response. + * + * @var string + */ + protected $responseExceptionMessage = 'Product Attribute creating by curl handler was not successful!'; + /** * Mapping values for data. * @@ -85,14 +99,15 @@ class Curl extends AbstractCurl implements CatalogProductAttributeInterface } $data = $this->changeStructureOfTheData($data); - $url = $_ENV['app_backend_url'] . 'catalog/product_attribute/save/back/edit'; + $url = $_ENV['app_backend_url'] . $this->urlActionPath; $curl = new BackendDecorator(new CurlTransport(), $this->_configuration); $curl->write($url, $data); $response = $curl->read(); $curl->close(); if (!strpos($response, 'data-ui-id="messages-message-success"')) { - throw new \Exception("Product Attribute creating by curl handler was not successful! \n" . $response); + $this->_eventManager->dispatchEvent(['curl_failed'], [$response]); + throw new \Exception($this->responseExceptionMessage); } $resultData = []; diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.xml index 96e78f58d78c8402a133184b633614e4e4fd20c7..43b4a251edd1b5a97d68d458b7203bd4435d69e0 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.xml @@ -32,7 +32,7 @@ <constraint name="Magento\Newsletter\Test\Constraint\AssertCustomerIsSubscribedToNewsletter" /> </variation> <variation name="RegisterCustomerFrontendEntityTestVariation3" summary="Register Customer" ticketId="MAGETWO-12394"> - <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test</data> + <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test, stable:no</data> <data name="customer/data/firstname" xsi:type="string">john</data> <data name="customer/data/lastname" xsi:type="string">doe</data> <data name="customer/data/email" xsi:type="string">johndoe%isolation%@example.com</data> diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/element/date-time.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/element/date-time.test.js new file mode 100644 index 0000000000000000000000000000000000000000..4271ecc563b9ad0cda58076489a1c0a4c2f0ccf2 --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/element/date-time.test.js @@ -0,0 +1,41 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +/*eslint max-nested-callbacks: 0*/ + +define([ + 'Magento_Ui/js/form/element/date', + 'mageUtils', + 'moment' +], function (DateElement, utils, moment) { + 'use strict'; + + describe('Magento_Ui/js/form/element/date', function () { + var params, model; + + beforeEach(function () { + params = { + dataScope: 'abstract', + options: { + showsTime: true + } + }; + model = new DateElement(params); + }); + + it('Check prepareDateTimeFormats function', function () { + spyOn(utils, 'convertToMomentFormat').and.callThrough(); + model.prepareDateTimeFormats(); + expect(utils.convertToMomentFormat).toHaveBeenCalled(); + }); + + it('Check onShiftedValueChange function', function () { + spyOn(moment, 'tz').and.callThrough(); + model.onShiftedValueChange('2016-12-23 9:11 PM'); + expect(moment.tz).toHaveBeenCalled(); + }); + + }); +}); diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/ko/bind/datepicker.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/ko/bind/datepicker.test.js index e5f90863ec63071f191b82b0df7fdbba0ac411fa..3e99c1c454cf4b2261d99e3623f365570684a1e3 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/ko/bind/datepicker.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/ko/bind/datepicker.test.js @@ -1,5 +1,5 @@ /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © 2017 Magento. All rights reserved. * See COPYING.txt for license details. */ @@ -18,21 +18,23 @@ define([ config; beforeEach(function () { - element = $('<input />'); + element = $('<input />'); observable = ko.observable(); config = { - options : { + options: { dateFormat: 'M/d/yy', - 'storeLocale': 'en_US', - 'timeFormat': 'h:mm: a' + storeLocale: 'en_US', + timeFormat: 'h:mm: a' }, - storage:ko.observable(moment().format('MM/DD/YYYY')) + storage: observable }; $(document.body).append(element); - ko.applyBindingsToNode(element[0], { datepicker: config }); + ko.applyBindingsToNode(element[0], { + datepicker: config + }); }); afterEach(function () { @@ -40,20 +42,16 @@ define([ }); it('writes picked date\'s value to assigned observable', function () { - var todayDate, - momentFormat, - result, - inputFormat; - - inputFormat = 'M/d/yy'; + var todayDate, momentFormat, result, + inputFormat = 'M/d/yy'; momentFormat = utils.convertToMomentFormat(inputFormat); + todayDate = moment().format(momentFormat); - todayDate = moment().format(momentFormat); - - result = $('input:last').val(); + element.datepicker('setTimezoneDate').blur().trigger('change'); + result = moment(observable()).format(momentFormat); expect(todayDate).toEqual(result); }); }); -}); \ No newline at end of file +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/misc.test.js b/dev/tests/js/jasmine/tests/lib/mage/misc.test.js index a9ea5ed90192fa46e3e223802d872be0a32afba2..62950372d3a73f54a68f7b56d0eb67c1f982402f 100644 --- a/dev/tests/js/jasmine/tests/lib/mage/misc.test.js +++ b/dev/tests/js/jasmine/tests/lib/mage/misc.test.js @@ -15,7 +15,7 @@ define([ var format, momentFormat; format = 'M/d/yy'; - momentFormat = 'MM/DD/YYYY'; + momentFormat = 'M/DD/YYYY'; expect(utils.convertToMomentFormat(format)).toBe(momentFormat); }); diff --git a/lib/internal/Magento/Framework/App/Http/Context.php b/lib/internal/Magento/Framework/App/Http/Context.php index 4146dac725f03a70971e85d6a29b27803e795412..59ab6f7602c3f4cc3369584ff5fa09f9629fae6e 100644 --- a/lib/internal/Magento/Framework/App/Http/Context.php +++ b/lib/internal/Magento/Framework/App/Http/Context.php @@ -1,6 +1,6 @@ <?php /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © 2017 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Framework\App\Http; @@ -27,6 +27,16 @@ class Context */ protected $default = []; + /** + * @param array $data + * @param array $default + */ + public function __construct(array $data = [], array $default = []) + { + $this->data = $data; + $this->default = $default; + } + /** * Data setter * @@ -99,4 +109,17 @@ class Context } return null; } + + /** + * Get data and default data in "key-value" format + * + * @return array + */ + public function toArray() + { + return [ + 'data' => $this->data, + 'default' => $this->default + ]; + } } diff --git a/lib/internal/Magento/Framework/App/PageCache/Kernel.php b/lib/internal/Magento/Framework/App/PageCache/Kernel.php index 8a83592bc322e86c046b68480f815878f3de8855..02d6646c67d0f76ee4a527bf29e7d0f165a8f822 100644 --- a/lib/internal/Magento/Framework/App/PageCache/Kernel.php +++ b/lib/internal/Magento/Framework/App/PageCache/Kernel.php @@ -1,12 +1,10 @@ <?php /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © 2017 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Framework\App\PageCache; -use Magento\Framework\App\ObjectManager; - /** * Builtin cache processor */ @@ -34,19 +32,76 @@ class Kernel */ private $fullPageCache; + /** + * @var \Magento\Framework\Serialize\SerializerInterface + */ + private $serializer; + + /** + * @var \Magento\Framework\App\Http\Context + */ + private $context; + + /** + * @var \Magento\Framework\App\Http\ContextFactory + */ + private $contextFactory; + + /** + * @var \Magento\Framework\App\Response\HttpFactory + */ + private $httpFactory; + /** * @param Cache $cache * @param Identifier $identifier * @param \Magento\Framework\App\Request\Http $request + * @param \Magento\Framework\App\Http\Context|null $context + * @param \Magento\Framework\App\Http\ContextFactory|null $contextFactory + * @param \Magento\Framework\App\Response\HttpFactory|null $httpFactory + * @param \Magento\Framework\Serialize\SerializerInterface|null $serializer */ public function __construct( \Magento\Framework\App\PageCache\Cache $cache, \Magento\Framework\App\PageCache\Identifier $identifier, - \Magento\Framework\App\Request\Http $request + \Magento\Framework\App\Request\Http $request, + \Magento\Framework\App\Http\Context $context = null, + \Magento\Framework\App\Http\ContextFactory $contextFactory = null, + \Magento\Framework\App\Response\HttpFactory $httpFactory = null, + \Magento\Framework\Serialize\SerializerInterface $serializer = null ) { $this->cache = $cache; $this->identifier = $identifier; $this->request = $request; + + if ($context) { + $this->context = $context; + } else { + $this->context = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\App\Http\Context::class + ); + } + if ($contextFactory) { + $this->contextFactory = $contextFactory; + } else { + $this->contextFactory = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\App\Http\ContextFactory::class + ); + } + if ($httpFactory) { + $this->httpFactory = $httpFactory; + } else { + $this->httpFactory = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\App\Response\HttpFactory::class + ); + } + if ($serializer) { + $this->serializer = $serializer; + } else { + $this->serializer = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Serialize\SerializerInterface::class + ); + } } /** @@ -57,7 +112,12 @@ class Kernel public function load() { if ($this->request->isGet() || $this->request->isHead()) { - return unserialize($this->getCache()->load($this->identifier->getValue())); + $responseData = $this->serializer->unserialize($this->getCache()->load($this->identifier->getValue())); + if (!$responseData) { + return false; + } + + return $this->buildResponse($responseData); } return false; } @@ -84,11 +144,63 @@ class Kernel if (!headers_sent()) { header_remove('Set-Cookie'); } - $this->getCache()->save(serialize($response), $this->identifier->getValue(), $tags, $maxAge); + + $this->getCache()->save( + $this->serializer->serialize($this->getPreparedData($response)), + $this->identifier->getValue(), + $tags, + $maxAge + ); } } } + /** + * Get prepared data for storage in the cache. + * + * @param \Magento\Framework\App\Response\Http $response + * @return array + */ + private function getPreparedData(\Magento\Framework\App\Response\Http $response) + { + return [ + 'content' => $response->getContent(), + 'status_code' => $response->getStatusCode(), + 'headers' => $response->getHeaders()->toArray(), + 'context' => $this->context->toArray() + ]; + + } + + /** + * Build response using response data. + * + * @param array $responseData + * @return \Magento\Framework\App\Response\Http + */ + private function buildResponse($responseData) + { + $context = $this->contextFactory->create( + [ + 'data' => $responseData['context']['data'], + 'default' => $responseData['context']['default'] + ] + ); + + $response = $this->httpFactory->create( + [ + 'context' => $context + ] + ); + $response->setStatusCode($responseData['status_code']); + $response->setContent($responseData['content']); + foreach ($responseData['headers'] as $headerKey => $headerValue) { + $response->setHeader($headerKey, $headerValue, true); + } + + return $response; + } + /** * TODO: Workaround to support backwards compatibility, will rework to use Dependency Injection in MAGETWO-49547 * @@ -97,7 +209,9 @@ class Kernel private function getCache() { if (!$this->fullPageCache) { - $this->fullPageCache = ObjectManager::getInstance()->get(\Magento\PageCache\Model\Cache\Type::class); + $this->fullPageCache = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\PageCache\Model\Cache\Type::class + ); } return $this->fullPageCache; } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php index 05f589e0dc61a9299f717aeab0905f8b205fdafe..8ce4f006861e8d3cc518df48a0882cda22a15b14 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php @@ -1,6 +1,6 @@ <?php /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © 2017 Magento. All rights reserved. * See COPYING.txt for license details. */ @@ -64,4 +64,19 @@ class ContextTest extends \PHPUnit_Framework_TestCase ksort($data); $this->assertEquals(sha1(serialize($data)), $this->object->getVaryString()); } + + public function testToArray() + { + $newObject = new \Magento\Framework\App\Http\Context(['key' => 'value']); + + $newObject->setValue('key1', 'value1', 'default1'); + $newObject->setValue('key2', 'value2', 'default2'); + $this->assertEquals( + [ + 'data' => ['key' => 'value', 'key1' => 'value1', 'key2' => 'value2'], + 'default' => ['key1' => 'default1', 'key2' => 'default2'] + ], + $newObject->toArray() + ); + } } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/PageCache/KernelTest.php b/lib/internal/Magento/Framework/App/Test/Unit/PageCache/KernelTest.php index 81b828b3f938c45333a5ac8b096d8b23d013a81a..7e65b174abdd97a3adc231b415c96a62f634e194 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/PageCache/KernelTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/PageCache/KernelTest.php @@ -1,12 +1,17 @@ <?php /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © 2017 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Framework\App\Test\Unit\PageCache; use \Magento\Framework\App\PageCache\Kernel; +use \Magento\Framework\App\Http\ContextFactory; +use \Magento\Framework\App\Response\HttpFactory; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class KernelTest extends \PHPUnit_Framework_TestCase { /** @var Kernel */ @@ -27,39 +32,136 @@ class KernelTest extends \PHPUnit_Framework_TestCase /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\PageCache\Model\Cache\Type */ private $fullPageCacheMock; + /** @var \Magento\Framework\App\Response\Http|\PHPUnit_Framework_MockObject_MockObject */ + private $httpResponseMock; + + /** @var ContextFactory|\PHPUnit_Framework_MockObject_MockObject */ + private $contextFactoryMock; + + /** @var HttpFactory|\PHPUnit_Framework_MockObject_MockObject */ + private $httpFactoryMock; + + /** @var \Magento\Framework\Serialize\SerializerInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $serializer; + + /** @var \Magento\Framework\App\Http\Context|\PHPUnit_Framework_MockObject_MockObject */ + private $contextMock; + /** * Setup */ protected function setUp() { + $headersMock = $this->getMock(\Zend\Http\Headers::class, [], [], '', false); $this->cacheMock = $this->getMock(\Magento\Framework\App\PageCache\Cache::class, [], [], '', false); $this->fullPageCacheMock = $this->getMock(\Magento\PageCache\Model\Cache\Type::class, [], [], '', false); - $this->identifierMock = - $this->getMock(\Magento\Framework\App\PageCache\Identifier::class, [], [], '', false); + $this->contextMock = $this->getMock(\Magento\Framework\App\Http\Context::class, [], [], '', false); + $this->httpResponseMock = $this->getMock(\Magento\Framework\App\Response\Http::class, [], [], '', false); + $this->identifierMock = $this->getMock(\Magento\Framework\App\PageCache\Identifier::class, [], [], '', false); $this->requestMock = $this->getMock(\Magento\Framework\App\Request\Http::class, [], [], '', false); - $this->kernel = new Kernel($this->cacheMock, $this->identifierMock, $this->requestMock); + $this->serializer = $this->getMock(\Magento\Framework\Serialize\SerializerInterface::class, [], [], '', false); + $this->responseMock = $this->getMock(\Magento\Framework\App\Response\Http::class, [], [], '', false); + $this->contextFactoryMock = $this->getMock(ContextFactory::class, ['create'], [], '', false); + $this->httpFactoryMock = $this->getMock(HttpFactory::class, ['create'], [], '', false); + $this->responseMock->expects($this->any())->method('getHeaders')->willReturn($headersMock); + + $this->kernel = new Kernel( + $this->cacheMock, + $this->identifierMock, + $this->requestMock, + $this->contextMock, + $this->contextFactoryMock, + $this->httpFactoryMock, + $this->serializer + ); $reflection = new \ReflectionClass(\Magento\Framework\App\PageCache\Kernel::class); $reflectionProperty = $reflection->getProperty('fullPageCache'); $reflectionProperty->setAccessible(true); $reflectionProperty->setValue($this->kernel, $this->fullPageCacheMock); + } - $this->responseMock = $this->getMockBuilder( - \Magento\Framework\App\Response\Http::class - )->setMethods( - ['getHeader', 'getHttpResponseCode', 'setNoCacheHeaders', 'clearHeader', '__wakeup'] - )->disableOriginalConstructor()->getMock(); + /** + * @dataProvider dataProviderForResultWithCachedData + * @param string $id + * @param mixed $cache + * @param bool $isGet + * @param bool $isHead + */ + public function testLoadWithCachedData($id, $cache, $isGet, $isHead) + { + $this->serializer->expects($this->once()) + ->method('unserialize') + ->willReturnCallback( + function ($value) { + return json_decode($value, true); + } + ); + + $this->contextFactoryMock + ->expects($this->once()) + ->method('create') + ->with( + [ + 'data' => ['context_data'], + 'default' => ['context_default_data'] + ] + ) + ->willReturn($this->contextMock); + + $this->httpFactoryMock + ->expects($this->once()) + ->method('create') + ->with(['context' => $this->contextMock]) + ->willReturn($this->httpResponseMock); + + $this->requestMock->expects($this->once())->method('isGet')->will($this->returnValue($isGet)); + $this->requestMock->expects($this->any())->method('isHead')->will($this->returnValue($isHead)); + $this->fullPageCacheMock->expects( + $this->any() + )->method( + 'load' + )->with( + $this->equalTo($id) + )->will( + $this->returnValue(json_encode($cache)) + ); + $this->httpResponseMock->expects($this->once())->method('setStatusCode')->with($cache['status_code']); + $this->httpResponseMock->expects($this->once())->method('setContent')->with($cache['content']); + $this->httpResponseMock->expects($this->once())->method('setHeader')->with(0, 'header', true); + $this->identifierMock->expects($this->any())->method('getValue')->will($this->returnValue($id)); + $this->assertEquals($this->httpResponseMock, $this->kernel->load()); + } + + /** + * @return array + */ + public function dataProviderForResultWithCachedData() + { + $data = [ + 'context' => [ + 'data' => ['context_data'], + 'default' => ['context_default_data'] + ], + 'status_code' => 'status_code', + 'content' => 'content', + 'headers' => ['header'] + ]; + + return [ + ['existing key', $data, true, false], + ['existing key', $data, false, true], + ]; } /** - * @dataProvider loadProvider - * @param mixed $expected + * @dataProvider dataProviderForResultWithoutCachedData * @param string $id * @param mixed $cache * @param bool $isGet * @param bool $isHead */ - public function testLoad($expected, $id, $cache, $isGet, $isHead) + public function testLoadWithoutCachedData($id, $cache, $isGet, $isHead) { $this->requestMock->expects($this->once())->method('isGet')->will($this->returnValue($isGet)); $this->requestMock->expects($this->any())->method('isHead')->will($this->returnValue($isHead)); @@ -70,31 +172,21 @@ class KernelTest extends \PHPUnit_Framework_TestCase )->with( $this->equalTo($id) )->will( - $this->returnValue(serialize($cache)) + $this->returnValue(json_encode($cache)) ); $this->identifierMock->expects($this->any())->method('getValue')->will($this->returnValue($id)); - $this->assertEquals($expected, $this->kernel->load()); + $this->assertEquals(false, $this->kernel->load()); } /** * @return array */ - public function loadProvider() + public function dataProviderForResultWithoutCachedData() { - $data = [1, 2, 3]; return [ - [$data, 'existing key', $data, true, false], - [$data, 'existing key', $data, false, true], - [ - new \Magento\Framework\DataObject($data), - 'existing key', - new \Magento\Framework\DataObject($data), - true, - false - ], - [false, 'existing key', $data, false, false], - [false, 'non existing key', false, true, false], - [false, 'non existing key', false, false, false] + ['existing key', [], false, false], + ['non existing key', false, true, false], + ['non existing key', false, false, false] ]; } @@ -104,6 +196,14 @@ class KernelTest extends \PHPUnit_Framework_TestCase */ public function testProcessSaveCache($httpCode, $at) { + $this->serializer->expects($this->once()) + ->method('serialize') + ->willReturnCallback( + function ($value) { + return json_encode($value); + } + ); + $cacheControlHeader = \Zend\Http\Header\CacheControl::fromString( 'Cache-Control: public, max-age=100, s-maxage=100' ); diff --git a/lib/internal/Magento/Framework/View/Layout.php b/lib/internal/Magento/Framework/View/Layout.php index 3334967c8da8327cb1de7eb396fb46978fc0c08c..ac3938c94c5c7432ba8095ea98c29162afb8b954 100755 --- a/lib/internal/Magento/Framework/View/Layout.php +++ b/lib/internal/Magento/Framework/View/Layout.php @@ -1,6 +1,6 @@ <?php /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © 2017 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Framework\View; @@ -8,11 +8,13 @@ namespace Magento\Framework\View; use Magento\Framework\Cache\FrontendInterface; use Magento\Framework\Event\ManagerInterface; use Magento\Framework\Message\ManagerInterface as MessageManagerInterface; +use Magento\Framework\Serialize\SerializerInterface; use Magento\Framework\View\Layout\Element; use Magento\Framework\View\Layout\ScheduledStructure; use Magento\Framework\App\State as AppState; use Psr\Log\LoggerInterface as Logger; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\App\ObjectManager; /** * Layout model @@ -165,6 +167,11 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra */ protected $logger; + /** + * @var SerializerInterface + */ + private $serializer; + /** * @param Layout\ProcessorFactory $processorFactory * @param ManagerInterface $eventManager @@ -179,6 +186,7 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra * @param \Magento\Framework\App\State $appState * @param \Psr\Log\LoggerInterface $logger * @param bool $cacheable + * @param SerializerInterface|null $serializer */ public function __construct( Layout\ProcessorFactory $processorFactory, @@ -193,10 +201,12 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra Layout\Generator\ContextFactory $generatorContextFactory, AppState $appState, Logger $logger, - $cacheable = true + $cacheable = true, + SerializerInterface $serializer = null ) { $this->_elementClass = \Magento\Framework\View\Layout\Element::class; $this->_renderingOutput = new \Magento\Framework\DataObject(); + $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); $this->_processorFactory = $processorFactory; $this->_eventManager = $eventManager; @@ -308,12 +318,19 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra $cacheId = 'structure_' . $this->getUpdate()->getCacheId(); $result = $this->cache->load($cacheId); if ($result) { - $this->readerContext = unserialize($result); + $data = $this->serializer->unserialize($result); + $this->getReaderContext()->getPageConfigStructure()->populateWithArray($data['pageConfigStructure']); + $this->getReaderContext()->getScheduledStructure()->populateWithArray($data['scheduledStructure']); } else { \Magento\Framework\Profiler::start('build_structure'); $this->readerPool->interpret($this->getReaderContext(), $this->getNode()); \Magento\Framework\Profiler::stop('build_structure'); - $this->cache->save(serialize($this->getReaderContext()), $cacheId, $this->getUpdate()->getHandles()); + + $data = [ + 'pageConfigStructure' => $this->getReaderContext()->getPageConfigStructure()->__toArray(), + 'scheduledStructure' => $this->getReaderContext()->getScheduledStructure()->__toArray(), + ]; + $this->cache->save($this->serializer->serialize($data), $cacheId, $this->getUpdate()->getHandles()); } $generatorContext = $this->generatorContextFactory->create( diff --git a/lib/internal/Magento/Framework/View/Layout/ScheduledStructure.php b/lib/internal/Magento/Framework/View/Layout/ScheduledStructure.php index cf1981335d6be9a6b12b38944623d727abe6fdeb..117fb8278145f89f22674b7ab25d21fab57946ff 100644 --- a/lib/internal/Magento/Framework/View/Layout/ScheduledStructure.php +++ b/lib/internal/Magento/Framework/View/Layout/ScheduledStructure.php @@ -1,6 +1,6 @@ <?php /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © 2017 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Framework\View\Layout; @@ -19,6 +19,23 @@ class ScheduledStructure const ELEMENT_IS_AFTER = 'isAfter'; /**#@-*/ + /** + * Map of class properties. + * + * @var array + */ + private $serializableProperties = [ + 'scheduledStructure', + 'scheduledData', + 'scheduledElements', + 'scheduledMoves', + 'scheduledRemoves', + 'scheduledIfconfig', + 'scheduledPaths', + 'elementsToSort', + 'brokenParent', + ]; + /** * Information about structural elements, scheduled for creation * @@ -84,18 +101,10 @@ class ScheduledStructure /** * @param array $data - * - * @SuppressWarnings(PHPMD.NPathComplexity) */ public function __construct(array $data = []) { - $this->scheduledStructure = isset($data['scheduledStructure']) ? $data['scheduledStructure'] : []; - $this->scheduledData = isset($data['scheduledData']) ? $data['scheduledData'] : []; - $this->scheduledElements = isset($data['scheduledElements']) ? $data['scheduledElements'] : []; - $this->scheduledMoves = isset($data['scheduledMoves']) ? $data['scheduledMoves'] : []; - $this->scheduledRemoves = isset($data['scheduledRemoves']) ? $data['scheduledRemoves'] : []; - $this->scheduledIfconfig = isset($data['scheduledIfconfig']) ? $data['scheduledIfconfig'] : []; - $this->scheduledPaths = isset($data['scheduledPaths']) ? $data['scheduledPaths'] : []; + $this->populateWithArray($data); } /** @@ -531,4 +540,44 @@ class ScheduledStructure $this->scheduledElements = []; $this->scheduledStructure = []; } + + /** + * Reformat 'Layout scheduled structure' to array. + * + * @return array + */ + public function __toArray() + { + $result = []; + foreach ($this->serializableProperties as $property) { + $result[$property] = $this->{$property}; + } + + return $result; + } + + /** + * Update 'Layout scheduled structure' data. + * + * @param array $data + * @return void + */ + public function populateWithArray(array $data) + { + foreach ($this->serializableProperties as $property) { + $this->{$property} = $this->getArrayValueByKey($property, $data); + } + } + + /** + * Get value from array by key. + * + * @param string $key + * @param array $array + * @return array + */ + private function getArrayValueByKey($key, array $array) + { + return isset($array[$key]) ? $array[$key] : []; + } } diff --git a/lib/internal/Magento/Framework/View/Page/Config/Structure.php b/lib/internal/Magento/Framework/View/Page/Config/Structure.php index 4ab89319f6d82aeeaad6e637076ed7e181fab2d4..d7fe402044e8ffd589e2669eb0c0611cdb4b7f61 100644 --- a/lib/internal/Magento/Framework/View/Page/Config/Structure.php +++ b/lib/internal/Magento/Framework/View/Page/Config/Structure.php @@ -1,6 +1,6 @@ <?php /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © 2017 Magento. All rights reserved. * See COPYING.txt for license details. */ @@ -12,6 +12,22 @@ namespace Magento\Framework\View\Page\Config; */ class Structure { + /** + * Map of class properties. + * + * @var array + */ + private $serializableProperties = [ + 'assets', + 'removeAssets', + 'title', + 'metadata', + 'elementAttributes', + 'removeElementAttributes', + 'bodyClasses', + 'isBodyClassesDeleted', + ]; + /** * Information assets elements on page * @@ -194,4 +210,44 @@ class Structure { return $this->assets; } + + /** + * Reformat 'Page config structure' to array. + * + * @return array + */ + public function __toArray() + { + $result = []; + foreach ($this->serializableProperties as $property) { + $result[$property] = $this->{$property}; + } + + return $result; + } + + /** + * Update 'Page config structure' data. + * + * @param array $data + * @return void + */ + public function populateWithArray(array $data) + { + foreach ($this->serializableProperties as $property) { + $this->{$property} = $this->getArrayValueByKey($property, $data); + } + } + + /** + * Get value from array by key. + * + * @param string $key + * @param array $array + * @return array + */ + private function getArrayValueByKey($key, array $array) + { + return isset($array[$key]) ? $array[$key] : []; + } } diff --git a/lib/internal/Magento/Framework/View/Test/Unit/LayoutTest.php b/lib/internal/Magento/Framework/View/Test/Unit/LayoutTest.php index 413b1e4cd1ac83008600dbf062d038796a408642..640ece658edaa0620c3c470206914b431cf403bc 100755 --- a/lib/internal/Magento/Framework/View/Test/Unit/LayoutTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/LayoutTest.php @@ -1,10 +1,12 @@ <?php /** - * Copyright © 2016 Magento. All rights reserved. + * Copyright © 2017 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Framework\View\Test\Unit; +use Magento\Framework\Serialize\SerializerInterface; + /** * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -81,6 +83,16 @@ class LayoutTest extends \PHPUnit_Framework_TestCase */ protected $readerContextMock; + /** + * @var \Magento\Framework\View\Page\Config\Structure|\PHPUnit_Framework_MockObject_MockObject + */ + private $pageConfigStructure; + + /** + * @var \Magento\Framework\View\Layout\ScheduledStructure|\PHPUnit_Framework_MockObject_MockObject + */ + private $layoutScheduledSructure; + /** * @var \Magento\Framework\View\Layout\Generator\ContextFactory|\PHPUnit_Framework_MockObject_MockObject */ @@ -96,6 +108,11 @@ class LayoutTest extends \PHPUnit_Framework_TestCase */ protected $loggerMock; + /** + * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $serializer; + protected function setUp() { $this->structureMock = $this->getMockBuilder(\Magento\Framework\View\Layout\Data\Structure::class) @@ -141,9 +158,22 @@ class LayoutTest extends \PHPUnit_Framework_TestCase $this->readerContextFactoryMock = $this->getMockBuilder( \Magento\Framework\View\Layout\Reader\ContextFactory::class )->disableOriginalConstructor()->getMock(); + + $this->pageConfigStructure = $this->getMockBuilder(\Magento\Framework\View\Page\Config\Structure::class) + ->setMethods(['__toArray', 'populateWithArray']) + ->getMock(); + $this->layoutScheduledSructure = $this->getMockBuilder(\Magento\Framework\View\Layout\ScheduledStructure::class) + ->setMethods(['__toArray', 'populateWithArray']) + ->getMock(); $this->readerContextMock = $this->getMockBuilder(\Magento\Framework\View\Layout\Reader\Context::class) + ->setMethods(['getPageConfigStructure', 'getScheduledStructure']) ->disableOriginalConstructor() ->getMock(); + $this->readerContextMock->expects($this->any())->method('getPageConfigStructure') + ->willReturn($this->pageConfigStructure); + $this->readerContextMock->expects($this->any())->method('getScheduledStructure') + ->willReturn($this->layoutScheduledSructure); + $this->generatorContextFactoryMock = $this->getMockBuilder( \Magento\Framework\View\Layout\Generator\ContextFactory::class ) @@ -154,6 +184,15 @@ class LayoutTest extends \PHPUnit_Framework_TestCase ->getMock(); $this->loggerMock = $this->getMockBuilder(\Psr\Log\LoggerInterface::class) ->getMock(); + $this->serializer = $this->getMock(\Magento\Framework\Serialize\SerializerInterface::class); + $this->serializer->expects($this->any())->method('serialize') + ->willReturnCallback(function ($value) { + return json_encode($value); + }); + $this->serializer->expects($this->any())->method('unserialize') + ->willReturnCallback(function ($value) { + return json_decode($value, true); + }); $this->model = new \Magento\Framework\View\Layout( $this->processorFactoryMock, @@ -168,7 +207,8 @@ class LayoutTest extends \PHPUnit_Framework_TestCase $this->generatorContextFactoryMock, $this->appStateMock, $this->loggerMock, - true + true, + $this->serializer ); } @@ -735,9 +775,32 @@ class LayoutTest extends \PHPUnit_Framework_TestCase ->with($this->readerContextMock, $xml) ->willReturnSelf(); + $pageConfigStructureData = [ + 'field_1' => 123, + 'field_2' => 'text', + 'field_3' => [ + 'field_3_1' => '1244', + 'field_3_2' => null, + 'field_3_3' => false, + ] + ]; + $this->pageConfigStructure->expects($this->any())->method('__toArray') + ->willReturn($pageConfigStructureData); + + $layoutScheduledStructureData = [ + 'field_1' => 1283, + 'field_2' => 'text_qwertyuiop[]asdfghjkl;' + ]; + $this->layoutScheduledSructure->expects($this->any())->method('__toArray') + ->willReturn($layoutScheduledStructureData); + $data = [ + 'pageConfigStructure' => $pageConfigStructureData, + 'scheduledStructure' => $layoutScheduledStructureData + ]; + $this->cacheMock->expects($this->once()) ->method('save') - ->with(serialize($this->readerContextMock), 'structure_' . $layoutCacheId, $handles) + ->with(json_encode($data), 'structure_' . $layoutCacheId, $handles) ->willReturn(true); $generatorContextMock = $this->getMockBuilder(\Magento\Framework\View\Layout\Generator\Context::class) @@ -774,6 +837,9 @@ class LayoutTest extends \PHPUnit_Framework_TestCase $xml = simplexml_load_string('<layout/>', \Magento\Framework\View\Layout\Element::class); $this->model->setXml($xml); + $this->readerContextFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->readerContextMock); $themeMock = $this->getMockForAbstractClass(\Magento\Framework\View\Design\ThemeInterface::class); $this->themeResolverMock->expects($this->once()) ->method('get') @@ -787,14 +853,33 @@ class LayoutTest extends \PHPUnit_Framework_TestCase ->method('getCacheId') ->willReturn($layoutCacheId); - $readerContextMock = $this->getMockBuilder(\Magento\Framework\View\Layout\Reader\Context::class) - ->disableOriginalConstructor() - ->getMock(); + $pageConfigStructureData = [ + 'field_1' => 123, + 'field_2' => 'text', + 'field_3' => [ + 'field_3_1' => '1244', + 'field_3_2' => null, + 'field_3_3' => false, + ] + ]; + $this->pageConfigStructure->expects($this->once())->method('populateWithArray') + ->with($pageConfigStructureData); + + $layoutScheduledStructureData = [ + 'field_1' => 1283, + 'field_2' => 'text_qwertyuiop[]asdfghjkl;' + ]; + $this->layoutScheduledSructure->expects($this->once())->method('populateWithArray') + ->with($layoutScheduledStructureData); + $data = [ + 'pageConfigStructure' => $pageConfigStructureData, + 'scheduledStructure' => $layoutScheduledStructureData + ]; $this->cacheMock->expects($this->once()) ->method('load') ->with('structure_' . $layoutCacheId) - ->willReturn(serialize($readerContextMock)); + ->willReturn(json_encode($data)); $this->readerPoolMock->expects($this->never()) ->method('interpret'); @@ -811,7 +896,7 @@ class LayoutTest extends \PHPUnit_Framework_TestCase $this->generatorPoolMock->expects($this->once()) ->method('process') - ->with($readerContextMock, $generatorContextMock) + ->with($this->readerContextMock, $generatorContextMock) ->willReturn(true); $elements = [ diff --git a/lib/web/mage/utils/misc.js b/lib/web/mage/utils/misc.js index 29fed485f290c86f92099fc6cba68734711980d2..3fdcf3e7de542cb69ab406adcd294ed712c9cd64 100644 --- a/lib/web/mage/utils/misc.js +++ b/lib/web/mage/utils/misc.js @@ -220,7 +220,6 @@ define([ newFormat = format.replace(/yy|y/gi, 'YYYY'); // replace the year newFormat = newFormat.replace(/dd|d/g, 'DD'); // replace the date - newFormat = newFormat.replace(/mm|m/gi, 'MM'); //replace the month return newFormat; }