Skip to content

Commit bc13dc0

Browse files
authored
Merge branch '2.4-develop' into redis-session-compatible
2 parents 2b52116 + a2e0ef1 commit bc13dc0

File tree

98 files changed

+3140
-85
lines changed

Some content is hidden

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

98 files changed

+3140
-85
lines changed

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ trim_trailing_whitespace = false
1414
[*.{yml,yaml,json}]
1515
indent_size = 2
1616

17-
[{composer, auth}.json]
17+
[{composer,auth}.json]
1818
indent_size = 4
1919

2020
[db_schema_whitelist.json]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
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="StorefrontCheckPriceForDynamicBundleProductWithMixedDiscountsTest">
12+
<annotations>
13+
<features value="Bundle"/>
14+
<stories value="View bundle product"/>
15+
<title value="Check mixed discount prices for bundle product"/>
16+
<description value="The testcase purpose to verify mixed discount prices for bundle product on storefront"/>
17+
<testCaseId value="AC-4571"/>
18+
<severity value="MAJOR"/>
19+
</annotations>
20+
<before>
21+
<!-- create three categories-->
22+
<createData entity="_defaultCategory" stepKey="category1"/>
23+
<createData entity="_defaultCategory" stepKey="category2"/>
24+
<createData entity="_defaultCategory" stepKey="category3"/>
25+
<!-- login to backend -->
26+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
27+
<actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="clearExistingCatalogPriceRules"/>
28+
<!-- create two catalog rules for categories -->
29+
<!-- first catalog rule -->
30+
<actionGroup ref="AdminOpenNewCatalogPriceRuleFormPageActionGroup" stepKey="openNewCatalogPriceRulePage"/>
31+
<actionGroup ref="AdminCatalogPriceRuleFillMainInfoActionGroup" stepKey="fillMainInfoForCatalogPriceRule"/>
32+
<actionGroup ref="AdminFillCatalogRuleConditionActionGroup" stepKey="fillConditionsForCatalogPriceRule">
33+
<argument name="conditionValue" value="$category2.id$"/>
34+
</actionGroup>
35+
<actionGroup ref="AdminCatalogPriceRuleFillActionsActionGroup" stepKey="fillActionsForCatalogPriceRule">
36+
<argument name="apply" value="by_percent"/>
37+
<argument name="discountAmount" value="100"/>
38+
</actionGroup>
39+
<actionGroup ref="AdminCatalogPriceRuleSaveAndApplyActionGroup" stepKey="saveAndApplyFirstPriceRule"/>
40+
<!-- second catalog rule -->
41+
<actionGroup ref="AdminOpenNewCatalogPriceRuleFormPageActionGroup" stepKey="openAgainNewCatalogPriceRulePage"/>
42+
<actionGroup ref="AdminCatalogPriceRuleFillMainInfoActionGroup" stepKey="fillMainInfoForSecondCatalogPriceRule"/>
43+
<actionGroup ref="AdminFillCatalogRuleConditionActionGroup" stepKey="fillConditionsForSecondCatalogPriceRule">
44+
<argument name="conditionValue" value="$category3.id$"/>
45+
</actionGroup>
46+
<actionGroup ref="AdminCatalogPriceRuleFillActionsActionGroup" stepKey="fillActionsForSecondCatalogPriceRule">
47+
<argument name="apply" value="by_percent"/>
48+
<argument name="discountAmount" value="70"/>
49+
</actionGroup>
50+
<actionGroup ref="AdminCatalogPriceRuleSaveAndApplyActionGroup" stepKey="saveAndApplySecondPriceRule"/>
51+
<!-- create 6 simple products -->
52+
<!-- create first product -->
53+
<createData entity="_defaultProduct" stepKey="firstProduct">
54+
<field key="price">10.5</field>
55+
<field key="quantity">1000</field>
56+
<requiredEntity createDataKey="category1"/>
57+
</createData>
58+
<createData entity="tierPriceForSimpleProduct" stepKey="addTierPrice">
59+
<requiredEntity createDataKey="firstProduct"/>
60+
</createData>
61+
<!-- create second product -->
62+
<createData entity="SimpleProduct4" stepKey="secondProduct">
63+
<field key="price">15</field>
64+
<requiredEntity createDataKey="category2"/>
65+
</createData>
66+
<!-- create third product -->
67+
<createData entity="_defaultProduct" stepKey="thirdProduct">
68+
<field key="price">23.40</field>
69+
<field key="quantity">1000</field>
70+
<requiredEntity createDataKey="category1"/>
71+
</createData>
72+
<createData entity="specialProductPriceForProduct" stepKey="addSpecialPrice">
73+
<requiredEntity createDataKey="thirdProduct"/>
74+
</createData>
75+
<!-- create fourth product -->
76+
<createData entity="_defaultProduct" stepKey="fourthProduct">
77+
<field key="price">30</field>
78+
<field key="quantity">1000</field>
79+
<requiredEntity createDataKey="category3"/>
80+
</createData>
81+
<!-- create fifth product -->
82+
<createData entity="_defaultProduct" stepKey="fifthProduct">
83+
<field key="price">25</field>
84+
<field key="status">0</field>
85+
<field key="quantity">1000</field>
86+
<requiredEntity createDataKey="category1"/>
87+
</createData>
88+
<!-- create sixth product -->
89+
<createData entity="_defaultProduct" stepKey="sixthProduct">
90+
<field key="price">25</field>
91+
<field key="quantity">1000</field>
92+
<requiredEntity createDataKey="category1"/>
93+
</createData>
94+
<createData entity="specialProductPriceForSimpleProduct" stepKey="addSpecialPriceForSixthProduct">
95+
<requiredEntity createDataKey="sixthProduct"/>
96+
</createData>
97+
<!--Create Bundle product -->
98+
<createData entity="ApiBundleProductPriceViewRange" stepKey="createBundleProduct">
99+
<requiredEntity createDataKey="category1"/>
100+
</createData>
101+
<!-- Add options to the product -->
102+
<createData entity="MultipleSelectOption" stepKey="createBundleOption1_1">
103+
<requiredEntity createDataKey="createBundleProduct"/>
104+
<field key="required">false</field>
105+
</createData>
106+
<createData entity="DropDownBundleOption" stepKey="createBundleOption1_2">
107+
<requiredEntity createDataKey="createBundleProduct"/>
108+
<field key="required">false</field>
109+
</createData>
110+
<!-- add products to checkbox option -->
111+
<createData entity="ApiBundleLink" stepKey="linkOptionToFifthProduct">
112+
<requiredEntity createDataKey="createBundleProduct"/>
113+
<requiredEntity createDataKey="createBundleOption1_2"/>
114+
<requiredEntity createDataKey="fifthProduct"/>
115+
<field key="qty">1</field>
116+
</createData>
117+
<createData entity="ApiBundleLink" stepKey="linkOptionToFourthProduct">
118+
<requiredEntity createDataKey="createBundleProduct"/>
119+
<requiredEntity createDataKey="createBundleOption1_2"/>
120+
<requiredEntity createDataKey="fourthProduct"/>
121+
<field key="qty">3</field>
122+
</createData>
123+
<createData entity="ApiBundleLink" stepKey="linkOptionToSixthProduct">
124+
<requiredEntity createDataKey="createBundleProduct"/>
125+
<requiredEntity createDataKey="createBundleOption1_2"/>
126+
<requiredEntity createDataKey="sixthProduct"/>
127+
<field key="qty">1</field>
128+
</createData>
129+
<!-- add products to multiselect option -->
130+
<createData entity="ApiBundleLink" stepKey="linkOptionToSecondProduct">
131+
<requiredEntity createDataKey="createBundleProduct"/>
132+
<requiredEntity createDataKey="createBundleOption1_1"/>
133+
<requiredEntity createDataKey="secondProduct"/>
134+
<field key="qty">3</field>
135+
</createData>
136+
<createData entity="ApiBundleLink" stepKey="linkOptionToFirstProduct">
137+
<requiredEntity createDataKey="createBundleProduct"/>
138+
<requiredEntity createDataKey="createBundleOption1_1"/>
139+
<requiredEntity createDataKey="firstProduct"/>
140+
<field key="qty">2</field>
141+
</createData>
142+
<createData entity="ApiBundleLink" stepKey="linkOptionToThirdProduct">
143+
<requiredEntity createDataKey="createBundleProduct"/>
144+
<requiredEntity createDataKey="createBundleOption1_1"/>
145+
<requiredEntity createDataKey="thirdProduct"/>
146+
<field key="qty">1</field>
147+
</createData>
148+
<!-- Add advanced pricing to bundle product -->
149+
<actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="openProductForEdit">
150+
<argument name="productId" value="$createBundleProduct.id$"/>
151+
</actionGroup>
152+
<actionGroup ref="AdminBundleProductSetAdvancedPricingActionGroup" stepKey="addProductTierPrice">
153+
<argument name="quantity" value="1"/>
154+
<argument name="price" value="Discount"/>
155+
<argument name="amount" value="75"/>
156+
<argument name="priceView" value="Price Range"/>
157+
</actionGroup>
158+
<!-- Reindex invalidated indices after product attribute has been created/deleted -->
159+
<actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindexInvalidatedIndices">
160+
<argument name="indices" value="catalogsearch_fulltext catalog_category_product catalog_product_price catalogrule_rule"/>
161+
</actionGroup>
162+
<actionGroup ref="CliCacheCleanActionGroup" stepKey="cleanCache">
163+
<argument name="tags" value="full_page"/>
164+
</actionGroup>
165+
</before>
166+
<after>
167+
<!-- delete created data -->
168+
<deleteData createDataKey="firstProduct" stepKey="deleteFirstProduct"/>
169+
<deleteData createDataKey="secondProduct" stepKey="deleteSecondProduct"/>
170+
<deleteData createDataKey="thirdProduct" stepKey="deleteThirdProduct"/>
171+
<deleteData createDataKey="fourthProduct" stepKey="deleteFourthProduct"/>
172+
<deleteData createDataKey="fifthProduct" stepKey="deleteFifthProduct"/>
173+
<deleteData createDataKey="sixthProduct" stepKey="deleteSixthProduct"/>
174+
<deleteData createDataKey="createBundleProduct" stepKey="deleteBundleProduct"/>
175+
<actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteCatalogPriceRules"/>
176+
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
177+
</after>
178+
<!-- Go to storefront category page -->
179+
<!-- check product prices on category and product page -->
180+
<actionGroup ref="StorefrontNavigateCategoryPageActionGroup" stepKey="amOnCategoryPage">
181+
<argument name="category" value="$$category1$$"/>
182+
</actionGroup>
183+
<waitForText userInput="From $4.69 Regular Price $21.00" selector="{{StorefrontCategoryProductSection.priceFromByProductId($$createBundleProduct.id$$)}}" stepKey="seePriceFromInCategoryBundle"/>
184+
<waitForText userInput="To $16.44 Regular Price $134.40" selector="{{StorefrontCategoryProductSection.priceToByProductId($$createBundleProduct.id$$)}}" stepKey="seePriceToInCategoryBundle"/>
185+
<actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="openBundleProductPage">
186+
<argument name="productUrl" value="$$createBundleProduct.custom_attributes[url_key]$$"/>
187+
</actionGroup>
188+
<waitForElement selector="{{StorefrontProductInfoMainSection.priceFrom('From $4.69 Regular Price $21.00')}}" stepKey="seePriceFromBundle"/>
189+
<waitForElement selector="{{StorefrontProductInfoMainSection.priceTo('To $16.44 Regular Price $134.40')}}" stepKey="seePriceToBundle"/>
190+
</test>
191+
</tests>

