Skip to content

Commit fa7f229

Browse files
committed
ACP2E-906: Bundle product option title is overwritten by API
1 parent cd826aa commit fa7f229

File tree

2 files changed

+75
-16
lines changed

2 files changed

+75
-16
lines changed

app/code/Magento/Bundle/Model/Option/SaveAction.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class SaveAction
5050
* @param Type $type
5151
* @param ProductLinkManagementInterface $linkManagement
5252
* @param StoreManagerInterface|null $storeManager
53+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
5354
*/
5455
public function __construct(
5556
Option $optionResource,
@@ -84,11 +85,10 @@ public function save(ProductInterface $bundleProduct, OptionInterface $option)
8485
$optionId = $option->getOptionId();
8586
$linksToAdd = [];
8687
$optionCollection = $this->type->getOptionsCollection($bundleProduct);
87-
$optionCollection->setIdFilter($option->getOptionId());
88-
$optionCollection->setProductLinkFilter($parentId);
8988

9089
/** @var \Magento\Bundle\Model\Option $existingOption */
91-
$existingOption = $optionCollection->getFirstItem();
90+
$existingOption = $optionCollection->getItemById($option->getOptionId())
91+
?? $optionCollection->getNewEmptyItem();
9292
if (!$optionId || $existingOption->getParentId() != $parentId) {
9393
//If option ID is empty or existing option's parent ID is different
9494
//we'd need a new ID for the option.

dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php

Lines changed: 72 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@
66

77
namespace Magento\Bundle\Api;
88

9+
use Magento\Bundle\Test\Fixture\Option as BundleOptionFixture;
10+
use Magento\Bundle\Test\Fixture\Product as BundleProductFixture;
911
use Magento\Catalog\Api\Data\ProductInterface;
12+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
1013
use Magento\Framework\Api\ExtensibleDataInterface;
14+
use Magento\Store\Test\Fixture\Store as StoreFixture;
15+
use Magento\TestFramework\Fixture\DataFixture;
16+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
1117
use Magento\TestFramework\Helper\Bootstrap;
1218
use Magento\TestFramework\TestCase\WebapiAbstract;
1319
use Magento\Bundle\Api\Data\LinkInterface;
@@ -17,31 +23,39 @@
1723
*/
1824
class ProductServiceTest extends WebapiAbstract
1925
{
20-
const SERVICE_NAME = 'catalogProductRepositoryV1';
21-
const SERVICE_VERSION = 'V1';
22-
const RESOURCE_PATH = '/V1/products';
23-
const BUNDLE_PRODUCT_ID = 'sku-test-product-bundle';
26+
private const SERVICE_NAME = 'catalogProductRepositoryV1';
27+
private const SERVICE_VERSION = 'V1';
28+
private const RESOURCE_PATH = '/V1/products';
29+
private const BUNDLE_PRODUCT_ID = 'sku-test-product-bundle';
2430

2531
/**
2632
* @var \Magento\Catalog\Model\ResourceModel\Product\Collection
2733
*/
2834
protected $productCollection;
2935

36+
/**
37+
* @var bool
38+
*/
39+
private $cleanUpOnTearDown = true;
40+
3041
/**
3142
* Execute per test initialization
3243
*/
3344
protected function setUp(): void
3445
{
3546
$objectManager = Bootstrap::getObjectManager();
3647
$this->productCollection = $objectManager->get(\Magento\Catalog\Model\ResourceModel\Product\Collection::class);
48+
$this->cleanUpOnTearDown = true;
3749
}
3850

3951
/**
4052
* Execute per test cleanup
4153
*/
4254
protected function tearDown(): void
4355
{
44-
$this->deleteProductBySku(self::BUNDLE_PRODUCT_ID);
56+
if ($this->cleanUpOnTearDown) {
57+
$this->deleteProductBySku(self::BUNDLE_PRODUCT_ID);
58+
}
4559
parent::tearDown();
4660
}
4761

@@ -269,7 +283,6 @@ public function testUpdateFixedPriceBundleProductOptionSelectionPrice()
269283
$bundleProduct = $this->createFixedPriceBundleProduct();
270284
$bundleProductOptions = $this->getBundleProductOptions($bundleProduct);
271285

272-
$oldOptionId = $bundleProductOptions[0]['option_id'];
273286
//replace current option with a new option
274287
$bundleProductOptions[0] = [
275288
'title' => 'new option',
@@ -295,6 +308,52 @@ public function testUpdateFixedPriceBundleProductOptionSelectionPrice()
295308
$this->assertEquals($optionPrice, $bundleOptions[0]['product_links'][0]['price']);
296309
}
297310

311+
#[
312+
DataFixture(StoreFixture::class, as: 'store2'),
313+
DataFixture(ProductFixture::class, ['price' => 10], 'p1'),
314+
DataFixture(ProductFixture::class, ['price' => 20], 'p2'),
315+
DataFixture(BundleOptionFixture::class, ['product_links' => ['$p1$']], 'opt1'),
316+
DataFixture(BundleOptionFixture::class, ['product_links' => ['$p2$']], 'opt2'),
317+
DataFixture(
318+
BundleProductFixture::class,
319+
['_options' => ['$opt1$', '$opt2$']],
320+
'bundle1'
321+
),
322+
]
323+
324+
public function testUpdateBundleProductOptionsTitleOnStoreView(): void
325+
{
326+
$this->cleanUpOnTearDown = false;
327+
$fixtures = DataFixtureStorageManager::getStorage();
328+
$product = $fixtures->get('bundle1');
329+
$store2 = $fixtures->get('store2');
330+
$data = $this->getProduct($product->getSku());
331+
$defaultOptions = $this->getBundleProductOptions($data);
332+
$store2Options = $defaultOptions;
333+
$store2Options[0]['title'] .= ' - custom';
334+
$store2Options[1]['title'] .= ' - custom';
335+
$this->setBundleProductOptions($data, $store2Options);
336+
$this->saveProduct($data, $store2->getCode());
337+
338+
// check that option titles are updated on store 2
339+
$data = $this->getProduct($product->getSku(), $store2->getCode());
340+
$options = $this->getBundleProductOptions($data);
341+
$this->assertEquals($store2Options[0]['title'], $options[0]['title']);
342+
$this->assertEquals($store2Options[1]['title'], $options[1]['title']);
343+
344+
// check that option titles have not changed on default store
345+
$data = $this->getProduct($product->getSku(), 'default');
346+
$options = $this->getBundleProductOptions($data);
347+
$this->assertEquals($defaultOptions[0]['title'], $options[0]['title']);
348+
$this->assertEquals($defaultOptions[1]['title'], $options[1]['title']);
349+
350+
// check that option titles have not changed in global scope
351+
$data = $this->getProduct($product->getSku(), 'all');
352+
$options = $this->getBundleProductOptions($data);
353+
$this->assertEquals($defaultOptions[0]['title'], $options[0]['title']);
354+
$this->assertEquals($defaultOptions[1]['title'], $options[1]['title']);
355+
}
356+
298357
/**
299358
* Get the bundle_product_options custom attribute from product, null if the attribute is not set
300359
*
@@ -457,7 +516,7 @@ protected function convertCustomAttributes($customAttributes)
457516
* @param string $productSku
458517
* @return array the product data
459518
*/
460-
protected function getProduct($productSku)
519+
protected function getProduct($productSku, ?string $storeCode = null)
461520
{
462521
$serviceInfo = [
463522
'rest' => [
@@ -471,10 +530,9 @@ protected function getProduct($productSku)
471530
],
472531
];
473532

474-
$response = (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) ?
475-
$this->_webApiCall($serviceInfo, ['sku' => $productSku]) : $this->_webApiCall($serviceInfo);
476-
477-
return $response;
533+
return TESTS_WEB_API_ADAPTER === self::ADAPTER_SOAP
534+
? $this->_webApiCall($serviceInfo, ['sku' => $productSku], storeCode: $storeCode)
535+
: $this->_webApiCall($serviceInfo, storeCode: $storeCode);
478536
}
479537

480538
/**
@@ -530,9 +588,10 @@ protected function deleteProductBySku($productSku)
530588
* Save product
531589
*
532590
* @param array $product
591+
* @param string|null $storeCode
533592
* @return array the created product data
534593
*/
535-
protected function saveProduct($product)
594+
protected function saveProduct($product, ?string $storeCode = null)
536595
{
537596
if (isset($product['custom_attributes'])) {
538597
$count = count($product['custom_attributes']);
@@ -557,7 +616,7 @@ protected function saveProduct($product)
557616
],
558617
];
559618
$requestData = ['product' => $product];
560-
$response = $this->_webApiCall($serviceInfo, $requestData);
619+
$response = $this->_webApiCall($serviceInfo, $requestData, storeCode: $storeCode);
561620
return $response;
562621
}
563622
}

0 commit comments

Comments
 (0)