Skip to content

Commit 60e3a73

Browse files
authored
Merge pull request #3985 from magento-epam/EPAM-PR-45
- fixed MAGETWO-65232: Product name does not display special characters properly - fixed MAGETWO-58219: [Github] Product Attribute Option Values for storeview instead of admin on product creation #6507 - fixed MAGETWO-70232: [GITHUB] Import customizable options adds it to another product if same SKU is filled#9457 - fixed MAGETWO-58226: Calendar Custom Options are displayed broken on Storefront if JS validation is performed
2 parents 05217b0 + 4068de1 commit 60e3a73

File tree

20 files changed

+264
-31
lines changed

20 files changed

+264
-31
lines changed

app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Catalog\Model\Product\Option;
79

810
use Magento\Catalog\Api\ProductCustomOptionRepositoryInterface as OptionRepository;
@@ -58,11 +60,26 @@ public function execute($entity, $arguments = [])
5860
}
5961
}
6062
if ($options) {
61-
foreach ($options as $option) {
62-
$this->optionRepository->save($option);
63-
}
63+
$this->processOptionsSaving($options, (bool)$entity->dataHasChangedFor('sku'), (string)$entity->getSku());
6464
}
6565

6666
return $entity;
6767
}
68+
69+
/**
70+
* Save custom options
71+
*
72+
* @param array $options
73+
* @param bool $hasChangedSku
74+
* @param string $newSku
75+
*/
76+
private function processOptionsSaving(array $options, bool $hasChangedSku, string $newSku)
77+
{
78+
foreach ($options as $option) {
79+
if ($hasChangedSku && $option->hasData('product_sku')) {
80+
$option->setProductSku($newSku);
81+
}
82+
$this->optionRepository->save($option);
83+
}
84+
}
6885
}

