Completed
Push — master ( a30f79...cb6756 )
by Alejandro
27s queued 13s
created

notificationsAreNotSentWhenVisitCannotBeFound()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 19
dl 0
loc 25
rs 9.6333
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 notificationsAreNotSentWhenVisitCannotBeFound(): 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
        $buildNewShortUrlVisitUpdate = $this->updatesGenerator->newShortUrlVisitUpdate(
56
            Argument::type(Visit::class),
57
        )->willReturn(new Update('', ''));
58
        $buildNewVisitUpdate = $this->updatesGenerator->newVisitUpdate(Argument::type(Visit::class))->willReturn(
59
            new Update('', ''),
60
        );
61
        $publish = $this->publisher->__invoke(Argument::type(Update::class));
62
63
        ($this->listener)(new VisitLocated($visitId));
64
65
        $findVisit->shouldHaveBeenCalledOnce();
66
        $logWarning->shouldHaveBeenCalledOnce();
67
        $logDebug->shouldNotHaveBeenCalled();
68
        $buildNewShortUrlVisitUpdate->shouldNotHaveBeenCalled();
69
        $buildNewVisitUpdate->shouldNotHaveBeenCalled();
70
        $publish->shouldNotHaveBeenCalled();
71
    }
72
73
    /** @test */
74
    public function notificationsAreSentWhenVisitIsFound(): void
75
    {
76
        $visitId = '123';
77
        $visit = new Visit(new ShortUrl(''), Visitor::emptyInstance());
78
        $update = new Update('', '');
79
80
        $findVisit = $this->em->find(Visit::class, $visitId)->willReturn($visit);
81
        $logWarning = $this->logger->warning(Argument::cetera());
82
        $logDebug = $this->logger->debug(Argument::cetera());
83
        $buildNewShortUrlVisitUpdate = $this->updatesGenerator->newShortUrlVisitUpdate($visit)->willReturn($update);
84
        $buildNewVisitUpdate = $this->updatesGenerator->newVisitUpdate($visit)->willReturn($update);
85
        $publish = $this->publisher->__invoke($update);
86
87
        ($this->listener)(new VisitLocated($visitId));
88
89
        $findVisit->shouldHaveBeenCalledOnce();
90
        $logWarning->shouldNotHaveBeenCalled();
91
        $logDebug->shouldNotHaveBeenCalled();
92
        $buildNewShortUrlVisitUpdate->shouldHaveBeenCalledOnce();
93
        $buildNewVisitUpdate->shouldHaveBeenCalledOnce();
94
        $publish->shouldHaveBeenCalledTimes(2);
95
    }
96
97
    /** @test */
98
    public function debugIsLoggedWhenExceptionIsThrown(): void
99
    {
100
        $visitId = '123';
101
        $visit = new Visit(new ShortUrl(''), Visitor::emptyInstance());
102
        $update = new Update('', '');
103
        $e = new RuntimeException('Error');
104
105
        $findVisit = $this->em->find(Visit::class, $visitId)->willReturn($visit);
106
        $logWarning = $this->logger->warning(Argument::cetera());
107
        $logDebug = $this->logger->debug('Error while trying to notify mercure hub with new visit. {e}', [
108
            'e' => $e,
109
        ]);
110
        $buildNewShortUrlVisitUpdate = $this->updatesGenerator->newShortUrlVisitUpdate($visit)->willReturn($update);
111
        $buildNewVisitUpdate = $this->updatesGenerator->newVisitUpdate($visit)->willReturn($update);
112
        $publish = $this->publisher->__invoke($update)->willThrow($e);
113
114
        ($this->listener)(new VisitLocated($visitId));
115
116
        $findVisit->shouldHaveBeenCalledOnce();
117
        $logWarning->shouldNotHaveBeenCalled();
118
        $logDebug->shouldHaveBeenCalledOnce();
119
        $buildNewShortUrlVisitUpdate->shouldHaveBeenCalledOnce();
120
        $buildNewVisitUpdate->shouldNotHaveBeenCalled();
121
        $publish->shouldHaveBeenCalledOnce();
122
    }
123
}
124