Completed
Push — master ( a73a59...6682b5 )
by Alejandro
21s queued 11s
created

entityManagerIsReopenedAfterAnExceptionWhichClosedIt()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
c 0
b 0
f 0
dl 0
loc 15
rs 9.8666
cc 2
nc 3
nop 1
1
<?php
2
declare(strict_types=1);
3
4
namespace ShlinkioTest\Shlink\Common\Middleware;
5
6
use Doctrine\DBAL\Connection;
7
use Doctrine\ORM\EntityManagerInterface;
8
use PHPUnit\Framework\TestCase;
9
use Prophecy\Prophecy\ObjectProphecy;
10
use Psr\Http\Server\RequestHandlerInterface;
11
use RuntimeException;
12
use Shlinkio\Shlink\Common\Middleware\CloseDbConnectionMiddleware;
13
use Throwable;
14
use Zend\Diactoros\Response;
15
use Zend\Diactoros\ServerRequest;
16
17
class CloseDbConnectionMiddlewareTest extends TestCase
18
{
19
    /** @var CloseDbConnectionMiddleware */
20
    private $middleware;
21
    /** @var ObjectProphecy */
22
    private $handler;
23
    /** @var ObjectProphecy */
24
    private $em;
25
    /** @var ObjectProphecy */
26
    private $conn;
27
28
    public function setUp(): void
29
    {
30
        $this->handler = $this->prophesize(RequestHandlerInterface::class);
31
        $this->em = $this->prophesize(EntityManagerInterface::class);
32
        $this->conn = $this->prophesize(Connection::class);
33
        $this->conn->close()->will(function () {
34
        });
35
        $this->em->getConnection()->willReturn($this->conn->reveal());
36
        $this->em->clear()->will(function () {
37
        });
38
        $this->em->isOpen()->willReturn(true);
39
40
        $this->middleware = new CloseDbConnectionMiddleware($this->em->reveal());
41
    }
42
43
    /** @test */
44
    public function connectionIsClosedWhenMiddlewareIsProcessed(): void
45
    {
46
        $req = new ServerRequest();
47
        $resp = new Response();
48
        $handle = $this->handler->handle($req)->willReturn($resp);
49
50
        $result = $this->middleware->process($req, $this->handler->reveal());
51
52
        $this->assertSame($result, $resp);
53
        $this->em->getConnection()->shouldHaveBeenCalledOnce();
54
        $this->conn->close()->shouldHaveBeenCalledOnce();
55
        $this->em->clear()->shouldHaveBeenCalledOnce();
56
        $handle->shouldHaveBeenCalledOnce();
57
    }
58
59
    /** @test */
60
    public function connectionIsClosedEvenIfExceptionIsThrownOnInnerMiddlewares(): void
61
    {
62
        $req = new ServerRequest();
63
        $expectedError = new RuntimeException();
64
        $this->handler->handle($req)->willThrow($expectedError)
65
                                    ->shouldBeCalledOnce();
66
67
        $this->em->getConnection()->shouldBeCalledOnce();
68
        $this->conn->close()->shouldBeCalledOnce();
69
        $this->em->clear()->shouldBeCalledOnce();
70
        $this->expectExceptionObject($expectedError);
71
72
        $this->middleware->process($req, $this->handler->reveal());
73
    }
74
75
    /**
76
     * @test
77
     * @dataProvider provideClosed
78
     */
79
    public function entityManagerIsReopenedAfterAnExceptionWhichClosedIt(bool $closed): void
80
    {
81
        $req = new ServerRequest();
82
        $expectedError = new RuntimeException();
83
        $this->handler->handle($req)->willThrow($expectedError)
84
                                    ->shouldBeCalledOnce();
85
        $this->em->closed = $closed;
86
        $this->em->isOpen()->willReturn(false);
87
88
        try {
89
            $this->middleware->process($req, $this->handler->reveal());
90
            $this->fail('Expected exception to be thrown but it did not.');
91
        } catch (Throwable $e) {
92
            $this->assertSame($expectedError, $e);
93
            $this->assertFalse($this->em->closed);
94
        }
95
    }
96
97
    public function provideClosed(): iterable
98
    {
99
        return [[true, false]];
100
    }
101
}
102