app/code/Magento/Catalog/Test/Mftf/ActionGroup/CustomOptionsActionGroup.xml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,51 @@
5252
<selectOption selector="{{AdminProductCustomizableOptionsSection.optionPriceType('0')}}" userInput="{{option.price_type}}" stepKey="selectPriceType"/>
5353
<fillField selector="{{AdminProductCustomizableOptionsSection.optionFileExtensions('0')}}" userInput="{{option.file_extension}}" stepKey="fillCompatibleExtensions"/>
5454
</actionGroup>
55+
<actionGroup name="AddProductCustomOptionField">
56+
<arguments>
57+
<argument name="option" defaultValue="ProductOptionField"/>
58+
<argiment name="optionIndex" type="string"/>
59+
</arguments>
60+
<conditionalClick selector="{{AdminProductCustomizableOptionsSection.customizableOptions}}" dependentSelector="{{AdminProductCustomizableOptionsSection.addOptionBtn}}" visible="false" stepKey="openCustomOptionSection"/>
61+
<click selector="{{AdminProductCustomizableOptionsSection.addOptionBtn}}" stepKey="clickAddOption"/>
62+
<waitForElementVisible selector="{{AdminProductCustomizableOptionsSection.lastOptionTitle}}" stepKey="waitForOption"/>
63+
<fillField selector="{{AdminProductCustomizableOptionsSection.lastOptionTitle}}" userInput="{{option.title}}" stepKey="fillTitle"/>
64+
<click selector="{{AdminProductCustomizableOptionsSection.lastOptionTypeParent}}" stepKey="openTypeSelect"/>
65+
<click selector="{{AdminProductCustomizableOptionsSection.optionType('Field')}}" stepKey="selectTypeFile"/>
66+
<waitForElementVisible selector="{{AdminProductCustomizableOptionsSection.optionPrice(optionIndex)}}" stepKey="waitForElements"/>
67+
<fillField selector="{{AdminProductCustomizableOptionsSection.optionPrice(optionIndex)}}" userInput="{{option.price}}" stepKey="fillPrice"/>
68+
<selectOption selector="{{AdminProductCustomizableOptionsSection.optionPriceType(optionIndex)}}" userInput="{{option.price_type}}" stepKey="selectPriceType"/>
69+
<fillField selector="{{AdminProductCustomizableOptionsSection.optionSku(optionIndex)}}" userInput="{{option.title}}" stepKey="fillSku"/>
70+
</actionGroup>
71+
<actionGroup name="importProductCustomizableOptions">
72+
<arguments>
73+
<argument name="productName" type="string"/>
74+
</arguments>
75+
<click selector="{{AdminProductCustomizableOptionsSection.importOptions}}" stepKey="clickImportOptions"/>
76+
<waitForElementVisible selector="{{AdminProductImportOptionsSection.selectProductTitle}}" stepKey="waitForTitleVisible"/>
77+
<conditionalClick selector="{{AdminProductImportOptionsSection.resetFiltersButton}}" dependentSelector="{{AdminProductImportOptionsSection.resetFiltersButton}}" visible="true" stepKey="clickResetFilters"/>
78+
<click selector="{{AdminProductImportOptionsSection.filterButton}}" stepKey="clickFilterButton"/>
79+
<waitForElementVisible selector="{{AdminProductImportOptionsSection.nameField}}" stepKey="waitForNameField"/>
80+
<fillField selector="{{AdminProductImportOptionsSection.nameField}}" userInput="{{productName}}" stepKey="fillProductName"/>
81+
<click selector="{{AdminProductImportOptionsSection.applyFiltersButton}}" stepKey="clickApplyFilters"/>
82+
<checkOption selector="{{AdminProductImportOptionsSection.firstRowItemCheckbox}}" stepKey="checkProductCheckbox"/>
83+
<click selector="{{AdminProductImportOptionsSection.importButton}}" stepKey="clickImport"/>
84+
</actionGroup>
85+
<actionGroup name="resetImportOptionFilter">
86+
<conditionalClick selector="{{AdminProductCustomizableOptionsSection.customizableOptions}}" dependentSelector="{{AdminProductCustomizableOptionsSection.addOptionBtn}}" visible="false" stepKey="openCustomOptionSection"/>
87+
<click selector="{{AdminProductCustomizableOptionsSection.importOptions}}" stepKey="clickImportOptions"/>
88+
<click selector="{{AdminProductImportOptionsSection.resetFiltersButton}}" stepKey="clickResetFilterButton"/>
89+
</actionGroup>
90+
<actionGroup name="checkCustomizableOptionImport">
91+
<arguments>
92+
<argument name="option" defaultValue="ProductOptionField"/>
93+
<argiment name="optionIndex" type="string"/>
94+
</arguments>
95+
<grabValueFrom selector="{{AdminProductCustomizableOptionsSection.optionTitleInput(optionIndex)}}" stepKey="grabOptionTitle"/>
96+
<grabValueFrom selector="{{AdminProductCustomizableOptionsSection.optionPrice(optionIndex)}}" stepKey="grabOptionPrice"/>
97+
<grabValueFrom selector="{{AdminProductCustomizableOptionsSection.optionSku(optionIndex)}}" stepKey="grabOptionSku"/>
98+
<assertEquals expected="{{option.title}}" expectedType="string" actual="$grabOptionTitle" stepKey="assertOptionTitle"/>
99+
<assertEquals expected="{{option.price}}" expectedType="string" actual="$grabOptionPrice" stepKey="assertOptionPrice"/>
100+
<assertEquals expected="{{option.title}}" expectedType="string" actual="$grabOptionSku" stepKey="assertOptionSku"/>
101+
</actionGroup>
55102
</actionGroups>

app/code/Magento/Catalog/Test/Mftf/Data/ConstData.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,8 @@
1313
<data key="one">1</data>
1414
<data key="two">2</data>
1515
</entity>
16+
<entity name="prodNameWithSpecChars">
17+
<data key="trademark">"Pursuit Lumaflex™ Tone Band"</data>
18+
<data key="skumark">"x™"</data>
19+
</entity>
1620
</entities>

app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
<requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity>
3636
<requiredEntity type="custom_attribute_array">CustomAttributeCategoryIds</requiredEntity>
3737
</entity>
38+
<entity name="ApiSimpleProductWithSpecCharInName" type="product" extends="ApiSimpleProduct">
39+
<data key="name">Pursuit Lumaflex&#38;trade; Tone Band</data>
40+
<data key="sku" unique="suffix">x&#38;trade;</data>
41+
</entity>
3842
<entity name="ApiSimpleProductWithCustomPrice" type="product" extends="ApiSimpleProduct">
3943
<data key="price">100</data>
4044
</entity>

