Skip to content

Commit de9332c

Browse files
authored
Merge pull request #5934 from magento-tsg/2.4-develop-pr67
[TSG] Fixes for 2.4 (pr67) (2.4-develop)
2 parents 48d7868 + 60282bf commit de9332c

File tree

8 files changed

+212
-34
lines changed

8 files changed

+212
-34
lines changed

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

Lines changed: 20 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,13 @@ 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 (preg_match('/associated_product_\d+/', $key)
87+
&& $this->isAddAction($productOptions['info_buyRequest'])
88+
) {
8589
unset($options1[$key]);
8690
unset($options2[$key]);
8791
}
@@ -90,4 +94,18 @@ public function beforeCompareOptions(
9094

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

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/Model/Wishlist.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,9 @@ public function addNewItem($product, $buyRequest = null, $forciblySetQty = false
492492
} else {
493493
$_buyRequest = new DataObject();
494494
}
495+
if ($_buyRequest->getData('action') !== 'updateItem') {
496+
$_buyRequest->setData('action', 'add');
497+
}
495498

496499
/* @var $product Product */
497500
$cartCandidates = $product->getTypeInstance()->processConfiguration($_buyRequest, clone $product);
@@ -750,15 +753,16 @@ public function updateItem($itemId, $buyRequest, $params = null)
750753
}
751754
$params->setCurrentConfig($item->getBuyRequest());
752755
$buyRequest = $this->_catalogProduct->addParamsToBuyRequest($buyRequest, $params);
756+
$buyRequest->setData('action', 'updateItem');
753757

