Skip to content

Commit 9ef10be

Browse files
committed
MC-29293: Storefront: Configurable Product with Out Of Stock Child(s)
1 parent b762938 commit 9ef10be

File tree

5 files changed

+95
-47
lines changed

5 files changed

+95
-47
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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+
namespace Magento\TestFramework\ConfigurableProduct\Model;
9+
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\Catalog\Model\ResourceModel\Product as ProductResource;
12+
use Magento\Framework\Exception\NoSuchEntityException;
13+
use Magento\Framework\Registry;
14+
15+
/**
16+
* Delete configurable product with linked products
17+
*/
18+
class DeleteConfigurableProduct
19+
{
20+
/** @var ProductRepositoryInterface */
21+
private $productRepository;
22+
23+
/** @var ProductResource */
24+
private $productResource;
25+
26+
/** @var Registry */
27+
private $registry;
28+
29+
/**
30+
* @param ProductRepositoryInterface $productRepository
31+
* @param ProductResource $productResource
32+
*/
33+
public function __construct(
34+
ProductRepositoryInterface $productRepository,
35+
ProductResource $productResource,
36+
Registry $registry
37+
) {
38+
$this->productRepository = $productRepository;
39+
$this->productResource = $productResource;
40+
$this->registry = $registry;
41+
}
42+
43+
/**
44+
* Delete configurable product and linked products
45+
*
46+
* @param string $sku
47+
* @return void
48+
*/
49+
public function execute(string $sku): void
50+
{
51+
$configurableProduct = $this->productRepository->get($sku, false, null, true);
52+
$childrenIds = $configurableProduct->getExtensionAttributes()->getConfigurableProductLinks();
53+
$childrenSkus = $this->productResource->getProductsSku($childrenIds);
54+
$childrenSkus[]['sku'] = $sku;
55+
$this->registry->unregister('isSecureArea');
56+
$this->registry->register('isSecureArea', true);
57+
foreach ($childrenSkus as $childSku) {
58+
try {
59+
$this->productRepository->deleteById($childSku['sku']);
60+
} catch (NoSuchEntityException $e) {
61+
//product already removed
62+
}
63+
}
64+
$this->registry->unregister('isSecureArea');
65+
$this->registry->register('isSecureArea', false);
66+
}
67+
}

dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/ConfigurableViewOnCategoryPageTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*
2020
* @magentoDbIsolation disabled
2121
* @magentoAppIsolation enabled
22+
* @magentoAppArea frontend
2223
* @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_product_with_out_of_stock_children.php
2324
*/
2425
class ConfigurableViewOnCategoryPageTest extends TestCase

dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/ConfigurableViewOnProductPageTest.php

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ class ConfigurableViewOnProductPageTest extends TestCase
4949
/** @var ProductResource */
5050
private $productResource;
5151

52+
/** @var StoreManagerInterface */
53+
private $storeManager;
54+
5255
/**
5356
* @inheritdoc
5457
*/
@@ -63,6 +66,7 @@ protected function setUp()
6366
$this->block = $this->layout->createBlock(Configurable::class);
6467
$this->json = $this->objectManager->get(SerializerInterface::class);
6568
$this->productResource = $this->objectManager->get(ProductResource::class);
69+
$this->storeManager = $this->objectManager->get(StoreManagerInterface::class);
6670
}
6771

6872
/**
@@ -76,7 +80,7 @@ protected function setUp()
7680
*/
7781
public function testOneChildNotVisible(string $sku, array $data, array $expectedData): void
7882
{
79-
$configurableProduct = $this->prepareProductToTest($sku, $data);
83+
$configurableProduct = $this->prepareConfigurableProduct($sku, $data);
8084
$result = $this->renderStockBlock($configurableProduct);
8185
$this->performAsserts($result, $expectedData);
8286
}
@@ -142,7 +146,7 @@ public function testOneChildNotVisibleWithEnabledShowOutOfStockProducts(
142146
array $data,
143147
array $expectedData
144148
): void {
145-
$configurableProduct = $this->prepareProductToTest($sku, $data);
149+
$configurableProduct = $this->prepareConfigurableProduct($sku, $data);
146150
$result = $this->renderStockBlock($configurableProduct);
147151
$this->performAsserts($result, $expectedData);
148152
}
@@ -206,34 +210,34 @@ public function oneChildNotVisibleDataProviderWithEnabledConfig(): array
206210
*/
207211
private function updateProduct(string $sku, array $data): void
208212
{
209-
$storeManager = $this->objectManager->get(StoreManagerInterface::class);
210-
$currentStore = $storeManager->getStore();
213+
$currentStore = $this->storeManager->getStore();
211214
try {
212-
$storeManager->setCurrentStore(Store::DEFAULT_STORE_ID);
215+
$this->storeManager->setCurrentStore(Store::DEFAULT_STORE_ID);
213216
$product = $this->productRepository->get($sku);
214217
$product->addData($data);
215218
$this->productRepository->save($product);
216219
} finally {
217-
$storeManager->setCurrentStore($currentStore);
220+
$this->storeManager->setCurrentStore($currentStore);
218221
}
219222
}
220223

