Passed
Push — master ( 7438ce...69adc8 )
by Guilherme
01:29 queued 11s
created

LongPollingUtilsTest   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 159
Duplicated Lines 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
dl 0
loc 159
rs 10
c 1
b 1
f 0
wmc 10
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 LoginCidadao\CoreBundle\Tests\LongPolling;
12
13
use Doctrine\ORM\EntityManagerInterface;
14
use LoginCidadao\APIBundle\Exception\RequestTimeoutException;
15
use LoginCidadao\CoreBundle\Entity\Person;
16
use LoginCidadao\CoreBundle\Entity\PersonRepository;
17
use LoginCidadao\CoreBundle\LongPolling\LongPollingUtils;
18
use LoginCidadao\CoreBundle\Model\PersonInterface;
19
use PHPUnit\Framework\MockObject\MockObject;
20
use PHPUnit\Framework\TestCase;
21
use Symfony\Component\Stopwatch\Stopwatch;
22
23
/**
24
 * @group time-sensitive
25
 */
26
class LongPollingUtilsTest extends TestCase
27
{
28
    public function testRunTimeLimited()
29
    {
30
        $timer = 'timeLimited';
31
        $stopwatch = new Stopwatch();
32
        $stopwatch->start($timer);
33
34
        $longPolling = new LongPollingUtils($this->getEntityManager(), 60);
35
36
        $count = 5;
37
        $response = $longPolling->runTimeLimited(function () use (&$count) {
38
            return --$count <= 0;
39
        });
40
        $duration = $stopwatch->stop($timer)->getDuration();
41
42
        $this->assertTrue($response);
43
        $this->assertEquals(0, $count);
44
        $this->assertLessThan(60, $duration);
45
    }
46
47
    public function testTimeout()
48
    {
49
        $this->expectException(RequestTimeoutException::class);
50
51
        $longPolling = new LongPollingUtils($this->getEntityManager(), 30);
52
        $longPolling->runTimeLimited(function () {
53
            return false;
54
        });
55
    }
56
57
    public function testEntityUpdateCheckerCallback()
58
    {
59
        $updatedAt = new \DateTime('-1 hour');
60
        $currentUpdatedAt = new \DateTime('-1 hour');
61
62
        $person = $this->getPerson();
63
        $person->expects($this->any())->method('getUpdatedAt')
64
            ->willReturnCallback(function () use (&$currentUpdatedAt) {
65
                return $currentUpdatedAt;
66
            });
67
68
        $em = $this->getEntityManager();
69
        $em->expects($this->once())->method('getRepository')
70
            ->willReturn($this->getEvolvingPersonRepo($person, $currentUpdatedAt));
71
72
        $longPolling = new LongPollingUtils($em);
73
        $callback = $longPolling->getEntityUpdateCheckerCallback($person, $updatedAt);
74
75
        call_user_func($callback);
76
        $response = call_user_func($callback);
77
78
        $this->assertNotFalse($response);
79
        $this->assertNotEquals($updatedAt, $currentUpdatedAt);
80
        $this->assertEquals($person, $response);
81
    }
82
83
    public function testEntityUpdateCheckerCallbackNeverUpdated()
84
    {
85
        $person = $this->getPerson();
86
        $person->expects($this->once())->method('getUpdatedAt')->willReturn(null);
87
88
        $repo = $this->getPersonRepository();
89
        $repo->expects($this->any())->method('find')->willReturn($person);
90
91
        $em = $this->getEntityManager();
92
        $em->expects($this->once())->method('getRepository')->willReturn($repo);
93
94
        $longPolling = new LongPollingUtils($em);
95
        $callback = $longPolling->getEntityUpdateCheckerCallback($person, new \DateTime());
96
        $response = call_user_func($callback);
97
98
        $this->assertFalse($response);
99
    }
100
101
    public function testObviouslyValidEmail()
102
    {
103
        $person = $this->getPerson();
104
        $person->expects($this->once())->method('getEmailConfirmedAt')->willReturn(new \DateTime());
105
106
        $longPolling = new LongPollingUtils($this->getEntityManager());
107
        $response = $longPolling->waitValidEmail($person, new \DateTime());
108
109
        $this->assertTrue($response);
110
    }
111
112
    public function testWaitValidEmail()
113
    {
114
        $updatedAt = new \DateTime('-1 hour');
115
        $currentUpdatedAt = new \DateTime('-1 hour');
116
117
        $person = new Person();
118
        $person->setUpdatedAt($updatedAt);
119
120
        $repo = $this->getEvolvingPersonRepoWithRealPerson($person, $currentUpdatedAt);
121
122
        $em = $this->getEntityManager();
123
        $em->expects($this->once())->method('getRepository')->willReturn($repo);
124
125
        $longPolling = new LongPollingUtils($em);
126
        $response = $longPolling->waitValidEmail($person, $updatedAt);
127
128
        $this->assertTrue($response);
129
    }
130
131
    /**
132
     * @return MockObject|EntityManagerInterface
133
     */
134
    private function getEntityManager()
135
    {
136
        $em = $this->createMock(EntityManagerInterface::class);
137
138
        return $em;
139
    }
140
141
    /**
142
     * @return MockObject|PersonRepository
143
     */
144
    private function getPersonRepository()
145
    {
146
        $repo = $this->getMockBuilder(PersonRepository::class)
147
            ->disableOriginalConstructor()->getMock();
148
149
        return $repo;
150
    }
151
152
    /**
153
     * @return PersonInterface|MockObject
154
     */
155
    private function getPerson()
156
    {
157
        /** @var MockObject|PersonInterface $person */
158
        $person = $this->createMock(PersonInterface::class);
159
        $person->expects($this->any())->method('getId')->willReturn(123);
160
161
        return $person;
162
    }
163
164
    /**
165
     * @param PersonInterface|MockObject $person
166
     * @param \DateTime|null $currentUpdatedAt
167
     * @return PersonRepository|MockObject
168
     */
169
    private function getEvolvingPersonRepo(&$person, &$currentUpdatedAt)
170
    {
171
        $repo = $this->getPersonRepository();
172
        $repo->expects($this->at(0))->method('find')->willReturn($person);
173
        $repo->expects($this->at(1))->method('find')
174
            ->willReturnCallback(function () use (&$person, &$currentUpdatedAt) {
175
                $currentUpdatedAt = new \DateTime();
176
                $person->expects($this->any())->method('getEmailConfirmedAt')->willReturn($currentUpdatedAt);
177
178
                return $person;
179
            });
180
181
        return $repo;
182
    }
183
184
    /**
185
     * @param PersonInterface $person
186
     * @param $currentUpdatedAt
187
     * @return PersonRepository|MockObject
188
     */
189
    private function getEvolvingPersonRepoWithRealPerson(PersonInterface &$person, &$currentUpdatedAt)
190
    {
191
        $repo = $this->getPersonRepository();
192
        $repo->expects($this->at(0))->method('find')->willReturn($person);
193
        $repo->expects($this->at(1))->method('find')
194
            ->willReturnCallback(function () use (&$person, &$currentUpdatedAt) {
195
                $person->setUpdatedAt($currentUpdatedAt);
196
                $person->setEmailConfirmedAt($currentUpdatedAt);
197
198
                return $person;
199
            });
200
201
        return $repo;
202
    }
203
}
204