app/code/Magento/Catalog/Block/Product/Widget/NewWidget.php

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\Catalog\Block\Product\Widget;
77

8+
use Magento\Framework\App\Http\Context as HttpContext;
9+
810
/**
911
* New products widget
1012
*/
@@ -13,29 +15,29 @@ class NewWidget extends \Magento\Catalog\Block\Product\NewProduct implements \Ma
1315
/**
1416
* Display products type - all products
1517
*/
16-
const DISPLAY_TYPE_ALL_PRODUCTS = 'all_products';
18+
public const DISPLAY_TYPE_ALL_PRODUCTS = 'all_products';
1719

1820
/**
1921
* Display products type - new products
2022
*/
21-
const DISPLAY_TYPE_NEW_PRODUCTS = 'new_products';
23+
public const DISPLAY_TYPE_NEW_PRODUCTS = 'new_products';
2224

2325
/**
2426
* Default value whether show pager or not
2527
*/
26-
const DEFAULT_SHOW_PAGER = false;
28+
public const DEFAULT_SHOW_PAGER = false;
2729

2830
/**
2931
* Default value for products per page
3032
*/
31-
const DEFAULT_PRODUCTS_PER_PAGE = 5;
33+
public const DEFAULT_PRODUCTS_PER_PAGE = 5;
3234