754758
$product->setWishlistStoreId($item->getStoreId());
755759
$items = $this->getItemCollection();
756760
$isForceSetQuantity = true;
757-
foreach ($items as $_item) {
758-
/* @var $_item Item */
759-
if ($_item->getProductId() == $product->getId() && $_item->representProduct(
760-
$product
761-
) && $_item->getId() != $item->getId()
761+
foreach ($items as $wishlistItem) {
762+
/* @var $wishlistItem Item */
763+
if ($wishlistItem->getProductId() == $product->getId()
764+
&& $wishlistItem->getId() != $item->getId()
765+
&& $wishlistItem->representProduct($product)
762766
) {
763767
// We do not add new wishlist item, but updating the existing one
764768
$isForceSetQuantity = false;

app/code/Magento/Wishlist/Test/Unit/Model/WishlistTest.php

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -243,34 +243,22 @@ public function testLoadByCustomerId()
243243

244244
/**
245245
* @param int|Item|MockObject $itemId
246-
* @param DataObject $buyRequest
246+
* @param DataObject|MockObject $buyRequest
247247
* @param null|array|DataObject $param
248248
* @throws LocalizedException
249249
*
250250
* @dataProvider updateItemDataProvider
251251
*/
252-
public function testUpdateItem($itemId, $buyRequest, $param)
252+
public function testUpdateItem($itemId, $buyRequest, $param): void
253253
{
254254
$storeId = 1;
255255
$productId = 1;
256256
$stores = [(new DataObject())->setId($storeId)];
257257

258-
$newItem = $this->getMockBuilder(Item::class)
259-
->setMethods(
260-
['setProductId', 'setWishlistId', 'setStoreId', 'setOptions', 'setProduct', 'setQty', 'getItem', 'save']
261-
)
262-
->disableOriginalConstructor()
263-
->getMock();
264-
$newItem->expects($this->any())->method('setProductId')->willReturnSelf();
265-
$newItem->expects($this->any())->method('setWishlistId')->willReturnSelf();
266-
$newItem->expects($this->any())->method('setStoreId')->willReturnSelf();
267-
$newItem->expects($this->any())->method('setOptions')->willReturnSelf();
268-
$newItem->expects($this->any())->method('setProduct')->willReturnSelf();
269-
$newItem->expects($this->any())->method('setQty')->willReturnSelf();
270-
$newItem->expects($this->any())->method('getItem')->willReturn(2);
271-
$newItem->expects($this->any())->method('save')->willReturnSelf();
258+
$newItem = $this->prepareWishlistItem();
272259

273260
$this->itemFactory->expects($this->once())->method('create')->willReturn($newItem);
261+
$this->productHelper->expects($this->once())->method('addParamsToBuyRequest')->willReturn($buyRequest);
274262

275263
$this->storeManager->expects($this->any())->method('getStores')->willReturn($stores);
276264
$this->storeManager->expects($this->any())->method('getStore')->willReturn($stores[0]);
@@ -355,13 +343,48 @@ public function testUpdateItem($itemId, $buyRequest, $param)
355343
);
356344
}
357345

346+
/**
347+
* Prepare wishlist item mock.
348+
*
349+
* @return MockObject
350+
*/
351+
private function prepareWishlistItem(): MockObject
352+
{
353+
$newItem = $this->getMockBuilder(Item::class)
354+
->setMethods(
355+
['setProductId', 'setWishlistId', 'setStoreId', 'setOptions', 'setProduct', 'setQty', 'getItem', 'save']
356+
)
357+
->disableOriginalConstructor()
358+
->getMock();
359+
$newItem->expects($this->any())->method('setProductId')->willReturnSelf();
360+
$newItem->expects($this->any())->method('setWishlistId')->willReturnSelf();
361+
$newItem->expects($this->any())->method('setStoreId')->willReturnSelf();
362+
$newItem->expects($this->any())->method('setOptions')->willReturnSelf();
363+
$newItem->expects($this->any())->method('setProduct')->willReturnSelf();
364+
$newItem->expects($this->any())->method('setQty')->willReturnSelf();
365+
$newItem->expects($this->any())->method('getItem')->willReturn(2);
366+
$newItem->expects($this->any())->method('save')->willReturnSelf();
367+
368+
return $newItem;
369+
}
370+
358371
/**
359372
* @return array
360373
*/
361-
public function updateItemDataProvider()
374+
public function updateItemDataProvider(): array
362375
{
376+
$dataObjectMock = $this->createMock(DataObject::class);
377+
$dataObjectMock->expects($this->once())
378+
->method('setData')
379+
->with('action', 'updateItem')
380+
->willReturnSelf();
381+
$dataObjectMock->expects($this->once())
382+
->method('getData')
383+
->with('action')
384+
->willReturn('updateItem');
385+
363386
return [
364-
'0' => [1, new DataObject(), null]
387+
'0' => [1, $dataObjectMock, null]
365388
];
366389
}
367390

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
}

dev/tests/integration/testsuite/Magento/Wishlist/Model/WishlistTest.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,12 @@ public function testAddConfigurableProductToWishList(): void
143143
$configurableOptions = $configurableProduct->getTypeInstance()->getConfigurableOptions($configurableProduct);
144144
$attributeId = key($configurableOptions);
145145
$option = reset($configurableOptions[$attributeId]);
146-
$buyRequest = ['super_attribute' => [$attributeId => $option['value_index']]];
146+
$buyRequest = [
147+
'super_attribute' => [
148+
$attributeId => $option['value_index']
149+
],
150+
'action' => 'add',
151+
];
147152
$wishlist = $this->getWishlistByCustomerId->execute(1);
148153
$wishlist->addNewItem($configurableProduct, $buyRequest);
149154
$item = $this->getWishlistByCustomerId->getItemBySku(1, 'Configurable product');
@@ -166,7 +171,12 @@ public function testAddBundleProductToWishList(): void
166171
$option = reset($bundleOptions);
167172
$productLinks = $option->getProductLinks();
168173
$this->assertNotNull($productLinks[0]);
169-
$buyRequest = ['bundle_option' => [$option->getOptionId() => $productLinks[0]->getId()]];
174+
$buyRequest = [
175+
'bundle_option' => [
176+
$option->getOptionId() => $productLinks[0]->getId()
177+
],
178+
'action' => 'add',
179+
];
170180
$skuWithChosenOption = implode('-', [$bundleProduct->getSku(), $productLinks[0]->getSku()]);
171181
$wishlist = $this->getWishlistByCustomerId->execute(1);
172182
$wishlist->addNewItem($bundleProduct, $buyRequest);
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->get(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->get(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)