Skip to content

Commit 14a84d4

Browse files
committed
Merge remote-tracking branch 'tango/MC-37630' into PR-10-14
2 parents 2a8c5c7 + 790e401 commit 14a84d4

File tree

3 files changed

+276
-49
lines changed

3 files changed

+276
-49
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Theme\Model\Indexer\Design;
10+
11+
use Magento\Framework\App\ResourceConnection;
12+
use Magento\Framework\Indexer\IndexStructureInterface;
13+
use Magento\Framework\Indexer\SaveHandler\Batch;
14+
use Magento\Framework\Indexer\SaveHandler\Grid;
15+
use Magento\Framework\Indexer\SaveHandler\IndexerInterface;
16+
use Magento\Framework\Indexer\ScopeResolver\FlatScopeResolver;
17+
use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver;
18+
use Magento\Framework\Search\Request\Dimension;
19+
20+
class IndexerHandler extends Grid
21+
{
22+
/**
23+
* @var FlatScopeResolver
24+
*/
25+
private $flatScopeResolver;
26+
27+
/**
28+
* @param IndexStructureInterface $indexStructure
29+
* @param ResourceConnection $resource
30+
* @param Batch $batch
31+
* @param IndexScopeResolver $indexScopeResolver
32+
* @param FlatScopeResolver $flatScopeResolver
33+
* @param array $data
34+
* @param int $batchSize
35+
*/
36+
public function __construct(
37+
IndexStructureInterface $indexStructure,
38+
ResourceConnection $resource,
39+
Batch $batch,
40+
IndexScopeResolver $indexScopeResolver,
41+
FlatScopeResolver $flatScopeResolver,
42+
array $data,
43+
$batchSize = 100
44+
) {
45+
parent::__construct(
46+
$indexStructure,
47+
$resource,
48+
$batch,
49+
$indexScopeResolver,
50+
$flatScopeResolver,
51+
$data,
52+
$batchSize
53+
);
54+
55+
$this->flatScopeResolver = $flatScopeResolver;
56+
}
57+
58+
/**
59+
* Clean index table by deleting all records unconditionally or create the index table if not exists
60+
*
61+
* @param Dimension[] $dimensions
62+
* @return IndexerInterface
63+
*/
64+
public function cleanIndex($dimensions)
65+
{
66+
$tableName = $this->flatScopeResolver->resolve($this->getIndexName(), $dimensions);
67+
68+
if ($this->connection->isTableExists($tableName)) {
69+
$this->connection->delete($tableName);
70+
} else {
71+
$this->indexStructure->create($this->getIndexName(), $this->fields, $dimensions);
72+
}
73+
74+
return $this;
75+
}
76+
}

app/code/Magento/Theme/Test/Unit/Model/Indexer/Design/ConfigTest.php

Lines changed: 199 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,82 +10,196 @@
1010
*/
1111
namespace Magento\Theme\Test\Unit\Model\Indexer\Design;
1212

13+
use Magento\Framework\App\ResourceConnection;
1314
use Magento\Framework\Data\Collection;
1415
use Magento\Framework\Indexer\FieldsetInterface;
1516
use Magento\Framework\Indexer\FieldsetPool;
1617
use Magento\Framework\Indexer\HandlerInterface;
1718
use Magento\Framework\Indexer\HandlerPool;
1819
use Magento\Framework\Indexer\IndexStructureInterface;
19-
use Magento\Framework\Indexer\SaveHandler\IndexerInterface;
20+
use Magento\Framework\Indexer\SaveHandler\Batch;
2021
use Magento\Framework\Indexer\SaveHandlerFactory;
22+
use Magento\Framework\Indexer\ScopeResolver\FlatScopeResolver;
23+
use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver;
2124
use Magento\Framework\Indexer\StructureFactory;
25+
use Magento\Theme\Model\Data\Design\Config as DesignConfig;
2226
use Magento\Theme\Model\Indexer\Design\Config;
27+
use Magento\Theme\Model\ResourceModel\Design\Config\Scope\CollectionFactory;
28+
use PHPUnit\Framework\MockObject\MockObject;
2329
use PHPUnit\Framework\TestCase;
30+
use Magento\Theme\Model\Indexer\Design\IndexerHandler;
31+
use Magento\Framework\DB\Adapter\AdapterInterface;
2432

