From 69357ce0134a6b287ab3488fa43f599009ec092a Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh Date: Mon, 15 Jun 2020 10:48:38 +0300 Subject: [PATCH 1/6] MC-34998: suspected degradation in performance due to targetrule --- app/code/Magento/Catalog/etc/db_schema.xml | 5 +++++ app/code/Magento/Catalog/etc/db_schema_whitelist.json | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml index 1c97c920266df..a0aa48fb76b13 100644 --- a/app/code/Magento/Catalog/etc/db_schema.xml +++ b/app/code/Magento/Catalog/etc/db_schema.xml @@ -138,6 +138,11 @@ + + + + + diff --git a/app/code/Magento/Catalog/etc/db_schema_whitelist.json b/app/code/Magento/Catalog/etc/db_schema_whitelist.json index d4bd6927d4345..f4cda73c371d0 100644 --- a/app/code/Magento/Catalog/etc/db_schema_whitelist.json +++ b/app/code/Magento/Catalog/etc/db_schema_whitelist.json @@ -69,7 +69,8 @@ }, "index": { "CATALOG_PRODUCT_ENTITY_INT_ATTRIBUTE_ID": true, - "CATALOG_PRODUCT_ENTITY_INT_STORE_ID": true + "CATALOG_PRODUCT_ENTITY_INT_STORE_ID": true, + "CATALOG_PRODUCT_ENTITY_INT_ATTRIBUTE_ID_STORE_ID_VALUE": true }, "constraint": { "PRIMARY": true, From 182c7e5e65afbdc83c0f0595ec41fcb17e58ddbb Mon Sep 17 00:00:00 2001 From: Vasya Tsviklinskyi Date: Wed, 17 Jun 2020 09:09:13 +0300 Subject: [PATCH 2/6] MC-35058: Error when trying to remove categories from product --- .../GoogleOptimizer/Observer/AbstractSave.php | 12 ++++++- ...SaveGoogleExperimentScriptObserverTest.php | 33 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/GoogleOptimizer/Observer/AbstractSave.php b/app/code/Magento/GoogleOptimizer/Observer/AbstractSave.php index 135c8c92c6aa9..975788abe52e4 100644 --- a/app/code/Magento/GoogleOptimizer/Observer/AbstractSave.php +++ b/app/code/Magento/GoogleOptimizer/Observer/AbstractSave.php @@ -5,12 +5,16 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\GoogleOptimizer\Observer; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; /** + * Abstract entity for saving codes + * * @api * @since 100.0.2 */ @@ -96,7 +100,9 @@ protected function _processCode() $this->_initRequestParams(); if ($this->_isNewCode()) { - $this->_saveCode(); + if (!$this->_isEmptyCode()) { + $this->_saveCode(); + } } else { $this->_loadCode(); if ($this->_isEmptyCode()) { @@ -185,6 +191,8 @@ protected function _deleteCode() } /** + * Check data availability + * * @return bool */ private function isDataAvailable() @@ -194,6 +202,8 @@ private function isDataAvailable() } /** + * Get request data + * * @return mixed */ private function getRequestData() diff --git a/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/Product/SaveGoogleExperimentScriptObserverTest.php b/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/Product/SaveGoogleExperimentScriptObserverTest.php index 8a5c247369657..c6d02957c4be9 100644 --- a/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/Product/SaveGoogleExperimentScriptObserverTest.php +++ b/app/code/Magento/GoogleOptimizer/Test/Unit/Observer/Product/SaveGoogleExperimentScriptObserverTest.php @@ -127,6 +127,39 @@ public function testCreatingCodeIfRequestIsValid() $this->_modelObserver->execute($this->_eventObserverMock); } + /** + * Test that code is not saving when request is empty + * + * @return void + */ + public function testCreatingCodeIfRequestIsEmpty(): void + { + $this->_helperMock->expects( + $this->once() + )->method( + 'isGoogleExperimentActive' + )->with( + $this->_storeId + )->willReturn( + true + ); + + $this->_requestMock->expects( + $this->exactly(3) + )->method( + 'getParam' + )->with( + 'google_experiment' + )->willReturn( + ['code_id' => '', 'experiment_script' => ''] + ); + + $this->_codeMock->expects($this->never())->method('addData'); + $this->_codeMock->expects($this->never())->method('save'); + + $this->_modelObserver->execute($this->_eventObserverMock); + } + /** * @param array $params * @dataProvider dataProviderWrongRequestForCreating From 60df223978e203a31811e626f983df5ae045aa9c Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin Date: Wed, 17 Jun 2020 11:34:33 +0300 Subject: [PATCH 3/6] MC-34394: [OnPrem] QUANS - Async/bulk operations. --- .../Model/Product/Price/Validation/Result.php | 6 ++ .../Product/Price/SpecialPriceStorageTest.php | 69 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Price/SpecialPriceStorageTest.php diff --git a/app/code/Magento/Catalog/Model/Product/Price/Validation/Result.php b/app/code/Magento/Catalog/Model/Product/Price/Validation/Result.php index 3d4d9f607da48..40fe6a01e260c 100644 --- a/app/code/Magento/Catalog/Model/Product/Price/Validation/Result.php +++ b/app/code/Magento/Catalog/Model/Product/Price/Validation/Result.php @@ -83,6 +83,12 @@ public function getFailedItems() } } + /** + * Clear validation messages to prevent wrong validation for subsequent price update. + * Work around for backward compatible changes. + */ + $this->failedItems = []; + return $failedItems; } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Price/SpecialPriceStorageTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Price/SpecialPriceStorageTest.php new file mode 100644 index 0000000000000..0d8b0a825d24c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Price/SpecialPriceStorageTest.php @@ -0,0 +1,69 @@ +model = $objectManager->get(SpecialPriceStorage::class); + $this->specialPriceFactory = $objectManager->get(SpecialPriceInterfaceFactory::class); + } + + /** + * Test that price update validation works correctly + * + * @magentoDataFixture Magento/Catalog/_files/category_product.php + */ + public function testUpdateValidationResult() + { + $date = new \Datetime('+2 days'); + $date->setTime(0, 0); + /** @var SpecialPriceInterface $price */ + $price = $this->specialPriceFactory->create(); + $price->setSku('invalid') + ->setStoreId(0) + ->setPrice(5.0) + ->setPriceFrom($date->format('Y-m-d H:i:s')) + ->setPriceTo( + $date->modify('+1 day') + ->format('Y-m-d H:i:s') + ); + $result = $this->model->update([$price]); + $this->assertCount(1, $result); + $this->assertStringContainsString( + 'The product that was requested doesn\'t exist.', + (string) $result[0]->getMessage() + ); + $price->setSku('simple333'); + $result = $this->model->update([$price]); + $this->assertCount(0, $result); + } +} From 4025502baf2391e6e1ad9956106313759b1bad8d Mon Sep 17 00:00:00 2001 From: Vasya Tsviklinskyi Date: Wed, 17 Jun 2020 12:57:06 +0300 Subject: [PATCH 4/6] MC-34655: [on prem] reCaptcha V3 error thrown randomly in most of the captcha enabled forms --- .../view/frontend/templates/form.phtml | 58 +++++++++++-------- .../templates/form/forgotpassword.phtml | 11 ++++ .../view/frontend/templates/form/login.phtml | 24 +++++++- .../frontend/templates/form/register.phtml | 12 ++-- .../frontend/web/js/block-submit-on-send.js | 22 +++++++ .../view/frontend/templates/subscribe.phtml | 9 +++ 6 files changed, 104 insertions(+), 32 deletions(-) create mode 100644 app/code/Magento/Customer/view/frontend/web/js/block-submit-on-send.js diff --git a/app/code/Magento/Contact/view/frontend/templates/form.phtml b/app/code/Magento/Contact/view/frontend/templates/form.phtml index d218e650657ac..eee9f742a59a4 100644 --- a/app/code/Magento/Contact/view/frontend/templates/form.phtml +++ b/app/code/Magento/Contact/view/frontend/templates/form.phtml @@ -4,6 +4,9 @@ * See COPYING.txt for license details. */ +// phpcs:disable Magento2.Templates.ThisInTemplate +// phpcs:disable Generic.Files.LineLength.TooLong + /** @var \Magento\Contact\Block\ContactForm $block */ /** @var \Magento\Contact\ViewModel\UserDataProvider $viewModel */ @@ -23,35 +26,35 @@ $viewModel = $block->getViewModel();
-
-
@@ -60,12 +63,12 @@ $viewModel = $block->getViewModel(); escapeHtml(__('What’s on your mind?')) ?>
-
@@ -81,3 +84,12 @@ $viewModel = $block->getViewModel(); + diff --git a/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml b/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml index be201afa8f66c..caa501d48da83 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml @@ -6,6 +6,8 @@ * @var $block \Magento\Customer\Block\Account\Forgotpassword */ +// phpcs:disable Generic.Files.LineLength.TooLong + /** @var \Magento\Customer\Block\Account\Forgotpassword $block */ ?>
+ diff --git a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml index ef74b0062c023..a1d1a0260672a 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ +// phpcs:disable Generic.Files.LineLength.TooLong + /** @var \Magento\Customer\Block\Form\Login $block */ ?> + diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index f7d10f6df1728..e84861b9b5cf6 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -301,13 +301,6 @@ require([ ignore: ignore ? ':hidden:not(' + ignore + ')' : ':hidden' }).find('input:text').attr('autocomplete', 'off'); - dataForm.submit(function () { - $(this).find(':submit').attr('disabled', 'disabled'); - }); - dataForm.bind("invalid-form.validate", function () { - $(this).find(':submit').prop('disabled', false); - }); - }); getShowAddressFields()): ?> @@ -337,6 +330,11 @@ require([ "passwordStrengthIndicator": { "formSelector": "form.form-create-account" } + }, + "*": { + "Magento_Customer/js/block-submit-on-send": { + "formId": "form-validate" + } } } diff --git a/app/code/Magento/Customer/view/frontend/web/js/block-submit-on-send.js b/app/code/Magento/Customer/view/frontend/web/js/block-submit-on-send.js new file mode 100644 index 0000000000000..b941ec7a254d8 --- /dev/null +++ b/app/code/Magento/Customer/view/frontend/web/js/block-submit-on-send.js @@ -0,0 +1,22 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'jquery', + 'mage/mage' +], function ($) { + 'use strict'; + + return function (config) { + var dataForm = $('#' + config.formId); + + dataForm.submit(function () { + $(this).find(':submit').attr('disabled', 'disabled'); + }); + dataForm.bind('invalid-form.validate', function () { + $(this).find(':submit').prop('disabled', false); + }); + }; +}); diff --git a/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml b/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml index 429482e5795bf..768c97ef316f7 100644 --- a/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml +++ b/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml @@ -40,3 +40,12 @@ + From c5563f254f3e28d9c1b6cc4ae04bcad4fd7faf56 Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh Date: Wed, 17 Jun 2020 15:01:16 +0300 Subject: [PATCH 5/6] MC-34063: After Magento upgrade to 2.3.4, price "sales_order_item.price" is now incorrectly saving item value for child items in a bundle item. --- .../Quote/Model/Quote/Item/Processor.php | 4 +- .../Unit/Model/Quote/Item/ProcessorTest.php | 48 ++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Quote/Model/Quote/Item/Processor.php b/app/code/Magento/Quote/Model/Quote/Item/Processor.php index ef4b853862681..c6bef1cc80bfb 100644 --- a/app/code/Magento/Quote/Model/Quote/Item/Processor.php +++ b/app/code/Magento/Quote/Model/Quote/Item/Processor.php @@ -97,7 +97,9 @@ public function prepare(Item $item, DataObject $request, Product $candidate): vo $item->addQty($candidate->getCartQty()); $customPrice = $request->getCustomPrice(); - $item->setPrice($candidate->getFinalPrice()); + if (!$item->getParentItem() || $item->getParentItem()->isChildrenCalculated()) { + $item->setPrice($candidate->getFinalPrice()); + } if (!empty($customPrice)) { $item->setCustomPrice($customPrice); $item->setOriginalCustomPrice($customPrice); diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/ProcessorTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/ProcessorTest.php index cbcb7dd0adc3c..3025a72410671 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/ProcessorTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/ProcessorTest.php @@ -77,7 +77,16 @@ protected function setUp(): void $this->itemMock = $this->getMockBuilder(Item::class) ->addMethods(['setOriginalCustomPrice']) - ->onlyMethods(['getId', 'setOptions', 'setProduct', 'addQty', 'setCustomPrice', 'setData', 'setPrice']) + ->onlyMethods([ + 'getId', + 'setOptions', + 'setProduct', + 'addQty', + 'setCustomPrice', + 'setData', + 'setPrice', + 'getParentItem' + ]) ->disableOriginalConstructor() ->getMock(); $this->quoteItemFactoryMock->expects($this->any()) @@ -438,4 +447,41 @@ public function testPrepareWithResetCountAndNotStickAndSameItemId() $this->processor->prepare($this->itemMock, $this->objectMock, $this->productMock); } + + /** + * @param bool $isChildrenCalculated + * @dataProvider prepareChildProductDataProvider + */ + public function testPrepareChildProduct(bool $isChildrenCalculated): void + { + $finalPrice = 10; + $this->objectMock->method('getResetCount') + ->willReturn(false); + $this->productMock->method('getFinalPrice') + ->willReturn($finalPrice); + $this->itemMock->expects($isChildrenCalculated ? $this->once() : $this->never()) + ->method('setPrice') + ->with($finalPrice) + ->willReturnSelf(); + $parentItem = $this->createConfiguredMock( + \Magento\Quote\Model\Quote\Item::class, + [ + 'isChildrenCalculated' => $isChildrenCalculated + ] + ); + $this->itemMock->method('getParentItem') + ->willReturn($parentItem); + $this->processor->prepare($this->itemMock, $this->objectMock, $this->productMock); + } + + /** + * @return array + */ + public function prepareChildProductDataProvider(): array + { + return [ + [false], + [true] + ]; + } } From 4c3280b08f4b806812e96915a26894ff74e5c641 Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh Date: Wed, 17 Jun 2020 16:04:53 +0300 Subject: [PATCH 6/6] MC-34793: Coupon code based on shipping method remains applied after shipping method changed to another one --- .../view/frontend/requirejs-config.js | 3 ++ .../js/model/shipping-save-processor-mixin.js | 34 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 app/code/Magento/SalesRule/view/frontend/web/js/model/shipping-save-processor-mixin.js diff --git a/app/code/Magento/SalesRule/view/frontend/requirejs-config.js b/app/code/Magento/SalesRule/view/frontend/requirejs-config.js index 13b701c6fe65a..21f49fb3080fc 100644 --- a/app/code/Magento/SalesRule/view/frontend/requirejs-config.js +++ b/app/code/Magento/SalesRule/view/frontend/requirejs-config.js @@ -8,6 +8,9 @@ var config = { mixins: { 'Magento_Checkout/js/action/select-payment-method': { 'Magento_SalesRule/js/action/select-payment-method-mixin': true + }, + 'Magento_Checkout/js/model/shipping-save-processor': { + 'Magento_SalesRule/js/model/shipping-save-processor-mixin': true } } } diff --git a/app/code/Magento/SalesRule/view/frontend/web/js/model/shipping-save-processor-mixin.js b/app/code/Magento/SalesRule/view/frontend/web/js/model/shipping-save-processor-mixin.js new file mode 100644 index 0000000000000..193acb8eed2f4 --- /dev/null +++ b/app/code/Magento/SalesRule/view/frontend/web/js/model/shipping-save-processor-mixin.js @@ -0,0 +1,34 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'mage/utils/wrapper', + 'Magento_Checkout/js/model/quote', + 'Magento_SalesRule/js/model/coupon' +], function (wrapper, quote, coupon) { + 'use strict'; + + return function (shippingSaveProcessor) { + shippingSaveProcessor.saveShippingInformation = wrapper.wrapSuper( + shippingSaveProcessor.saveShippingInformation, + function (type) { + var updateCouponCallback; + + /** + * Update coupon form + */ + updateCouponCallback = function () { + if (quote.totals() && !quote.totals()['coupon_code']) { + coupon.setCouponCode(''); + coupon.setIsApplied(false); + } + }; + + return this._super(type).done(updateCouponCallback); + } + ); + + return shippingSaveProcessor; + }; +});