3335
/**
3436
* Name of request parameter for page number value
3537
*
3638
* @deprecated
3739
*/
38-
const PAGE_VAR_NAME = 'np';
40+
public const PAGE_VAR_NAME = 'np';
3941

4042
/**
4143
* Instance of pager block
@@ -134,13 +136,15 @@ public function getCurrentPage()
134136
*/
135137
public function getCacheKeyInfo()
136138
{
139+
$store = $this->_storeManager->getStore();
137140
return array_merge(
138141
parent::getCacheKeyInfo(),
139142
[
140143
$this->getDisplayType(),
141144
$this->getProductsPerPage(),
142145
(int) $this->getRequest()->getParam($this->getData('page_var_name'), 1),
143-
$this->serializer->serialize($this->getRequest()->getParams())
146+
$this->serializer->serialize($this->getRequest()->getParams()),
147+
$this->httpContext->getValue(HttpContext::CONTEXT_CURRENCY) ?: $store->getDefaultCurrency()->getCode()
144148
]
145149
);
146150
}
@@ -268,7 +272,7 @@ public function getProductPriceHtml(
268272
? $arguments['display_minimal_price']
269273
: true;
270274

271-
/** @var \Magento\Framework\Pricing\Render $priceRender */
275+
/** @var \Magento\Framework\Pricing\Render $priceRender */
272276
$priceRender = $this->getLayout()->getBlock('product.price.render.default');
273277

274278
$price = '';

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ public function get($sku, $editMode = false, $storeId = null, $forceReload = fal
307307
*/
308308
public function getById($productId, $editMode = false, $storeId = null, $forceReload = false)
309309
{
310-
$cacheKey = $this->getCacheKey([$editMode, $storeId]);
310+
$cacheKey = $this->getCacheKey([$editMode, $storeId === null ? $storeId : (int) $storeId]);
311311
if (!isset($this->instancesById[$productId][$cacheKey]) || $forceReload) {
312312
$product = $this->productFactory->create();
313313
if ($editMode) {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="ScrollToUpSellSectionAtStorefrontActionGroup">
12+
<annotations>
13+
<description>Admin scroll to upsell section on storefront preview page.</description>
14+
</annotations>
15+
<scrollTo selector="{{StorefrontProductUpSellProductsSection.upSellSection}}" stepKey="scrollToUpSellSection" />
16+
<waitForText selector="{{StorefrontProductUpSellProductsSection.upSellHeading}}" userInput="We found other products you might like!" stepKey="seeTheUpSellHeading"/>
17+
</actionGroup>
18+
</actionGroups>

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,14 @@
2323
<data key="store_id">0</data>
2424
<var key="sku" entityType="product" entityKey="sku" />
2525
</entity>
26+
<entity name="specialProductPriceForProduct" type="catalogSpecialPrice">
27+
<data key="price">18.77</data>
28+
<data key="store_id">0</data>
29+
<var key="sku" entityType="product" entityKey="sku" />
30+
</entity>
31+
<entity name="specialProductPriceForSimpleProduct" type="catalogSpecialPrice">
32+
<data key="price">19.99</data>
33+
<data key="store_id">0</data>
34+
<var key="sku" entityType="product" entityKey="sku" />
35+
</entity>
2636
</entities>

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,5 +465,15 @@
465465
<data key="frontend_input">price</data>
466466
<data key="used_for_sort_by">false</data>
467467
</entity>
468+
<entity name="productAttributeFPT" type="ProductAttribute">
469+
<data key="default_frontend_label">FPT</data>
470+
<data key="attribute_code">fpt</data>
471+
<data key="frontend_input">weee</data>
472+
<data key="scope">global</data>
473+
<data key="is_used_in_grid">true</data>
474+
<data key="is_visible_in_grid">true</data>
475+
<data key="is_filterable_in_grid">true</data>
476+
<requiredEntity type="FrontendLabel">ProductAttributeFrontendLabel</requiredEntity>
477+
</entity>
468478
</entities>
469479

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,12 @@
100100
<data key="customer_group">General</data>
101101
<data key="quantity">3</data>
102102
</entity>
103+
<entity name="tierPriceForSimpleProduct" type="catalogTierPrice">
104+
<data key="price">9.99</data>
105+
<data key="price_type">fixed</data>
106+
<data key="website_id">0</data>
107+
<data key="customer_group">ALL GROUPS</data>
108+
<data key="quantity">1</data>
109+
<var key="sku" entityType="product" entityKey="sku" />
110+
</entity>
103111
</entities>

app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection/AdminAddRelatedProductsModalSection.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010
<section name="AdminAddRelatedProductsModalSection">
1111
<element name="AddSelectedProductsButton" type="button" selector="//aside[contains(@class, 'related_modal')]//button[contains(@class, 'action-primary')]" timeout="30"/>
1212
<element name="AddUpSellProductsButton" type="button" selector="//aside[contains(@class, 'upsell_modal')]//button[contains(@class, 'action-primary')]" timeout="30"/>
13+
<element name="AddCrossSellProductsButton" type="button" selector="//aside[contains(@class, 'crosssell_modal')]//button[contains(@class, 'action-primary')]" timeout="30"/>
1314
</section>
1415
</sections>

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,7 @@
4141
<element name="storeViewOptions" type="text" selector=".admin__data-grid-outer-wrap select[name='store_id'] > option[value='{{value}}']" parameterized="true"/>
4242
<element name="viewColumnOptionName" type="text" selector="//div[contains(@class, '_active')]//div[contains(@class, 'admin__data-grid-action-columns-menu')]//div[@class='admin__field-option']//label[text()='{{col}}']" parameterized="true"/>
4343
<element name="customAttribute" type="text" selector="input.admin__control-text[name='{{var}}']" parameterized="true"/>
44+
<element name="crossSellFilters" type="button" selector="//*[contains(@class, 'crosssell_product')]//button[text()='Filters']"/>
45+
<element name="upSellFilters" type="button" selector="//*[contains(@class, 'upsell_product')]//button[text()='Filters']"/>
4446
</section>
4547
</sections>

0 commit comments

Comments
 (0)