Skip to content

Commit e19824d

Browse files
author
Serhii Balko
committed
Merge remote-tracking branch 'origin/MC-41499' into 2.4-develop-pr57
2 parents 533ec2e + e2ff88d commit e19824d

File tree

2 files changed

+108
-41
lines changed

2 files changed

+108
-41
lines changed

app/code/Magento/CatalogInventory/Model/Indexer/Stock/CacheCleaner.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Magento\CatalogInventory\Model\Indexer\Stock;
88

9+
use Magento\Catalog\Model\Category;
910
use Magento\CatalogInventory\Api\StockConfigurationInterface;
1011
use Magento\Framework\App\ResourceConnection;
1112
use Magento\Framework\App\ObjectManager;
@@ -88,6 +89,11 @@ public function clean(array $productIds, callable $reindex)
8889
if ($productIds) {
8990
$this->cacheContext->registerEntities(Product::CACHE_TAG, array_unique($productIds));
9091
$this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
92+
$categoryIds = $this->getCategoryIdsByProductIds($productIds);
93+
if ($categoryIds){
94+
$this->cacheContext->registerEntities(Category::CACHE_TAG, array_unique($categoryIds));
95+
$this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
96+
}
9197
}
9298
}
9399

@@ -159,6 +165,22 @@ private function getProductIdsForCacheClean(array $productStatusesBefore, array
159165
return $productIds;
160166
}
161167

