-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from sabbelasichon/add-event-middleware
FEATURE: Add EventMiddleware
- Loading branch information
Showing
7 changed files
with
288 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the "t3_tactician" Extension for TYPO3 CMS. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.txt file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Ssch\T3Tactician\Middleware\Event; | ||
|
||
interface CommandEventInterface | ||
{ | ||
public function getCommand(): object; | ||
|
||
public function getName(): string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the "t3_tactician" Extension for TYPO3 CMS. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.txt file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Ssch\T3Tactician\Middleware\Event; | ||
|
||
final class CommandFailed implements CommandEventInterface | ||
{ | ||
private object $command; | ||
|
||
private \Exception $exception; | ||
|
||
private bool $exceptionCaught = false; | ||
|
||
public function __construct(object $command, \Exception $exception) | ||
{ | ||
$this->command = $command; | ||
$this->exception = $exception; | ||
} | ||
|
||
public function getException(): \Exception | ||
{ | ||
return $this->exception; | ||
} | ||
|
||
public function catchException(): void | ||
{ | ||
$this->exceptionCaught = true; | ||
} | ||
|
||
public function getCommand(): object | ||
{ | ||
return $this->command; | ||
} | ||
|
||
public function getName(): string | ||
{ | ||
return 'command.failed'; | ||
} | ||
|
||
public function isExceptionCaught(): bool | ||
{ | ||
return $this->exceptionCaught; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the "t3_tactician" Extension for TYPO3 CMS. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.txt file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Ssch\T3Tactician\Middleware\Event; | ||
|
||
final class CommandHandled implements CommandEventInterface | ||
{ | ||
private object $command; | ||
|
||
public function __construct(object $command) | ||
{ | ||
$this->command = $command; | ||
} | ||
|
||
public function getCommand(): object | ||
{ | ||
return $this->command; | ||
} | ||
|
||
public function getName(): string | ||
{ | ||
return 'command.received'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the "t3_tactician" Extension for TYPO3 CMS. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.txt file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Ssch\T3Tactician\Middleware\Event; | ||
|
||
final class CommandReceived implements CommandEventInterface | ||
{ | ||
private object $command; | ||
|
||
public function __construct(object $command) | ||
{ | ||
$this->command = $command; | ||
} | ||
|
||
public function getCommand(): object | ||
{ | ||
return $this->command; | ||
} | ||
|
||
public function getName(): string | ||
{ | ||
return 'command.handled'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the "t3_tactician" Extension for TYPO3 CMS. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.txt file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Ssch\T3Tactician\Middleware; | ||
|
||
use League\Tactician\Middleware; | ||
use Psr\EventDispatcher\EventDispatcherInterface; | ||
use Ssch\T3Tactician\Middleware\Event\CommandFailed; | ||
use Ssch\T3Tactician\Middleware\Event\CommandHandled; | ||
use Ssch\T3Tactician\Middleware\Event\CommandReceived; | ||
|
||
final class EventMiddleware implements Middleware | ||
{ | ||
private EventDispatcherInterface $eventDispatcher; | ||
|
||
public function __construct(EventDispatcherInterface $eventDispatcher) | ||
{ | ||
$this->eventDispatcher = $eventDispatcher; | ||
} | ||
|
||
public function execute($command, callable $next) | ||
{ | ||
try { | ||
$this->eventDispatcher->dispatch(new CommandReceived($command)); | ||
|
||
$returnValue = $next($command); | ||
|
||
$this->eventDispatcher->dispatch(new CommandHandled($command)); | ||
|
||
return $returnValue; | ||
} catch (\Exception $e) { | ||
$event = new CommandFailed($command, $e); | ||
$this->eventDispatcher->dispatch($event); | ||
|
||
if (! $event->isExceptionCaught()) { | ||
throw $e; | ||
} | ||
|
||
return null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the "t3_tactician" Extension for TYPO3 CMS. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.txt file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Ssch\T3Tactician\Tests\Unit\Middleware; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use Prophecy\PhpUnit\ProphecyTrait; | ||
use Psr\EventDispatcher\EventDispatcherInterface; | ||
use Ssch\T3Tactician\Middleware\Event\CommandFailed; | ||
use Ssch\T3Tactician\Middleware\EventMiddleware; | ||
use Ssch\T3Tactician\Tests\Unit\Fixtures\FakeCommand; | ||
|
||
final class EventMiddlewareTest extends TestCase | ||
{ | ||
use ProphecyTrait; | ||
|
||
public function testThatEventsAreCalledSuccessfully(): void | ||
{ | ||
// Arrange | ||
$eventDispatcher = new class() implements EventDispatcherInterface { | ||
public array $firedEvents = []; | ||
|
||
public function dispatch(object $event): object | ||
{ | ||
$this->firedEvents[] = $event; | ||
|
||
return $event; | ||
} | ||
}; | ||
|
||
$subject = new EventMiddleware($eventDispatcher); | ||
|
||
// Act | ||
$subject->execute(new FakeCommand(), function () { | ||
}); | ||
|
||
// Assert | ||
self::assertCount(2, $eventDispatcher->firedEvents); | ||
} | ||
|
||
public function testThatFailingCommandFiresEventButThrowsExceptionInTheEnd(): void | ||
{ | ||
// Assert | ||
$this->expectException(\Exception::class); | ||
|
||
// Arrange | ||
$eventDispatcher = new class() implements EventDispatcherInterface { | ||
public function dispatch(object $event): object | ||
{ | ||
return $event; | ||
} | ||
}; | ||
|
||
$subject = new EventMiddleware($eventDispatcher); | ||
|
||
// Act | ||
$subject->execute(new FakeCommand(), function () { | ||
throw new \Exception('Some deep failure is thrown in your application'); | ||
}); | ||
} | ||
|
||
public function testThatFailingCommandFiresEventAndCatchesException(): void | ||
{ | ||
$eventDispatcher = new class() implements EventDispatcherInterface { | ||
public array $firedEvents = []; | ||
|
||
public function dispatch(object $event): object | ||
{ | ||
if ($event instanceof CommandFailed) { | ||
$event->catchException(); | ||
} | ||
|
||
$this->firedEvents[] = $event; | ||
|
||
return $event; | ||
} | ||
}; | ||
|
||
$subject = new EventMiddleware($eventDispatcher); | ||
|
||
// Act | ||
$subject->execute(new FakeCommand(), function () { | ||
throw new \Exception('Some deep failure is thrown in your application'); | ||
}); | ||
|
||
// Assert | ||
self::assertCount(2, $eventDispatcher->firedEvents); | ||
} | ||
} |