From 971b7967decce25cc86420ed6f8d5e7ad0c4c951 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya <alejandro@alejandrocelaya.com> Date: Mon, 12 Aug 2019 20:54:30 +0200 Subject: [PATCH] Installed EventDispatcher module from external library --- composer.json | 8 +- module/EventDispatcher/LICENSE | 21 --- module/EventDispatcher/README.md | 13 -- .../config/event_dispatcher.config.php | 39 ---- .../config/task_runner.config.php | 21 --- .../EventDispatcher/functions/functions.php | 11 -- .../src/Async/TaskInterface.php | 13 -- .../EventDispatcher/src/Async/TaskRunner.php | 54 ------ .../src/Async/TaskRunnerDelegator.php | 25 --- .../src/Async/TaskRunnerFactory.php | 16 -- module/EventDispatcher/src/ConfigProvider.php | 14 -- .../src/Listener/AsyncEventListener.php | 25 --- .../src/Listener/EventListenerTask.php | 34 ---- .../src/Listener/ListenerProviderFactory.php | 52 ------ .../test/Async/TaskRunnerDelegatorTest.php | 46 ----- .../test/Async/TaskRunnerFactoryTest.php | 48 ----- .../test/Async/TaskRunnerTest.php | 107 ----------- .../test/ConfigProviderTest.php | 27 --- .../test/Listener/AsyncEventListenerTest.php | 41 ---- .../test/Listener/EventListenerTaskTest.php | 58 ------ .../Listener/ListenerProviderFactoryTest.php | 176 ------------------ phpunit.xml.dist | 3 - 22 files changed, 2 insertions(+), 850 deletions(-) delete mode 100644 module/EventDispatcher/LICENSE delete mode 100644 module/EventDispatcher/README.md delete mode 100644 module/EventDispatcher/config/event_dispatcher.config.php delete mode 100644 module/EventDispatcher/config/task_runner.config.php delete mode 100644 module/EventDispatcher/functions/functions.php delete mode 100644 module/EventDispatcher/src/Async/TaskInterface.php delete mode 100644 module/EventDispatcher/src/Async/TaskRunner.php delete mode 100644 module/EventDispatcher/src/Async/TaskRunnerDelegator.php delete mode 100644 module/EventDispatcher/src/Async/TaskRunnerFactory.php delete mode 100644 module/EventDispatcher/src/ConfigProvider.php delete mode 100644 module/EventDispatcher/src/Listener/AsyncEventListener.php delete mode 100644 module/EventDispatcher/src/Listener/EventListenerTask.php delete mode 100644 module/EventDispatcher/src/Listener/ListenerProviderFactory.php delete mode 100644 module/EventDispatcher/test/Async/TaskRunnerDelegatorTest.php delete mode 100644 module/EventDispatcher/test/Async/TaskRunnerFactoryTest.php delete mode 100644 module/EventDispatcher/test/Async/TaskRunnerTest.php delete mode 100644 module/EventDispatcher/test/ConfigProviderTest.php delete mode 100644 module/EventDispatcher/test/Listener/AsyncEventListenerTest.php delete mode 100644 module/EventDispatcher/test/Listener/EventListenerTaskTest.php delete mode 100644 module/EventDispatcher/test/Listener/ListenerProviderFactoryTest.php diff --git a/composer.json b/composer.json index c1ed913e..994febcc 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,7 @@ "phly/phly-event-dispatcher": "^1.0", "predis/predis": "^1.1", "shlinkio/shlink-common": "^1.0", + "shlinkio/shlink-event-dispatcher": "^1.0", "shlinkio/shlink-installer": "^1.2.1", "shlinkio/shlink-ip-geolocation": "^1.0", "symfony/console": "^4.3", @@ -76,12 +77,8 @@ "Shlinkio\\Shlink\\CLI\\": "module/CLI/src", "Shlinkio\\Shlink\\Rest\\": "module/Rest/src", "Shlinkio\\Shlink\\Core\\": "module/Core/src", - "Shlinkio\\Shlink\\EventDispatcher\\": "module/EventDispatcher/src", "Shlinkio\\Shlink\\PreviewGenerator\\": "module/PreviewGenerator/src/" - }, - "files": [ - "module/EventDispatcher/functions/functions.php" - ] + } }, "autoload-dev": { "psr-4": { @@ -92,7 +89,6 @@ "module/Core/test", "module/Core/test-db" ], - "ShlinkioTest\\Shlink\\EventDispatcher\\": "module/EventDispatcher/test", "ShlinkioTest\\Shlink\\PreviewGenerator\\": "module/PreviewGenerator/test" } }, diff --git a/module/EventDispatcher/LICENSE b/module/EventDispatcher/LICENSE deleted file mode 100644 index 31778387..00000000 --- a/module/EventDispatcher/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2019 Alejandro Celaya - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/module/EventDispatcher/README.md b/module/EventDispatcher/README.md deleted file mode 100644 index 47938c12..00000000 --- a/module/EventDispatcher/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Shlink Event Dispatcher - -This library provides a PSR-14 EventDispatcher which is capable of dispatching both regular listeners and async listeners which are run using [swoole]'s task system. - -Most of the elements it provides require a [PSR-11] container, and it's easy to integrate on [expressive] applications thanks to the `ConfigProvider` it includes. - -## Install - -Install this library using composer: - - composer require shlinkio/shlink-event-dispatcher - -> This library is also an expressive module which provides its own `ConfigProvider`. Add it to your configuration to get everything automatically set up. diff --git a/module/EventDispatcher/config/event_dispatcher.config.php b/module/EventDispatcher/config/event_dispatcher.config.php deleted file mode 100644 index 8941443f..00000000 --- a/module/EventDispatcher/config/event_dispatcher.config.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -declare(strict_types=1); - -namespace Shlinkio\Shlink\EventDispatcher; - -use Phly\EventDispatcher as Phly; -use Psr\EventDispatcher as Psr; -use Zend\ServiceManager\Proxy\LazyServiceFactory; - -return [ - - 'events' => [ - 'regular' => [], - 'async' => [], - ], - - 'dependencies' => [ - 'factories' => [ - Phly\EventDispatcher::class => Phly\EventDispatcherFactory::class, - Psr\ListenerProviderInterface::class => Listener\ListenerProviderFactory::class, - ], - 'aliases' => [ - Psr\EventDispatcherInterface::class => Phly\EventDispatcher::class, - ], - 'delegators' => [ - // The listener provider has to be lazy, because it uses the Swoole server to generate AsyncEventListeners - // Without making this lazy, CLI commands which depend on the EventDispatcher fail - Psr\ListenerProviderInterface::class => [ - LazyServiceFactory::class, - ], - ], - 'lazy_services' => [ - 'class_map' => [ - Psr\ListenerProviderInterface::class => Psr\ListenerProviderInterface::class, - ], - ], - ], - -]; diff --git a/module/EventDispatcher/config/task_runner.config.php b/module/EventDispatcher/config/task_runner.config.php deleted file mode 100644 index a0a23db5..00000000 --- a/module/EventDispatcher/config/task_runner.config.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php -declare(strict_types=1); - -namespace Shlinkio\Shlink\EventDispatcher; - -use Swoole\Http\Server as HttpServer; - -return [ - - 'dependencies' => [ - 'factories' => [ - Async\TaskRunner::class => Async\TaskRunnerFactory::class, - ], - 'delegators' => [ - HttpServer::class => [ - Async\TaskRunnerDelegator::class, - ], - ], - ], - -]; diff --git a/module/EventDispatcher/functions/functions.php b/module/EventDispatcher/functions/functions.php deleted file mode 100644 index a1c93231..00000000 --- a/module/EventDispatcher/functions/functions.php +++ /dev/null @@ -1,11 +0,0 @@ -<?php -declare(strict_types=1); - -namespace Shlinkio\Shlink\EventDispatcher; - -use Swoole\Http\Server as HttpServer; - -function asyncListener(HttpServer $server, string $regularListenerName): Listener\AsyncEventListener -{ - return new Listener\AsyncEventListener($server, $regularListenerName); -} diff --git a/module/EventDispatcher/src/Async/TaskInterface.php b/module/EventDispatcher/src/Async/TaskInterface.php deleted file mode 100644 index b9f20486..00000000 --- a/module/EventDispatcher/src/Async/TaskInterface.php +++ /dev/null @@ -1,13 +0,0 @@ -<?php -declare(strict_types=1); - -namespace Shlinkio\Shlink\EventDispatcher\Async; - -use Psr\Container\ContainerInterface; - -interface TaskInterface -{ - public function run(ContainerInterface $container): void; - - public function toString(): string; -} diff --git a/module/EventDispatcher/src/Async/TaskRunner.php b/module/EventDispatcher/src/Async/TaskRunner.php deleted file mode 100644 index a4ae026a..00000000 --- a/module/EventDispatcher/src/Async/TaskRunner.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -declare(strict_types=1); - -namespace Shlinkio\Shlink\EventDispatcher\Async; - -use Psr\Container\ContainerInterface; -use Psr\Log\LoggerInterface; -use Swoole\Http\Server as HttpServer; -use Throwable; - -use function get_class; -use function gettype; -use function is_object; - -class TaskRunner -{ - /** @var LoggerInterface */ - private $logger; - /** @var ContainerInterface */ - private $container; - - public function __construct(LoggerInterface $logger, ContainerInterface $container) - { - $this->logger = $logger; - $this->container = $container; - } - - public function __invoke(HttpServer $server, int $taskId, int $fromId, $task): void - { - if (! $task instanceof TaskInterface) { - $this->logger->warning('Invalid task provided to task worker: {type}. Task ignored', [ - 'type' => is_object($task) ? get_class($task) : gettype($task), - ]); - $server->finish(''); - return; - } - - $this->logger->notice('Starting work on task {taskId}: {task}', [ - 'taskId' => $taskId, - 'task' => $task->toString(), - ]); - - try { - $task->run($this->container); - } catch (Throwable $e) { - $this->logger->error('Error processing task {taskId}: {e}', [ - 'taskId' => $taskId, - 'e' => $e, - ]); - } finally { - $server->finish(''); - } - } -} diff --git a/module/EventDispatcher/src/Async/TaskRunnerDelegator.php b/module/EventDispatcher/src/Async/TaskRunnerDelegator.php deleted file mode 100644 index 7c87826b..00000000 --- a/module/EventDispatcher/src/Async/TaskRunnerDelegator.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -declare(strict_types=1); - -namespace Shlinkio\Shlink\EventDispatcher\Async; - -use Psr\Container\ContainerInterface; -use Psr\Log\LoggerInterface; -use Swoole\Http\Server as HttpServer; - -class TaskRunnerDelegator -{ - public function __invoke(ContainerInterface $container, $name, callable $callback): HttpServer - { - /** @var HttpServer $server */ - $server = $callback(); - $logger = $container->get(LoggerInterface::class); - - $server->on('task', $container->get(TaskRunner::class)); - $server->on('finish', function (HttpServer $server, int $taskId) use ($logger) { - $logger->notice('Task #{taskId} has finished processing', ['taskId' => $taskId]); - }); - - return $server; - } -} diff --git a/module/EventDispatcher/src/Async/TaskRunnerFactory.php b/module/EventDispatcher/src/Async/TaskRunnerFactory.php deleted file mode 100644 index cacfefc5..00000000 --- a/module/EventDispatcher/src/Async/TaskRunnerFactory.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -declare(strict_types=1); - -namespace Shlinkio\Shlink\EventDispatcher\Async; - -use Psr\Container\ContainerInterface; -use Psr\Log\LoggerInterface; - -class TaskRunnerFactory -{ - public function __invoke(ContainerInterface $container): TaskRunner - { - $logger = $container->get(LoggerInterface::class); - return new TaskRunner($logger, $container); - } -} diff --git a/module/EventDispatcher/src/ConfigProvider.php b/module/EventDispatcher/src/ConfigProvider.php deleted file mode 100644 index 88f2045e..00000000 --- a/module/EventDispatcher/src/ConfigProvider.php +++ /dev/null @@ -1,14 +0,0 @@ -<?php -declare(strict_types=1); - -namespace Shlinkio\Shlink\EventDispatcher; - -use function Shlinkio\Shlink\Common\loadConfigFromGlob; - -class ConfigProvider -{ - public function __invoke() - { - return loadConfigFromGlob(__DIR__ . '/../config/{,*.}config.php'); - } -} diff --git a/module/EventDispatcher/src/Listener/AsyncEventListener.php b/module/EventDispatcher/src/Listener/AsyncEventListener.php deleted file mode 100644 index 7f59221a..00000000 --- a/module/EventDispatcher/src/Listener/AsyncEventListener.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -declare(strict_types=1); - -namespace Shlinkio\Shlink\EventDispatcher\Listener; - -use Swoole\Http\Server as HttpServer; - -class AsyncEventListener -{ - /** @var string */ - private $regularListenerName; - /** @var HttpServer */ - private $server; - - public function __construct(HttpServer $server, string $regularListenerName) - { - $this->regularListenerName = $regularListenerName; - $this->server = $server; - } - - public function __invoke(object $event): void - { - $this->server->task(new EventListenerTask($this->regularListenerName, $event)); - } -} diff --git a/module/EventDispatcher/src/Listener/EventListenerTask.php b/module/EventDispatcher/src/Listener/EventListenerTask.php deleted file mode 100644 index bc1e3689..00000000 --- a/module/EventDispatcher/src/Listener/EventListenerTask.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php -declare(strict_types=1); - -namespace Shlinkio\Shlink\EventDispatcher\Listener; - -use Psr\Container\ContainerInterface; -use Shlinkio\Shlink\EventDispatcher\Async\TaskInterface; - -use function get_class; -use function sprintf; - -class EventListenerTask implements TaskInterface -{ - /** @var string */ - private $listenerName; - /** @var object */ - private $event; - - public function __construct(string $listenerName, object $event) - { - $this->listenerName = $listenerName; - $this->event = $event; - } - - public function run(ContainerInterface $container): void - { - ($container->get($this->listenerName))($this->event); - } - - public function toString(): string - { - return sprintf('Listener -> "%s", Event -> "%s"', $this->listenerName, get_class($this->event)); - } -} diff --git a/module/EventDispatcher/src/Listener/ListenerProviderFactory.php b/module/EventDispatcher/src/Listener/ListenerProviderFactory.php deleted file mode 100644 index 7e9198a8..00000000 --- a/module/EventDispatcher/src/Listener/ListenerProviderFactory.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -declare(strict_types=1); - -namespace Shlinkio\Shlink\EventDispatcher\Listener; - -use Phly\EventDispatcher\ListenerProvider\AttachableListenerProvider; -use Psr\Container\ContainerInterface; -use Swoole\Http\Server as HttpServer; - -use function Phly\EventDispatcher\lazyListener; -use function Shlinkio\Shlink\EventDispatcher\asyncListener; - -class ListenerProviderFactory -{ - public function __invoke(ContainerInterface $container) - { - $config = $container->has('config') ? $container->get('config') : []; - $events = $config['events'] ?? []; - $provider = new AttachableListenerProvider(); - - $this->registerListeners($events['regular'] ?? [], $container, $provider); - $this->registerListeners($events['async'] ?? [], $container, $provider, true); - - return $provider; - } - - private function registerListeners( - array $events, - ContainerInterface $container, - AttachableListenerProvider $provider, - bool $isAsync = false - ): void { - if (empty($events)) { - return; - } - - // Avoid registering async event listeners when the swoole server is not registered - if ($isAsync && ! $container->has(HttpServer::class)) { - return; - } - - foreach ($events as $eventName => $listeners) { - foreach ($listeners as $listenerName) { - $eventListener = $isAsync - ? asyncListener($container->get(HttpServer::class), $listenerName) - : lazyListener($container, $listenerName); - - $provider->listen($eventName, $eventListener); - } - } - } -} diff --git a/module/EventDispatcher/test/Async/TaskRunnerDelegatorTest.php b/module/EventDispatcher/test/Async/TaskRunnerDelegatorTest.php deleted file mode 100644 index ad0978e7..00000000 --- a/module/EventDispatcher/test/Async/TaskRunnerDelegatorTest.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -declare(strict_types=1); - -namespace ShlinkioTest\Shlink\EventDispatcher\Async; - -use PHPUnit\Framework\TestCase; -use Psr\Container\ContainerInterface; -use Psr\Log\LoggerInterface; -use Shlinkio\Shlink\EventDispatcher\Async\TaskRunner; -use Shlinkio\Shlink\EventDispatcher\Async\TaskRunnerDelegator; -use Swoole\Http\Server as HttpServer; - -class TaskRunnerDelegatorTest extends TestCase -{ - /** @var TaskRunnerDelegator */ - private $delegator; - - public function setUp(): void - { - $this->delegator = new TaskRunnerDelegator(); - } - - /** @test */ - public function serverIsFetchedFromCallbackAndDecorated(): void - { - $server = $this->createMock(HttpServer::class); - $server - ->expects($this->exactly(2)) - ->method('on'); - $callback = function () use ($server) { - return $server; - }; - - $container = $this->prophesize(ContainerInterface::class); - $getTaskRunner = $container->get(TaskRunner::class)->willReturn($this->prophesize(TaskRunner::class)->reveal()); - $getLogger = $container->get(LoggerInterface::class)->willReturn( - $this->prophesize(LoggerInterface::class)->reveal() - ); - - $result = ($this->delegator)($container->reveal(), '', $callback); - - $this->assertSame($server, $result); - $getTaskRunner->shouldHaveBeenCalledOnce(); - $getLogger->shouldHaveBeenCalledOnce(); - } -} diff --git a/module/EventDispatcher/test/Async/TaskRunnerFactoryTest.php b/module/EventDispatcher/test/Async/TaskRunnerFactoryTest.php deleted file mode 100644 index cf139b62..00000000 --- a/module/EventDispatcher/test/Async/TaskRunnerFactoryTest.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -declare(strict_types=1); - -namespace ShlinkioTest\Shlink\EventDispatcher\Async; - -use PHPUnit\Framework\TestCase; -use Psr\Container\ContainerInterface; -use Psr\Log\LoggerInterface; -use ReflectionObject; -use Shlinkio\Shlink\EventDispatcher\Async\TaskRunner; -use Shlinkio\Shlink\EventDispatcher\Async\TaskRunnerFactory; - -class TaskRunnerFactoryTest extends TestCase -{ - /** @var TaskRunnerFactory */ - private $factory; - - public function setUp(): void - { - $this->factory = new TaskRunnerFactory(); - } - - /** @test */ - public function properlyCreatesService(): void - { - $loggerMock = $this->prophesize(LoggerInterface::class); - $logger = $loggerMock->reveal(); - $containerMock = $this->prophesize(ContainerInterface::class); - $getLogger = $containerMock->get(LoggerInterface::class)->willReturn($logger); - $container = $containerMock->reveal(); - - $taskRunner = ($this->factory)($container, ''); - $loggerProp = $this->getPropertyFromTaskRunner($taskRunner, 'logger'); - $containerProp = $this->getPropertyFromTaskRunner($taskRunner, 'container'); - - $this->assertSame($container, $containerProp); - $this->assertSame($logger, $loggerProp); - $getLogger->shouldHaveBeenCalledOnce(); - } - - private function getPropertyFromTaskRunner(TaskRunner $taskRunner, string $propertyName) - { - $ref = new ReflectionObject($taskRunner); - $prop = $ref->getProperty($propertyName); - $prop->setAccessible(true); - return $prop->getValue($taskRunner); - } -} diff --git a/module/EventDispatcher/test/Async/TaskRunnerTest.php b/module/EventDispatcher/test/Async/TaskRunnerTest.php deleted file mode 100644 index 0bf56d7c..00000000 --- a/module/EventDispatcher/test/Async/TaskRunnerTest.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php -declare(strict_types=1); - -namespace ShlinkioTest\Shlink\EventDispatcher\Async; - -use Exception; -use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\Prophecy\ObjectProphecy; -use Psr\Container\ContainerInterface; -use Psr\Log\LoggerInterface; -use Shlinkio\Shlink\EventDispatcher\Async\TaskInterface; -use Shlinkio\Shlink\EventDispatcher\Async\TaskRunner; -use Swoole\Http\Server as HttpServer; - -class TaskRunnerTest extends TestCase -{ - /** @var TaskRunner */ - private $taskRunner; - /** @var ObjectProphecy */ - private $logger; - /** @var ObjectProphecy */ - private $container; - /** @var HttpServer */ - private $server; - /** @var ObjectProphecy */ - private $task; - - public function setUp(): void - { - $this->logger = $this->prophesize(LoggerInterface::class); - $this->container = $this->prophesize(ContainerInterface::class); - $this->task = $this->prophesize(TaskInterface::class); - - $this->server = $this->createMock(HttpServer::class); - $this->server - ->expects($this->once()) - ->method('finish') - ->with(''); - - $this->taskRunner = new TaskRunner($this->logger->reveal(), $this->container->reveal()); - } - - /** @test */ - public function warningIsLoggedWhenProvidedTaskIsInvalid(): void - { - $logWarning = $this->logger->warning('Invalid task provided to task worker: {type}. Task ignored', [ - 'type' => 'string', - ]); - $logInfo = $this->logger->info(Argument::cetera()); - $logError = $this->logger->error(Argument::cetera()); - - ($this->taskRunner)($this->server, 1, 1, 'invalid_task'); - - $logWarning->shouldHaveBeenCalledOnce(); - $logInfo->shouldNotHaveBeenCalled(); - $logError->shouldNotHaveBeenCalled(); - } - - /** @test */ - public function properTasksAreRun(): void - { - $logWarning = $this->logger->warning(Argument::cetera()); - $logInfo = $this->logger->notice('Starting work on task {taskId}: {task}', [ - 'taskId' => 1, - 'task' => 'The task', - ]); - $logError = $this->logger->error(Argument::cetera()); - $taskToString = $this->task->toString()->willReturn('The task'); - $taskRun = $this->task->run($this->container->reveal())->will(function () { - }); - - ($this->taskRunner)($this->server, 1, 1, $this->task->reveal()); - - $logWarning->shouldNotHaveBeenCalled(); - $logInfo->shouldHaveBeenCalledOnce(); - $logError->shouldNotHaveBeenCalled(); - $taskToString->shouldHaveBeenCalledOnce(); - $taskRun->shouldHaveBeenCalledOnce(); - } - - /** @test */ - public function errorIsLoggedWhenTasksFail(): void - { - $e = new Exception('Error'); - - $logWarning = $this->logger->warning(Argument::cetera()); - $logInfo = $this->logger->notice('Starting work on task {taskId}: {task}', [ - 'taskId' => 1, - 'task' => 'The task', - ]); - $logError = $this->logger->error('Error processing task {taskId}: {e}', [ - 'taskId' => 1, - 'e' => $e, - ]); - $taskToString = $this->task->toString()->willReturn('The task'); - $taskRun = $this->task->run($this->container->reveal())->willThrow($e); - - ($this->taskRunner)($this->server, 1, 1, $this->task->reveal()); - - $logWarning->shouldNotHaveBeenCalled(); - $logInfo->shouldHaveBeenCalledOnce(); - $logError->shouldHaveBeenCalledOnce(); - $taskToString->shouldHaveBeenCalledOnce(); - $taskRun->shouldHaveBeenCalledOnce(); - } -} diff --git a/module/EventDispatcher/test/ConfigProviderTest.php b/module/EventDispatcher/test/ConfigProviderTest.php deleted file mode 100644 index 8c344467..00000000 --- a/module/EventDispatcher/test/ConfigProviderTest.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php -declare(strict_types=1); - -namespace ShlinkioTest\Shlink\EventDispatcher; - -use PHPUnit\Framework\TestCase; -use Shlinkio\Shlink\EventDispatcher\ConfigProvider; - -class ConfigProviderTest extends TestCase -{ - /** @var ConfigProvider */ - private $configProvider; - - public function setUp(): void - { - $this->configProvider = new ConfigProvider(); - } - - /** @test */ - public function configIsReturned(): void - { - $config = $this->configProvider->__invoke(); - - $this->assertArrayHasKey('dependencies', $config); - $this->assertArrayHasKey('events', $config); - } -} diff --git a/module/EventDispatcher/test/Listener/AsyncEventListenerTest.php b/module/EventDispatcher/test/Listener/AsyncEventListenerTest.php deleted file mode 100644 index 554528cd..00000000 --- a/module/EventDispatcher/test/Listener/AsyncEventListenerTest.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php -declare(strict_types=1); - -namespace ShlinkioTest\Shlink\EventDispatcher\Listener; - -use PHPUnit\Framework\TestCase; -use Shlinkio\Shlink\EventDispatcher\Listener\AsyncEventListener; -use Shlinkio\Shlink\EventDispatcher\Listener\EventListenerTask; -use stdClass; -use Swoole\Http\Server as HttpServer; - -class AsyncEventListenerTest extends TestCase -{ - /** @var AsyncEventListener */ - private $eventListener; - /** @var HttpServer */ - private $server; - /** @var string */ - private $regularListenerName; - - public function setUp(): void - { - $this->regularListenerName = 'the_regular_listener'; - $this->server = $this->createMock(HttpServer::class); - - $this->eventListener = new AsyncEventListener($this->server, $this->regularListenerName); - } - - /** @test */ - public function enqueuesTaskWhenInvoked(): void - { - $event = new stdClass(); - - $this->server - ->expects($this->once()) - ->method('task') - ->with(new EventListenerTask($this->regularListenerName, $event)); - - ($this->eventListener)($event); - } -} diff --git a/module/EventDispatcher/test/Listener/EventListenerTaskTest.php b/module/EventDispatcher/test/Listener/EventListenerTaskTest.php deleted file mode 100644 index 5cc6d5a9..00000000 --- a/module/EventDispatcher/test/Listener/EventListenerTaskTest.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php -declare(strict_types=1); - -namespace ShlinkioTest\Shlink\EventDispatcher\Listener; - -use PHPUnit\Framework\Assert; -use PHPUnit\Framework\TestCase; -use Psr\Container\ContainerInterface; -use Shlinkio\Shlink\EventDispatcher\Listener\EventListenerTask; -use stdClass; - -use function get_class; -use function sprintf; - -class EventListenerTaskTest extends TestCase -{ - /** @var EventListenerTask */ - private $task; - /** @var object */ - private $event; - /** @var string */ - private $listenerName; - - public function setUp(): void - { - $this->event = new stdClass(); - $this->listenerName = 'the_listener'; - - $this->task = new EventListenerTask($this->listenerName, $this->event); - } - - /** @test */ - public function toStringReturnsTheStringRepresentation(): void - { - $this->assertEquals( - sprintf('Listener -> "%s", Event -> "%s"', $this->listenerName, get_class($this->event)), - $this->task->toString() - ); - } - - /** @test */ - public function runInvokesContainerAndListenerWithEvent(): void - { - $invoked = false; - $container = $this->prophesize(ContainerInterface::class); - $listener = function (object $event) use (&$invoked) { - $invoked = true; - Assert::assertSame($event, $this->event); - }; - - $getListener = $container->get($this->listenerName)->willReturn($listener); - - $this->task->run($container->reveal()); - - $this->assertTrue($invoked); - $getListener->shouldHaveBeenCalledOnce(); - } -} diff --git a/module/EventDispatcher/test/Listener/ListenerProviderFactoryTest.php b/module/EventDispatcher/test/Listener/ListenerProviderFactoryTest.php deleted file mode 100644 index 493940a3..00000000 --- a/module/EventDispatcher/test/Listener/ListenerProviderFactoryTest.php +++ /dev/null @@ -1,176 +0,0 @@ -<?php -declare(strict_types=1); - -namespace ShlinkioTest\Shlink\EventDispatcher\Listener; - -use Phly\EventDispatcher\ListenerProvider\AttachableListenerProvider; -use PHPUnit\Framework\TestCase; -use Psr\Container\ContainerInterface; -use ReflectionObject; -use Shlinkio\Shlink\EventDispatcher\Listener\ListenerProviderFactory; -use Swoole\Http\Server as HttpServer; - -use function Phly\EventDispatcher\lazyListener; -use function Shlinkio\Shlink\EventDispatcher\asyncListener; - -class ListenerProviderFactoryTest extends TestCase -{ - /** @var ListenerProviderFactory */ - private $factory; - - public function setUp(): void - { - $this->factory = new ListenerProviderFactory(); - } - - /** - * @test - * @dataProvider provideContainersWithoutEvents - */ - public function noListenersAreAttachedWhenNoConfigOrEventsAreRegistered(ContainerInterface $container): void - { - $provider = ($this->factory)($container, ''); - $listeners = $this->getListenersFromProvider($provider); - - $this->assertInstanceOf(AttachableListenerProvider::class, $provider); - $this->assertEmpty($listeners); - } - - public function provideContainersWithoutEvents(): iterable - { - yield 'no config' => [(function () { - $container = $this->prophesize(ContainerInterface::class); - $container->has('config')->willReturn(false); - - return $container->reveal(); - })()]; - yield 'no events' => [(function () { - $container = $this->prophesize(ContainerInterface::class); - $container->has('config')->willReturn(true); - $container->get('config')->willReturn([]); - - return $container->reveal(); - })()]; - } - - /** @test */ - public function configuredRegularEventsAreProperlyAttached(): void - { - $containerMock = $this->prophesize(ContainerInterface::class); - $containerMock->has('config')->willReturn(true); - $containerMock->get('config')->willReturn([ - 'events' => [ - 'regular' => [ - 'foo' => [ - 'bar', - 'baz', - ], - 'something' => [ - 'some_listener', - 'another_listener', - 'foobar', - ], - ], - ], - ]); - $container = $containerMock->reveal(); - - $provider = ($this->factory)($container, ''); - $listeners = $this->getListenersFromProvider($provider); - - $this->assertInstanceOf(AttachableListenerProvider::class, $provider); - $this->assertEquals([ - 'foo' => [ - lazyListener($container, 'bar'), - lazyListener($container, 'baz'), - ], - 'something' => [ - lazyListener($container, 'some_listener'), - lazyListener($container, 'another_listener'), - lazyListener($container, 'foobar'), - ], - ], $listeners); - } - - /** @test */ - public function configuredAsyncEventsAreProperlyAttached(): void - { - $server = $this->createMock(HttpServer::class); // Some weird errors are thrown if prophesize is used - - $containerMock = $this->prophesize(ContainerInterface::class); - $containerMock->has('config')->willReturn(true); - $containerMock->get('config')->willReturn([ - 'events' => [ - 'async' => [ - 'foo' => [ - 'bar', - 'baz', - ], - 'something' => [ - 'some_listener', - 'another_listener', - 'foobar', - ], - ], - ], - ]); - $containerMock->has(HttpServer::class)->willReturn(true); - $containerMock->get(HttpServer::class)->willReturn($server); - $container = $containerMock->reveal(); - - $provider = ($this->factory)($container, ''); - $listeners = $this->getListenersFromProvider($provider); - - $this->assertInstanceOf(AttachableListenerProvider::class, $provider); - $this->assertEquals([ - 'foo' => [ - asyncListener($server, 'bar'), - asyncListener($server, 'baz'), - ], - 'something' => [ - asyncListener($server, 'some_listener'), - asyncListener($server, 'another_listener'), - asyncListener($server, 'foobar'), - ], - ], $listeners); - } - - /** @test */ - public function ignoresAsyncEventsWhenServerIsNotRegistered(): void - { - $containerMock = $this->prophesize(ContainerInterface::class); - $containerMock->has('config')->willReturn(true); - $containerMock->get('config')->willReturn([ - 'events' => [ - 'async' => [ - 'foo' => [ - 'bar', - 'baz', - ], - 'something' => [ - 'some_listener', - 'another_listener', - 'foobar', - ], - ], - ], - ]); - $containerMock->has(HttpServer::class)->willReturn(false); - $container = $containerMock->reveal(); - - $provider = ($this->factory)($container, ''); - $listeners = $this->getListenersFromProvider($provider); - - $this->assertInstanceOf(AttachableListenerProvider::class, $provider); - $this->assertEmpty($listeners); - } - - private function getListenersFromProvider($provider): array - { - $ref = new ReflectionObject($provider); - $prop = $ref->getProperty('listeners'); - $prop->setAccessible(true); - - return $prop->getValue($provider); - } -} diff --git a/phpunit.xml.dist b/phpunit.xml.dist index bb78e85b..1ae25124 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -15,9 +15,6 @@ <testsuite name="CLI"> <directory>./module/CLI/test</directory> </testsuite> - <testsuite name="EventDispatcher"> - <directory>./module/EventDispatcher/test</directory> - </testsuite> <testsuite name="PreviewGenerator"> <directory>./module/PreviewGenerator/test</directory> </testsuite>