111 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
<?php
 | 
						|
/**
 | 
						|
 * Copyright © Magento, Inc. All rights reserved.
 | 
						|
 * See COPYING.txt for license details.
 | 
						|
 */
 | 
						|
namespace Magento\Test\Integrity;
 | 
						|
 | 
						|
use Magento\Framework\App\Utility\Files;
 | 
						|
 | 
						|
/**
 | 
						|
 * PAY ATTENTION: Current implementation does not support of virtual types
 | 
						|
 */
 | 
						|
class ObserverImplementationTest extends \PHPUnit\Framework\TestCase
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * Observer interface
 | 
						|
     */
 | 
						|
    const OBSERVER_INTERFACE = \Magento\Framework\Event\ObserverInterface::class;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var array
 | 
						|
     */
 | 
						|
    protected static $observerClasses = [];
 | 
						|
 | 
						|
    public static function setUpBeforeClass(): void
 | 
						|
    {
 | 
						|
        self::$observerClasses = array_merge(
 | 
						|
            self::getObserverClasses('{*/events.xml,events.xml}', '//observer')
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    public function testObserverInterfaceImplementation()
 | 
						|
    {
 | 
						|
        $errors = [];
 | 
						|
        foreach (self::$observerClasses as $observerClass) {
 | 
						|
            if (!is_subclass_of($observerClass, self::OBSERVER_INTERFACE)) {
 | 
						|
                $errors[] = $observerClass;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if ($errors) {
 | 
						|
            $errors = array_unique($errors);
 | 
						|
            sort($errors);
 | 
						|
            $this->fail(
 | 
						|
                sprintf(
 | 
						|
                    '%d of observers which not implement \Magento\Framework\Event\ObserverInterface: %s',
 | 
						|
                    count($errors),
 | 
						|
                    "\n" . implode("\n", $errors)
 | 
						|
                )
 | 
						|
            );
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function testObserverHasNoExtraPublicMethods()
 | 
						|
    {
 | 
						|
        $errors = [];
 | 
						|
        foreach (self::$observerClasses as $observerClass) {
 | 
						|
            $reflection = (new \ReflectionClass($observerClass));
 | 
						|
            $maxCountMethod = $reflection->getConstructor() ? 2 : 1;
 | 
						|
 | 
						|
            if (count($reflection->getMethods(\ReflectionMethod::IS_PUBLIC)) > $maxCountMethod) {
 | 
						|
                $errors[] = $observerClass;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if ($errors) {
 | 
						|
            $errors = array_unique($errors);
 | 
						|
            sort($errors);
 | 
						|
            $this->fail(
 | 
						|
                sprintf(
 | 
						|
                    '%d of observers have extra public methods: %s',
 | 
						|
                    count($errors),
 | 
						|
                    implode("\n", $errors)
 | 
						|
                )
 | 
						|
            );
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param string $fileNamePattern
 | 
						|
     * @param string $xpath
 | 
						|
     * @return array
 | 
						|
     */
 | 
						|
    protected static function getObserverClasses($fileNamePattern, $xpath)
 | 
						|
    {
 | 
						|
        $observerClasses = [];
 | 
						|
        foreach (Files::init()->getConfigFiles($fileNamePattern, [], false) as $configFile) {
 | 
						|
            foreach (simplexml_load_file($configFile)->xpath($xpath) as $observer) {
 | 
						|
                $className = (string)$observer->attributes()->instance;
 | 
						|
                // $className may be empty in cases like this <observer name="observer_name" disabled="true" />
 | 
						|
                if ($className) {
 | 
						|
                    $observerClasses[] = trim((string)$observer->attributes()->instance, '\\');
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        $blacklistFiles = str_replace('\\', '/', realpath(__DIR__)) . '/_files/blacklist/observers*.txt';
 | 
						|
        $blacklistExceptions = [];
 | 
						|
        foreach (glob($blacklistFiles) as $fileName) {
 | 
						|
            $blacklistExceptions = array_merge(
 | 
						|
                $blacklistExceptions,
 | 
						|
                file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
 | 
						|
            );
 | 
						|
        }
 | 
						|
        return array_diff(
 | 
						|
            array_unique($observerClasses),
 | 
						|
            $blacklistExceptions
 | 
						|
        );
 | 
						|
    }
 | 
						|
}
 |