Skip to content

Commit 484d0b9

Browse files
committed
ACP2E-1443: Graphql requests looping when adding bundled product
1 parent 6c89a9c commit 484d0b9

File tree

2 files changed

+245
-3
lines changed

2 files changed

+245
-3
lines changed

dev/tests/integration/testsuite/Magento/Bundle/Model/ResourceModel/Indexer/StockTest.php

Lines changed: 138 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@
66

77
namespace Magento\Bundle\Model\ResourceModel\Indexer;
88

9+
use Magento\Bundle\Test\Fixture\Link as BundleSelectionFixture;
10+
use Magento\Bundle\Test\Fixture\Option as BundleOptionFixture;
11+
use Magento\Bundle\Test\Fixture\Product as BundleProductFixture;
12+
use Magento\Catalog\Api\ProductRepositoryInterface;
13+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
14+
use Magento\CatalogInventory\Model\ResourceModel\Stock\Status as StockStatusResource;
15+
use Magento\TestFramework\Fixture\DataFixture;
16+
use Magento\TestFramework\Helper\Bootstrap;
17+
918
class StockTest extends \PHPUnit\Framework\TestCase
1019
{
1120
/**
@@ -15,7 +24,7 @@ class StockTest extends \PHPUnit\Framework\TestCase
1524

1625
protected function setUp(): void
1726
{
18-
$this->processor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
27+
$this->processor = Bootstrap::getObjectManager()->get(
1928
\Magento\CatalogInventory\Model\Indexer\Stock\Processor::class
2029
);
2130
}
@@ -29,11 +38,11 @@ public function testReindexAll()
2938
{
3039
$this->processor->reindexAll();
3140

32-
$categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
41+
$categoryFactory = Bootstrap::getObjectManager()->get(
3342
\Magento\Catalog\Model\CategoryFactory::class
3443
);
3544
/** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
36-
$listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
45+
$listProduct = Bootstrap::getObjectManager()->get(
3746
\Magento\Catalog\Block\Product\ListProduct::class
3847
);
3948

@@ -63,4 +72,130 @@ public function testReindexAll()
6372
$this->assertEquals($expectedResult[$product->getName()], $product->getQty());
6473
}
6574
}
75+
76+
#[
77+
DataFixture(
78+
ProductFixture::class,
79+
['sku' => 'simple1', 'stock_item' => ['use_config_manage_stock' => 0, 'use_config_backorders' => 0]],
80+
's1'
81+
),
82+
DataFixture(
83+
ProductFixture::class,
84+
['sku' => 'simple2', 'stock_item' => ['use_config_manage_stock' => 0, 'use_config_backorders' => 0]],
85+
's2'
86+
),
87+
DataFixture(
88+
ProductFixture::class,
89+
['sku' => 'simple3', 'stock_item' => ['use_config_manage_stock' => 0, 'use_config_backorders' => 0]],
90+
's3'
91+
),
92+
DataFixture(
93+
ProductFixture::class,
94+
['sku' => 'simple4', 'stock_item' => ['use_config_manage_stock' => 0, 'use_config_backorders' => 0]],
95+
's4'
96+
),
97+
DataFixture(
98+
BundleSelectionFixture::class,
99+
['sku' => '$s1.sku$', 'qty' => 2, 'can_change_quantity' => 0],
100+
'link1'
101+
),
102+
DataFixture(
103+
BundleSelectionFixture::class,
104+
['sku' => '$s2.sku$', 'qty' => 2, 'can_change_quantity' => 0],
105+
'link2'
106+
),
107+
DataFixture(
108+
BundleSelectionFixture::class,
109+
['sku' => '$s3.sku$', 'qty' => 2, 'can_change_quantity' => 1],
110+
'link3'
111+
),
112+
DataFixture(
113+
BundleSelectionFixture::class,
114+
['sku' => '$s4.sku$', 'qty' => 2, 'can_change_quantity' => 0],
115+
'link4'
116+
),
117+
DataFixture(BundleOptionFixture::class, ['product_links' => ['$link1$', '$link2$']], 'opt1'),
118+
DataFixture(BundleOptionFixture::class, ['product_links' => ['$link3$']], 'opt2'),
119+
DataFixture(BundleOptionFixture::class, ['product_links' => ['$link4$'], 'required' => false], 'opt3'),
120+
DataFixture(BundleProductFixture::class, ['sku' => 'bundle1', '_options' => ['$opt1$', '$opt2$', '$opt3$']]),
121+
]
122+
/**
123+
* @dataProvider reindexRowDataProvider
124+
* @param array $stockItems
125+
* @param bool $expectedStockStatus
126+
* @return void
127+
*/
128+
public function testReindexRow(array $stockItems, bool $expectedStockStatus): void
129+
{
130+
$productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
131+
foreach ($stockItems as $sku => $stockItem) {
132+
$child = $productRepository->get($sku);
133+
$child->setStockData($stockItem);
134+
$productRepository->save($child);
135+
}
136+
$bundle = $productRepository->get('bundle1');
137+
$this->processor->reindexRow($bundle->getId());
138+
139+
$stockStatusResource = Bootstrap::getObjectManager()->get(StockStatusResource::class);
140+
$stockStatus = $stockStatusResource->getProductsStockStatuses($bundle->getId(), 0);
141+
self::assertEquals($expectedStockStatus, (bool) $stockStatus[$bundle->getId()]);
142+
}
143+
144+
public function reindexRowDataProvider(): array
145+
{
146+
return [
147+
[
148+
[
149+
'simple1' => ['manage_stock' => true, 'backorders' => false, 'qty' => 2],
150+
'simple2' => ['manage_stock' => true, 'backorders' => false, 'qty' => 2],
151+
'simple3' => ['manage_stock' => true, 'backorders' => false, 'qty' => 2],
152+
'simple4' => ['manage_stock' => true, 'backorders' => false, 'qty' => 2],
153+
],
154+
true,
155+
],
156+
[
157+
[
158+
'simple1' => ['manage_stock' => true, 'backorders' => false, 'qty' => 1],
159+
'simple3' => ['manage_stock' => true, 'backorders' => false, 'qty' => 1],
160+
'simple4' => ['manage_stock' => true, 'backorders' => false, 'qty' => 1],
161+
],
162+
true,
163+
],
164+
[
165+
[
166+
'simple1' => ['manage_stock' => true, 'backorders' => false, 'qty' => 1],
167+
'simple2' => ['manage_stock' => true, 'backorders' => false, 'qty' => 1],
168+
],
169+
false,
170+
],
171+
[
172+
[
173+
'simple3' => ['manage_stock' => true, 'backorders' => false, 'qty' => 0],
174+
],
175+
false,
176+
],
177+
[
178+
[
179+
'simple4' => ['manage_stock' => true, 'backorders' => false, 'qty' => 0],
180+
],
181+
true,
182+
],
183+
[
184+
[
185+
'simple1' => ['manage_stock' => false, 'backorders' => false, 'qty' => 0],
186+
'simple2' => ['manage_stock' => false, 'backorders' => false, 'qty' => 0],
187+
'simple3' => ['manage_stock' => false, 'backorders' => false, 'qty' => 0],
188+
],
189+
true,
190+
],
191+
[
192+
[
193+
'simple1' => ['manage_stock' => true, 'backorders' => true, 'qty' => 0],
194+
'simple2' => ['manage_stock' => true, 'backorders' => true, 'qty' => 0],
195+
'simple3' => ['manage_stock' => true, 'backorders' => true, 'qty' => 0],
196+
],
197+
true,
198+
],
199+
];
200+
}
66201
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
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\Bundle\Model\ResourceModel\Option;
9+
10+
use Magento\Bundle\Test\Fixture\Link as BundleSelectionFixture;
11+
use Magento\Bundle\Test\Fixture\Option as BundleOptionFixture;
12+
use Magento\Bundle\Test\Fixture\Product as BundleProductFixture;
13+
use Magento\Catalog\Api\ProductRepositoryInterface;
14+
use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus;
15+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
16+
use Magento\Store\Api\StoreRepositoryInterface;
17+
use Magento\Store\Test\Fixture\Group as StoreGroupFixture;
18+
use Magento\Store\Test\Fixture\Store as StoreFixture;
19+
use Magento\Store\Test\Fixture\Website as WebsiteFixture;
20+
use Magento\TestFramework\Fixture\DataFixture;
21+
use Magento\TestFramework\Fixture\DbIsolation;
22+
use Magento\TestFramework\Helper\Bootstrap;
23+
use PHPUnit\Framework\TestCase;
24+
25+
class AreBundleOptionsSalableTest extends TestCase
26+
{
27+
/**
28+
* @var AreBundleOptionsSalable
29+
*/
30+
private $areBundleOptionsSalable;
31+
32+
/**
33+
* @var ProductRepositoryInterface
34+
*/
35+
private $productRepository;
36+
37+
/**
38+
* @var StoreRepositoryInterface
39+
*/
40+
private $storeRepository;
41+
42+
protected function setUp(): void
43+
{
44+
$this->areBundleOptionsSalable = Bootstrap::getObjectManager()->create(AreBundleOptionsSalable::class);
45+
$this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
46+
$this->storeRepository = Bootstrap::getObjectManager()->get(StoreRepositoryInterface::class);
47+
}
48+
49+
#[
50+
DbIsolation(false),
51+
DataFixture(WebsiteFixture::class, as: 'website2'),
52+
DataFixture(StoreGroupFixture::class, ['website_id' => '$website2.id$'], 'group2'),
53+
DataFixture(StoreFixture::class, ['store_group_id' => '$group2.id$', 'code' => 'store2'], 'store2'),
54+
DataFixture(ProductFixture::class, ['sku' => 'simple1', 'website_ids' => [1, '$website2.id']], 's1'),
55+
DataFixture(ProductFixture::class, ['sku' => 'simple2', 'website_ids' => [1, '$website2.id']], 's2'),
56+
DataFixture(ProductFixture::class, ['sku' => 'simple3', 'website_ids' => [1, '$website2.id']], 's3'),
57+
DataFixture(BundleSelectionFixture::class, ['sku' => '$s1.sku$'], 'link1'),
58+
DataFixture(BundleSelectionFixture::class, ['sku' => '$s2.sku$'], 'link2'),
59+
DataFixture(BundleSelectionFixture::class, ['sku' => '$s3.sku$'], 'link3'),
60+
DataFixture(BundleOptionFixture::class, ['product_links' => ['$link1$', '$link2$']], 'opt1'),
61+
DataFixture(BundleOptionFixture::class, ['product_links' => ['$link3$'], 'required' => false], 'opt2'),
62+
DataFixture(
63+
BundleProductFixture::class,
64+
['sku' => 'bundle1', '_options' => ['$opt1$', '$opt2$'], 'website_ids' => [1, '$website2.id']]
65+
),
66+
]
67+
/**
68+
* @dataProvider executeDataProvider
69+
* @param string $storeCodeForChange
70+
* @param array $disabledChildren
71+
* @param string $storeCodeForCheck
72+
* @param bool $expectedResult
73+
* @return void
74+
*/
75+
public function testExecute(
76+
string $storeCodeForChange,
77+
array $disabledChildren,
78+
string $storeCodeForCheck,
79+
bool $expectedResult
80+
): void {
81+
$storeForChange = $this->storeRepository->get($storeCodeForChange);
82+
foreach ($disabledChildren as $childSku) {
83+
$child = $this->productRepository->get($childSku, true, $storeForChange->getId(), true);
84+
$child->setStatus(ProductStatus::STATUS_DISABLED);
85+
$this->productRepository->save($child);
86+
}
87+
88+
$bundle = $this->productRepository->get('bundle1');
89+
$storeForCheck = $this->storeRepository->get($storeCodeForCheck);
90+
$result = $this->areBundleOptionsSalable->execute((int) $bundle->getId(), (int) $storeForCheck->getId());
91+
self::assertEquals($expectedResult, $result);
92+
}
93+
94+
public function executeDataProvider(): array
95+
{
96+
return [
97+
['default', ['simple1'], 'default', true],
98+
['default', ['simple3'], 'default', true],
99+
['default', ['simple1', 'simple2'], 'default', false],
100+
['default', ['simple1', 'simple2'], 'store2', true],
101+
['store2', ['simple1', 'simple2', 'simple3'], 'store2', false],
102+
['store2', ['simple1', 'simple2', 'simple3'], 'default', true],
103+
['admin', ['simple1', 'simple2'], 'default', false],
104+
['admin', ['simple1', 'simple2'], 'store2', false],
105+
];
106+
}
107+
}

0 commit comments

Comments
 (0)