From: Philipp Date: Fri, 21 Jul 2023 20:41:36 +0000 (+0200) Subject: Adhere feedback X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=cba656383eb3af306fcd62752620c241a76960f1;p=friendica.git Adhere feedback - rename hooks.config.php to strategies.config.php - change all corresponding classes and tests --- diff --git a/doc/StrategyHooks.md b/doc/StrategyHooks.md index cb355f93f0..39fc1bd8df 100644 --- a/doc/StrategyHooks.md +++ b/doc/StrategyHooks.md @@ -43,7 +43,7 @@ public class ConcreteClassB implements ExampleInterface } } -/** @var \Friendica\Core\Hooks\Capabilities\ICanRegisterInstances $instanceRegister */ +/** @var \Friendica\Core\Hooks\Capabilities\ICanRegisterStrategies $instanceRegister */ $instanceRegister->registerStrategy(ExampleInterface::class, ConcreteClassA::class, 'A'); $instanceRegister->registerStrategy(ExampleInterface::class, ConcreteClassB::class, 'B'); diff --git a/src/Core/Hooks/Capabilities/ICanCreateInstances.php b/src/Core/Hooks/Capabilities/ICanCreateInstances.php index f2e4b8b0a1..77d4c4b366 100644 --- a/src/Core/Hooks/Capabilities/ICanCreateInstances.php +++ b/src/Core/Hooks/Capabilities/ICanCreateInstances.php @@ -32,10 +32,10 @@ interface ICanCreateInstances * The instance will be build based on the registered strategy and the (unique) name * * @param string $class The fully-qualified name of the given class or interface which will get returned - * @param string $name An arbitrary identifier to find a concrete instance strategy. + * @param string $strategy An arbitrary identifier to find a concrete instance strategy. * @param array $arguments Additional arguments, which can be passed to the constructor of "$class" at runtime * * @return object The concrete instance of the type "$class" */ - public function create(string $class, string $name, array $arguments = []): object; + public function create(string $class, string $strategy, array $arguments = []): object; } diff --git a/src/Core/Hooks/Capabilities/ICanRegisterInstances.php b/src/Core/Hooks/Capabilities/ICanRegisterInstances.php deleted file mode 100644 index f7689bbee7..0000000000 --- a/src/Core/Hooks/Capabilities/ICanRegisterInstances.php +++ /dev/null @@ -1,46 +0,0 @@ -. - * - */ - -namespace Friendica\Core\Hooks\Capabilities; - -use Friendica\Core\Hooks\Exceptions\HookRegisterArgumentException; - -/** - * Register strategies for given classes - */ -interface ICanRegisterInstances -{ - /** - * Register a class(strategy) for a given interface with a unique name. - * - * @see https://refactoring.guru/design-patterns/strategy - * - * @param string $interface The interface, which the given class implements - * @param string $class The fully-qualified given class name - * A placeholder for dependencies is possible as well - * @param ?string $name An arbitrary identifier for the given class, which will be used for factories, dependency injections etc. - * - * @return $this This interface for chain-calls - * - * @throws HookRegisterArgumentException in case the given class for the interface isn't valid or already set - */ - public function registerStrategy(string $interface, string $class, ?string $name = null): self; -} diff --git a/src/Core/Hooks/Capabilities/ICanRegisterStrategies.php b/src/Core/Hooks/Capabilities/ICanRegisterStrategies.php new file mode 100644 index 0000000000..911eb3499f --- /dev/null +++ b/src/Core/Hooks/Capabilities/ICanRegisterStrategies.php @@ -0,0 +1,46 @@ +. + * + */ + +namespace Friendica\Core\Hooks\Capabilities; + +use Friendica\Core\Hooks\Exceptions\HookRegisterArgumentException; + +/** + * Register strategies for given classes + */ +interface ICanRegisterStrategies +{ + /** + * Register a class(strategy) for a given interface with a unique name. + * + * @see https://refactoring.guru/design-patterns/strategy + * + * @param string $interface The interface, which the given class implements + * @param string $class The fully-qualified given class name + * A placeholder for dependencies is possible as well + * @param ?string $name An arbitrary identifier for the given strategy, which will be used for factories, dependency injections etc. + * + * @return $this This interface for chain-calls + * + * @throws HookRegisterArgumentException in case the given class for the interface isn't valid or already set + */ + public function registerStrategy(string $interface, string $class, ?string $name = null): self; +} diff --git a/src/Core/Hooks/Model/DiceInstanceManager.php b/src/Core/Hooks/Model/DiceInstanceManager.php index 77b9c4d495..a8b0b540ce 100644 --- a/src/Core/Hooks/Model/DiceInstanceManager.php +++ b/src/Core/Hooks/Model/DiceInstanceManager.php @@ -23,31 +23,31 @@ namespace Friendica\Core\Hooks\Model; use Dice\Dice; use Friendica\Core\Hooks\Capabilities\ICanCreateInstances; -use Friendica\Core\Hooks\Capabilities\ICanRegisterInstances; +use Friendica\Core\Hooks\Capabilities\ICanRegisterStrategies; use Friendica\Core\Hooks\Exceptions\HookInstanceException; use Friendica\Core\Hooks\Exceptions\HookRegisterArgumentException; -use Friendica\Core\Hooks\Util\HookFileManager; +use Friendica\Core\Hooks\Util\StrategiesFileManager; /** * This class represents an instance register, which uses Dice for creation * * @see Dice */ -class DiceInstanceManager implements ICanCreateInstances, ICanRegisterInstances +class DiceInstanceManager implements ICanCreateInstances, ICanRegisterStrategies { protected $instance = []; /** @var Dice */ protected $dice; - public function __construct(Dice $dice, HookFileManager $hookFileManager) + public function __construct(Dice $dice, StrategiesFileManager $strategiesFileManager) { $this->dice = $dice; - $hookFileManager->setupHooks($this); + $strategiesFileManager->setupStrategies($this); } /** {@inheritDoc} */ - public function registerStrategy(string $interface, string $class, ?string $name = null): ICanRegisterInstances + public function registerStrategy(string $interface, string $class, ?string $name = null): ICanRegisterStrategies { if (!empty($this->instance[$interface][$name])) { throw new HookRegisterArgumentException(sprintf('A class with the name %s is already set for the interface %s', $name, $interface)); @@ -59,12 +59,12 @@ class DiceInstanceManager implements ICanCreateInstances, ICanRegisterInstances } /** {@inheritDoc} */ - public function create(string $class, string $name, array $arguments = []): object + public function create(string $class, string $strategy, array $arguments = []): object { - if (empty($this->instance[$class][$name])) { - throw new HookInstanceException(sprintf('The class with the name %s isn\'t registered for the class or interface %s', $name, $class)); + if (empty($this->instance[$class][$strategy])) { + throw new HookInstanceException(sprintf('The class with the name %s isn\'t registered for the class or interface %s', $strategy, $class)); } - return $this->dice->create($this->instance[$class][$name], $arguments); + return $this->dice->create($this->instance[$class][$strategy], $arguments); } } diff --git a/src/Core/Hooks/Util/HookFileManager.php b/src/Core/Hooks/Util/HookFileManager.php deleted file mode 100644 index b83f2b49c6..0000000000 --- a/src/Core/Hooks/Util/HookFileManager.php +++ /dev/null @@ -1,107 +0,0 @@ -. - * - */ - -namespace Friendica\Core\Hooks\Util; - -use Friendica\Core\Addon\Capabilities\ICanLoadAddons; -use Friendica\Core\Hooks\Capabilities\BehavioralHookType; -use Friendica\Core\Hooks\Capabilities\ICanRegisterInstances; -use Friendica\Core\Hooks\Exceptions\HookConfigException; - -/** - * Manage all hooks.config.php files - */ -class HookFileManager -{ - const STATIC_DIR = 'static'; - const CONFIG_NAME = 'hooks'; - - /** @var ICanLoadAddons */ - protected $addonLoader; - /** @var array */ - protected $hookConfig = []; - /** @var string */ - protected $basePath; - - public function __construct(string $basePath, ICanLoadAddons $addonLoader) - { - $this->basePath = $basePath; - $this->addonLoader = $addonLoader; - } - - /** - * Loads all kinds of hooks and registers the corresponding instances - * - * @param ICanRegisterInstances $instanceRegister The instance register - * - * @return void - */ - public function setupHooks(ICanRegisterInstances $instanceRegister) - { - // In case it wasn't used before, reload the whole hook config - if (empty($this->hookConfig)) { - $this->reloadHookConfig(); - } - - foreach ($this->hookConfig as $hookType => $classList) { - switch ($hookType) { - case BehavioralHookType::STRATEGY: - foreach ($classList as $interface => $strategy) { - foreach ($strategy as $dependencyName => $names) { - if (is_array($names)) { - foreach ($names as $name) { - $instanceRegister->registerStrategy($interface, $dependencyName, $name); - } - } else { - $instanceRegister->registerStrategy($interface, $dependencyName, $names); - } - } - } - break; - } - } - } - - /** - * Reloads all hook config files into the config cache for later usage - * - * Merges all hook configs from every addon - if present - as well - * - * @return void - */ - protected function reloadHookConfig() - { - // load core hook config - $configFile = $this->basePath . '/' . static::STATIC_DIR . '/' . static::CONFIG_NAME . '.config.php'; - - if (!file_exists($configFile)) { - throw new HookConfigException(sprintf('config file %s does not exist.', $configFile)); - } - - $config = include $configFile; - - if (!is_array($config)) { - throw new HookConfigException(sprintf('Error loading config file %s.', $configFile)); - } - - $this->hookConfig = array_merge_recursive($config, $this->addonLoader->getActiveAddonConfig(static::CONFIG_NAME)); - } -} diff --git a/src/Core/Hooks/Util/StrategiesFileManager.php b/src/Core/Hooks/Util/StrategiesFileManager.php new file mode 100644 index 0000000000..700c401f2b --- /dev/null +++ b/src/Core/Hooks/Util/StrategiesFileManager.php @@ -0,0 +1,95 @@ +. + * + */ + +namespace Friendica\Core\Hooks\Util; + +use Friendica\Core\Addon\Capabilities\ICanLoadAddons; +use Friendica\Core\Hooks\Capabilities\ICanRegisterStrategies; +use Friendica\Core\Hooks\Exceptions\HookConfigException; + +/** + * Manage all strategies.config.php files + */ +class StrategiesFileManager +{ + const STATIC_DIR = 'static'; + const CONFIG_NAME = 'strategies'; + + /** @var ICanLoadAddons */ + protected $addonLoader; + /** @var array */ + protected $config = []; + /** @var string */ + protected $basePath; + + public function __construct(string $basePath, ICanLoadAddons $addonLoader) + { + $this->basePath = $basePath; + $this->addonLoader = $addonLoader; + } + + /** + * Loads all kinds of hooks and registers the corresponding instances + * + * @param ICanRegisterStrategies $instanceRegister The instance register + * + * @return void + */ + public function setupStrategies(ICanRegisterStrategies $instanceRegister) + { + foreach ($this->config as $interface => $strategy) { + foreach ($strategy as $dependencyName => $names) { + if (is_array($names)) { + foreach ($names as $name) { + $instanceRegister->registerStrategy($interface, $dependencyName, $name); + } + } else { + $instanceRegister->registerStrategy($interface, $dependencyName, $names); + } + } + } + } + + /** + * Reloads all hook config files into the config cache for later usage + * + * Merges all hook configs from every addon - if present - as well + * + * @return void + */ + public function loadConfig() + { + // load core hook config + $configFile = $this->basePath . '/' . static::STATIC_DIR . '/' . static::CONFIG_NAME . '.config.php'; + + if (!file_exists($configFile)) { + throw new HookConfigException(sprintf('config file %s does not exist.', $configFile)); + } + + $config = include $configFile; + + if (!is_array($config)) { + throw new HookConfigException(sprintf('Error loading config file %s.', $configFile)); + } + + $this->config = array_merge_recursive($config, $this->addonLoader->getActiveAddonConfig(static::CONFIG_NAME)); + } +} diff --git a/src/Core/Logger/Factory/Logger.php b/src/Core/Logger/Factory/Logger.php index 81f8887efc..c370cc4dd7 100644 --- a/src/Core/Logger/Factory/Logger.php +++ b/src/Core/Logger/Factory/Logger.php @@ -43,7 +43,7 @@ class Logger $this->channel = $channel; } - public function create(ICanCreateInstances $createInstances, IManageConfigValues $config, Profiler $profiler): LoggerInterface + public function create(ICanCreateInstances $instanceCreator, IManageConfigValues $config, Profiler $profiler): LoggerInterface { if (empty($config->get('system', 'debugging') ?? false)) { return new NullLogger(); @@ -53,7 +53,7 @@ class Logger try { /** @var LoggerInterface $logger */ - $logger = $createInstances->create(LoggerInterface::class, $name, [$this->channel]); + $logger = $instanceCreator->create(LoggerInterface::class, $name, [$this->channel]); if ($config->get('system', 'profiling') ?? false) { return new ProfilerLoggerClass($logger, $profiler); } else { diff --git a/src/DI.php b/src/DI.php index c62b5e8d79..1917f710d3 100644 --- a/src/DI.php +++ b/src/DI.php @@ -297,7 +297,7 @@ abstract class DI static::init($flushDice); } - public static function loggCheck(): ICheckLoggerSettings + public static function logCheck(): ICheckLoggerSettings { return self::$dice->create(LoggerSettingsCheck::class); } diff --git a/src/Module/Admin/Summary.php b/src/Module/Admin/Summary.php index 80437305dc..99d0e3325b 100644 --- a/src/Module/Admin/Summary.php +++ b/src/Module/Admin/Summary.php @@ -126,10 +126,10 @@ class Summary extends BaseAdmin } // Check logfile permission - if (($return = DI::loggCheck()->checkLogfile()) !== null) { + if (($return = DI::logCheck()->checkLogfile()) !== null) { $warningtext[] = $return; } - if (($return = DI::loggCheck()->checkDebugLogfile()) !== null) { + if (($return = DI::logCheck()->checkDebugLogfile()) !== null) { $warningtext[] = $return; } diff --git a/static/dependencies.config.php b/static/dependencies.config.php index ce8a5bd9df..98a9f3077d 100644 --- a/static/dependencies.config.php +++ b/static/dependencies.config.php @@ -38,7 +38,7 @@ use Friendica\App; use Friendica\Core\Cache; use Friendica\Core\Config; use Friendica\Core\Hooks\Capabilities\ICanCreateInstances; -use Friendica\Core\Hooks\Capabilities\ICanRegisterInstances; +use Friendica\Core\Hooks\Capabilities\ICanRegisterStrategies; use Friendica\Core\Hooks\Model\DiceInstanceManager; use Friendica\Core\PConfig; use Friendica\Core\L10n; @@ -91,12 +91,15 @@ return [ [Dice::INSTANCE => Dice::SELF], ] ], - \Friendica\Core\Hooks\Util\HookFileManager::class => [ + \Friendica\Core\Hooks\Util\StrategiesFileManager::class => [ 'constructParams' => [ [Dice::INSTANCE => '$basepath'], ], + 'call' => [ + ['loadConfig'], + ], ], - ICanRegisterInstances::class => [ + ICanRegisterStrategies::class => [ 'instanceOf' => DiceInstanceManager::class, 'constructParams' => [ [Dice::INSTANCE => Dice::SELF], diff --git a/static/hooks.config.php b/static/hooks.config.php deleted file mode 100644 index d46762f871..0000000000 --- a/static/hooks.config.php +++ /dev/null @@ -1,34 +0,0 @@ -. - * - */ - -use Friendica\Core\Hooks\Capabilities\BehavioralHookType as H; -use Friendica\Core\Logger\Type; -use Psr\Log; - -return [ - H::STRATEGY => [ - Log\LoggerInterface::class => [ - Log\NullLogger::class => [''], - Type\SyslogLogger::class => ['syslog'], - Type\StreamLogger::class => ['stream'], - ], - ], -]; diff --git a/static/strategies.config.php b/static/strategies.config.php new file mode 100644 index 0000000000..bb3598c369 --- /dev/null +++ b/static/strategies.config.php @@ -0,0 +1,32 @@ +. + * + */ + +use Friendica\Core\Hooks\Capabilities\BehavioralHookType as H; +use Friendica\Core\Logger\Type; +use Psr\Log; + +return [ + Log\LoggerInterface::class => [ + Log\NullLogger::class => [''], + Type\SyslogLogger::class => ['syslog'], + Type\StreamLogger::class => ['stream'], + ], +]; diff --git a/tests/src/Core/Hooks/Model/InstanceManagerTest.php b/tests/src/Core/Hooks/Model/InstanceManagerTest.php index de2bdc6b83..44459eb2ee 100644 --- a/tests/src/Core/Hooks/Model/InstanceManagerTest.php +++ b/tests/src/Core/Hooks/Model/InstanceManagerTest.php @@ -25,7 +25,7 @@ use Dice\Dice; use Friendica\Core\Hooks\Exceptions\HookInstanceException; use Friendica\Core\Hooks\Exceptions\HookRegisterArgumentException; use Friendica\Core\Hooks\Model\DiceInstanceManager; -use Friendica\Core\Hooks\Util\HookFileManager; +use Friendica\Core\Hooks\Util\StrategiesFileManager; use Friendica\Test\MockedTest; use Friendica\Test\Util\Hooks\InstanceMocks\FakeInstance; use Friendica\Test\Util\Hooks\InstanceMocks\FakeInstanceDecorator; @@ -34,15 +34,15 @@ use Mockery\MockInterface; class InstanceManagerTest extends MockedTest { - /** @var HookFileManager|MockInterface */ + /** @var StrategiesFileManager|MockInterface */ protected $hookFileManager; protected function setUp(): void { parent::setUp(); - $this->hookFileManager = \Mockery::mock(HookFileManager::class); - $this->hookFileManager->shouldReceive('setupHooks')->withAnyArgs(); + $this->hookFileManager = \Mockery::mock(StrategiesFileManager::class); + $this->hookFileManager->shouldReceive('setupStrategies')->withAnyArgs(); } protected function tearDown(): void diff --git a/tests/src/Core/Hooks/Util/HookFileManagerTest.php b/tests/src/Core/Hooks/Util/HookFileManagerTest.php deleted file mode 100644 index f718e8a92f..0000000000 --- a/tests/src/Core/Hooks/Util/HookFileManagerTest.php +++ /dev/null @@ -1,240 +0,0 @@ -. - * - */ - -namespace Friendica\Test\src\Core\Hooks\Util; - -use Friendica\Core\Addon\Capabilities\ICanLoadAddons; -use Friendica\Core\Hooks\Capabilities\ICanRegisterInstances; -use Friendica\Core\Hooks\Exceptions\HookConfigException; -use Friendica\Core\Hooks\Util\HookFileManager; -use Friendica\Test\MockedTest; -use Friendica\Test\Util\VFSTrait; -use org\bovigo\vfs\vfsStream; -use Psr\Log\LoggerInterface; -use Psr\Log\NullLogger; - -class HookFileManagerTest extends MockedTest -{ - use VFSTrait; - - protected function setUp(): void - { - parent::setUp(); - - $this->setUpVfsDir(); - } - - public function dataHooks(): array - { - return [ - 'normal' => [ - 'content' => << [ - \Psr\Log\LoggerInterface::class => [ - \Psr\Log\NullLogger::class => [''], - ], - ], -]; -EOF, - 'addonsArray' => [], - 'assertStrategies' => [ - [LoggerInterface::class, NullLogger::class, ''], - ], - ], - 'normalWithString' => [ - 'content' => << [ - \Psr\Log\LoggerInterface::class => [ - \Psr\Log\NullLogger::class => '', - ], - ], -]; -EOF, - 'addonsArray' => [], - 'assertStrategies' => [ - [LoggerInterface::class, NullLogger::class, ''], - ], - ], - 'withAddons' => [ - 'content' => << [ - \Psr\Log\LoggerInterface::class => [ - \Psr\Log\NullLogger::class => [''], - ], - ], -]; -EOF, - 'addonsArray' => [ - \Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [ - \Psr\Log\LoggerInterface::class => [ - \Psr\Log\NullLogger::class => ['null'], - ], - ], - ], - 'assertStrategies' => [ - [LoggerInterface::class, NullLogger::class, ''], - [LoggerInterface::class, NullLogger::class, 'null'], - ], - ], - 'withAddonsWithString' => [ - 'content' => << [ - \Psr\Log\LoggerInterface::class => [ - \Psr\Log\NullLogger::class => [''], - ], - ], -]; -EOF, - 'addonsArray' => [ - \Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [ - \Psr\Log\LoggerInterface::class => [ - \Psr\Log\NullLogger::class => 'null', - ], - ], - ], - 'assertStrategies' => [ - [LoggerInterface::class, NullLogger::class, ''], - [LoggerInterface::class, NullLogger::class, 'null'], - ], - ], - // This should work because unique name convention is part of the instance manager logic, not of the file-infrastructure layer - 'withAddonsDoubleNamed' => [ - 'content' => << [ - \Psr\Log\LoggerInterface::class => [ - \Psr\Log\NullLogger::class => [''], - ], - ], -]; -EOF, - 'addonsArray' => [ - \Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [ - \Psr\Log\LoggerInterface::class => [ - \Psr\Log\NullLogger::class => [''], - ], - ], - ], - 'assertStrategies' => [ - [LoggerInterface::class, NullLogger::class, ''], - [LoggerInterface::class, NullLogger::class, ''], - ], - ], - 'withWrongContentButAddons' => [ - 'content' => << [ - \Psr\Log\LoggerInterface::class => [ - \Psr\Log\NullLogger::class => [''], - ], - ], -]; -EOF, - 'addonsArray' => [ - \Friendica\Core\Hooks\Capabilities\BehavioralHookType::STRATEGY => [ - \Psr\Log\LoggerInterface::class => [ - \Psr\Log\NullLogger::class => [''], - ], - ], - ], - 'assertStrategies' => [ - [LoggerInterface::class, NullLogger::class, ''], - ], - ], - ]; - } - - /** - * @dataProvider dataHooks - */ - public function testSetupHooks(string $content, array $addonsArray, array $assertStrategies) - { - vfsStream::newFile('static/hooks.config.php') - ->withContent($content) - ->at($this->root); - - $addonLoader = \Mockery::mock(ICanLoadAddons::class); - $addonLoader->shouldReceive('getActiveAddonConfig')->andReturn($addonsArray)->once(); - - $hookFileManager = new HookFileManager($this->root->url(), $addonLoader); - - $instanceManager = \Mockery::mock(ICanRegisterInstances::class); - foreach ($assertStrategies as $assertStrategy) { - $instanceManager->shouldReceive('registerStrategy')->withArgs($assertStrategy)->once(); - } - - $hookFileManager->setupHooks($instanceManager); - - self::expectNotToPerformAssertions(); - } - - /** - * Test the exception in case the hooks.config.php file is missing - */ - public function testMissingHooksFile() - { - $addonLoader = \Mockery::mock(ICanLoadAddons::class); - $instanceManager = \Mockery::mock(ICanRegisterInstances::class); - $hookFileManager = new HookFileManager($this->root->url(), $addonLoader); - - self::expectException(HookConfigException::class); - self::expectExceptionMessage(sprintf('config file %s does not exist.', - $this->root->url() . '/' . HookFileManager::STATIC_DIR . '/' . HookFileManager::CONFIG_NAME . '.config.php')); - - $hookFileManager->setupHooks($instanceManager); - } - - /** - * Test the exception in case the hooks.config.php file is wrong - */ - public function testWrongHooksFile() - { - $addonLoader = \Mockery::mock(ICanLoadAddons::class); - $instanceManager = \Mockery::mock(ICanRegisterInstances::class); - $hookFileManager = new HookFileManager($this->root->url(), $addonLoader); - - vfsStream::newFile('static/hooks.config.php') - ->withContent("at($this->root); - - self::expectException(HookConfigException::class); - self::expectExceptionMessage(sprintf('Error loading config file %s.', - $this->root->url() . '/' . HookFileManager::STATIC_DIR . '/' . HookFileManager::CONFIG_NAME . '.config.php')); - - $hookFileManager->setupHooks($instanceManager); - } -} diff --git a/tests/src/Core/Hooks/Util/StrategiesFileManagerTest.php b/tests/src/Core/Hooks/Util/StrategiesFileManagerTest.php new file mode 100644 index 0000000000..9e1855da14 --- /dev/null +++ b/tests/src/Core/Hooks/Util/StrategiesFileManagerTest.php @@ -0,0 +1,202 @@ +. + * + */ + +namespace Friendica\Test\src\Core\Hooks\Util; + +use Friendica\Core\Addon\Capabilities\ICanLoadAddons; +use Friendica\Core\Hooks\Capabilities\ICanRegisterStrategies; +use Friendica\Core\Hooks\Exceptions\HookConfigException; +use Friendica\Core\Hooks\Util\StrategiesFileManager; +use Friendica\Test\MockedTest; +use Friendica\Test\Util\VFSTrait; +use org\bovigo\vfs\vfsStream; +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; + +class StrategiesFileManagerTest extends MockedTest +{ + use VFSTrait; + + protected function setUp(): void + { + parent::setUp(); + + $this->setUpVfsDir(); + } + + public function dataHooks(): array + { + return [ + 'normal' => [ + 'content' => << [ + \Psr\Log\NullLogger::class => [''], + ], +]; +EOF, + 'addonsArray' => [], + 'assertStrategies' => [ + [LoggerInterface::class, NullLogger::class, ''], + ], + ], + 'normalWithString' => [ + 'content' => << [ + \Psr\Log\NullLogger::class => '', + ], +]; +EOF, + 'addonsArray' => [], + 'assertStrategies' => [ + [LoggerInterface::class, NullLogger::class, ''], + ], + ], + 'withAddons' => [ + 'content' => << [ + \Psr\Log\NullLogger::class => [''], + ], +]; +EOF, + 'addonsArray' => [ + \Psr\Log\LoggerInterface::class => [ + \Psr\Log\NullLogger::class => ['null'], + ], + ], + 'assertStrategies' => [ + [LoggerInterface::class, NullLogger::class, ''], + [LoggerInterface::class, NullLogger::class, 'null'], + ], + ], + 'withAddonsWithString' => [ + 'content' => << [ + \Psr\Log\NullLogger::class => [''], + ], +]; +EOF, + 'addonsArray' => [ + \Psr\Log\LoggerInterface::class => [ + \Psr\Log\NullLogger::class => 'null', + ], + ], + 'assertStrategies' => [ + [LoggerInterface::class, NullLogger::class, ''], + [LoggerInterface::class, NullLogger::class, 'null'], + ], + ], + // This should work because unique name convention is part of the instance manager logic, not of the file-infrastructure layer + 'withAddonsDoubleNamed' => [ + 'content' => << [ + \Psr\Log\NullLogger::class => [''], + ], +]; +EOF, + 'addonsArray' => [ + \Psr\Log\LoggerInterface::class => [ + \Psr\Log\NullLogger::class => [''], + ], + ], + 'assertStrategies' => [ + [LoggerInterface::class, NullLogger::class, ''], + [LoggerInterface::class, NullLogger::class, ''], + ], + ], + ]; + } + + /** + * @dataProvider dataHooks + */ + public function testSetupHooks(string $content, array $addonsArray, array $assertStrategies) + { + vfsStream::newFile(StrategiesFileManager::STATIC_DIR . '/' . StrategiesFileManager::CONFIG_NAME . '.config.php') + ->withContent($content) + ->at($this->root); + + $addonLoader = \Mockery::mock(ICanLoadAddons::class); + $addonLoader->shouldReceive('getActiveAddonConfig')->andReturn($addonsArray)->once(); + + $hookFileManager = new StrategiesFileManager($this->root->url(), $addonLoader); + + $instanceManager = \Mockery::mock(ICanRegisterStrategies::class); + foreach ($assertStrategies as $assertStrategy) { + $instanceManager->shouldReceive('registerStrategy')->withArgs($assertStrategy)->once(); + } + + $hookFileManager->loadConfig(); + $hookFileManager->setupStrategies($instanceManager); + + self::expectNotToPerformAssertions(); + } + + /** + * Test the exception in case the strategies.config.php file is missing + */ + public function testMissingStrategiesFile() + { + $addonLoader = \Mockery::mock(ICanLoadAddons::class); + $instanceManager = \Mockery::mock(ICanRegisterStrategies::class); + $hookFileManager = new StrategiesFileManager($this->root->url(), $addonLoader); + + self::expectException(HookConfigException::class); + self::expectExceptionMessage(sprintf('config file %s does not exist.', + $this->root->url() . '/' . StrategiesFileManager::STATIC_DIR . '/' . StrategiesFileManager::CONFIG_NAME . '.config.php')); + + $hookFileManager->loadConfig(); + } + + /** + * Test the exception in case the strategies.config.php file is wrong + */ + public function testWrongStrategiesFile() + { + $addonLoader = \Mockery::mock(ICanLoadAddons::class); + $instanceManager = \Mockery::mock(ICanRegisterStrategies::class); + $hookFileManager = new StrategiesFileManager($this->root->url(), $addonLoader); + + vfsStream::newFile(StrategiesFileManager::STATIC_DIR . '/' . StrategiesFileManager::CONFIG_NAME . '.config.php') + ->withContent("at($this->root); + + self::expectException(HookConfigException::class); + self::expectExceptionMessage(sprintf('Error loading config file %s.', + $this->root->url() . '/' . StrategiesFileManager::STATIC_DIR . '/' . StrategiesFileManager::CONFIG_NAME . '.config.php')); + + $hookFileManager->loadConfig(); + } +}