168+
/**
169+
* Get category ids for products
170+
*
171+
* @param array $productIds
172+
* @return array
173+
*/
174+
private function getCategoryIdsByProductIds(array $productIds): array
175+
{
176+
$categoryProductTable = $this->getConnection()->getTableName('catalog_category_product');
177+
$select = $this->getConnection()->select()
178+
->from(['catalog_category_product' => $categoryProductTable], ['category_id'])
179+
->where('product_id IN (?)', $productIds);
180+
181+
return $this->getConnection()->fetchCol($select);
182+
}
183+
162184
/**
163185
* Get database connection.
164186
*

app/code/Magento/CatalogInventory/Test/Unit/Model/Indexer/Stock/CacheCleanerTest.php

Lines changed: 86 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Magento\CatalogInventory\Test\Unit\Model\Indexer\Stock;
99

10+
use Magento\Catalog\Model\Category;
1011
use Magento\Catalog\Model\Product;
1112
use Magento\CatalogInventory\Api\StockConfigurationInterface;
1213
use Magento\CatalogInventory\Model\Indexer\Stock\CacheCleaner;
@@ -20,6 +21,9 @@
2021
use PHPUnit\Framework\MockObject\MockObject;
2122
use PHPUnit\Framework\TestCase;
2223

24+
/**
25+
* Test for CacheCleaner
26+
*/
2327
class CacheCleanerTest extends TestCase
2428
{
2529
/**
@@ -70,14 +74,16 @@ protected function setUp(): void
7074
$this->connectionMock = $this->getMockBuilder(AdapterInterface::class)
7175
->getMock();
7276
$this->stockConfigurationMock = $this->getMockBuilder(StockConfigurationInterface::class)
73-
->setMethods(['getStockThresholdQty'])->getMockForAbstractClass();
77+
->setMethods(['getStockThresholdQty'])
78+
->getMockForAbstractClass();
7479
$this->cacheContextMock = $this->getMockBuilder(CacheContext::class)
7580
->disableOriginalConstructor()
7681
->getMock();
7782
$this->eventManagerMock = $this->getMockBuilder(ManagerInterface::class)
7883
->getMock();
7984
$this->metadataPoolMock = $this->getMockBuilder(MetadataPool::class)
80-
->setMethods(['getMetadata', 'getLinkField'])->disableOriginalConstructor()
85+
->setMethods(['getMetadata', 'getLinkField'])
86+
->disableOriginalConstructor()
8187
->getMock();
8288
$this->selectMock = $this->getMockBuilder(Select::class)
8389
->disableOriginalConstructor()
@@ -100,37 +106,63 @@ protected function setUp(): void
100106
}
101107

102108
/**
109+
* Test clean cache by product ids and category ids
110+
*
103111
* @param bool $stockStatusBefore
104112
* @param bool $stockStatusAfter
105113
* @param int $qtyAfter
106114
* @param bool|int $stockThresholdQty
107115
* @dataProvider cleanDataProvider
116+
* @return void
108117
*/
109-
public function testClean($stockStatusBefore, $stockStatusAfter, $qtyAfter, $stockThresholdQty)
118+
public function testClean($stockStatusBefore, $stockStatusAfter, $qtyAfter, $stockThresholdQty): void
110119
{
111120
$productId = 123;
112-
$this->selectMock->expects($this->any())->method('from')->willReturnSelf();
113-
$this->selectMock->expects($this->any())->method('where')->willReturnSelf();
114-
$this->selectMock->expects($this->any())->method('joinLeft')->willReturnSelf();
115-
$this->connectionMock->expects($this->exactly(2))->method('select')->willReturn($this->selectMock);
116-
$this->connectionMock->expects($this->exactly(2))->method('fetchAll')->willReturnOnConsecutiveCalls(
117-
[
118-
['product_id' => $productId, 'stock_status' => $stockStatusBefore],
119-
],
120-
[
121-
['product_id' => $productId, 'stock_status' => $stockStatusAfter, 'qty' => $qtyAfter],
122-
]
123-
);
124-
$this->stockConfigurationMock->expects($this->once())->method('getStockThresholdQty')
121+
$categoryId = 3;
122+
$this->selectMock->expects($this->any())
123+
->method('from')
124+
->willReturnSelf();
125+
$this->selectMock->expects($this->any())
126+
->method('where')
127+
->willReturnSelf();
128+
$this->selectMock->expects($this->any())
129+
->method('joinLeft')
130+
->willReturnSelf();
131+
$this->connectionMock->expects($this->exactly(3))
132+
->method('select')
133+
->willReturn($this->selectMock);
134+
$this->connectionMock->expects($this->exactly(2))
135+
->method('fetchAll')
136+
->willReturnOnConsecutiveCalls(
137+
[
138+
['product_id' => $productId, 'stock_status' => $stockStatusBefore],
139+
],
140+
[
141+
['product_id' => $productId, 'stock_status' => $stockStatusAfter, 'qty' => $qtyAfter],
142+
]
143+
);
144+
$this->connectionMock->expects($this->exactly(1))
145+
->method('fetchCol')
146+
->willReturn([$categoryId]);
147+
$this->stockConfigurationMock->expects($this->once())
148+
->method('getStockThresholdQty')
125149
->willReturn($stockThresholdQty);
126-
$this->cacheContextMock->expects($this->once())->method('registerEntities')
127-
->with(Product::CACHE_TAG, [$productId]);
128-
$this->eventManagerMock->expects($this->once())->method('dispatch')
150+
$this->cacheContextMock->expects($this->exactly(2))
151+
->method('registerEntities')
152+
->withConsecutive(
153+
[Product::CACHE_TAG, [$productId]],
154+
[Category::CACHE_TAG, [$categoryId]],
155+
);
156+
$this->eventManagerMock->expects($this->exactly(2))
157+
->method('dispatch')
129158
->with('clean_cache_by_tags', ['object' => $this->cacheContextMock]);
130-
$this->metadataPoolMock->expects($this->exactly(2))->method('getMetadata')
159+
$this->metadataPoolMock->expects($this->exactly(2))
160+
->method('getMetadata')
131161
->willReturnSelf();
132-
$this->metadataPoolMock->expects($this->exactly(2))->method('getLinkField')
162+
$this->metadataPoolMock->expects($this->exactly(2))
163+
->method('getLinkField')
133164
->willReturn('row_id');
165+
134166
$callback = function () {
135167
};
136168
$this->unit->clean([], $callback);
@@ -139,7 +171,7 @@ public function testClean($stockStatusBefore, $stockStatusAfter, $qtyAfter, $sto
139171
/**
140172
* @return array
141173
*/
142-
public function cleanDataProvider()
174+
public function cleanDataProvider(): array
143175
{
144176
return [
145177
[true, false, 1, false],
@@ -155,29 +187,42 @@ public function cleanDataProvider()
155187
* @param int $qtyAfter
156188
* @param bool|int $stockThresholdQty
157189
* @dataProvider notCleanCacheDataProvider
190+
* @return void
158191
*/
159-
public function testNotCleanCache($stockStatusBefore, $stockStatusAfter, $qtyAfter, $stockThresholdQty)
192+
public function testNotCleanCache($stockStatusBefore, $stockStatusAfter, $qtyAfter, $stockThresholdQty): void
160193
{
161194
$productId = 123;
162-
$this->selectMock->expects($this->any())->method('from')->willReturnSelf();
163-
$this->selectMock->expects($this->any())->method('where')->willReturnSelf();
164-
$this->selectMock->expects($this->any())->method('joinLeft')->willReturnSelf();
165-
$this->connectionMock->expects($this->exactly(2))->method('select')->willReturn($this->selectMock);
166-
$this->connectionMock->expects($this->exactly(2))->method('fetchAll')->willReturnOnConsecutiveCalls(
167-
[
168-
['product_id' => $productId, 'stock_status' => $stockStatusBefore],
169-
],
170-
[
171-
['product_id' => $productId, 'stock_status' => $stockStatusAfter, 'qty' => $qtyAfter],
172-
]
173-
);
174-
$this->stockConfigurationMock->expects($this->once())->method('getStockThresholdQty')
195+
$this->selectMock->expects($this->any())->method('from')
196+
->willReturnSelf();
197+
$this->selectMock->expects($this->any())->method('where')
198+
->willReturnSelf();
199+
$this->selectMock->expects($this->any())->method('joinLeft')
200+
->willReturnSelf();
201+
$this->connectionMock->expects($this->exactly(2))
202+
->method('select')
203+
->willReturn($this->selectMock);
204+
$this->connectionMock->expects($this->exactly(2))
205+
->method('fetchAll')
206+
->willReturnOnConsecutiveCalls(
207+
[
208+
['product_id' => $productId, 'stock_status' => $stockStatusBefore],
209+
],
210+
[
211+
['product_id' => $productId, 'stock_status' => $stockStatusAfter, 'qty' => $qtyAfter],
212+
]
213+
);
214+
$this->stockConfigurationMock->expects($this->once())
215+
->method('getStockThresholdQty')
175216
->willReturn($stockThresholdQty);
176-
$this->cacheContextMock->expects($this->never())->method('registerEntities');
177-
$this->eventManagerMock->expects($this->never())->method('dispatch');
178-
$this->metadataPoolMock->expects($this->exactly(2))->method('getMetadata')
217+
$this->cacheContextMock->expects($this->never())
218+
->method('registerEntities');
219+
$this->eventManagerMock->expects($this->never())
220+
->method('dispatch');
221+
$this->metadataPoolMock->expects($this->exactly(2))
222+
->method('getMetadata')
179223
->willReturnSelf();
180-
$this->metadataPoolMock->expects($this->exactly(2))->method('getLinkField')
224+
$this->metadataPoolMock->expects($this->exactly(2))
225+
->method('getLinkField')
181226
->willReturn('row_id');
182227

183228
$callback = function () {
@@ -188,7 +233,7 @@ public function testNotCleanCache($stockStatusBefore, $stockStatusAfter, $qtyAft
188233
/**
189234
* @return array
190235
*/
191-
public function notCleanCacheDataProvider()
236+
public function notCleanCacheDataProvider(): array
192237
{
193238
return [
194239
[true, true, 1, false],

0 commit comments

Comments
 (0)