196 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
<?php
 | 
						|
/**
 | 
						|
 * Copyright © Magento, Inc. All rights reserved.
 | 
						|
 * See COPYING.txt for license details.
 | 
						|
 */
 | 
						|
declare(strict_types=1);
 | 
						|
 | 
						|
namespace Magento\Framework\App;
 | 
						|
 | 
						|
use Magento\Framework\Event\ManagerInterface;
 | 
						|
use Magento\TestFramework\ObjectManager;
 | 
						|
use Magento\TestFramework\Request as TestHttpRequest;
 | 
						|
use Magento\TestFramework\Response;
 | 
						|
use PHPUnit\Framework\TestCase;
 | 
						|
 | 
						|
/**
 | 
						|
 * @magentoAppIsolation enabled
 | 
						|
 */
 | 
						|
class FrontControllerEventsTest extends TestCase
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * @var ManagerInterface
 | 
						|
     */
 | 
						|
    private $eventManager;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var ObjectManager
 | 
						|
     */
 | 
						|
    private $objectManager;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var TestHttpRequest
 | 
						|
     */
 | 
						|
    private $request;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @inheritDoc
 | 
						|
     */
 | 
						|
    protected function setUp(): void
 | 
						|
    {
 | 
						|
        $this->objectManager = ObjectManager::getInstance();
 | 
						|
        $this->setupEventManagerSpy();
 | 
						|
        $this->eventManager = $this->objectManager->get(ManagerInterface::class);
 | 
						|
        $this->request = $this->objectManager->get(TestHttpRequest::class);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test if frontend controller dispatches events
 | 
						|
     *
 | 
						|
     * @magentoAppArea frontend
 | 
						|
     *
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    public function testFrontendControllerDispatchesEvents(): void
 | 
						|
    {
 | 
						|
        $this->setupEventManagerSpy();
 | 
						|
 | 
						|
        /** @var FrontControllerInterface $frontController */
 | 
						|
        $frontController = ObjectManager::getInstance()->create(FrontControllerInterface::class);
 | 
						|
        $this->configureRequestForAction('cms', 'index', 'index');
 | 
						|
        $frontController->dispatch($this->request);
 | 
						|
 | 
						|
        $this->assertPreAndPostDispatchEventsAreDispatched();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test if no dispatch flag prevents dispatching action
 | 
						|
     *
 | 
						|
     * @magentoAppArea frontend
 | 
						|
     *
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    public function testSettingTheNoDispatchActionFlagProhibitsExecuteAndPostdispatchEvents(): void
 | 
						|
    {
 | 
						|
        $this->setupEventManagerSpy();
 | 
						|
 | 
						|
        /** @var FrontControllerInterface $frontController */
 | 
						|
        $frontController = ObjectManager::getInstance()->create(FrontControllerInterface::class);
 | 
						|
        $this->configureRequestForAction('cms', 'index', 'index');
 | 
						|
 | 
						|
        /** @var ActionFlag $actionFlag */
 | 
						|
        $actionFlag = ObjectManager::getInstance()->get(ActionFlag::class);
 | 
						|
        $actionFlag->set('', ActionInterface::FLAG_NO_DISPATCH, true);
 | 
						|
 | 
						|
        $result1 = $frontController->dispatch($this->request);
 | 
						|
        $this->assertTrue($result1 instanceof Response, 'Action was dispatched!');
 | 
						|
        $this->assertPreDispatchEventsAreDispatched();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Prepare spy on event manager
 | 
						|
     *
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    public function setupEventManagerSpy(): void
 | 
						|
    {
 | 
						|
        $eventManager = $this->objectManager->get(ManagerInterface::class);
 | 
						|
        $eventManagerSpy = new class($eventManager) implements ManagerInterface {
 | 
						|
            /**
 | 
						|
             * @var ManagerInterface
 | 
						|
             */
 | 
						|
            private $delegate;
 | 
						|
 | 
						|
            /**
 | 
						|
             * @var array[];
 | 
						|
             */
 | 
						|
            private $dispatchedEvents;
 | 
						|
 | 
						|
            /**
 | 
						|
             * @param ManagerInterface $delegate
 | 
						|
             */
 | 
						|
            public function __construct(ManagerInterface $delegate)
 | 
						|
            {
 | 
						|
                $this->delegate = $delegate;
 | 
						|
            }
 | 
						|
 | 
						|
            public function dispatch($eventName, array $data = [])
 | 
						|
            {
 | 
						|
                $this->dispatchedEvents[$eventName][] = [$eventName, $data];
 | 
						|
                $this->delegate->dispatch($eventName, $data);
 | 
						|
            }
 | 
						|
 | 
						|
            public function spyOnDispatchedEvent(string $eventName): array
 | 
						|
            {
 | 
						|
                return $this->dispatchedEvents[$eventName] ?? [];
 | 
						|
            }
 | 
						|
        };
 | 
						|
 | 
						|
        $this->objectManager->addSharedInstance($eventManagerSpy, get_class($eventManager));
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Check if event was dispatched exactly as many times as expected
 | 
						|
     *
 | 
						|
     * @param string $eventName
 | 
						|
     * @param int $expectedCount
 | 
						|
     *
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    private function assertEventDispatchCount(string $eventName, int $expectedCount): void
 | 
						|
    {
 | 
						|
        $message = sprintf('Event %s was expected to be dispatched %d time(s).', $eventName, $expectedCount);
 | 
						|
        $this->assertCount($expectedCount, $this->eventManager->spyOnDispatchedEvent($eventName), $message);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Prepare request for test action
 | 
						|
     *
 | 
						|
     * @param string $route
 | 
						|
     * @param string $actionPath
 | 
						|
     * @param string $actionName
 | 
						|
     *
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    private function configureRequestForAction(string $route, string $actionPath, string $actionName): void
 | 
						|
    {
 | 
						|
        $request = $this->request;
 | 
						|
 | 
						|
        $request->setRouteName($route);
 | 
						|
        $request->setControllerName($actionPath);
 | 
						|
        $request->setActionName($actionName);
 | 
						|
        $request->setDispatched();
 | 
						|
        $request->setRequestUri("$route/$actionPath/$actionName");
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Check events dispatched before and after execute
 | 
						|
     *
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    private function assertPreAndPostDispatchEventsAreDispatched(): void
 | 
						|
    {
 | 
						|
        $this->assertEventDispatchCount('controller_action_predispatch', 1);
 | 
						|
        $this->assertEventDispatchCount('controller_action_predispatch_cms', 1);
 | 
						|
        $this->assertEventDispatchCount('controller_action_predispatch_cms_index_index', 1);
 | 
						|
        $this->assertEventDispatchCount('controller_action_postdispatch_cms_index_index', 1);
 | 
						|
        $this->assertEventDispatchCount('controller_action_postdispatch_cms', 1);
 | 
						|
        $this->assertEventDispatchCount('controller_action_postdispatch', 1);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Check events are dispatched only before execute
 | 
						|
     *
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    private function assertPreDispatchEventsAreDispatched(): void
 | 
						|
    {
 | 
						|
        $this->assertEventDispatchCount('controller_action_predispatch', 1);
 | 
						|
        $this->assertEventDispatchCount('controller_action_predispatch_cms', 1);
 | 
						|
        $this->assertEventDispatchCount('controller_action_predispatch_cms_index_index', 1);
 | 
						|
        $this->assertEventDispatchCount('controller_action_postdispatch_cms_index_index', 0);
 | 
						|
        $this->assertEventDispatchCount('controller_action_postdispatch_cms', 0);
 | 
						|
        $this->assertEventDispatchCount('controller_action_postdispatch', 0);
 | 
						|
    }
 | 
						|
}
 |