Skip to content

Commit 1061a2f

Browse files
committed
Merge branch 'MC-41758' of https://github.com/magento-l3/magento2ce into PR-20210423
2 parents dfaf4a0 + 69b55cb commit 1061a2f

File tree

3 files changed

+65
-19
lines changed

3 files changed

+65
-19
lines changed

app/code/Magento/Catalog/Model/Product/Option/Repository.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ public function save(\Magento\Catalog\Api\Data\ProductCustomOptionInterface $opt
158158
$option->setData('product_id', $product->getData($metadata->getLinkField()));
159159
$option->setData('store_id', $product->getStoreId());
160160

161+
$backedOptions = $option->getValues();
161162
if ($option->getOptionId()) {
162163
$options = $product->getOptions();
163164
if (!$options) {
@@ -174,6 +175,9 @@ public function save(\Magento\Catalog\Api\Data\ProductCustomOptionInterface $opt
174175
}
175176
$originalValues = $persistedOption->getValues();
176177
$newValues = $option->getData('values');
178+
if (!$newValues) {
179+
$newValues = $this->getOptionValues($option);
180+
}
177181
if ($newValues) {
178182
if (isset($originalValues)) {
179183
$newValues = $this->markRemovedValues($newValues, $originalValues);
@@ -182,6 +186,8 @@ public function save(\Magento\Catalog\Api\Data\ProductCustomOptionInterface $opt
182186
}
183187
}
184188
$option->save();
189+
// Required for API response data consistency
190+
$option->setValues($backedOptions);
185191
return $option;
186192
}
187193

@@ -249,4 +255,28 @@ private function getHydratorPool()
249255
}
250256
return $this->hydratorPool;
251257
}
258+
259+
/**
260+
* Get Option values from property
261+
*
262+
* Gets Option values stored in property, modifies for needed format and clears the property
263+
*
264+
* @param \Magento\Catalog\Api\Data\ProductCustomOptionInterface $option
265+
* @return array|null
266+
*/
267+
private function getOptionValues(\Magento\Catalog\Api\Data\ProductCustomOptionInterface $option): ?array
268+
{
269+
if ($option->getValues() === null) {
270+
return null;
271+
}
272+
273+
$optionValues = [];
274+
275+
foreach ($option->getValues() as $optionValue) {
276+
$optionValues[] = $optionValue->getData();
277+
}
278+
$option->setValues(null);
279+
280+
return $optionValues;
281+
}
252282
}

app/code/Magento/Catalog/Test/Unit/Model/Product/Option/RepositoryTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ public function testSave()
262262
->getMock();
263263
$optionCollection->expects($this->once())->method('getProductOptions')->willReturn([$this->optionMock]);
264264
$this->optionCollectionFactory->expects($this->once())->method('create')->willReturn($optionCollection);
265-
$this->optionMock->expects($this->once())->method('getValues')->willReturn([
265+
$this->optionMock->expects($this->exactly(2))->method('getValues')->willReturn([
266266
$originalValue1,
267267
$originalValue2,
268268
$originalValue3
@@ -291,7 +291,7 @@ public function testSaveWhenOptionTypeWasChanged()
291291
->getMock();
292292
$optionCollection->expects($this->once())->method('getProductOptions')->willReturn([$this->optionMock]);
293293
$this->optionCollectionFactory->expects($this->once())->method('create')->willReturn($optionCollection);
294-
$this->optionMock->expects($this->once())->method('getValues')->willReturn(null);
294+
$this->optionMock->expects($this->exactly(2))->method('getValues')->willReturn(null);
295295
$this->assertEquals($this->optionMock, $this->optionRepository->save($this->optionMock));
296296
}
297297
}

dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -301,13 +301,15 @@ public function testUpdate()
301301

302302
/**
303303
* @param string $optionType
304-
*
304+
* @param bool $includedExisting
305+
* @param int $expectedOptionValuesCount
306+
* @throws \Magento\Framework\Exception\NoSuchEntityException
305307
* @magentoApiDataFixture Magento/Catalog/_files/product_with_options.php
306308
* @magentoAppIsolation enabled
307309
* @dataProvider validOptionDataProvider
308310
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
309311
*/
310-
public function testUpdateOptionAddingNewValue($optionType)
312+
public function testUpdateOptionAddingNewValue($optionType, $includedExisting, $expectedOptionValuesCount)
311313
{
312314
$fixtureOption = null;
313315
$valueData = [
@@ -334,17 +336,21 @@ public function testUpdateOptionAddingNewValue($optionType)
334336
}
335337

336338
$values = [];
337-
foreach ($option->getValues() as $key => $value) {
338-
$values[] =
339-
[
340-
'price' => $value->getPrice(),
341-
'price_type' => $value->getPriceType(),
342-
'sku' => $value->getSku(),
343-
'title' => $value->getTitle(),
344-
'sort_order' => $value->getSortOrder(),
345-
];
346-
}
347339
$values[] = $valueData;
340+
// Keeps the existing Option Values when adding a new Option Value
341+
if ($includedExisting) {
342+
foreach ($option->getValues() as $key => $value) {
343+
$values[] =
344+
[
345+
'price' => $value->getPrice(),
346+
'price_type' => $value->getPriceType(),
347+
'sku' => $value->getSku(),
348+
'title' => $value->getTitle(),
349+
'sort_order' => $value->getSortOrder(),
350+
];
351+
}
352+
}
353+
348354
$data = [
349355
'product_sku' => $option->getProductSku(),
350356
'title' => $option->getTitle(),
@@ -375,21 +381,31 @@ public function testUpdateOptionAddingNewValue($optionType)
375381
$valueObject = $this->_webApiCall($serviceInfo, ['option' => $data]);
376382
}
377383

378-
$values = end($valueObject['values']);
384+
$values = reset($valueObject['values']);
379385
$this->assertEquals($valueData['price'], $values['price']);
380386
$this->assertEquals($valueData['price_type'], $values['price_type']);
381387
$this->assertEquals($valueData['sku'], $values['sku']);
382388
$this->assertEquals('New Option Title', $values['title']);
383389
$this->assertEquals(100, $values['sort_order']);
390+
391+
$product = $productRepository->get('simple', false, null, true);
392+
// Assert correct number of Option Values after Option is updated
393+
foreach ($product->getOptions() as $option) {
394+
if ($option->getId() === $fixtureOption->getId()) {
395+
$this->assertEquals($expectedOptionValuesCount, count($option->getValues()));
396+
}
397+
}
384398
}
385399

386400
public function validOptionDataProvider()
387401
{
388402
return [
389-
'drop_down' => ['drop_down'],
390-
'checkbox' => ['checkbox'],
391-
'radio' => ['radio'],
392-
'multiple' => ['multiple']
403+
'drop_down including previous values' => ['drop_down', true, 3],
404+
'drop_down with new value only' => ['drop_down', false, 1],
405+
'checkbox including previous values' => ['checkbox', true, 3],
406+
'checkbox with new value only' => ['checkbox', false, 1],
407+
'radio including previous values' => ['radio', true, 3],
408+
'multiple with new value only' => ['multiple', false, 1],
393409
];
394410
}
395411

0 commit comments

Comments
 (0)