Skip to content

Commit 3b5fce7

Browse files
committed
Merge branch '2.4-develop' into foxes-pr
2 parents 8f5e798 + 0d3d7bb commit 3b5fce7

File tree

9 files changed

+529
-25
lines changed

9 files changed

+529
-25
lines changed

app/code/Magento/Downloadable/view/frontend/web/js/downloadable.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,19 @@ define([
1717
*/
1818
$.widget('mage.downloadable', {
1919
options: {
20-
priceHolderSelector: '.price-box'
20+
priceHolderSelector: '.price-box',
21+
linkElement: '',
22+
allElements: ''
23+
},
24+
25+
/**
26+
* @inheritdoc
27+
*/
28+
_init: function initLinks() {
29+
var element = this.element,
30+
options = $(this.options.linkElement, element);
31+
32+
options.trigger('change');
2133
},
2234

2335
/**

app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminEnhancedMediaGalleryDeletedAllImagesActionGroup.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<amOnPage url="{{AdminStandaloneMediaGalleryPage.url}}" stepKey="openMediaGalleryPage"/>
1313
<!-- It sometimes is loading too long for default 10s -->
1414
<waitForPageLoad time="60" stepKey="waitForPageFullyLoaded"/>
15-
<conditionalClick selector="{{AdminEnhancedMediaGalleryFiltersSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFilters"/>
15+
<conditionalClick selector="{{AdminEnhancedMediaGalleryFiltersSection.clearFilters}}" dependentSelector="{{AdminEnhancedMediaGalleryFiltersSection.clearFilters}}" visible="true" stepKey="clearExistingFilters"/>
1616
<helper class="\Magento\MediaGalleryUi\Test\Mftf\Helper\MediaGalleryUiHelper" method="deleteAllImagesUsingMassAction" stepKey="deleteAllImagesUsingMassAction">
1717
<argument name="emptyRow">{{AdminMediaGalleryGridSection.noDataMessage}}</argument>
1818
<argument name="deleteImagesButton">{{AdminEnhancedMediaGalleryMassActionSection.deleteImages}}</argument>
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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="StorefrontAddBundleProductWithOptionToWishlistTest">
12+
<annotations>
13+
<stories value="Wishlist"/>
14+
<title value="Add Dynamic Bundle Product with selected option to Wishlist"/>
15+
<description value="Add Dynamic Bundle Product with selected option to Wishlist on Frontend"/>
16+
<severity value="MAJOR"/>
17+
<testCaseId value="MC-40586"/>
18+
<group value="wishlist"/>
19+
</annotations>
20+
<before>
21+
<createData entity="Simple_US_Customer" stepKey="createCustomer"/>
22+
<createData entity="_defaultCategory" stepKey="createCategory"/>
23+
<createData entity="SimpleProduct2" stepKey="simpleProduct1">
24+
<field key="price">100.00</field>
25+
</createData>
26+
<createData entity="SimpleProduct2" stepKey="simpleProduct2">
27+
<field key="price">20.00</field>
28+
</createData>
29+
<createData entity="ApiBundleProductPriceViewRange" stepKey="createBundleProduct">
30+
<requiredEntity createDataKey="createCategory"/>
31+
</createData>
32+
<createData entity="DropDownBundleOption" stepKey="createBundleOption">
33+
<requiredEntity createDataKey="createBundleProduct"/>
34+
</createData>
35+
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct">
36+
<requiredEntity createDataKey="createBundleProduct"/>
37+
<requiredEntity createDataKey="createBundleOption"/>
38+
<requiredEntity createDataKey="simpleProduct1"/>
39+
</createData>
40+
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct2">
41+
<requiredEntity createDataKey="createBundleProduct"/>
42+
<requiredEntity createDataKey="createBundleOption"/>
43+
<requiredEntity createDataKey="simpleProduct2"/>
44+
</createData>
45+
<actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex">
46+
<argument name="indices" value="cataloginventory_stock catalog_product_price"/>
47+
</actionGroup>
48+
</before>
49+
<after>
50+
<deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/>
51+
<deleteData createDataKey="createCategory" stepKey="deleteCategory"/>
52+
<deleteData createDataKey="createBundleProduct" stepKey="deleteBundleProduct"/>
53+
<deleteData createDataKey="simpleProduct1" stepKey="deleteProduct1"/>
54+
<deleteData createDataKey="simpleProduct2" stepKey="deleteProduct2"/>
55+
</after>
56+
57+
<actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefrontAccount">
58+
<argument name="Customer" value="$$createCustomer$$"/>
59+
</actionGroup>
60+
<actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="openProductFromCategory">
61+
<argument name="productUrlKey" value="$$createBundleProduct.custom_attributes[url_key]$$"/>
62+
</actionGroup>
63+
<actionGroup ref="StorefrontSelectCustomizeAndAddToTheCartButtonActionGroup" stepKey="clickCustomizeButton"/>
64+
<selectOption selector="{{StorefrontBundledSection.dropDownOptionOneProducts($$createBundleOption.title$$)}}" userInput="$$simpleProduct1.sku$$ +$100.00" stepKey="selectOption"/>
65+
<actionGroup ref="StorefrontCustomerAddProductToWishlistActionGroup" stepKey="addBundleProductWithOptionToWishlist">
66+
<argument name="productVar" value="$$createBundleProduct$$"/>
67+
</actionGroup>
68+
<actionGroup ref="AssertProductIsPresentInWishListActionGroup" stepKey="assertProductWithOptionInWishList">
69+
<argument name="productName" value="$$createBundleProduct.name$$"/>
70+
<argument name="productPrice" value="$100"/>
71+
</actionGroup>
72+
</test>
73+
</tests>

app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,22 @@ define([
118118
buttons = this._getAddToWishlistButton(event);
119119

120120
buttons.each(function (index, element) {
121-
var params = $(element).data('post');
121+
var params = $(element).data('post'),
122+
currentTarget = event.currentTarget,
123+
targetElement,
124+
targetValue;
122125

123126
if (!params) {
124127
params = {
125128
'data': {}
126129
};
130+
} else if ($(currentTarget).data('selector') || $(currentTarget).attr('name')) {
131+
targetElement = self._getElementData(currentTarget);
132+
targetValue = Object.keys(targetElement)[0];
133+
134+
if (params.data.hasOwnProperty(targetValue) && !dataToAdd.hasOwnProperty(targetValue)) {
135+
delete params.data[targetValue];
136+
}
127137
}
128138

129139
params.data = $.extend({}, params.data, dataToAdd, {
@@ -144,7 +154,7 @@ define([
144154
return productListWrapper.find(this.options.actionElement);
145155
}
146156

147-
return $(this.options.productPageWrapper).find(this.options.actionElement);
157+
return $(this.options.actionElement);
148158
},
149159

150160
/**

dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php

Lines changed: 107 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* Copyright © Magento, Inc. All rights reserved.
55
* See COPYING.txt for license details.
66
*/
7+
declare(strict_types=1);
8+
79
namespace Magento\ConfigurableProduct\Api;
810

911
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
@@ -43,8 +45,10 @@ protected function setUp(): void
4345

4446
/**
4547
* @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
48+
*
49+
* @return void
4650
*/
47-
public function testGetChildren()
51+
public function testGetChildren(): void
4852
{
4953
$productSku = 'configurable';
5054

@@ -72,8 +76,10 @@ public function testGetChildren()
7276
* @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
7377
* @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_simple_77.php
7478
* @magentoApiDataFixture Magento/ConfigurableProduct/_files/delete_association.php
79+
*
80+
* @return void
7581
*/
76-
public function testAddChild()
82+
public function testAddChild(): void
7783
{
7884
$productSku = 'configurable';
7985
$childSku = 'simple_77';
@@ -85,8 +91,10 @@ public function testAddChild()
8591
* Test the full flow of creating a configurable product and adding a child via REST
8692
*
8793
* @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_attribute.php
94+
*
95+
* @return void
8896
*/
89-
public function testAddChildFullRestCreation()
97+
public function testAddChildFullRestCreation(): void
9098
{
9199
$productSku = 'configurable-product-sku';
92100
$childSku = 'simple-product-sku';
@@ -96,7 +104,7 @@ public function testAddChildFullRestCreation()
96104

97105
$this->addOptionToConfigurableProduct(
98106
$productSku,
99-
$attribute->getAttributeId(),
107+
(int)$attribute->getAttributeId(),
100108
[
101109
[
102110
'value_index' => $attribute->getOptions()[1]->getValue()
@@ -139,8 +147,10 @@ public function testAddChildFullRestCreation()
139147
* configurable product.
140148
*
141149
* @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_attributes_for_position_test.php
150+
*
151+
* @return void
142152
*/
143-
public function testConfigurableOptionPositionPreservation()
153+
public function testConfigurableOptionPositionPreservation(): void
144154
{
145155
$productSku = 'configurable-product-sku';
146156
$childProductSkus = [
@@ -160,19 +170,19 @@ public function testConfigurableOptionPositionPreservation()
160170
/** @var Attribute $attribute */
161171
$attribute = $this->attributeRepository->get('catalog_product', $attributeToAdd);
162172

163-
/** @var Option $options[] */
173+
/** @var Option $options [] */
164174
$options = $attribute->getOptions();
165175
array_shift($options);
166176

167177
$attributeOptions[$attributeToAdd] = $options;
168178

169179
$valueIndexesData = [];
170180
foreach ($options as $option) {
171-
$valueIndexesData []['value_index']= $option->getValue();
181+
$valueIndexesData[]['value_index'] = $option->getValue();
172182
}
173183
$this->addOptionToConfigurableProduct(
174184
$productSku,
175-
$attribute->getAttributeId(),
185+
(int)$attribute->getAttributeId(),
176186
$valueIndexesData,
177187
$position
178188
);
@@ -284,7 +294,14 @@ protected function getConfigurableAttribute(string $productSku): array
284294
return $this->_webApiCall($serviceInfo, ['sku' => $productSku]);
285295
}
286296

287-
private function addChild($productSku, $childSku)
297+
/**
298+
* Perform add child product Api call
299+
*
300+
* @param string $productSku
301+
* @param string $childSku
302+
* @return array|int|string|float|bool
303+
*/
304+
private function addChild(string $productSku, string $childSku)
288305
{
289306
$serviceInfo = [
290307
'rest' => [
@@ -300,7 +317,13 @@ private function addChild($productSku, $childSku)
300317
return $this->_webApiCall($serviceInfo, ['sku' => $productSku, 'childSku' => $childSku]);
301318
}
302319

303-
protected function createConfigurableProduct($productSku)
320+
/**
321+
* Perform create configurable product api call
322+
*
323+
* @param string $productSku
324+
* @return array|bool|float|int|string
325+
*/
326+
protected function createConfigurableProduct(string $productSku)
304327
{
305328
$requestData = [
306329
'product' => [
@@ -325,8 +348,21 @@ protected function createConfigurableProduct($productSku)
325348
return $this->_webApiCall($serviceInfo, $requestData);
326349
}
327350

328-
protected function addOptionToConfigurableProduct($productSku, $attributeId, $attributeValues, $position = 0)
329-
{
351+
/**
352+
* Add option to configurable product
353+
*
354+
* @param string $productSku
355+
* @param int $attributeId
356+
* @param array $attributeValues
357+
* @param int $position
358+
* @return array|bool|float|int|string
359+
*/
360+
protected function addOptionToConfigurableProduct(
361+
string $productSku,
362+
int $attributeId,
363+
array $attributeValues,
364+
int $position = 0
365+
) {
330366
$requestData = [
331367
'sku' => $productSku,
332368
'option' => [
@@ -339,7 +375,7 @@ protected function addOptionToConfigurableProduct($productSku, $attributeId, $at
339375
];
340376
$serviceInfo = [
341377
'rest' => [
342-
'resourcePath' => '/V1/configurable-products/'. $productSku .'/options',
378+
'resourcePath' => '/V1/configurable-products/' . $productSku . '/options',
343379
'httpMethod' => Request::HTTP_METHOD_POST,
344380
],
345381
'soap' => [
@@ -381,15 +417,67 @@ protected function createSimpleProduct($sku, $customAttributes)
381417

382418
/**
383419
* @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
420+
*
421+
* @return void
384422
*/
385-
public function testRemoveChild()
423+
public function testRemoveChild(): void
386424
{
387425
$productSku = 'configurable';
388426
$childSku = 'simple_10';
389427
$this->assertTrue($this->removeChild($productSku, $childSku));
390428
}
391429

392-
protected function removeChild($productSku, $childSku)
430+
/**
431+
* @dataProvider errorsDataProvider
432+
*
433+
* @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
434+
* @magentoApiDataFixture Magento/Catalog/_files/second_product_simple.php
435+
*
436+
* @param string $parentSku
437+
* @param string $childSku
438+
* @param string $errorMessage
439+
* @return void
440+
*/
441+
public function testAddChildWithError(string $parentSku, string $childSku, string $errorMessage): void
442+
{
443+
$this->expectException(\Exception::class);
444+
$this->expectExceptionMessage($errorMessage);
445+
$this->addChild($parentSku, $childSku);
446+
}
447+
448+
/**
449+
* @return array
450+
*/
451+
public function errorsDataProvider(): array
452+
{
453+
return [
454+
'simple_instead_of_configurable' => [
455+
'parent_sku' => 'simple2',
456+
'child_sku' => 'configurable',
457+
'error_message' => (string)__("The parent product doesn't have configurable product options."),
458+
],
459+
'simple_with_empty_configurable_attribute_value' => [
460+
'parent_sku' => 'configurable',
461+
'child_sku' => 'simple2',
462+
'error_message' => TESTS_WEB_API_ADAPTER === self::ADAPTER_SOAP
463+
? (string)__(
464+
'The child product doesn\'t have the "%1" attribute value. Verify the value and try again.'
465+
)
466+
: (string)__(
467+
'The child product doesn\'t have the \\"%1\\" attribute value. Verify the value and try again.'
468+
),
469+
],
470+
];
471+
}
472+
473+
/**
474+
* Remove child product
475+
*
476+
* @param string $productSku
477+
* @param string $childSku
478+
* @return array|bool|float|int|string
479+
*/
480+
protected function removeChild(string $productSku, string $childSku)
393481
{
394482
$resourcePath = self::RESOURCE_PATH . '/%s/children/%s';
395483
$serviceInfo = [
@@ -408,14 +496,16 @@ protected function removeChild($productSku, $childSku)
408496
}
409497

410498
/**
499+
* Get child products
500+
*
411501
* @param string $productSku
412502
* @return string[]
413503
*/
414-
protected function getChildren($productSku)
504+
protected function getChildren(string $productSku)
415505
{
416506
$serviceInfo = [
417507
'rest' => [
418-
'resourcePath' => self::RESOURCE_PATH . '/' . $productSku . '/children',
508+
'resourcePath' => self::RESOURCE_PATH . '/' . $productSku . '/children',
419509
'httpMethod' => Request::HTTP_METHOD_GET
420510
],
421511
'soap' => [

0 commit comments

Comments
 (0)