Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
48 / 48
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
10pest()->group('integration');
11
12use DI\Container;
13use Phexium\Application\Query\QueryResponseInterface;
14use Phexium\Plugin\Logger\Adapter\NullLogger;
15use Phexium\Plugin\QueryBus\Adapter\SyncQueryBus;
16use Tests\Phexium\Fake\Application\Query\Handler as FakeHandler;
17use Tests\Phexium\Fake\Application\Query\InvalidQueryHandler as FakeInvalidQueryHandler;
18use Tests\Phexium\Fake\Application\Query\OrphanQuery as FakeOrphanQuery;
19use Tests\Phexium\Fake\Application\Query\Query as FakeQuery;
20use Tests\Phexium\Fake\Application\Query\QueryAlternative as FakeQueryAlternative;
21use Tests\Phexium\Fake\Plugin\Logger\Logger as FakeLogger;
22
23describe('Dispatching', function (): void {
24    it('dispatches a query to its auto-discovered handler', function (): void {
25        $container = new Container();
26        $logger = new NullLogger();
27
28        $handler = new FakeHandler();
29        $container->set(FakeHandler::class, $handler);
30
31        $queryBus = new SyncQueryBus($container, $logger);
32
33        $query = new FakeQuery();
34        $result = $queryBus->dispatch($query);
35
36        expect($result)->toBeInstanceOf(QueryResponseInterface::class)
37            ->and($handler->handled)->toBeTrue()
38        ;
39    });
40
41    it('logs the query dispatch with context', function (): void {
42        $container = new Container();
43        $logger = new FakeLogger();
44
45        $handler = new FakeHandler();
46        $container->set(FakeHandler::class, $handler);
47
48        $queryBus = new SyncQueryBus($container, $logger);
49
50        $query = new FakeQuery();
51        $queryBus->dispatch($query);
52
53        expect($logger->hasLog('debug', 'QueryBus: Dispatching query', [
54            'query' => FakeQuery::class,
55        ]))->toBeTrue();
56    });
57});
58
59describe('Error handling', function (): void {
60    it('throws an exception for a non-existent handler', function (): void {
61        $container = new Container();
62        $logger = new NullLogger();
63
64        $queryBus = new SyncQueryBus($container, $logger);
65
66        $query = new FakeOrphanQuery();
67
68        expect(fn (): QueryResponseInterface => $queryBus->dispatch($query))
69            ->toThrow(InvalidArgumentException::class, 'Handler not found for query')
70        ;
71    });
72
73    it('throws an exception for an invalid handler', function (): void {
74        $container = new Container();
75        $container->set(FakeInvalidQueryHandler::class, new FakeInvalidQueryHandler());
76
77        $logger = new NullLogger();
78
79        $queryBus = new SyncQueryBus($container, $logger);
80
81        $query = new FakeQueryAlternative();
82
83        expect(fn (): QueryResponseInterface => $queryBus->dispatch($query))
84            ->toThrow(InvalidArgumentException::class, 'Handler must implement')
85        ;
86    });
87});