Skip to content

Commit 8f4b448

Browse files
authored
ENGCOM-3391: #18979 - API: Bundle Product Option Repository Delete method removes incorrect option #19027
2 parents ada0912 + 040f565 commit 8f4b448

File tree

2 files changed

+76
-16
lines changed

2 files changed

+76
-16
lines changed

app/code/Magento/Bundle/Model/OptionRepository.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,18 @@ public function get($sku, $optionId)
106106

107107
$productLinks = $this->linkManagement->getChildren($product->getSku(), $optionId);
108108

109-
/** @var \Magento\Bundle\Api\Data\OptionInterface $option */
109+
/** @var \Magento\Bundle\Api\Data\OptionInterface $optionDataObject */
110110
$optionDataObject = $this->optionFactory->create();
111111
$this->dataObjectHelper->populateWithArray(
112112
$optionDataObject,
113113
$option->getData(),
114114
\Magento\Bundle\Api\Data\OptionInterface::class
115115
);
116-
$optionDataObject->setOptionId($option->getId())
117-
->setTitle($option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle())
118-
->setSku($product->getSku())
119-
->setProductLinks($productLinks);
116+
117+
$optionDataObject->setOptionId($option->getId());
118+
$optionDataObject->setTitle($option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle());
119+
$optionDataObject->setSku($product->getSku());
120+
$optionDataObject->setProductLinks($productLinks);
120121

121122
return $optionDataObject;
122123
}
@@ -160,10 +161,9 @@ public function delete(\Magento\Bundle\Api\Data\OptionInterface $option)
160161
*/
161162
public function deleteById($sku, $optionId)
162163
{
163-
$product = $this->getProduct($sku);
164-
$optionCollection = $this->type->getOptionsCollection($product);
165-
$optionCollection->setIdFilter($optionId);
166-
$hasBeenDeleted = $this->delete($optionCollection->getFirstItem());
164+
/** @var \Magento\Bundle\Api\Data\OptionInterface $option */
165+
$option = $this->get($sku, $optionId);
166+
$hasBeenDeleted = $this->delete($option);
167167

168168
return $hasBeenDeleted;
169169
}

app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Magento\Bundle\Test\Unit\Model;
99

1010
use Magento\Bundle\Model\OptionRepository;
11+
use Magento\Framework\Exception\NoSuchEntityException;
1112

1213
/**
1314
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -84,7 +85,7 @@ protected function setUp()
8485
->getMock();
8586
$this->optionResourceMock = $this->createPartialMock(
8687
\Magento\Bundle\Model\ResourceModel\Option::class,
87-
['delete', '__wakeup', 'save', 'removeOptionSelections']
88+
['get', 'delete', '__wakeup', 'save', 'removeOptionSelections']
8889
);
8990
$this->storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
9091
$this->linkManagementMock = $this->createMock(\Magento\Bundle\Api\ProductLinkManagementInterface::class);
@@ -227,32 +228,91 @@ public function testDeleteThrowsExceptionIfCannotDelete()
227228
$this->model->delete($optionMock);
228229
}
229230

231+
/**
232+
* Test successful delete action for given $optionId
233+
*/
230234
public function testDeleteById()
231235
{
232236
$productSku = 'sku';
233237
$optionId = 100;
234-
$productMock = $this->createMock(\Magento\Catalog\Api\Data\ProductInterface::class);
238+
239+
$optionMock = $this->createMock(\Magento\Bundle\Model\Option::class);
240+
$optionMock->expects($this->exactly(2))
241+
->method('getId')
242+
->willReturn($optionId);
243+
244+
$optionMock->expects($this->once())
245+
->method('getData')
246+
->willReturn([
247+
'title' => 'Option title',
248+
'option_id' => $optionId
249+
]);
250+
251+
$this->optionFactoryMock->expects($this->once())
252+
->method('create')
253+
->willReturn($optionMock);
254+
255+
$productMock = $this->createPartialMock(
256+
\Magento\Catalog\Model\Product::class,
257+
['getTypeId', 'getTypeInstance', 'getStoreId', 'getPriceType', '__wakeup', 'getSku']
258+
);
235259
$productMock->expects($this->once())
236260
->method('getTypeId')
237261
->willReturn(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE);
238-
$this->productRepositoryMock->expects($this->once())
262+
$productMock->expects($this->exactly(2))->method('getSku')->willReturn($productSku);
263+
264+
$this->productRepositoryMock
265+
->expects($this->once())
239266
->method('get')
240267
->with($productSku)
241268
->willReturn($productMock);
242269

270+
$optCollectionMock = $this->createMock(\Magento\Bundle\Model\ResourceModel\Option\Collection::class);
271+
$optCollectionMock->expects($this->once())->method('getItemById')->with($optionId)->willReturn($optionMock);
272+
$this->typeMock->expects($this->once())
273+
->method('getOptionsCollection')
274+
->with($productMock)
275+
->willReturn($optCollectionMock);
276+
277+
$this->assertTrue($this->model->deleteById($productSku, $optionId));
278+
}
279+
280+
/**
281+
* Tests if NoSuchEntityException thrown when provided $optionId not found
282+
*/
283+
public function testDeleteByIdException() {
284+
$productSku = 'sku';
285+
$optionId = null;
286+
243287
$optionMock = $this->createMock(\Magento\Bundle\Model\Option::class);
288+
$optionMock->expects($this->exactly(1))
289+
->method('getId')
290+
->willReturn($optionId);
291+
292+
$productMock = $this->createPartialMock(
293+
\Magento\Catalog\Model\Product::class,
294+
['getTypeId', 'getTypeInstance', 'getStoreId', 'getPriceType', '__wakeup', 'getSku']
295+
);
296+
$productMock->expects($this->once())
297+
->method('getTypeId')
298+
->willReturn(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE);
299+
300+
$this->productRepositoryMock
301+
->expects($this->once())
302+
->method('get')
303+
->with($productSku)
304+
->willReturn($productMock);
244305

245306
$optCollectionMock = $this->createMock(\Magento\Bundle\Model\ResourceModel\Option\Collection::class);
307+
$optCollectionMock->expects($this->once())->method('getItemById')->with($optionId)->willReturn($optionMock);
246308
$this->typeMock->expects($this->once())
247309
->method('getOptionsCollection')
248310
->with($productMock)
249311
->willReturn($optCollectionMock);
250312

251-
$optCollectionMock->expects($this->once())->method('setIdFilter')->with($optionId)->willReturnSelf();
252-
$optCollectionMock->expects($this->once())->method('getFirstItem')->willReturn($optionMock);
313+
$this->expectException(NoSuchEntityException::class);
253314

254-
$this->optionResourceMock->expects($this->once())->method('delete')->with($optionMock)->willReturnSelf();
255-
$this->assertTrue($this->model->deleteById($productSku, $optionId));
315+
$this->model->deleteById($productSku, $optionId);
256316
}
257317

258318
/**

0 commit comments

Comments
 (0)