app/code/Magento/Catalog/Test/Mftf/Section/AdminProductCustomizableOptionsSection.xml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,15 @@
4545
<element name="optionPriceType" type="select" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr//*[@name='product[options][{{var}}][price_type]']" parameterized="true"/>
4646
<element name="optionSku" type="input" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr//*[@name='product[options][{{index}}][sku]']" parameterized="true"/>
4747
<element name="optionFileExtensions" type="input" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr//*[@name='product[options][{{index}}][file_extension]']" parameterized="true"/>
48+
<element name="importOptions" type="button" selector="//button[@data-index='button_import']" timeout="30"/>
4849
</section>
49-
</sections>
50+
<section name="AdminProductImportOptionsSection">
51+
<element name="selectProductTitle" type="text" selector="//h1[contains(text(), 'Select Product')]" timeout="30"/>
52+
<element name="filterButton" type="button" selector="//button[@data-action='grid-filter-expand']" timeout="30"/>
53+
<element name="nameField" type="input" selector="//input[@name='name']" timeout="30"/>
54+
<element name="applyFiltersButton" type="button" selector="//button[@data-action='grid-filter-apply']" timeout="30"/>
55+
<element name="resetFiltersButton" type="button" selector="//button[@data-action='grid-filter-reset']" timeout="30"/>
56+
<element name="firstRowItemCheckbox" type="input" selector="//input[@data-action='select-row']" timeout="30"/>
57+
<element name="importButton" type="button" selector="//button[contains(@class, 'action-primary')]/span[contains(text(), 'Import')]" timeout="30"/>
58+
</section>
59+
</sections>

app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridSection.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<element name="productGridElement2" type="text" selector="#addselector" />
1818
<element name="productGridRows" type="text" selector="table.data-grid tr.data-row"/>
1919
<element name="firstProductRow" type="text" selector="table.data-grid tr.data-row:first-of-type"/>
20+
<element name="firstProductRowName" type="text" selector="table.data-grid tr.data-row:first-of-type > td:nth-of-type(4)"/>
2021
<element name="firstProductRowEditButton" type="button" selector="table.data-grid tr.data-row td .action-menu-item:first-of-type"/>
2122
<element name="productThumbnail" type="text" selector="table.data-grid tr:nth-child({{row}}) td.data-grid-thumbnail-cell > img" parameterized="true"/>
2223
<element name="productThumbnailBySrc" type="text" selector="img.admin__control-thumbnail[src*='{{pattern}}']" parameterized="true"/>

