Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
IndexerReindexCommandTest.php
Go to the documentation of this file.
1 <?php
7 
17 use Symfony\Component\Console\Tester\CommandTester;
18 
23 {
29  private $command;
30 
34  protected $configMock;
35 
39  private $indexerRegistryMock;
40 
44  private $dependencyInfoProviderMock;
45 
49  private $objectManagerHelper;
50 
54  public function setUp()
55  {
56  $this->objectManagerHelper = new ObjectManagerHelper($this);
57  $this->configMock = $this->createMock(\Magento\Indexer\Model\Config::class);
58  $this->indexerRegistryMock = $this->getMockBuilder(IndexerRegistry::class)
59  ->disableOriginalConstructor()
60  ->getMock();
61  $this->dependencyInfoProviderMock = $this->objectManagerHelper->getObject(
62  DependencyInfoProvider::class,
63  [
64  'config' => $this->configMock,
65  ]
66  );
67  parent::setUp();
68  }
69 
75  protected function getObjectManagerReturnValueMap()
76  {
77  $result = parent::getObjectManagerReturnValueMap();
78  $result[] = [\Magento\Framework\Indexer\ConfigInterface::class, $this->configMock];
79  $result[] = [DependencyInfoProvider::class, $this->dependencyInfoProviderMock];
80  return $result;
81  }
82 
83  public function testGetOptions()
84  {
85  $this->stateMock->expects($this->never())->method('setAreaCode');
86  $this->command = new IndexerReindexCommand($this->objectManagerFactory);
87  $optionsList = $this->command->getInputList();
88  $this->assertSame(1, sizeof($optionsList));
89  $this->assertSame('index', $optionsList[0]->getName());
90  }
91 
92  public function testExecuteAll()
93  {
94  $this->configMock->expects($this->once())->method('getIndexer')->will($this->returnValue([
95  'title' => 'Title_indexerOne',
96  'shared_index' => null
97  ]));
98  $this->configureAdminArea();
100  $this->getIndexerMock(
101  ['reindexAll', 'getStatus'],
102  ['indexer_id' => 'id_indexerOne', 'title' => 'Title_indexerOne']
103  )
104  ]);
105  $this->indexerFactory->expects($this->never())->method('create');
106  $this->command = new IndexerReindexCommand($this->objectManagerFactory);
107  $commandTester = new CommandTester($this->command);
108  $commandTester->execute([]);
109  $actualValue = $commandTester->getDisplay();
110  $this->assertSame(Cli::RETURN_SUCCESS, $commandTester->getStatusCode());
111  $this->assertStringStartsWith('Title_indexerOne index has been rebuilt successfully in', $actualValue);
112  }
113 
123  public function testExecuteWithIndex(
124  array $inputIndexers,
125  array $indexers,
126  array $states,
127  array $reindexAllCallMatchers,
128  array $executedIndexers,
129  array $executedSharedIndexers
130  ) {
131  $this->addSeparateIndexersToConfigMock($indexers);
132  $this->addAllIndexersToConfigMock($indexers);
133 
134  $indexerMocks = [];
135  foreach ($indexers as $indexerData) {
136  $indexer = $this->getIndexerMock(['getState', 'reindexAll', 'isInvalid'], $indexerData);
137  $indexer->method('getState')
138  ->willReturn(
139  $this->getStateMock(
140  ['loadByIndexer', 'setStatus', 'save'],
141  $states[$indexer->getId()] ?? []
142  )
143  );
144  $indexer->method('isInvalid')
145  ->willReturn(StateInterface::STATUS_INVALID === ($states[$indexer->getId()]['status'] ?? ''));
146  $indexer->expects($reindexAllCallMatchers[$indexer->getId()])
147  ->method('reindexAll');
148  $indexerMocks[] = $indexer;
149  }
150  $this->initIndexerCollectionByItems($indexerMocks);
151 
152  $emptyIndexer = $this->getIndexerMock(['load', 'getState']);
153  $this->indexerRegistryMock
154  ->expects($this->exactly(count($executedSharedIndexers)))
155  ->method('get')
156  ->withConsecutive(...$executedSharedIndexers)
157  ->willReturn($emptyIndexer);
158  $emptyIndexer->method('getState')
159  ->willReturn($this->getStateMock(['setStatus', 'save']));
160 
161  $this->configureAdminArea();
162 
163  $this->command = new IndexerReindexCommand(
164  $this->objectManagerFactory,
165  $this->indexerRegistryMock
166  );
167  $commandTester = new CommandTester($this->command);
168  $commandTester->execute(['index' => $inputIndexers]);
169  $this->assertSame(Cli::RETURN_SUCCESS, $commandTester->getStatusCode());
170  $pattern = '#^';
171  $template = '{Title} index has been rebuilt successfully in \d{2}:\d{2}:\d{2}\W*';
172  foreach ($executedIndexers as $indexerId) {
173  $pattern .= str_replace(
174  '{Title}',
175  $indexers[$indexerId]['title'],
176  $template
177  );
178  }
179  $pattern .= '$#';
180  $this->assertRegExp($pattern, $commandTester->getDisplay());
181  }
182 
186  private function addSeparateIndexersToConfigMock(array $indexers)
187  {
188  $this->configMock
189  ->method('getIndexer')
190  ->willReturnMap(
191  array_map(
192  function ($elem) {
193  return [$elem['indexer_id'], $elem];
194  },
195  $indexers
196  )
197  );
198  }
199 
203  private function addAllIndexersToConfigMock(array $indexers)
204  {
205  $this->configMock
206  ->method('getIndexers')
207  ->willReturn($indexers);
208  }
209 
215  private function getStateMock(array $methods = null, array $data = [])
216  {
218  $state = $this->getMockBuilder(StateInterface::class)
219  ->setMethods($methods)
220  ->disableOriginalConstructor()
221  ->getMockForAbstractClass();
222  $state->method('getStatus')
223  ->willReturn($data['status'] ?? StateInterface::STATUS_INVALID);
224  return $state;
225  }
226 
232  {
233  return [
234  'Without dependencies' => [
235  'inputIndexers' => [
236  'indexer_1'
237  ],
238  'indexers' => [
239  'indexer_1' => [
240  'indexer_id' => 'indexer_1',
241  'title' => 'Title_indexer_1',
242  'shared_index' => null,
243  'dependencies' => [],
244  ],
245  'indexer_2' => [
246  'indexer_id' => 'indexer_2',
247  'title' => 'Title_indexer_2',
248  'shared_index' => 'with_indexer_3',
249  'dependencies' => [],
250  ],
251  'indexer_3' => [
252  'indexer_id' => 'indexer_3',
253  'title' => 'Title_indexer_3',
254  'shared_index' => 'with_indexer_3',
255  'dependencies' => [],
256  ],
257  ],
258  'indexer_states' => [
259  'indexer_2' => [
260  'status' => StateInterface::STATUS_VALID,
261  ],
262  'indexer_3' => [
263  'status' => StateInterface::STATUS_VALID,
264  ],
265  ],
266  'expected_reindex_all_calls' => [
267  'indexer_1' => $this->once(),
268  'indexer_2' => $this->never(),
269  'indexer_3' => $this->never(),
270  ],
271  'executed_indexers' => ['indexer_1'],
272  'executed_shared_indexers' => [],
273  ],
274  'With dependencies and some indexers is invalid' => [
275  'inputIndexers' => [
276  'indexer_1'
277  ],
278  'indexers' => [
279  'indexer_2' => [
280  'indexer_id' => 'indexer_2',
281  'title' => 'Title_indexer_2',
282  'shared_index' => 'with_indexer_3',
283  'dependencies' => [],
284  ],
285  'indexer_3' => [
286  'indexer_id' => 'indexer_3',
287  'title' => 'Title_indexer_3',
288  'shared_index' => 'with_indexer_3',
289  'dependencies' => [],
290  ],
291  'indexer_1' => [
292  'indexer_id' => 'indexer_1',
293  'title' => 'Title_indexer_1',
294  'shared_index' => null,
295  'dependencies' => ['indexer_2', 'indexer_3'],
296  ],
297  'indexer_4' => [
298  'indexer_id' => 'indexer_4',
299  'title' => 'Title_indexer_4',
300  'shared_index' => null,
301  'dependencies' => [],
302  ],
303  'indexer_5' => [
304  'indexer_id' => 'indexer_5',
305  'title' => 'Title_indexer_5',
306  'shared_index' => null,
307  'dependencies' => ['indexer_1'],
308  ],
309  ],
310  'indexer_states' => [
311  'indexer_2' => [
312  'status' => StateInterface::STATUS_VALID,
313  ],
314  'indexer_3' => [
315  'status' => StateInterface::STATUS_INVALID,
316  ],
317  'indexer_4' => [
318  'status' => StateInterface::STATUS_INVALID,
319  ],
320  'indexer_5' => [
321  'status' => StateInterface::STATUS_VALID,
322  ],
323  ],
324  'expected_reindex_all_calls' => [
325  'indexer_1' => $this->once(),
326  'indexer_2' => $this->never(),
327  'indexer_3' => $this->once(),
328  'indexer_4' => $this->never(),
329  'indexer_5' => $this->once(),
330  ],
331  'executed_indexers' => ['indexer_3', 'indexer_1', 'indexer_5'],
332  'executed_shared_indexers' => [['indexer_2'],['indexer_3']],
333  ],
334  'With dependencies and multiple indexers in request' => [
335  'inputIndexers' => [
336  'indexer_1', 'indexer_3'
337  ],
338  'indexers' => [
339  'indexer_2' => [
340  'indexer_id' => 'indexer_2',
341  'title' => 'Title_indexer_2',
342  'shared_index' => null,
343  'dependencies' => [],
344  ],
345  'indexer_1' => [
346  'indexer_id' => 'indexer_1',
347  'title' => 'Title_indexer_1',
348  'shared_index' => null,
349  'dependencies' => ['indexer_2'],
350  ],
351  'indexer_4' => [
352  'indexer_id' => 'indexer_4',
353  'title' => 'Title_indexer_4',
354  'shared_index' => null,
355  'dependencies' => [],
356  ],
357  'indexer_3' => [
358  'indexer_id' => 'indexer_3',
359  'title' => 'Title_indexer_3',
360  'shared_index' => null,
361  'dependencies' => ['indexer_4'],
362  ],
363  'indexer_5' => [
364  'indexer_id' => 'indexer_5',
365  'title' => 'Title_indexer_5',
366  'shared_index' => null,
367  'dependencies' => ['indexer_1'],
368  ],
369  ],
370  'indexer_states' => [
371  'indexer_2' => [
372  'status' => StateInterface::STATUS_VALID,
373  ],
374  'indexer_4' => [
375  'status' => StateInterface::STATUS_INVALID,
376  ],
377  'indexer_5' => [
378  'status' => StateInterface::STATUS_VALID,
379  ],
380  ],
381  'expected_reindex_all_calls' => [
382  'indexer_1' => $this->once(),
383  'indexer_2' => $this->never(),
384  'indexer_3' => $this->once(),
385  'indexer_4' => $this->once(),
386  'indexer_5' => $this->once(),
387  ],
388  'executed_indexers' => ['indexer_1', 'indexer_4', 'indexer_3', 'indexer_5'],
389  'executed_shared_indexers' => [],
390  ],
391  ];
392  }
393 
395  {
396  $this->configureAdminArea();
397  $indexerOne = $this->getIndexerMock(['reindexAll', 'getStatus'], ['indexer_id' => 'indexer_1']);
398  $localizedException = new LocalizedException(new Phrase('Some Exception Message'));
399  $indexerOne->expects($this->once())->method('reindexAll')->will($this->throwException($localizedException));
400  $this->initIndexerCollectionByItems([$indexerOne]);
401  $this->command = new IndexerReindexCommand($this->objectManagerFactory);
402  $commandTester = new CommandTester($this->command);
403  $commandTester->execute(['index' => ['indexer_1']]);
404  $actualValue = $commandTester->getDisplay();
405  $this->assertSame(Cli::RETURN_FAILURE, $commandTester->getStatusCode());
406  $this->assertStringStartsWith('Some Exception Message', $actualValue);
407  }
408 
409  public function testExecuteWithException()
410  {
411  $this->configureAdminArea();
412  $indexerOne = $this->getIndexerMock(
413  ['reindexAll', 'getStatus'],
414  ['indexer_id' => 'indexer_1', 'title' => 'Title_indexer_1']
415  );
416  $indexerOne->expects($this->once())
417  ->method('reindexAll')
418  ->willThrowException(new \Exception());
419  $this->initIndexerCollectionByItems([$indexerOne]);
420  $this->command = new IndexerReindexCommand($this->objectManagerFactory);
421  $commandTester = new CommandTester($this->command);
422  $commandTester->execute(['index' => ['indexer_1']]);
423  $actualValue = $commandTester->getDisplay();
424  $this->assertSame(Cli::RETURN_FAILURE, $commandTester->getStatusCode());
425  $this->assertStringStartsWith('Title_indexer_1' . ' indexer process unknown error:', $actualValue);
426  }
427 
428  public function testExecuteWithExceptionInGetIndexers()
429  {
430  $this->configureAdminArea();
431  $inputIndexers = ['indexer_2'];
432  $indexerData = [
433  'indexer_id' => 'indexer_1',
434  'shared_index' => 'new',
435  ];
436  $indexerOne = $this->getIndexerMock(
437  ['reindexAll', 'getStatus', 'load'],
438  $indexerData
439  );
440  $this->initIndexerCollectionByItems([$indexerOne]);
441 
442  $indexerOne->expects($this->never())->method('getTitle');
443  $this->expectException(\InvalidArgumentException::class);
444  $this->expectExceptionMessage(
445  "The following requested index types are not supported: '"
446  . join("', '", $inputIndexers)
447  . "'." . PHP_EOL . 'Supported types: '
448  . join(", ", array_map(
449  function ($item) {
451  $item->getId();
452  },
453  $this->indexerCollectionMock->getItems()
454  ))
455  );
456  $this->command = new IndexerReindexCommand($this->objectManagerFactory);
457  $commandTester = new CommandTester($this->command);
458  $commandTester->execute(['index' => $inputIndexers]);
459  $this->assertSame(Cli::RETURN_FAILURE, $commandTester->getStatusCode());
460  }
461 }
$pattern
Definition: website.php:22
testExecuteWithIndex(array $inputIndexers, array $indexers, array $states, array $reindexAllCallMatchers, array $executedIndexers, array $executedSharedIndexers)
$methods
Definition: billing.phtml:71
$template
Definition: export.php:12