Completed
Push — issue#752 ( 4f5583...0f30ab )
by Guilherme
16:18 queued 08:06
created

getPhoneVerification()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 2
dl 0
loc 9
ccs 0
cts 8
cp 0
crap 2
rs 9.6666
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the login-cidadao project or it's bundles.
4
 *
5
 * (c) Guilherme Donato <guilhermednt on github>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace PROCERGS\LoginCidadao\PhoneVerificationBundle\Tests\Event;
12
13
use Eljam\CircuitBreaker\Breaker;
14
use Eljam\CircuitBreaker\Exception\CircuitOpenException;
15
use libphonenumber\PhoneNumber;
16
use LoginCidadao\CoreBundle\Model\PersonInterface;
17
use LoginCidadao\PhoneVerificationBundle\Event\SendPhoneVerificationEvent;
18
use LoginCidadao\PhoneVerificationBundle\Model\PhoneVerificationInterface;
19
use LoginCidadao\PhoneVerificationBundle\PhoneVerificationEvents;
20
use PROCERGS\LoginCidadao\PhoneVerificationBundle\Event\PhoneVerificationSubscriber;
21
use PROCERGS\Sms\Exception\InvalidCountryException;
22
use PROCERGS\Sms\SmsService;
23
use Psr\Log\LogLevel;
24
25
class PhoneVerificationSubscriberTest extends \PHPUnit_Framework_TestCase
26
{
27
    public function testGetSubscribedEvents()
28
    {
29
        $this->assertArrayHasKey(
30
            PhoneVerificationEvents::PHONE_VERIFICATION_REQUESTED,
31
            PhoneVerificationSubscriber::getSubscribedEvents()
32
        );
33
    }
34
35
    public function testOnVerificationRequestClosedCircuitBreaker()
36
    {
37
        $phoneNumber = $this->getMock('libphonenumber\PhoneNumber');
38
        $person = $this->getMock('LoginCidadao\CoreBundle\Model\PersonInterface');
39
        $phoneVerification = $this->getPhoneVerification($person, $phoneNumber);
40
        $event = $this->getEvent($phoneVerification, true);
41
        $dispatcher = $this->getDispatcher($event);
42
43
        $subscriber = $this->getPhoneVerificationSubscriber();
44
        $subscriber->onVerificationRequest($event, PhoneVerificationEvents::PHONE_VERIFICATION_REQUESTED, $dispatcher);
45
    }
46
47
    public function testOnVerificationRequestOpenCircuitBreaker()
48
    {
49
        $phoneNumber = $this->getMock('libphonenumber\PhoneNumber');
50
        $person = $this->getMock('LoginCidadao\CoreBundle\Model\PersonInterface');
51
        $phoneVerification = $this->getPhoneVerification($person, $phoneNumber);
52
        $event = $this->getEvent($phoneVerification, false);
53
        $dispatcher = $this->getDispatcher();
54
        $breaker = $this->getBreaker(new CircuitOpenException());
55
56
        $subscriber = $this->getPhoneVerificationSubscriber($breaker, false);
57
        $subscriber->onVerificationRequest($event, PhoneVerificationEvents::PHONE_VERIFICATION_REQUESTED, $dispatcher);
58
    }
59
60
    public function testOnVerificationRequestCloseCircuitBreaker()
61
    {
62
        $phoneNumber = $this->getMock('libphonenumber\PhoneNumber');
63
        $person = $this->getMock('LoginCidadao\CoreBundle\Model\PersonInterface');
64
        $phoneVerification = $this->getPhoneVerification($person, $phoneNumber);
65
        $event = $this->getEvent($phoneVerification, false);
66
        $dispatcher = $this->getDispatcher();
67
        $breaker = $this->getBreaker(new \Exception("Generic error"));
68
69
        $subscriber = $this->getPhoneVerificationSubscriber($breaker, false);
70
        $subscriber->onVerificationRequest($event, PhoneVerificationEvents::PHONE_VERIFICATION_REQUESTED, $dispatcher);
71
    }
72
73
    public function testUnsupportedCountry()
74
    {
75
        $phoneNumber = new PhoneNumber();
76
        $phoneNumber->setCountryCode(1)
77
            ->setNationalNumber('123456');
78
        $person = $this->getMock('LoginCidadao\CoreBundle\Model\PersonInterface');
79
        $phoneVerification = $this->getPhoneVerification($person, $phoneNumber);
80
        $event = $this->getEvent($phoneVerification, false);
81
        $dispatcher = $this->getDispatcher();
82
        $breakerConfig = [
83
            'allowed_exceptions' => ['PROCERGS\Sms\Exception\InvalidCountryException'],
84
        ];
85
        $breaker = new Breaker('my_breaker', $breakerConfig);
86
87
        $logger = $this->getMock('Psr\Log\LoggerInterface');
88
        $logger->expects($this->once())->method('log')->with(LogLevel::ERROR);
89
90
        $smsService = $this->getSmsService();
91
        $smsService->expects($this->once())->method('easySend')
92
            ->willThrowException(new InvalidCountryException('Unsupported Country'));
93
94
        $subscriber = $this->getPhoneVerificationSubscriber($breaker, false, $smsService, $logger);
95
        $subscriber->setLogger($logger);
96
97
        $subscriber->onVerificationRequest($event, PhoneVerificationEvents::PHONE_VERIFICATION_REQUESTED, $dispatcher);
98
    }
99
100
    /**
101
     * @param Breaker|null $breaker
102
     * @param bool $expectEasySend
103
     * @return PhoneVerificationSubscriber
104
     */
105
    private function getPhoneVerificationSubscriber(
106
        Breaker $breaker = null,
107
        $expectEasySend = true,
108
        $smsService = null,
109
        $logger = null
110
    ) {
111
        $smsService = $smsService ?: $this->getSmsService();
112
        if ($expectEasySend) {
113
            $smsService->expects($this->once())->method('easySend')->willReturn('012345');
114
        }
115
116
        $translator = $this->getMock('Symfony\Component\Translation\TranslatorInterface');
117
        $translator->expects($this->once())->method('trans')->willReturn('message');
118
119
        $router = $this->getMock('Symfony\Component\Routing\RouterInterface');
120
        $router->expects($this->once())->method('generate')->willReturnCallback(
121
            function ($routeName) {
122
                return $routeName;
123
            }
124
        );
125
126
        $breaker = $breaker ?: new Breaker('breaker');
127
128
        if ($logger === null) {
129
            $logger = $this->getMock('Psr\Log\LoggerInterface');
130
            $logger->expects($this->once())->method('log');
131
        }
132
133
        $subscriber = new PhoneVerificationSubscriber($smsService, $translator, $router, $breaker);
134
        $subscriber->setLogger($logger);
135
136
        return $subscriber;
137
    }
138
139
    /**
140
     * @return \PHPUnit_Framework_MockObject_MockObject|SmsService
141
     */
142
    private function getSmsService()
143
    {
144
        $smsService = $this->getMockBuilder('PROCERGS\Sms\SmsService')
145
            ->disableOriginalConstructor()
146
            ->getMock();
147
148
        return $smsService;
149
    }
150
151
    private function getPhoneVerification(PersonInterface $person, PhoneNumber $phoneNumber)
152
    {
153
        $phoneVerificationClass = 'LoginCidadao\PhoneVerificationBundle\Model\PhoneVerificationInterface';
154
        $phoneVerification = $this->getMock($phoneVerificationClass);
155
        $phoneVerification->expects($this->any())->method('getPerson')->willReturn($person);
156
        $phoneVerification->expects($this->any())->method('getVerificationCode')->willReturn(123456);
157
        $phoneVerification->expects($this->any())->method('getPhone')->willReturn($phoneNumber);
158
159
        return $phoneVerification;
160
    }
161
162
    private function getEvent(PhoneVerificationInterface $phoneVerification = null, $sent = true)
163
    {
164
        $event = $this->getMockBuilder('LoginCidadao\PhoneVerificationBundle\Event\SendPhoneVerificationEvent')
165
            ->disableOriginalConstructor()
166
            ->getMock();
167
168
        $event->expects($this->atLeastOnce())->method('getPhoneVerification')->willReturn($phoneVerification);
169
170
        if ($sent) {
171
            $event->expects($this->once())->method('setSentVerification')->with(
172
                $this->isInstanceOf('LoginCidadao\PhoneVerificationBundle\Entity\SentVerification')
173
            );
174
        }
175
176
        return $event;
177
    }
178
179
    private function getDispatcher(SendPhoneVerificationEvent $event = null)
180
    {
181
        $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
182
        if ($event) {
183
            $dispatcher->expects($this->once())->method('dispatch')->with(
184
                PhoneVerificationEvents::PHONE_VERIFICATION_CODE_SENT,
185
                $event
186
            );
187
        }
188
189
        return $dispatcher;
190
    }
191
192
    private function getBreaker($exception = null)
193
    {
194
        $breaker = null;
195
        if ($exception instanceof \Exception) {
196
            $breaker = $this->getMockBuilder('Eljam\CircuitBreaker\Breaker')
197
                ->disableOriginalConstructor()
198
                ->getMock();
199
            $breaker->expects($this->once())->method('protect')
200
                ->willThrowException($exception);
201
        }
202
203
        return $breaker ?: new Breaker('name');
204
    }
205
}
206