Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
34 / 34
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 Phexium\Plugin\CommandBus\Adapter\TransactionalCommandBus;
13use Phexium\Plugin\Transaction\Adapter\InMemoryTransaction;
14use Tests\Phexium\Fake\Application\Command\Command as FakeCommand;
15use Tests\Phexium\Fake\Plugin\CommandBus\CommandBus as FakeCommandBus;
16use Tests\Phexium\Fake\Plugin\CommandBus\CommandBusThatThrows;
17use Tests\Phexium\Fake\Plugin\Transaction\Transaction as FakeTransaction;
18
19describe('Dispatching', function (): void {
20    it('commits on success', function (): void {
21        $innerBus = new FakeCommandBus();
22        $transaction = new FakeTransaction(new InMemoryTransaction());
23        $bus = new TransactionalCommandBus($innerBus, $transaction);
24
25        $bus->dispatch(new FakeCommand());
26
27        expect($innerBus->count())->toBe(1)
28            ->and($transaction->getCallHistory())->toBe(['begin', 'commit'])
29        ;
30    });
31
32    it('skips transaction if already in transaction', function (): void {
33        $innerBus = new FakeCommandBus();
34        $realTransaction = new InMemoryTransaction();
35        $transaction = new FakeTransaction($realTransaction);
36        $bus = new TransactionalCommandBus($innerBus, $transaction);
37
38        $realTransaction->begin();
39        $bus->dispatch(new FakeCommand());
40
41        expect($innerBus->count())->toBe(1)
42            ->and($transaction->getCallHistory())->toBe([])
43        ;
44    });
45});
46
47describe('Transaction lifecycle', function (): void {
48    it('rollbacks on exception', function (): void {
49        $innerBus = new CommandBusThatThrows(new RuntimeException('fail'));
50        $transaction = new FakeTransaction(new InMemoryTransaction());
51        $bus = new TransactionalCommandBus($innerBus, $transaction);
52
53        expect(fn () => $bus->dispatch(new FakeCommand()))
54            ->toThrow(RuntimeException::class)
55            ->and($transaction->getCallHistory())->toBe(['begin', 'rollback'])
56        ;
57    });
58});