Skip to content

Commit 47ad3ae

Browse files
committed
MC-35618: Unexpected results of editing a Grouped Product in the Wish List by a Customer
1 parent cb1719f commit 47ad3ae

File tree

7 files changed

+153
-9
lines changed

7 files changed

+153
-9
lines changed

app/code/Magento/GroupedProduct/Model/Wishlist/Product/Item.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Magento\GroupedProduct\Model\Wishlist\Product;
99

10+
use Magento\Catalog\Model\Product\Configuration\Item\Option\OptionInterface;
1011
use Magento\Wishlist\Model\Item as WishlistItem;
1112
use Magento\GroupedProduct\Model\Product\Type\Grouped as TypeGrouped;
1213
use Magento\Catalog\Model\Product;
@@ -36,7 +37,7 @@ public function beforeRepresentProduct(
3637

3738
$diff = array_diff_key($itemOptions, $productOptions);
3839

39-
if (!$diff) {
40+
if (!$diff && $this->isAddAction($productOptions['info_buyRequest'])) {
4041
$buyRequest = $subject->getBuyRequest();
4142
$superGroupInfo = $buyRequest->getData('super_group');
4243

@@ -78,10 +79,14 @@ public function beforeCompareOptions(
7879
array $options2
7980
): array {
8081
$diff = array_diff_key($options1, $options2);
82+
$productOptions = isset($options1['info_buyRequest']['product']) ? $options1 : $options2;
8183

8284
if (!$diff) {
8385
foreach (array_keys($options1) as $key) {
84-
if (preg_match('/associated_product_\d+/', $key)) {
86+
if (
87+
preg_match('/associated_product_\d+/', $key)
88+
&& $this->isAddAction($productOptions['info_buyRequest'])
89+
) {
8590
unset($options1[$key]);
8691
unset($options2[$key]);
8792
}
@@ -90,4 +95,18 @@ public function beforeCompareOptions(
9095

9196
return [$options1, $options2];
9297
}
98+
99+
/**
100+
* Check that current request belongs to add to wishlist action.
101+
*
102+
* @param OptionInterface $buyRequest
103+
*
104+
* @return bool
105+
*/
106+
private function isAddAction(OptionInterface $buyRequest): bool
107+
{
108+
$requestValue = json_decode($buyRequest->getValue(), true);
109+
110+
return $requestValue['action'] === 'add';
111+
}
93112
}

app/code/Magento/GroupedProduct/Test/Unit/Model/Wishlist/Product/ItemTest.php

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,29 @@ public function testBeforeRepresentProduct()
115115
*/
116116
public function testBeforeCompareOptionsSameKeys()
117117
{
118-
$options1 = ['associated_product_34' => 3];
119-
$options2 = ['associated_product_34' => 2];
118+
$infoBuyRequestMock = $this->createPartialMock(
119+
\Magento\Catalog\Model\Product\Configuration\Item\Option::class,
120+
[
121+
'getValue',
122+
]
123+
);
124+
125+
$infoBuyRequestMock->expects($this->atLeastOnce())
126+
->method('getValue')
127+
->willReturn('{"product":"3","action":"add"}');
128+
$options1 = [
129+
'associated_product_34' => 3,
130+
'info_buyRequest' => $infoBuyRequestMock,
131+
];
132+
$options2 = [
133+
'associated_product_34' => 3,
134+
'info_buyRequest' => $infoBuyRequestMock,
135+
];
120136

121137
$res = $this->model->beforeCompareOptions($this->subjectMock, $options1, $options2);
122138

123-
$this->assertEquals([], $res[0]);
124-
$this->assertEquals([], $res[1]);
139+
$this->assertEquals(['info_buyRequest' => $infoBuyRequestMock], $res[0]);
140+
$this->assertEquals(['info_buyRequest' => $infoBuyRequestMock], $res[1]);
125141
}
126142

127143
/**
@@ -175,16 +191,26 @@ private function getProductAssocOption($initVal, $prodId)
175191
{
176192
$items = [];
177193

178-
$optionMock = $this->createPartialMock(
194+
$associatedProductMock = $this->createPartialMock(
195+
\Magento\Catalog\Model\Product\Configuration\Item\Option::class,
196+
[
197+
'getValue',
198+
]
199+
);
200+
$infoBuyRequestMock = $this->createPartialMock(
179201
\Magento\Catalog\Model\Product\Configuration\Item\Option::class,
180202
[
181203
'getValue',
182204
]
183205
);
184206

185-
$optionMock->expects($this->once())->method('getValue')->willReturn($initVal);
207+
$associatedProductMock->expects($this->once())->method('getValue')->willReturn($initVal);
208+
$infoBuyRequestMock->expects($this->once())
209+
->method('getValue')
210+
->willReturn('{"product":"'. $prodId . '","action":"add"}');
186211

187-
$items['associated_product_' . $prodId] = $optionMock;
212+
$items['associated_product_' . $prodId] = $associatedProductMock;
213+
$items['info_buyRequest'] = $infoBuyRequestMock;
188214

189215
return $items;
190216
}

app/code/Magento/Wishlist/Controller/Index/Add.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ public function execute()
112112

113113
try {
114114
$buyRequest = new \Magento\Framework\DataObject($requestParams);
115+
$buyRequest->setData('action', 'add');
115116

116117
$result = $wishlist->addNewItem($product, $buyRequest);
117118
if (is_string($result)) {

app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ public function execute()
104104
}
105105

106106
$buyRequest = new \Magento\Framework\DataObject($this->getRequest()->getParams());
107+
$buyRequest->setData('action', 'updateItem');
107108

108109
$wishlist->updateItem($id, $buyRequest)->save();
109110

dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/UpdateItemOptionsTest.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,33 @@ public function testUpdateItemNotSpecifyAsWishListItem(): void
153153
$this->assertRedirect($this->stringContains('wishlist/index/index/wishlist_id/'));
154154
}
155155

156+
/**
157+
* @magentoDataFixture Magento/Wishlist/_files/wishlist_with_grouped_product.php
158+
* @magentoDbIsolation disabled
159+
*
160+
* @return void
161+
*/
162+
public function testUpdateItemOptionsForGroupedProduct(): void
163+
{
164+
$this->customerSession->setCustomerId(1);
165+
$item = $this->getWishlistByCustomerId->getItemBySku(1, 'grouped');
166+
$this->assertNotNull($item);
167+
$params = [
168+
'id' => $item->getId(),
169+
'product' => $item->getProductId(),
170+
'super_group' => $this->performGroupedOption(),
171+
'qty' => 1,
172+
];
173+
$this->performUpdateWishListItemRequest($params);
174+
$message = sprintf("%s has been updated in your Wish List.", $item->getProduct()->getName());
175+
$this->assertSessionMessages($this->equalTo([(string)__($message)]), MessageInterface::TYPE_SUCCESS);
176+
$this->assertRedirect($this->stringContains('wishlist/index/index/wishlist_id/' . $item->getWishlistId()));
177+
$this->assertUpdatedItem(
178+
$this->getWishlistByCustomerId->getItemBySku(1, 'grouped'),
179+
$params
180+
);
181+
}
182+
156183
/**
157184
* Perform request update wish list item.
158185
*
@@ -195,4 +222,20 @@ private function performConfigurableOption(ProductInterface $product): array
195222

196223
return [$attributeId => $option['value_index']];
197224
}
225+
226+
/**
227+
* Perform group option to select.
228+
*
229+
* @return array
230+
*/
231+
private function performGroupedOption(): array
232+
{
233+
$simple1 = $this->productRepository->get('simple_11');
234+
$simple2 = $this->productRepository->get('simple_22');
235+
236+
return [
237+
$simple1->getId() => '3',
238+
$simple2->getId() => '3',
239+
];
240+
}
198241
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
use Magento\Catalog\Api\ProductRepositoryInterface;
9+
use Magento\Customer\Model\CustomerRegistry;
10+
use Magento\Framework\DataObject;
11+
use Magento\TestFramework\Helper\Bootstrap;
12+
use Magento\Wishlist\Model\WishlistFactory;
13+
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;
14+
15+
Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer.php');
16+
Resolver::getInstance()->requireDataFixture(
17+
'Magento/GroupedProduct/_files/product_grouped_with_simple.php'
18+
);
19+
20+
$objectManager = Bootstrap::getObjectManager();
21+
/** @var CustomerRegistry $customerRegistry */
22+
$customerRegistry = $objectManager->create(CustomerRegistry::class);
23+
$customer = $customerRegistry->retrieve(1);
24+
$wishlistFactory = $objectManager->get(WishlistFactory::class);
25+
$wishlist = $wishlistFactory->create();
26+
$wishlist->loadByCustomerId($customer->getId(), true);
27+
/** @var ProductRepositoryInterface $productRepository */
28+
$productRepository = $objectManager->create(ProductRepositoryInterface::class);
29+
$product = $productRepository->get('grouped');
30+
$simple1 = $productRepository->get('simple_11');
31+
$simple2 = $productRepository->get('simple_22');
32+
$buyRequest = new DataObject([
33+
'product' => $product->getId(),
34+
'super_group' =>
35+
[
36+
$simple1->getId() => '1',
37+
$simple2->getId() => '1',
38+
],
39+
'action' => 'add',
40+
]);
41+
$wishlist->addNewItem($product, $buyRequest);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;
9+
10+
Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer_rollback.php');
11+
Resolver::getInstance()->requireDataFixture(
12+
'Magento/GroupedProduct/_files/product_grouped_with_simple_rollback.php'
13+
);

0 commit comments

Comments
 (0)