Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
54 / 54
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2
3// ╔════════════════════════════════════════════════════════════╗
4// ║ MIT Licence (#Expat) - https://opensource.org/licenses/MIT ║
5// ║ Copyright 2026 Frederic Poeydomenge <dyno@phexium.com>     ║
6// ╚════════════════════════════════════════════════════════════╝
7
8declare(strict_types=1);
9
10use DI\Container;
11use Phexium\Plugin\CommandBus\Adapter\SyncCommandBus;
12use Phexium\Plugin\Logger\Adapter\NullLogger;
13use Tests\Phexium\Fake\Application\Command\Command as FakeCommand;
14use Tests\Phexium\Fake\Application\Command\CommandAlternative as FakeCommandAlternative;
15use Tests\Phexium\Fake\Application\Command\Handler as FakeHandler;
16use Tests\Phexium\Fake\Application\Command\InvalidCommandHandler as FakeInvalidCommandHandler;
17use Tests\Phexium\Fake\Application\Command\OrphanCommand as FakeOrphanCommand;
18use Tests\Phexium\Fake\Plugin\Logger\Logger as FakeLogger;
19
20test('it dispatches command to auto-discovered handler', function (): void {
21    $container = new Container();
22    $logger = new NullLogger();
23
24    $handler = new FakeHandler();
25    $container->set(FakeHandler::class, $handler);
26
27    $commandBus = new SyncCommandBus($container, $logger);
28
29    $command = new FakeCommand();
30    $commandBus->dispatch($command);
31
32    expect($handler->handled)->toBeTrue();
33});
34
35test('it invokes handler on each dispatch', function (): void {
36    $container = new Container();
37    $logger = new NullLogger();
38
39    $handler = new FakeHandler();
40    $container->set(FakeHandler::class, $handler);
41
42    $commandBus = new SyncCommandBus($container, $logger);
43
44    $command = new FakeCommand();
45    $commandBus->dispatch($command);
46    $commandBus->dispatch($command);
47
48    expect($handler->handled)->toBeTrue()
49        ->and($handler->handleCount)->toBe(2)
50    ;
51});
52
53test('it throws exception for non-existent handler', function (): void {
54    $container = new Container();
55    $logger = new NullLogger();
56
57    $commandBus = new SyncCommandBus($container, $logger);
58
59    $command = new FakeOrphanCommand();
60
61    expect(fn () => $commandBus->dispatch($command))
62        ->toThrow(InvalidArgumentException::class, 'Handler not found for command')
63    ;
64});
65
66test('it throws exception for invalid handler', function (): void {
67    $container = new Container();
68    $container->set(FakeInvalidCommandHandler::class, new FakeInvalidCommandHandler());
69
70    $logger = new NullLogger();
71
72    $commandBus = new SyncCommandBus($container, $logger);
73
74    $command = new FakeCommandAlternative();
75
76    expect(fn () => $commandBus->dispatch($command))
77        ->toThrow(InvalidArgumentException::class, 'CommandHandlerInterface')
78    ;
79});
80
81test('should log command dispatch with context', function (): void {
82    $container = new Container();
83    $logger = new FakeLogger();
84
85    $handler = new FakeHandler();
86    $container->set(FakeHandler::class, $handler);
87
88    $commandBus = new SyncCommandBus($container, $logger);
89
90    $command = new FakeCommand();
91    $commandBus->dispatch($command);
92
93    expect($logger->hasLog('debug', 'CommandBus: Dispatching command', [
94        'command' => FakeCommand::class,
95    ]))->toBeTrue();
96});