app/code/Magento/Catalog/Test/Mftf/Section/StorefrontNavigationSection.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
<element name="subCategory" type="button" selector="//ul[contains(@class,'submenu')]//span[contains(text(),'{{var1}}')]" parameterized="true"/>
1313
<element name="breadcrumbs" type="textarea" selector=".items"/>
1414
<element name="categoryBreadcrumbs" type="textarea" selector=".breadcrumbs li"/>
15+
<element name="categoryBreadcrumbsByNumber" type="textarea" selector=".breadcrumbs li:nth-of-type({{number}})" parameterized="true"/>
1516
</section>
1617
</sections>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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="AdminImportCustomizableOptionToProductWithSKUTest">
12+
<annotations>
13+
<features value="Catalog"/>
14+
<title value="Import customizable options to a product with existing SKU"/>
15+
<description value="Import customizable options to a product with existing SKU"/>
16+
<severity value="MAJOR"/>
17+
<testCaseId value="MAGETWO-98211"/>
18+
<useCaseId value="MAGETWO-70232"/>
19+
<group value="catalog"/>
20+
</annotations>
21+
<before>
22+
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/>
23+
<!--Create category-->
24+
<comment userInput="Create category" stepKey="commentCreateCategory"/>
25+
<createData entity="ApiCategory" stepKey="createCategory"/>
26+
<!-- Create two product -->
27+
<comment userInput="Create two product" stepKey="commentCreateTwoProduct"/>
28+
<createData entity="SimpleProduct2" stepKey="createFirstProduct"/>
29+
<createData entity="ApiSimpleProduct" stepKey="createSecondProduct">
30+
<requiredEntity createDataKey="createCategory"/>
31+
</createData>
32+
</before>
33+
<after>
34+
<!--Delete second product with changed sku-->
35+
<comment userInput="Delete second product with changed sku" stepKey="commentDeleteProduct"/>
36+
<actionGroup ref="deleteProductBySku" stepKey="deleteSecondProduct">
37+
<argument name="sku" value="$$createFirstProduct.sku$$-1"/>
38+
</actionGroup>
39+
<!--Delete created data-->
40+
<comment userInput="Delete created data" stepKey="commentDeleteCreatedData"/>
41+
<deleteData createDataKey="createCategory" stepKey="deleteCategory"/>
42+
<deleteData createDataKey="createFirstProduct" stepKey="deleteFirstProduct"/>
43+
<actionGroup ref="logout" stepKey="logoutOfAdmin"/>
44+
</after>
45+
<!--Go to product page -->
46+
<comment userInput="Go to product page" stepKey="commentGoToProductPage"/>
47+
<amOnPage url="{{AdminProductEditPage.url($$createFirstProduct.id$$)}}" stepKey="goToProductEditPage"/>
48+
<waitForPageLoad stepKey="waitForProductEditPageLoad"/>
49+
<actionGroup ref="AddProductCustomOptionField" stepKey="addCutomOption1">
50+
<argument name="option" value="ProductOptionField"/>
51+
<argument name="optionIndex" value="0"/>
52+
</actionGroup>
53+
<actionGroup ref="AddProductCustomOptionField" stepKey="addCutomOption2">
54+
<argument name="option" value="ProductOptionField2"/>
55+
<argument name="optionIndex" value="1"/>
56+
</actionGroup>
57+
<actionGroup ref="saveProductForm" stepKey="saveProduct"/>
58+
<!--Change second product sku to first product sku-->
59+
<comment userInput="Change second product sku to first product sku" stepKey="commentChangeSecondProduct"/>
60+
<amOnPage url="{{AdminProductEditPage.url($$createSecondProduct.id$$)}}" stepKey="goToProductEditPage1"/>
61+
<waitForPageLoad stepKey="waitForProductEditPageLoad1"/>
62+
<fillField selector="{{AdminProductFormSection.productSku}}" userInput="$$createFirstProduct.sku$$" stepKey="fillProductSku1"/>
63+
<!--Import customizable options and check-->
64+
<comment userInput="Import customizable options and check" stepKey="commentImportOptions"/>
65+
<conditionalClick selector="{{AdminProductCustomizableOptionsSection.customizableOptions}}" dependentSelector="{{AdminProductCustomizableOptionsSection.addOptionBtn}}" visible="false" stepKey="openCustomOptionSection"/>
66+
<actionGroup ref="importProductCustomizableOptions" stepKey="importOptions">
67+
<argument name="productName" value="$$createFirstProduct.name$$"/>
68+
</actionGroup>
69+
<actionGroup ref="checkCustomizableOptionImport" stepKey="checkFirstOptionImport">
70+
<argument name="option" value="ProductOptionField"/>
71+
<argument name="optionIndex" value="0"/>
72+
</actionGroup>
73+
<actionGroup ref="checkCustomizableOptionImport" stepKey="checkSecondOptionImport">
74+
<argument name="option" value="ProductOptionField2"/>
75+
<argument name="optionIndex" value="1"/>
76+
</actionGroup>
77+
<!--Save product and check sku changed message-->
78+
<comment userInput="Save product and check sku changed message" stepKey="commentSAveProductAndCheck"/>
79+
<actionGroup ref="saveProductForm" stepKey="saveProduct1"/>
80+
<see userInput="SKU for product $$createSecondProduct.name$$ has been changed to $$createFirstProduct.sku$$-1." stepKey="seeSkuChangedMessage"/>
81+
</test>
82+
</tests>

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
</actionGroup>
6666
<deleteData createDataKey="category" stepKey="deletePreReqCategory"/>
6767
<deleteData createDataKey="product" stepKey="deleteFirstProduct"/>
68+
<magentoCLI stepKey="reindex" command="indexer:reindex"/>
69+
<magentoCLI stepKey="flushCache" command="cache:flush"/>
6870
<actionGroup ref="logout" stepKey="logout"/>
6971
</after>
7072

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
<test name="AdminTierPriceNotAvailableForProductOptionsWithoutTierPriceTest">
1212
<annotations>
1313
<features value="Catalog"/>
14-
<title value="Check that 'trie price' block not available for simple product from options without 'trie price'"/>
15-
<description value="Check that 'trie price' block not available for simple product from options without 'trie price'"/>
14+
<title value="Check that 'tier price' block not available for simple product from options without 'tier price'"/>
15+
<description value="Check that 'tier price' block not available for simple product from options without 'tier price'"/>
1616
<severity value="MAJOR"/>
1717
<testCaseId value="MAGETWO-97050"/>
1818
<useCaseId value="MAGETWO-96842"/>

0 commit comments

Comments
 (0)