@@ -451,6 +451,111 @@ function () use (&$indexers) {
451451 $ this ->model ->reindexAll ();
452452 }
453453
454+ public function testReindexAllWithSharedIndexers ()
455+ {
456+ $ indexId = 'indexer_internal_name ' ;
457+
458+ // Ensure dependencies considered up-to-date so reset flag is true
459+ $ this ->dependencyInfoProviderMock
460+ ->method ('getIndexerIdsToRunBefore ' )
461+ ->willReturn ([]);
462+
463+ // Configure current indexer config to have a shared_index
464+ $ sharedIndex = 'shared_idx ' ;
465+ $ this ->configMock
466+ ->method ('getIndexer ' )
467+ ->willReturnCallback (function ($ requestedId ) use ($ indexId , $ sharedIndex ) {
468+ if ($ requestedId === $ indexId ) {
469+ return [
470+ 'indexer_id ' => $ indexId ,
471+ 'view_id ' => 'view_test ' ,
472+ 'action_class ' => 'Some \\Class \\Name ' ,
473+ 'title ' => 'Indexer public name ' ,
474+ 'description ' => 'Indexer public description ' ,
475+ 'shared_index ' => $ sharedIndex ,
476+ ];
477+ }
478+ return match ($ requestedId ) {
479+ 'indexer_a ' => ['shared_index ' => $ sharedIndex ],
480+ 'indexer_b ' => ['shared_index ' => $ sharedIndex ],
481+ 'indexer_c ' => ['shared_index ' => 'other ' ],
482+ default => ['shared_index ' => null ],
483+ };
484+ });
485+
486+ // Provide available indexers map for getSharedIndexers() iteration
487+ $ this ->configMock
488+ ->method ('getIndexers ' )
489+ ->willReturn ([
490+ $ indexId => [],
491+ 'indexer_a ' => [],
492+ 'indexer_b ' => [],
493+ 'indexer_c ' => [],
494+ ]);
495+
496+ // Prepare shared indexer mocks returned by factory
497+ $ sharedIndexerA = $ this ->createMock (Indexer::class);
498+ $ sharedViewA = $ this ->createMock (ViewInterface::class);
499+ $ sharedIndexerA ->expects ($ this ->once ())->method ('load ' )->with ('indexer_a ' )->willReturnSelf ();
500+ $ sharedIndexerA ->expects ($ this ->atLeastOnce ())->method ('getView ' )->willReturn ($ sharedViewA );
501+ $ sharedViewA ->expects ($ this ->once ())->method ('isEnabled ' )->willReturn (true );
502+ $ sharedViewA ->expects ($ this ->once ())->method ('suspend ' );
503+ $ sharedViewA ->expects ($ this ->once ())->method ('resume ' );
504+
505+ $ sharedIndexerB = $ this ->createMock (Indexer::class);
506+ $ sharedViewB = $ this ->createMock (ViewInterface::class);
507+ $ sharedIndexerB ->expects ($ this ->once ())->method ('load ' )->with ('indexer_b ' )->willReturnSelf ();
508+ $ sharedIndexerB ->expects ($ this ->atLeastOnce ())->method ('getView ' )->willReturn ($ sharedViewB );
509+ $ sharedViewB ->expects ($ this ->once ())->method ('isEnabled ' )->willReturn (true );
510+ $ sharedViewB ->expects ($ this ->once ())->method ('suspend ' );
511+ $ sharedViewB ->expects ($ this ->once ())->method ('resume ' );
512+
513+ $ this ->indexerFactoryMock
514+ ->expects ($ this ->exactly (2 ))
515+ ->method ('create ' )
516+ ->willReturnOnConsecutiveCalls ($ sharedIndexerA , $ sharedIndexerB );
517+
518+ // Model state expectations
519+ $ this ->workingStateProvider ->method ('isWorking ' )->willReturnOnConsecutiveCalls (false , true );
520+ $ stateMock = $ this ->createPartialMock (
521+ State::class,
522+ ['load ' , 'getId ' , 'setIndexerId ' , '__wakeup ' , 'getStatus ' , 'setStatus ' , 'save ' ]
523+ );
524+ $ stateMock ->expects ($ this ->once ())
525+ ->method ('load ' )->with ($ indexId , 'indexer_id ' )->willReturnSelf ();
526+ $ stateMock ->expects ($ this ->never ())->method ('setIndexerId ' );
527+ $ stateMock ->expects ($ this ->once ())->method ('getId ' )->willReturn (1 );
528+ $ stateMock ->expects ($ this ->exactly (3 ))->method ('setStatus ' )->willReturnSelf ();
529+ $ stateMock ->expects ($ this ->any ())->method ('getStatus ' )->willReturn ('idle ' );
530+ $ stateMock ->expects ($ this ->exactly (3 ))->method ('save ' )->willReturnSelf ();
531+ $ this ->stateFactoryMock ->expects ($ this ->once ())->method ('create ' )->willReturn ($ stateMock );
532+
533+ // Current indexer view
534+ $ this ->viewMock ->expects ($ this ->once ())->method ('isEnabled ' )->willReturn (true );
535+ $ this ->viewMock ->expects ($ this ->once ())->method ('suspend ' );
536+ $ this ->viewMock ->expects ($ this ->once ())->method ('resume ' );
537+
538+ // Action execution
539+ $ actionMock = $ this ->createPartialMock (
540+ ActionInterface::class,
541+ ['executeFull ' , 'executeList ' , 'executeRow ' ]
542+ );
543+ $ this ->actionFactoryMock ->expects ($ this ->once ())->method ('create ' )->with ('Some \\Class \\Name ' )
544+ ->willReturn ($ actionMock );
545+
546+ // Prepare model with ID set and required data
547+ $ this ->model ->setId ($ indexId );
548+ $ this ->model ->setData ([
549+ 'indexer_id ' => $ indexId ,
550+ 'view_id ' => 'view_test ' ,
551+ 'action_class ' => 'Some \\Class \\Name ' ,
552+ 'title ' => 'Indexer public name ' ,
553+ 'description ' => 'Indexer public description ' ,
554+ ]);
555+
556+ $ this ->model ->reindexAll ();
557+ }
558+
454559 /**
455560 * @return array
456561 */
@@ -581,7 +686,8 @@ public static function statusDataProvider()
581686 return [
582687 ['isValid ' , StateInterface::STATUS_VALID ],
583688 ['isInvalid ' , StateInterface::STATUS_INVALID ],
584- ['isWorking ' , StateInterface::STATUS_WORKING ]
689+ ['isWorking ' , StateInterface::STATUS_WORKING ],
690+ ['isSuspended ' , StateInterface::STATUS_SUSPENDED ]
585691 ];
586692 }
587693
@@ -646,4 +752,93 @@ public function testReindexList()
646752 $ actionMock ->expects ($ this ->once ())->method ('executeList ' )->with ($ ids )->willReturnSelf ();
647753 $ this ->model ->reindexList ($ ids );
648754 }
755+
756+ public function testGetFields ()
757+ {
758+ $ indexId = 'indexer_internal_name ' ;
759+ $ this ->loadIndexer ($ indexId );
760+
761+ $ expected = ['field_a ' , 'field_b ' ];
762+ $ this ->model ->setData ('fields ' , $ expected );
763+
764+ $ this ->assertEquals ($ expected , $ this ->model ->getFields ());
765+ }
766+
767+ public function testGetSources ()
768+ {
769+ $ indexId = 'indexer_internal_name ' ;
770+ $ this ->loadIndexer ($ indexId );
771+
772+ $ expected = ['source_a ' ];
773+ $ this ->model ->setData ('sources ' , $ expected );
774+
775+ $ this ->assertEquals ($ expected , $ this ->model ->getSources ());
776+ }
777+
778+ public function testGetHandlers ()
779+ {
780+ $ indexId = 'indexer_internal_name ' ;
781+ $ this ->loadIndexer ($ indexId );
782+
783+ $ expected = ['handler_a ' ];
784+ $ this ->model ->setData ('handlers ' , $ expected );
785+
786+ $ this ->assertEquals ($ expected , $ this ->model ->getHandlers ());
787+ }
788+
789+ public function testGetStructureInstanceCreatesStructureWhenConfigured ()
790+ {
791+ $ structureConfig = ['type ' => 'custom ' ];
792+
793+ $ structureFactory = $ this ->getMockBuilder (StructureFactory::class)
794+ ->disableOriginalConstructor ()
795+ ->onlyMethods (['create ' ])
796+ ->getMock ();
797+
798+ $ structureInstance = $ this ->createMock (\Magento \Framework \Indexer \IndexStructureInterface::class);
799+ $ structureFactory ->expects ($ this ->once ())
800+ ->method ('create ' )
801+ ->with ($ structureConfig )
802+ ->willReturn ($ structureInstance );
803+
804+ $ actionMock = $ this ->createPartialMock (
805+ ActionInterface::class,
806+ ['executeFull ' , 'executeList ' , 'executeRow ' ]
807+ );
808+
809+ $ this ->actionFactoryMock ->expects ($ this ->once ())
810+ ->method ('create ' )
811+ ->with (
812+ 'Some \\Class \\Name ' ,
813+ $ this ->callback (function ($ args ) use ($ structureInstance ) {
814+ return isset ($ args ['indexStructure ' ]) && $ args ['indexStructure ' ] === $ structureInstance ;
815+ })
816+ )
817+ ->willReturn ($ actionMock );
818+
819+ $ stateMock = $ this ->createPartialMock (State::class, ['save ' ]);
820+ $ stateMock ->expects ($ this ->once ())->method ('save ' )->willReturnSelf ();
821+
822+ $ model = new Indexer (
823+ $ this ->configMock ,
824+ $ this ->actionFactoryMock ,
825+ $ structureFactory ,
826+ $ this ->viewMock ,
827+ $ this ->stateFactoryMock ,
828+ $ this ->indexFactoryMock ,
829+ $ this ->workingStateProvider ,
830+ $ this ->indexerFactoryMock ,
831+ [],
832+ $ this ->dependencyInfoProviderMock
833+ );
834+ $ model ->setState ($ stateMock );
835+ $ model ->setData ([
836+ 'action_class ' => 'Some \\Class \\Name ' ,
837+ 'structure ' => $ structureConfig ,
838+ ]);
839+
840+ $ actionMock ->expects ($ this ->once ())->method ('executeRow ' )->with (123 )->willReturnSelf ();
841+
842+ $ model ->reindexRow (123 );
843+ }
649844}
0 commit comments