Skip to content

Commit 33f0c3a

Browse files
committed
Merge remote-tracking branch 'origin/MC-23536' into 2.4-develop-pr91
2 parents b134d69 + 17a1c3a commit 33f0c3a

File tree

63 files changed

+852
-149
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+852
-149
lines changed

app/code/Magento/Bundle/view/adminhtml/ui_component/bundle_product_listing.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
<label translate="true">Status</label>
5959
<dataScope>status</dataScope>
6060
<imports>
61-
<link name="visible">componentType = column, index = ${ $.index }:visible</link>
61+
<link name="visible">ns = ${ $.ns }, index = ${ $.index }:visible</link>
6262
</imports>
6363
</settings>
6464
</filterSelect>

app/code/Magento/Catalog/Model/Product/Option/Type/Date.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ public function validateUserValue($values)
7272
$dateValid = true;
7373
if ($this->_dateExists()) {
7474
if ($this->useCalendar()) {
75+
/* Fixed validation if the date was not saved correctly after re-saved the order
76+
for example: "09\/24\/2020,2020-09-24 00:00:00" */
77+
if (is_string($value) && preg_match('/^\d{1,4}.+\d{1,4}.+\d{1,4},+(\w|\W)*$/', $value)) {
78+
$value = [
79+
'date' => preg_replace('/,([^,]+),?$/', '', $value),
80+
];
81+
}
7582
$dateValid = isset($value['date']) && preg_match('/^\d{1,4}.+\d{1,4}.+\d{1,4}$/', $value['date']);
7683
} else {
7784
$dateValid = isset(
@@ -184,8 +191,10 @@ public function prepareForCart()
184191
$date = (new \DateTime())->setTimestamp($timestamp);
185192
$result = $date->format('Y-m-d H:i:s');
186193

194+
$originDate = (isset($value['date']) && $value['date'] != '') ? $value['date'] : null;
195+
187196
// Save date in internal format to avoid locale date bugs
188-
$this->_setInternalInRequest($result);
197+
$this->_setInternalInRequest($result, $originDate);
189198

190199
return $result;
191200
} else {
@@ -352,9 +361,10 @@ public function getYearEnd()
352361
* Save internal value of option in infoBuy_request
353362
*
354363
* @param string $internalValue Datetime value in internal format
364+
* @param string|null $originDate date value in origin format
355365
* @return void
356366
*/
357-
protected function _setInternalInRequest($internalValue)
367+
protected function _setInternalInRequest($internalValue, $originDate = null)
358368
{
359369
$requestOptions = $this->getRequest()->getOptions();
360370
if (!isset($requestOptions[$this->getOption()->getId()])) {
@@ -364,6 +374,9 @@ protected function _setInternalInRequest($internalValue)
364374
$requestOptions[$this->getOption()->getId()] = [];
365375
}
366376
$requestOptions[$this->getOption()->getId()]['date_internal'] = $internalValue;
377+
if ($originDate) {
378+
$requestOptions[$this->getOption()->getId()]['date'] = $originDate;
379+
}
367380
$this->getRequest()->setOptions($requestOptions);
368381
}
369382

app/code/Magento/Catalog/Model/ProductOptionProcessor.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
*/
66
namespace Magento\Catalog\Model;
77

8-
use Magento\Catalog\Api\Data\ProductOptionExtensionFactory;
98
use Magento\Catalog\Api\Data\ProductOptionInterface;
109
use Magento\Catalog\Model\CustomOptions\CustomOption;
1110
use Magento\Catalog\Model\CustomOptions\CustomOptionFactory;
1211
use Magento\Framework\DataObject;
1312
use Magento\Framework\DataObject\Factory as DataObjectFactory;
1413

14+
/**
15+
* Processor for product options
16+
*/
1517
class ProductOptionProcessor implements ProductOptionProcessorInterface
1618
{
1719
/**
@@ -88,7 +90,8 @@ public function convertToProductOption(DataObject $request)
8890
if (!empty($options) && is_array($options)) {
8991
$data = [];
9092
foreach ($options as $optionId => $optionValue) {
91-
if (is_array($optionValue)) {
93+
94+
if (is_array($optionValue) && !$this->isDateWithDateInternal($optionValue)) {
9295
$optionValue = $this->processFileOptionValue($optionValue);
9396
$optionValue = implode(',', $optionValue);
9497
}
@@ -126,6 +129,8 @@ private function processFileOptionValue(array $optionValue)
126129
}
127130

128131
/**
132+
* Get url builder
133+
*
129134
* @return \Magento\Catalog\Model\Product\Option\UrlBuilder
130135
*
131136
* @deprecated 101.0.0
@@ -138,4 +143,15 @@ private function getUrlBuilder()
138143
}
139144
return $this->urlBuilder;
140145
}
146+
147+
/**
148+
* Check if the option has a date_internal and date
149+
*
150+
* @param array $optionValue
151+
* @return bool
152+
*/
153+
private function isDateWithDateInternal(array $optionValue): bool
154+
{
155+
return array_key_exists('date_internal', $optionValue) && array_key_exists('date', $optionValue);
156+
}
141157
}

app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,7 @@
133133
<waitForPageLoad stepKey="waitForFiltersClear"/>
134134

135135
<!--Create Cart Price Rule-->
136-
<amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/>
137-
<waitForPageLoad stepKey="waitForPriceList"/>
136+
<actionGroup ref="AdminOpenCartPriceRulesPageActionGroup" stepKey="amOnCartPriceList"/>
138137
<click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/>
139138
<waitForPageLoad stepKey="waitForPageDiscountPageIsLoaded"/>
140139
<fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="ship" stepKey="fillRuleName"/>

app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ public function __construct(
421421

422422
$this->_initMessageTemplates();
423423

424-
$this->_initProductsSku()->_initOldCustomOptions();
424+
$this->_initProductsSku();
425425
}
426426

427427
/**
@@ -606,6 +606,9 @@ protected function _initOldCustomOptions()
606606
'option_title.store_id = ?',
607607
$storeId
608608
);
609+
if (!empty($this->_newOptionsOldData)) {
610+
$this->_optionCollection->addProductToFilter(array_keys($this->_newOptionsOldData));
611+
}
609612

610613
$this->_byPagesIterator->iterate($this->_optionCollection, $this->_pageSize, [$addCustomOptions]);
611614
}
@@ -614,6 +617,20 @@ protected function _initOldCustomOptions()
614617
return $this;
615618
}
616619

620+
/**
621+
* Get existing custom options data
622+
*
623+
* @return array
624+
*/
625+
private function getOldCustomOptions(): array
626+
{
627+
if ($this->_oldCustomOptions === null) {
628+
$this->_initOldCustomOptions();
629+
}
630+
631+
return $this->_oldCustomOptions;
632+
}
633+
617634
/**
618635
* Imported entity type code getter
619636
*
@@ -717,9 +734,9 @@ protected function _findOldOptionsWithTheSameTitles()
717734
$errorRows = [];
718735
foreach ($this->_newOptionsOldData as $productId => $options) {
719736
foreach ($options as $outerData) {
720-
if (isset($this->_oldCustomOptions[$productId])) {
737+
if (isset($this->getOldCustomOptions()[$productId])) {
721738
$optionsCount = 0;
722-
foreach ($this->_oldCustomOptions[$productId] as $innerData) {
739+
foreach ($this->getOldCustomOptions()[$productId] as $innerData) {
723740
if (count($outerData['titles']) == count($innerData['titles'])) {
724741
$outerTitles = $outerData['titles'];
725742
$innerTitles = $innerData['titles'];
@@ -753,8 +770,8 @@ protected function _findNewOldOptionsTypeMismatch()
753770
$errorRows = [];
754771
foreach ($this->_newOptionsOldData as $productId => $options) {
755772
foreach ($options as $outerData) {
756-
if (isset($this->_oldCustomOptions[$productId])) {
757-
foreach ($this->_oldCustomOptions[$productId] as $innerData) {
773+
if (isset($this->getOldCustomOptions()[$productId])) {
774+
foreach ($this->getOldCustomOptions()[$productId] as $innerData) {
758775
if (count($outerData['titles']) == count($innerData['titles'])) {
759776
$outerTitles = $outerData['titles'];
760777
$innerTitles = $innerData['titles'];
@@ -784,9 +801,9 @@ protected function _findNewOldOptionsTypeMismatch()
784801
protected function _findExistingOptionId(array $newOptionData, array $newOptionTitles)
785802
{
786803
$productId = $newOptionData['product_id'];
787-
if (isset($this->_oldCustomOptions[$productId])) {
804+
if (isset($this->getOldCustomOptions()[$productId])) {
788805
ksort($newOptionTitles);
789-
$existingOptions = $this->_oldCustomOptions[$productId];
806+
$existingOptions = $this->getOldCustomOptions()[$productId];
790807
foreach ($existingOptions as $optionId => $optionData) {
791808
if ($optionData['type'] == $newOptionData['type']
792809
&& $optionData['titles'][Store::DEFAULT_STORE_ID] == $newOptionTitles[Store::DEFAULT_STORE_ID]

app/code/Magento/CatalogWidget/Block/Product/ProductsList.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,13 @@ public function createCollection()
337337

338338
$collection->setVisibility($this->catalogProductVisibility->getVisibleInCatalogIds());
339339

340+
/**
341+
* Change sorting attribute to entity_id because created_at can be the same for products fastly created
342+
* one by one and sorting by created_at is indeterministic in this case.
343+
*/
340344
$collection = $this->_addProductAttributesAndPrices($collection)
341345
->addStoreFilter()
342-
->addAttributeToSort('created_at', 'desc')
346+
->addAttributeToSort('entity_id', 'desc')
343347
->setPageSize($this->getPageSize())
344348
->setCurPage($this->getRequest()->getParam($this->getData('page_var_name'), 1));
345349

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
11+
<test name="CatalogProductListCheckWidgetOrderTest">
12+
<annotations>
13+
<features value="CatalogWidget"/>
14+
<stories value="Product list widget"/>
15+
<title value="Checking order of products in the 'catalog Products List' widget"/>
16+
<description value="Check that products are ordered with recently added products first"/>
17+
<severity value="MAJOR"/>
18+
<testCaseId value="MC-27616"/>
19+
<useCaseId value="MC-5905"/>
20+
<group value="catalogWidget"/>
21+
<group value="catalog"/>
22+
<group value="WYSIWYGDisabled"/>
23+
</annotations>
24+
<before>
25+
<createData entity="SimpleSubCategory" stepKey="simplecategory"/>
26+
<createData entity="SimpleProduct" stepKey="createFirstProduct">
27+
<requiredEntity createDataKey="simplecategory"/>
28+
<field key="price">10</field>
29+
</createData>
30+
<createData entity="SimpleProduct" stepKey="createSecondProduct">
31+
<requiredEntity createDataKey="simplecategory"/>
32+
<field key="price">20</field>
33+
</createData>
34+
<createData entity="SimpleProduct" stepKey="createThirdProduct">
35+
<requiredEntity createDataKey="simplecategory"/>
36+
<field key="price">30</field>
37+
</createData>
38+
<createData entity="_defaultCmsPage" stepKey="createPreReqPage"/>
39+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
40+
<actionGroup ref="EnabledWYSIWYGActionGroup" stepKey="enableWYSIWYG"/>
41+
</before>
42+
<after>
43+
<actionGroup ref="DisabledWYSIWYGActionGroup" stepKey="disableWYSIWYG"/>
44+
<deleteData createDataKey="createPreReqPage" stepKey="deletePreReqPage" />
45+
<deleteData createDataKey="simplecategory" stepKey="deleteSimpleCategory"/>
46+
<deleteData createDataKey="createFirstProduct" stepKey="deleteFirstProduct"/>
47+
<deleteData createDataKey="createSecondProduct" stepKey="deleteSecondProduct"/>
48+
<deleteData createDataKey="createThirdProduct" stepKey="deleteThirdProduct"/>
49+
<actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/>
50+
</after>
51+
<!--Open created cms page-->
52+
<actionGroup ref="AdminOpenCmsPageActionGroup" stepKey="openEditPage">
53+
<argument name="page_id" value="$createPreReqPage.id$"/>
54+
</actionGroup>
55+
<click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickExpandContentTabForPage"/>
56+
<waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/>
57+
<!--Add widget to cms page-->
58+
<waitForElementVisible selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="waitInsertWidgetIconVisible"/>
59+
<click selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" />
60+
<waitForElementVisible selector="{{WidgetSection.WidgetType}}" stepKey="waitForWidgetTypeSelectorVisible"/>
61+
<selectOption selector="{{WidgetSection.WidgetType}}" userInput="Catalog Products List" stepKey="selectCatalogProductsList" />
62+
<waitForElementVisible selector="{{WidgetSection.AddParam}}" stepKey="waitForAddParamBtnVisible"/>
63+
<click selector="{{WidgetSection.AddParam}}" stepKey="clickAddParamBtn" />
64+
<waitForElementVisible selector="{{WidgetSection.ConditionsDropdown}}" stepKey="waitForDropdownVisible"/>
65+
<selectOption selector="{{WidgetSection.ConditionsDropdown}}" userInput="Category" stepKey="selectCategoryCondition" />
66+
<waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear2" />
67+
<waitForElementVisible selector="{{WidgetSection.RuleParam}}" stepKey="waitForRuleParamVisible"/>
68+
<click selector="{{WidgetSection.RuleParam}}" stepKey="clickRuleParam" />
69+
<waitForElementVisible selector="{{WidgetSection.Chooser}}" stepKey="waitForElement" />
70+
<click selector="{{WidgetSection.Chooser}}" stepKey="clickChooser" />
71+
<waitForElementVisible selector="{{WidgetSection.PreCreateCategory('$simplecategory.name$')}}" stepKey="waitForCategoryVisible" />
72+
<click selector="{{WidgetSection.PreCreateCategory('$simplecategory.name$')}}" stepKey="selectCategory" />
73+
<click selector="{{WidgetSection.InsertWidget}}" stepKey="clickInsertWidget" />
74+
<!--Save cms page and go to Storefront-->
75+
<actionGroup ref="SaveCmsPageActionGroup" stepKey="saveCmsPage"/>
76+
<actionGroup ref="NavigateToStorefrontForCreatedPageActionGroup" stepKey="navigateToTheStoreFront1">
77+
<argument name="page" value="$createPreReqPage.identifier$"/>
78+
</actionGroup>
79+
<!--Check order of products: recently added first-->
80+
<waitForElementVisible selector="{{InsertWidgetSection.checkElementStorefrontByName('1','$createThirdProduct.name$')}}" stepKey="waitForThirdProductVisible"/>
81+
<seeElement selector="{{InsertWidgetSection.checkElementStorefrontByName('1','$createThirdProduct.name$')}}" stepKey="seeElementByName1"/>
82+
<seeElement selector="{{InsertWidgetSection.checkElementStorefrontByName('2','$createSecondProduct.name$')}}" stepKey="seeElementByName2"/>
83+
<seeElement selector="{{InsertWidgetSection.checkElementStorefrontByName('3','$createFirstProduct.name$')}}" stepKey="seeElementByName3"/>
84+
</test>
85+
</tests>

app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOrderTest.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@
88

99
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1010
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
11-
<test name="CatalogProductListWidgetOrderTest">
11+
<test name="CatalogProductListWidgetOrderTest" deprecated="Use CatalogProductListCheckWidgetOrderTest instead">
1212
<annotations>
1313
<features value="CatalogWidget"/>
1414
<stories value="MC-5905: Wrong sorting on Products component"/>
15-
<title value="Checking order of products in the 'catalog Products List' widget"/>
15+
<title value="Deprecated. Checking order of products in the 'catalog Products List' widget"/>
1616
<description value="Check that products are ordered with recently added products first"/>
1717
<severity value="MAJOR"/>
1818
<testCaseId value="MC-13794"/>
1919
<group value="CatalogWidget"/>
2020
<group value="WYSIWYGDisabled"/>
2121
<skip>
22-
<issueId value="MC-13923"/>
22+
<issueId value="DEPRECATED">Use CatalogProductListCheckWidgetOrderTest instead</issueId>
2323
</skip>
2424
</annotations>
2525
<before>

app/code/Magento/CatalogWidget/Test/Unit/Block/Product/ProductsListTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ public function testCreateCollection($pagerEnable, $productsCount, $productsPerP
314314
$collection->expects($this->once())->method('addAttributeToSelect')->willReturnSelf();
315315
$collection->expects($this->once())->method('addUrlRewrite')->willReturnSelf();
316316
$collection->expects($this->once())->method('addStoreFilter')->willReturnSelf();
317-
$collection->expects($this->once())->method('addAttributeToSort')->with('created_at', 'desc')->willReturnSelf();
317+
$collection->expects($this->once())->method('addAttributeToSort')->with('entity_id', 'desc')->willReturnSelf();
318318
$collection->expects($this->once())->method('setPageSize')->with($expectedPageSize)->willReturnSelf();
319319
$collection->expects($this->once())->method('setCurPage')->willReturnSelf();
320320
$collection->expects($this->once())->method('distinct')->willReturnSelf();

app/code/Magento/Checkout/Test/Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@
4141
<deleteData createDataKey="simplecategory" stepKey="deleteCategory"/>
4242
</after>
4343

44-
<!--Open MARKETING > Cart Price Rules-->
45-
<amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/>
46-
<waitForPageLoad stepKey="waitForRulesPage"/>
44+
<actionGroup ref="AdminOpenCartPriceRulesPageActionGroup" stepKey="amOnCartPriceList"/>
4745

4846
<!--Add New Rule-->
4947
<click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/>

0 commit comments

Comments
 (0)