@@ -48,6 +48,11 @@ class ProcessorTest extends TestCase
4848 */
4949 protected $ viewProcessorMock ;
5050
51+ /**
52+ * @var IndexerRegistry|MockObject
53+ */
54+ private $ indexerRegistryMock ;
55+
5156 /**
5257 * @inheritDoc
5358 */
@@ -77,6 +82,11 @@ protected function setUp(): void
7782 false
7883 );
7984
85+ $ this ->indexerRegistryMock = $ this ->createPartialMock (
86+ IndexerRegistry::class,
87+ ['get ' ]
88+ );
89+
8090 $ indexerRegistryMock = $ this ->getIndexRegistryMock ([]);
8191 $ makeSharedValidMock = new MakeSharedIndexValid (
8292 $ this ->configMock ,
@@ -88,7 +98,8 @@ protected function setUp(): void
8898 $ this ->indexerFactoryMock ,
8999 $ this ->indexersFactoryMock ,
90100 $ this ->viewProcessorMock ,
91- $ makeSharedValidMock
101+ $ makeSharedValidMock ,
102+ $ this ->indexerRegistryMock
92103 );
93104 }
94105
@@ -97,39 +108,53 @@ protected function setUp(): void
97108 */
98109 public function testReindexAllInvalid (): void
99110 {
100- $ indexers = ['indexer1 ' => [], 'indexer2 ' => []];
111+ $ indexers = [
112+ 'indexer1 ' => [],
113+ 'indexer2 ' => [],
114+ 'indexer3 ' => []
115+ ];
116+ $ indexerReturnMap = [
117+ ['indexer1 ' , ['shared_index ' => null ]],
118+ ['indexer2 ' , ['shared_index ' => null ]],
119+ ['indexer3 ' , ['shared_index ' => null ]]
120+ ];
101121
102122 $ this ->configMock ->expects ($ this ->once ())->method ('getIndexers ' )->willReturn ($ indexers );
123+ $ this ->configMock ->method ('getIndexer ' )->willReturnMap ($ indexerReturnMap );
103124
125+ // Invalid Indexer
104126 $ state1Mock = $ this ->createPartialMock (State::class, ['getStatus ' , '__wakeup ' ]);
105- $ state1Mock ->expects ($ this ->exactly (2 ))
127+ $ state1Mock ->expects ($ this ->exactly (3 ))
106128 ->method ('getStatus ' )
107- ->willReturnOnConsecutiveCalls (StateInterface::STATUS_INVALID , StateInterface::STATUS_VALID );
108- $ indexer1Mock = $ this ->createPartialMock (
109- Indexer::class,
110- ['load ' , 'getState ' , 'reindexAll ' ]
111- );
112- $ indexer1Mock ->expects ($ this ->exactly (2 ))->method ('getState ' )->willReturn ($ state1Mock );
129+ ->willReturnOnConsecutiveCalls (
130+ StateInterface::STATUS_INVALID ,
131+ StateInterface::STATUS_INVALID ,
132+ StateInterface::STATUS_VALID
133+ );
134+ $ indexer1Mock = $ this ->createPartialMock (Indexer::class, ['load ' , 'getState ' , 'reindexAll ' ]);
135+ $ indexer1Mock ->expects ($ this ->exactly (3 ))->method ('getState ' )->willReturn ($ state1Mock );
113136 $ indexer1Mock ->expects ($ this ->once ())->method ('reindexAll ' );
114137
138+ // Valid Indexer
115139 $ state2Mock = $ this ->createPartialMock (State::class, ['getStatus ' , '__wakeup ' ]);
116- $ state2Mock ->expects (
117- $ this ->once ()
118- )->method (
119- 'getStatus '
120- )->willReturn (
121- StateInterface::STATUS_VALID
122- );
123- $ indexer2Mock = $ this ->createPartialMock (
124- Indexer::class,
125- ['load ' , 'getState ' , 'reindexAll ' ]
126- );
127- $ indexer2Mock ->expects ($ this ->never ())->method ('reindexAll ' );
140+ $ state2Mock ->expects ($ this ->once ())->method ('getStatus ' )->willReturn (StateInterface::STATUS_VALID );
141+ $ indexer2Mock = $ this ->createPartialMock (Indexer::class, ['load ' , 'getState ' , 'reindexAll ' ]);
128142 $ indexer2Mock ->expects ($ this ->once ())->method ('getState ' )->willReturn ($ state2Mock );
143+ $ indexer2Mock ->expects ($ this ->never ())->method ('reindexAll ' );
144+
145+ // Suspended Indexer
146+ $ state3Mock = $ this ->createPartialMock (State::class, ['getStatus ' , '__wakeup ' ]);
147+ $ state3Mock ->expects ($ this ->exactly (2 ))->method ('getStatus ' )->willReturnOnConsecutiveCalls (
148+ StateInterface::STATUS_INVALID ,
149+ StateInterface::STATUS_SUSPENDED
150+ );
151+ $ indexer3Mock = $ this ->createPartialMock (Indexer::class, ['load ' , 'getState ' , 'reindexAll ' ]);
152+ $ indexer3Mock ->expects ($ this ->exactly (2 ))->method ('getState ' )->willReturn ($ state3Mock );
153+ $ indexer3Mock ->expects ($ this ->never ())->method ('reindexAll ' );
129154
130155 $ this ->indexerFactoryMock
131156 ->method ('create ' )
132- ->willReturnOnConsecutiveCalls ($ indexer1Mock , $ indexer2Mock );
157+ ->willReturnOnConsecutiveCalls ($ indexer1Mock , $ indexer2Mock, $ indexer3Mock );
133158
134159 $ this ->model ->reindexAllInvalid ();
135160 }
@@ -163,12 +188,9 @@ function ($elem) {
163188 $ indexerMocks = [];
164189 foreach ($ indexers as $ indexerData ) {
165190 $ stateMock = $ this ->createPartialMock (State::class, ['getStatus ' , '__wakeup ' ]);
166- $ stateMock ->expects ($ this ->any ())
167- ->method ('getStatus ' )
168- ->willReturnOnConsecutiveCalls (
169- $ indexerStates [$ indexerData ['indexer_id ' ]],
170- StateInterface::STATUS_VALID
171- );
191+ $ sequence = $ indexerStates [$ indexerData ['indexer_id ' ]] ?? [StateInterface::STATUS_VALID ];
192+ $ stateMock ->method ('getStatus ' )->willReturnOnConsecutiveCalls (...$ sequence );
193+
172194 $ indexerMock = $ this ->createPartialMock (Indexer::class, ['load ' , 'getState ' , 'reindexAll ' ]);
173195 $ indexerMock ->expects ($ this ->any ())->method ('getState ' )->willReturn ($ stateMock );
174196 $ indexerMock ->expects ($ expectedReindexAllCalls [$ indexerData ['indexer_id ' ]])->method ('reindexAll ' );
@@ -178,6 +200,16 @@ function ($elem) {
178200 ->method ('create ' )
179201 ->willReturnOnConsecutiveCalls (...$ indexerMocks );
180202
203+ $ stateMock = $ this ->createPartialMock (State::class, ['getStatus ' , '__wakeup ' ]);
204+ $ stateMock ->expects ($ this ->any ())
205+ ->method ('getStatus ' )
206+ ->willReturn (StateInterface::STATUS_INVALID );
207+ $ indexerMock = $ this ->createPartialMock (Indexer::class, ['load ' , 'getState ' , 'reindexAll ' ]);
208+ $ indexerMock ->expects ($ this ->any ())->method ('getState ' )->willReturn ($ stateMock );
209+
210+ $ this ->indexerRegistryMock ->method ('get ' )
211+ ->willReturn ($ indexerMock );
212+
181213 $ indexerRegistryMock = $ this ->getIndexRegistryMock ($ executedSharedIndexers );
182214
183215 $ makeSharedValidMock = new MakeSharedIndexValid (
@@ -189,11 +221,69 @@ function ($elem) {
189221 $ this ->indexerFactoryMock ,
190222 $ this ->indexersFactoryMock ,
191223 $ this ->viewProcessorMock ,
192- $ makeSharedValidMock
224+ $ makeSharedValidMock ,
225+ $ this ->indexerRegistryMock
193226 );
194227 $ model ->reindexAllInvalid ();
195228 }
196229
230+ /**
231+ * Test that any indexers within a group that share a common 'shared_index' ID are suspended.
232+ *
233+ * @param array $indexers
234+ * @param array $indexerStates
235+ * @param array $expectedReindexAllCalls
236+ *
237+ * @return void
238+ * @dataProvider suspendedIndexDataProvider
239+ */
240+ public function testReindexAllInvalidWithSuspendedStatus (
241+ array $ indexers ,
242+ array $ indexerStates ,
243+ array $ expectedReindexAllCalls
244+ ): void {
245+ $ this ->configMock ->expects ($ this ->exactly (3 ))->method ('getIndexers ' )->willReturn ($ indexers );
246+ $ this ->configMock
247+ ->method ('getIndexer ' )
248+ ->willReturnMap (
249+ array_map (
250+ function ($ elem ) {
251+ return [$ elem ['indexer_id ' ], $ elem ];
252+ },
253+ $ indexers
254+ )
255+ );
256+ $ indexerMocks = [];
257+ foreach ($ indexers as $ indexerData ) {
258+ $ stateMock = $ this ->createPartialMock (State::class, ['getStatus ' , '__wakeup ' ]);
259+ $ sequence = $ indexerStates [$ indexerData ['indexer_id ' ]] ?? [StateInterface::STATUS_VALID ];
260+ $ stateMock ->method ('getStatus ' )->willReturnOnConsecutiveCalls (...$ sequence );
261+
262+ $ indexerMock = $ this ->createPartialMock (Indexer::class, ['load ' , 'getState ' , 'reindexAll ' ]);
263+ $ indexerMock ->expects ($ this ->any ())->method ('getState ' )->willReturn ($ stateMock );
264+ $ indexerMock ->expects ($ expectedReindexAllCalls [$ indexerData ['indexer_id ' ]])->method ('reindexAll ' );
265+ $ indexerMocks [] = $ indexerMock ;
266+ }
267+ $ this ->indexerFactoryMock
268+ ->method ('create ' )
269+ ->willReturnOnConsecutiveCalls (...$ indexerMocks );
270+
271+ $ stateMock = $ this ->createPartialMock (State::class, ['getStatus ' , '__wakeup ' ]);
272+ $ stateMock ->expects ($ this ->exactly (3 ))
273+ ->method ('getStatus ' )
274+ ->willReturnOnConsecutiveCalls (
275+ StateInterface::STATUS_SUSPENDED ,
276+ StateInterface::STATUS_INVALID ,
277+ StateInterface::STATUS_SUSPENDED
278+ );
279+ $ indexerMock = $ this ->createPartialMock (Indexer::class, ['load ' , 'getState ' , 'reindexAll ' ]);
280+ $ indexerMock ->expects ($ this ->exactly (3 ))->method ('getState ' )->willReturn ($ stateMock );
281+
282+ $ this ->indexerRegistryMock ->method ('get ' )->willReturn ($ indexerMock );
283+
284+ $ this ->model ->reindexAllInvalid ();
285+ }
286+
197287 /**
198288 * Reindex all test.
199289 *
@@ -262,9 +352,13 @@ public function sharedIndexDataProvider(): array
262352 ],
263353 ],
264354 'indexer_states ' => [
265- 'indexer_1 ' => StateInterface::STATUS_INVALID ,
266- 'indexer_2 ' => StateInterface::STATUS_VALID ,
267- 'indexer_3 ' => StateInterface::STATUS_VALID
355+ 'indexer_1 ' => [
356+ StateInterface::STATUS_INVALID ,
357+ StateInterface::STATUS_INVALID ,
358+ StateInterface::STATUS_VALID
359+ ],
360+ 'indexer_2 ' => [StateInterface::STATUS_VALID ],
361+ 'indexer_3 ' => [StateInterface::STATUS_VALID ]
268362 ],
269363 'expected_reindex_all_calls ' => [
270364 'indexer_1 ' => $ this ->once (),
@@ -301,10 +395,18 @@ public function sharedIndexDataProvider(): array
301395 ]
302396 ],
303397 'indexer_states ' => [
304- 'indexer_1 ' => StateInterface::STATUS_INVALID ,
305- 'indexer_2 ' => StateInterface::STATUS_VALID ,
306- 'indexer_3 ' => StateInterface::STATUS_INVALID ,
307- 'indexer_4 ' => StateInterface::STATUS_VALID
398+ 'indexer_1 ' => [
399+ StateInterface::STATUS_INVALID ,
400+ StateInterface::STATUS_INVALID ,
401+ StateInterface::STATUS_VALID
402+ ],
403+ 'indexer_2 ' => [StateInterface::STATUS_VALID ],
404+ 'indexer_3 ' => [
405+ StateInterface::STATUS_INVALID ,
406+ StateInterface::STATUS_INVALID ,
407+ StateInterface::STATUS_VALID
408+ ],
409+ 'indexer_4 ' => [StateInterface::STATUS_VALID ]
308410 ],
309411 'expected_reindex_all_calls ' => [
310412 'indexer_1 ' => $ this ->once (),
@@ -317,6 +419,59 @@ public function sharedIndexDataProvider(): array
317419 ];
318420 }
319421
422+ /**
423+ * @return array
424+ */
425+ public function suspendedIndexDataProvider (): array
426+ {
427+ return [
428+ 'Indexers ' => [
429+ 'indexers ' => [
430+ 'indexer_1 ' => [
431+ 'indexer_id ' => 'indexer_1 ' ,
432+ 'title ' => 'Title indexer 1 ' ,
433+ 'shared_index ' => null ,
434+ 'dependencies ' => []
435+ ],
436+ 'indexer_2 ' => [
437+ 'indexer_id ' => 'indexer_2 ' ,
438+ 'title ' => 'Title indexer 2 ' ,
439+ 'shared_index ' => 'common_shared_index ' ,
440+ 'dependencies ' => []
441+ ],
442+ 'indexer_3 ' => [
443+ 'indexer_id ' => 'indexer_3 ' ,
444+ 'title ' => 'Title indexer 3 ' ,
445+ 'shared_index ' => 'common_shared_index ' ,
446+ 'dependencies ' => []
447+ ]
448+ ],
449+ 'indexer_states ' => [
450+ 'indexer_1 ' => [
451+ StateInterface::STATUS_INVALID ,
452+ StateInterface::STATUS_INVALID ,
453+ StateInterface::STATUS_VALID
454+ ],
455+ 'indexer_2 ' => [
456+ StateInterface::STATUS_INVALID ,
457+ StateInterface::STATUS_INVALID ,
458+ StateInterface::STATUS_VALID
459+ ],
460+ 'indexer_3 ' => [
461+ StateInterface::STATUS_INVALID ,
462+ StateInterface::STATUS_INVALID ,
463+ StateInterface::STATUS_VALID
464+ ]
465+ ],
466+ 'expected_reindex_all_calls ' => [
467+ 'indexer_1 ' => $ this ->once (),
468+ 'indexer_2 ' => $ this ->never (),
469+ 'indexer_3 ' => $ this ->never ()
470+ ]
471+ ]
472+ ];
473+ }
474+
320475 /**
321476 * @param array $executedSharedIndexers
322477 *
0 commit comments