Completed
Pull Request — develop (#726)
by Alejandro
05:51
created

NotifyVisitToMercureTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 12
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ShlinkioTest\Shlink\Core\EventDispatcher;
6
7
use Doctrine\ORM\EntityManagerInterface;
8
use PHPUnit\Framework\TestCase;
9
use Prophecy\Argument;
10
use Prophecy\Prophecy\ObjectProphecy;
11
use Psr\Log\LoggerInterface;
12
use RuntimeException;
13
use Shlinkio\Shlink\Core\Entity\ShortUrl;
14
use Shlinkio\Shlink\Core\Entity\Visit;
15
use Shlinkio\Shlink\Core\EventDispatcher\NotifyVisitToMercure;
16
use Shlinkio\Shlink\Core\EventDispatcher\VisitLocated;
17
use Shlinkio\Shlink\Core\Mercure\MercureUpdatesGeneratorInterface;
18
use Shlinkio\Shlink\Core\Model\Visitor;
19
use Symfony\Component\Mercure\PublisherInterface;
20
use Symfony\Component\Mercure\Update;
21
22
class NotifyVisitToMercureTest extends TestCase
23
{
24
    private NotifyVisitToMercure $listener;
25
    private ObjectProphecy $publisher;
26
    private ObjectProphecy $updatesGenerator;
27
    private ObjectProphecy $em;
28
    private ObjectProphecy $logger;
29
30
    public function setUp(): void
31
    {
32
        $this->publisher = $this->prophesize(PublisherInterface::class);
33
        $this->updatesGenerator = $this->prophesize(MercureUpdatesGeneratorInterface::class);
34
        $this->em = $this->prophesize(EntityManagerInterface::class);
35
        $this->logger = $this->prophesize(LoggerInterface::class);
36
37
        $this->listener = new NotifyVisitToMercure(
38
            $this->publisher->reveal(),
39
            $this->updatesGenerator->reveal(),
40
            $this->em->reveal(),
41
            $this->logger->reveal(),
42
        );
43
    }
44
45
    /** @test */
46
    public function notificationIsNotSentWhenVisitCannotBeFound(): void
47
    {
48
        $visitId = '123';
49
        $findVisit = $this->em->find(Visit::class, $visitId)->willReturn(null);
50
        $logWarning = $this->logger->warning(
51
            'Tried to notify mercure for visit with id "{visitId}", but it does not exist.',
52
            ['visitId' => $visitId],
53
        );
54
        $logDebug = $this->logger->debug(Argument::cetera());
55
        $buildNewVisitUpdate = $this->updatesGenerator->newVisitUpdate(Argument::type(Visit::class))->willReturn(
56
            new Update('', ''),
57
        );
58
        $publish = $this->publisher->__invoke(Argument::type(Update::class));
59
60
        ($this->listener)(new VisitLocated($visitId));
61
62
        $findVisit->shouldHaveBeenCalledOnce();
63
        $logWarning->shouldHaveBeenCalledOnce();
64
        $logDebug->shouldNotHaveBeenCalled();
65
        $buildNewVisitUpdate->shouldNotHaveBeenCalled();
66
        $publish->shouldNotHaveBeenCalled();
67
    }
68
69
    /** @test */
70
    public function notificationIsSentWhenVisitIsFound(): void
71
    {
72
        $visitId = '123';
73
        $visit = new Visit(new ShortUrl(''), Visitor::emptyInstance());
74
        $update = new Update('', '');
75
76
        $findVisit = $this->em->find(Visit::class, $visitId)->willReturn($visit);
77
        $logWarning = $this->logger->warning(Argument::cetera());
78
        $logDebug = $this->logger->debug(Argument::cetera());
79
        $buildNewVisitUpdate = $this->updatesGenerator->newVisitUpdate($visit)->willReturn($update);
80
        $publish = $this->publisher->__invoke($update);
81
82
        ($this->listener)(new VisitLocated($visitId));
83
84
        $findVisit->shouldHaveBeenCalledOnce();
85
        $logWarning->shouldNotHaveBeenCalled();
86
        $logDebug->shouldNotHaveBeenCalled();
87
        $buildNewVisitUpdate->shouldHaveBeenCalledOnce();
88
        $publish->shouldHaveBeenCalledOnce();
89
    }
90
91
    /** @test */
92
    public function debugIsLoggedWhenExceptionIsThrown(): void
93
    {
94
        $visitId = '123';
95
        $visit = new Visit(new ShortUrl(''), Visitor::emptyInstance());
96
        $update = new Update('', '');
97
        $e = new RuntimeException('Error');
98
99
        $findVisit = $this->em->find(Visit::class, $visitId)->willReturn($visit);
100
        $logWarning = $this->logger->warning(Argument::cetera());
101
        $logDebug = $this->logger->debug('Error while trying to notify mercure hub with new visit. {e}', [
102
            'e' => $e,
103
        ]);
104
        $buildNewVisitUpdate = $this->updatesGenerator->newVisitUpdate($visit)->willReturn($update);
105
        $publish = $this->publisher->__invoke($update)->willThrow($e);
106
107
        ($this->listener)(new VisitLocated($visitId));
108
109
        $findVisit->shouldHaveBeenCalledOnce();
110
        $logWarning->shouldNotHaveBeenCalled();
111
        $logDebug->shouldHaveBeenCalledOnce();
112
        $buildNewVisitUpdate->shouldHaveBeenCalledOnce();
113
        $publish->shouldHaveBeenCalledOnce();
114
    }
115
}
116