33+
/**
34+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
35+
*/
2536
class ConfigTest extends TestCase
2637
{
27-
/** @var Config */
28-
protected $model;
38+
/**
39+
* @var AdapterInterface|MockObject
40+
*/
41+
private $adapter;
42+
/**
43+
* @var ResourceConnection|MockObject
44+
*/
45+
private $resourceConnection;
46+
/**
47+
* @var Batch|MockObject
48+
*/
49+
private $batch;
50+
/**
51+
* @var IndexStructureInterface|MockObject
52+
*/
53+
private $indexerStructure;
54+
/**
55+
* @var IndexScopeResolver|MockObject
56+
*/
57+
private $indexScopeResolver;
58+
/**
59+
* @var FlatScopeResolver|MockObject
60+
*/
61+
private $flatScopeResolver;
62+
/**
63+
* @var SaveHandlerFactory|MockObject
64+
*/
65+
private $saveHandlerFactory;
66+
/**
67+
* @var StructureFactory|MockObject
68+
*/
69+
private $structureFactory;
70+
/**
71+
* @var FieldsetInterface|MockObject
72+
*/
73+
private $indexerFieldset;
74+
/**
75+
* @var FieldsetPool|MockObject
76+
*/
77+
private $fieldsetPool;
78+
/**
79+
* @var HandlerInterface|MockObject
80+
*/
81+
private $indexerHandler;
82+
/**
83+
* @var HandlerPool|MockObject
84+
*/
85+
private $handlerPool;
86+
/**
87+
* @var Collection|MockObject
88+
*/
89+
private $collection;
90+
/**
91+
* @var CollectionFactory|MockObject
92+
*/
93+
private $collectionFactory;
2994

3095
protected function setUp(): void
3196
{
32-
$indexerStructure = $this->getMockBuilder(IndexStructureInterface::class)
97+
$this->indexerStructure = $this->getMockBuilder(IndexStructureInterface::class)
3398
->getMockForAbstractClass();
34-
$structureFactory = $this->getMockBuilder(StructureFactory::class)
99+
$this->structureFactory = $this->getMockBuilder(StructureFactory::class)
35100
->disableOriginalConstructor()
36101
->getMock();
37-
$structureFactory->expects($this->any())
38-
->method('create')
39-
->willReturn($indexerStructure);
40-
41-
$indexer = $this->getMockBuilder(IndexerInterface::class)
102+
$this->resourceConnection = $this->getMockBuilder(ResourceConnection::class)
103+
->disableOriginalConstructor()
104+
->getMock();
105+
$this->adapter = $this->getMockBuilder(AdapterInterface::class)
42106
->getMockForAbstractClass();
43-
$saveHandlerFactory = $this->getMockBuilder(SaveHandlerFactory::class)
107+
$this->batch = $this->getMockBuilder(Batch::class)
108+
->disableOriginalConstructor()
109+
->getMock();
110+
$this->indexScopeResolver = $this->getMockBuilder(IndexScopeResolver::class)
111+
->disableOriginalConstructor()
112+
->getMock();
113+
$this->flatScopeResolver = $this->getMockBuilder(FlatScopeResolver::class)
114+
->disableOriginalConstructor()
115+
->getMock();
116+
$this->saveHandlerFactory = $this->getMockBuilder(SaveHandlerFactory::class)
117+
->disableOriginalConstructor()
118+
->getMock();
119+
$this->fieldsetPool = $this->getMockBuilder(FieldsetPool::class)
44120
->disableOriginalConstructor()
45121
->getMock();
46-
$saveHandlerFactory->expects($this->any())
122+
$this->collection = $this->getMockBuilder(Collection::class)
123+
->disableOriginalConstructor()
124+
->getMock();
125+
$this->collectionFactory = $this->getMockBuilder(CollectionFactory::class)
126+
->disableOriginalConstructor()
127+
->getMock();
128+
$this->indexerHandler = $this->getMockBuilder(HandlerInterface::class)
129+
->getMockForAbstractClass();
130+
$this->handlerPool = $this->getMockBuilder(HandlerPool::class)
131+
->disableOriginalConstructor()
132+
->getMock();
133+
$this->indexerFieldset = $this->getMockBuilder(FieldsetInterface::class)
134+
->getMockForAbstractClass();
135+
}
136+
137+
/**
138+
* Generate flat index table name from design config grid index ID
139+
*
140+
* @return string
141+
*/
142+
private function getFlatIndexTableName(): string
143+
{
144+
return DesignConfig::DESIGN_CONFIG_GRID_INDEXER_ID . '_flat';
145+
}
146+
147+
/**
148+
* Initialize and return Design Config Indexer Model
149+
*
150+
* @return Config
151+
*/
152+
private function getDesignConfigIndexerModel(): Config
153+
{
154+
$this->structureFactory->expects($this->any())
155+
->method('create')
156+
->willReturn($this->indexerStructure);
157+
$this->resourceConnection
158+
->expects($this->any())
159+
->method('getConnection')
160+
->willReturn($this->adapter);
161+
$this->flatScopeResolver->expects($this->any())
162+
->method('resolve')
163+
->willReturn($this->getFlatIndexTableName());
164+
165+
$indexer = new IndexerHandler(
166+
$this->indexerStructure,
167+
$this->resourceConnection,
168+
$this->batch,
169+
$this->indexScopeResolver,
170+
$this->flatScopeResolver,
171+
[
172+
'fieldsets' => [],
173+
'indexer_id' => DesignConfig::DESIGN_CONFIG_GRID_INDEXER_ID
174+
]
175+
);
176+
177+
$this->saveHandlerFactory->expects($this->any())
47178
->method('create')
48179
->willReturn($indexer);
49180

50-
$indexerFieldset = $this->getMockBuilder(FieldsetInterface::class)
51-
->getMockForAbstractClass();
52-
$indexerFieldset->expects($this->any())
181+
$this->indexerFieldset->expects($this->any())
53182
->method('addDynamicData')
54183
->willReturnArgument(0);
55-
$fieldsetPool = $this->getMockBuilder(FieldsetPool::class)
56-
->disableOriginalConstructor()
57-
->getMock();
58-
$fieldsetPool->expects($this->any())
184+
185+
$this->fieldsetPool->expects($this->any())
59186
->method('get')
60-
->willReturn($indexerFieldset);
187+
->willReturn($this->indexerFieldset);
61188

62-
$indexerHandler = $this->getMockBuilder(HandlerInterface::class)
63-
->getMockForAbstractClass();
64-
$handlerPool = $this->getMockBuilder(HandlerPool::class)
65-
->disableOriginalConstructor()
66-
->getMock();
67-
$handlerPool->expects($this->any())
189+
$this->handlerPool->expects($this->any())
68190
->method('get')
69-
->willReturn($indexerHandler);
191+
->willReturn($this->indexerHandler);
70192

71-
$collection = $this->getMockBuilder(Collection::class)
72-
->disableOriginalConstructor()
73-
->getMock();
74-
$collectionFactory =
75-
$this->getMockBuilder(\Magento\Theme\Model\ResourceModel\Design\Config\Scope\CollectionFactory::class)
76-
->disableOriginalConstructor()
77-
->setMethods(['create'])
78-
->getMock();
79-
$collectionFactory->expects($this->any())
193+
$this->collectionFactory->expects($this->any())
80194
->method('create')
81-
->willReturn($collection);
82-
83-
$this->model = new Config(
84-
$structureFactory,
85-
$saveHandlerFactory,
86-
$fieldsetPool,
87-
$handlerPool,
88-
$collectionFactory,
195+
->willReturn($this->collection);
196+
197+
return new Config(
198+
$this->structureFactory,
199+
$this->saveHandlerFactory,
200+
$this->fieldsetPool,
201+
$this->handlerPool,
202+
$this->collectionFactory,
89203
[
90204
'fieldsets' => ['test_fieldset' => [
91205
'fields' => [
@@ -102,7 +216,7 @@ protected function setUp(): void
102216
'handler' => null,
103217
],
104218
],
105-
'provider' => $indexerFieldset,
219+
'provider' => $this->indexerFieldset,
106220
]
107221
],
108222
'saveHandler' => 'saveHandlerClass',
@@ -111,9 +225,46 @@ protected function setUp(): void
111225
);
112226
}
113227

114-
public function testExecuteFull()
228+
public function testFullReindex()
115229
{
116-
$result = $this->model->executeFull();
117-
$this->assertNull($result);
230+
$this->adapter->expects($this->any())
231+
->method('isTableExists')
232+
->willReturn(true);
233+
$this->indexerStructure->expects($this->never())->method('create')
234+
->with(DesignConfig::DESIGN_CONFIG_GRID_INDEXER_ID);
235+
$this->adapter->expects($this->once())->method('delete')
236+
->with($this->getFlatIndexTableName());
237+
$this->batch->expects($this->any())
238+
->method('getItems')->willReturn([]);
239+
240+
$this->getDesignConfigIndexerModel()->executeFull();
241+
}
242+
243+
public function testFullReindexWithFlatTableCreate()
244+
{
245+
$this->adapter->expects($this->any())->method('isTableExists')
246+
->willReturn(false);
247+
$this->indexerStructure->expects($this->once())->method('create')
248+
->with(DesignConfig::DESIGN_CONFIG_GRID_INDEXER_ID);
249+
$this->adapter->expects($this->never())->method('delete')
250+
->with($this->getFlatIndexTableName());
251+
$this->batch->expects($this->any())->method('getItems')
252+
->willReturn([]);
253+
254+
$this->getDesignConfigIndexerModel()->executeFull();
255+
}
256+
257+
public function testPartialReindex()
258+
{
259+
$this->adapter->expects($this->any())->method('isTableExists')
260+
->willReturn(true);
261+
$this->indexerStructure->expects($this->never())->method('create')
262+
->with(DesignConfig::DESIGN_CONFIG_GRID_INDEXER_ID);
263+
$this->adapter->expects($this->once())->method('delete')
264+
->with($this->getFlatIndexTableName(), ['entity_id IN(?)' => [1, 2, 3]]);
265+
$this->batch->expects($this->any())->method('getItems')
266+
->willReturn([[1, 2, 3]]);
267+
268+
$this->getDesignConfigIndexerModel()->executeList([1, 2, 3]);
118269
}
119270
}

app/code/Magento/Theme/etc/indexer.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<field name="store_group_id" xsi:type="filterable" dataType="int"/>
1818
<field name="store_id" xsi:type="filterable" dataType="int"/>
1919
</fieldset>
20-
<saveHandler class="Magento\Framework\Indexer\SaveHandler\Grid"/>
20+
<saveHandler class="Magento\Theme\Model\Indexer\Design\IndexerHandler"/>
2121
<structure class="Magento\Framework\Indexer\GridStructure"/>
2222
</indexer>
2323
</config>

0 commit comments

Comments
 (0)