221224
/**
222225
* Check attribute options
223226
*
224-
* @param array $actualAttributeDataData
225-
* @param array $actualOptionData
227+
* @param array $actualData
226228
* @param array $expectedData
227229
* @return void
228230
*/
229-
private function assertConfig(array $actualAttributeDataData, array $actualOptionData, array $expectedData): void
231+
private function assertConfig(array $actualData, array $expectedData): void
230232
{
231-
$this->assertCount(count($expectedData), $actualOptionData, 'Redundant options were loaded');
233+
$this->assertCount(count($expectedData), $actualData['options_data'], 'Redundant options were loaded');
234+
$sku = array_column($expectedData, 'product');
235+
$idBySkuMapping = $this->productResource->getProductsIdsBySkus($sku);
232236
foreach ($expectedData as $expectedOption) {
233-
$expectedId = $this->productResource->getIdBySku($expectedOption['product']);
234-
$itemToCheck = $actualOptionData[$expectedId] ?? null;
237+
$expectedId = $idBySkuMapping[$expectedOption['product']];
238+
$itemToCheck = $actualData['options_data'][$expectedId] ?? null;
235239
$this->assertNotNull($itemToCheck);
236-
foreach ($actualAttributeDataData['options'] as $actualAttributeDataItem) {
240+
foreach ($actualData['attributes']['options'] as $actualAttributeDataItem) {
237241
if ($actualAttributeDataItem['id'] === reset($itemToCheck)) {
238242
$this->assertEquals($expectedOption['label'], $actualAttributeDataItem['label']);
239243
}
@@ -266,7 +270,8 @@ private function performAsserts(string $result, array $expectedData): void
266270
{
267271
$this->assertEquals((string)__($expectedData['stock_status']), trim(strip_tags($result)));
268272
$config = $this->json->unserialize($this->block->getJsonConfig());
269-
$this->assertConfig(reset($config['attributes']), $config['index'], $expectedData['options']);
273+
$dataToCheck = ['attributes' => reset($config['attributes']), 'options_data' => $config['index']];
274+
$this->assertConfig($dataToCheck, $expectedData['options']);
270275
}
271276

272277
/**
@@ -276,11 +281,10 @@ private function performAsserts(string $result, array $expectedData): void
276281
* @param array $data
277282
* @return ProductInterface
278283
*/
279-
private function prepareProductToTest(string $sku, array $data): ProductInterface
284+
private function prepareConfigurableProduct(string $sku, array $data): ProductInterface
280285
{
281286
$this->updateProduct($sku, $data);
282-
$configurableProduct = $this->productRepository->get('configurable', false, null, true);
283287

284-
return $configurableProduct;
288+
return $this->productRepository->get('configurable', false, null, true);
285289
}
286290
}

dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/Configurable/SalableTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
/**
1818
* Check is configurable product salable with different conditions
19+
*
20+
* @magentoAppArea frontend
1921
*/
2022
class SalableTest extends TestCase
2123
{

dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_product_with_out_of_stock_children_rollback.php

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,15 @@
55
*/
66
declare(strict_types=1);
77

8-
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
9-
use Magento\Catalog\Api\ProductRepositoryInterface;
10-
use Magento\Framework\Exception\NoSuchEntityException;
118
use Magento\Framework\ObjectManagerInterface;
12-
use Magento\Framework\Registry;
9+
use Magento\TestFramework\ConfigurableProduct\Model\DeleteConfigurableProduct;
1310
use Magento\TestFramework\Helper\Bootstrap;
1411

1512
/** @var ObjectManagerInterface $objectManager */
1613
$objectManager = Bootstrap::getObjectManager();
17-
/** @var Registry $registry */
18-
$registry = $objectManager->get(Registry::class);
19-
$registry->unregister('isSecureArea');
20-
$registry->register('isSecureArea', true);
21-
/** @var ProductRepositoryInterface $productRepository */
22-
$productRepository = $objectManager->get(ProductRepositoryInterface::class);
23-
/** @var ProductAttributeRepositoryInterface $productAttributeRepository */
24-
$productAttributeRepository = $objectManager->get(ProductAttributeRepositoryInterface::class);
25-
$attribute = $productAttributeRepository->get('test_configurable');
26-
$options = $attribute->getOptions();
27-
array_shift($options);
28-
$productsArray = [];
29-
foreach ($options as $option) {
30-
$productsArray [] = strtolower(str_replace(' ', '_', 'simple ' . $option->getLabel()));
31-
}
32-
$productsArray[] = 'configurable';
33-
foreach ($productsArray as $sku) {
34-
try {
35-
$productRepository->deleteById($sku);
36-
} catch (NoSuchEntityException $e) {
37-
//Product already removed
38-
}
39-
}
40-
41-
$registry->unregister('isSecureArea');
42-
$registry->register('isSecureArea', false);
14+
/** @var DeleteConfigurableProduct $deleteConfigurableProductService */
15+
$deleteConfigurableProductService = $objectManager->get(DeleteConfigurableProduct::class);
16+
$deleteConfigurableProductService->execute('configurable');
4317

4418
require __DIR__ . '/configurable_attribute_rollback.php';
4519
require __DIR__ . '/../../Catalog/_files/category_rollback.php';

0 commit comments

Comments
 (0)