Passed
Push — master ( 0c254f...67a475 )
by Igor
02:07
created

ServiceTest::generateDetailLawyer()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 13
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 19
rs 9.8333
1
<?php
2
/** @noinspection PhpUnhandledExceptionInspection */
3
namespace SomeWork\Minjust\Tests\Unit;
4
5
use Psr\Http\Client\ClientExceptionInterface;
6
use ReflectionException;
7
use Exception;
8
use Generator;
9
use Iterator;
10
use PHPUnit\Framework\MockObject\MockObject;
11
use PHPUnit\Framework\TestCase;
12
use ReflectionClass;
13
use SomeWork\Minjust\Client;
14
use SomeWork\Minjust\Entity\DetailLawyer;
15
use SomeWork\Minjust\Entity\LawFormation;
16
use SomeWork\Minjust\Entity\Lawyer;
17
use SomeWork\Minjust\FindRequest;
18
use SomeWork\Minjust\FindResponse;
19
use SomeWork\Minjust\Parser\ParserInterface;
20
use SomeWork\Minjust\Service;
21
22
class ServiceTest extends TestCase
23
{
24
    public function testFind(): void
25
    {
26
        /**
27
         * @var ParserInterface|MockObject $parser
28
         * @var Service|MockObject         $service
29
         * @var Client|MockObject          $client
30
         */
31
        $lawyer = $this->generateLawyer();
32
33
        $response = (new FindResponse())
34
            ->addLawyer($lawyer)
35
            ->setPage(1)
36
            ->setTotalPage(1)
37
            ->setTotal(1);
38
39
        $client = $this->createMock(Client::class);
40
        $client
41
            ->method('list')
42
            ->willReturn('');
43
44
        $parser = $this->createMock(ParserInterface::class);
45
        $parser
46
            ->method('list')
47
            ->willReturn($response);
48
49
        $service = $this
50
            ->getMockBuilder(Service::class)
51
            ->onlyMethods(['getDetailLawyersGenerator'])
52
            ->setConstructorArgs([$client, $parser])
53
            ->getMock();
54
55
        $service
56
            ->method('getDetailLawyersGenerator')
57
            ->willReturn($this->generateDetailLawyerGenerator($lawyer));
58
59
        $response = $service->find(new FindRequest());
60
61
        $this->assertCount(1, $response->getLawyers());
62
        $this->assertInstanceOf(Lawyer::class, $response->getLawyers()[0]);
63
        $this->assertInstanceOf(Generator::class, $response->getDetailLawyers());
64
    }
65
66
    protected function generateLawyer(): Lawyer
67
    {
68
        try {
69
            $id = md5(random_bytes(16));
70
        } catch (Exception $exception) {
71
            $id = md5(microtime(true));
72
        }
73
74
        return (new Lawyer())
75
            ->setTerritorialSubject('Тестовая территория')
76
            ->setCertificateNumber('test/' . $id)
77
            ->setRegisterNumber('test/' . $id)
78
            ->setStatus('Тестовый статус')
79
            ->setFullName('Тестовый Тест Тестович')
80
            ->setUrl('/test/' . $id . '/');
81
    }
82
83
    /**
84
     * @param \SomeWork\Minjust\Entity\Lawyer $lawyer
85
     *
86
     * @return Generator
87
     */
88
    protected function generateDetailLawyerGenerator(Lawyer $lawyer): Generator
89
    {
90
        yield DetailLawyer::init($lawyer);
91
    }
92
93
    public function testFindFromToOffsetForOnePage(): void
94
    {
95
        $lawyer = $this->generateLawyer();
96
97
        $response = (new FindResponse())
98
            ->setTotal(1)
99
            ->setTotalPage(1)
100
            ->setPage(1)
101
            ->addLawyer($lawyer)
102
            ->setDetailLawyersGenerator(
103
                $this->generateDetailLawyerGenerator($lawyer)
104
            );
105
106
        $service = $this
107
            ->createPartialMock(Service::class, ['find']);
108
        $service
109
            ->method('find')
110
            ->willReturn($response);
111
112
        $request = new FindRequest();
113
        $request->setOffset(1000);
114
115
        $response = $service->findFromTo($request, 1, 2);
116
        $this->assertInstanceOf(Generator::class, $response);
117
118
        foreach ($response as $lawyer) {
119
            $this->assertNotInstanceOf(DetailLawyer::class, $lawyer);
120
        }
121
        $this->assertEquals(0, $request->getOffset());
122
123
        $request->setFullData(true);
124
        $response = $service->findFromTo($request, 1, 1);
125
126
        $this->assertContainsOnlyInstancesOf(DetailLawyer::class, $response);
127
    }
128
129
    /**
130
     * @dataProvider multipleProvider
131
     *
132
     * @param bool $isMultiple
133
     *
134
     * @throws ClientExceptionInterface
135
     */
136
    public function testFindFromToOffsetForMultiplePage(bool $isMultiple): void
137
    {
138
        $lawyerFirst = $this->generateLawyer();
139
        $lawyersSecond = $this->generateLawyer();
140
141
        $responseFirst = (new FindResponse())
142
            ->setTotal(1)
143
            ->setTotalPage(2)
144
            ->setPage(1)
145
            ->addLawyer($lawyerFirst)
146
            ->setDetailLawyersGenerator(
147
                $this->generateDetailLawyerGenerator($lawyerFirst)
148
            );
149
150
        $responseSecond = (new FindResponse())
151
            ->setTotal(1)
152
            ->setTotalPage(2)
153
            ->setPage(2)
154
            ->addLawyer($lawyersSecond)
155
            ->setDetailLawyersGenerator(
156
                $this->generateDetailLawyerGenerator($lawyersSecond)
157
            );
158
159
        $service = $this
160
            ->createPartialMock(Service::class, ['find']);
161
162
        $service
163
            ->expects($this->at(0))
164
            ->method('find')
165
            ->willReturn($responseFirst);
166
167
        $service
168
            ->expects($this->at(1))
169
            ->method('find')
170
            ->willReturn($responseSecond);
171
172
        $request = (new FindRequest())
173
            ->setMax(1);
174
175
        if (!$isMultiple) {
176
            $response = $service->findFromTo($request, 1, 2);
177
178
            $lawyer = $response->current();
179
            $this->assertInstanceOf(Lawyer::class, $lawyer);
180
            $this->assertEquals($lawyerFirst, $lawyer);
181
182
            $response->next();
183
            $this->assertEquals(1, $request->getOffset());
184
185
            $lawyer = $response->current();
186
            $this->assertInstanceOf(Lawyer::class, $lawyer);
187
            $this->assertEquals($lawyersSecond, $lawyer);
188
189
            $response->next();
190
            $this->assertFalse($response->valid());
191
192
            return;
193
        }
194
195
        $request->setFullData(true);
196
        $response = $service->findFromTo($request, 1, 2);
197
198
        $this->assertContainsOnlyInstancesOf(DetailLawyer::class, $response);
199
    }
200
201
    public function multipleProvider(): Iterator
202
    {
203
        yield [false];
204
        yield [true];
205
    }
206
207
    public function testGetDetailLawyersGenerator(): void
208
    {
209
        $detailFirst = $this->generateDetailLawyer();
210
        $detailSecond = $this->generateDetailLawyer();
211
212
        $lawyerFirst = $this->generateLawyer();
213
        $lawyerSecond = $this->generateLawyer();
214
215
        $client = $this->createMock(Client::class);
216
        $client
217
            ->method('detail')
218
            ->willReturn('');
219
220
        $parser = $this->createMock(ParserInterface::class);
221
        $parser
222
            ->expects($this->at(0))
223
            ->method('detail')
224
            ->willReturn($detailFirst);
225
226
        $parser
227
            ->expects($this->at(1))
228
            ->method('detail')
229
            ->willReturn($detailSecond);
230
231
        $service = new Service($client, $parser);
232
        $generator = $this->invokeMethod($service, 'getDetailLawyersGenerator', [[$lawyerFirst, $lawyerSecond]]);
233
234
        $this->assertInstanceOf(Generator::class, $generator);
235
236
        /**
237
         * @var DetailLawyer $lawyer
238
         */
239
        $lawyer = $generator->current();
240
        $this->assertInstanceOf(DetailLawyer::class, $lawyer);
241
        $this->assertEquals($lawyerFirst->getUrl(), $lawyer->getUrl());
242
        $this->assertEquals($lawyerFirst->getTerritorialSubject(), $lawyer->getTerritorialSubject());
243
        $this->assertEquals($lawyerFirst->getStatus(), $lawyer->getStatus());
244
        $this->assertEquals($lawyerFirst->getCertificateNumber(), $lawyer->getCertificateNumber());
245
        $this->assertEquals($lawyerFirst->getRegisterNumber(), $lawyer->getRegisterNumber());
246
        $this->assertEquals($lawyerFirst->getFullName(), $lawyer->getFullName());
247
        $this->assertEquals($detailFirst, $lawyer);
248
249
        $generator->next();
250
        $lawyer = $generator->current();
251
        $this->assertInstanceOf(DetailLawyer::class, $lawyer);
252
        $this->assertEquals($lawyerSecond->getUrl(), $lawyer->getUrl());
253
        $this->assertEquals($lawyerSecond->getTerritorialSubject(), $lawyer->getTerritorialSubject());
254
        $this->assertEquals($lawyerSecond->getStatus(), $lawyer->getStatus());
255
        $this->assertEquals($lawyerSecond->getCertificateNumber(), $lawyer->getCertificateNumber());
256
        $this->assertEquals($lawyerSecond->getRegisterNumber(), $lawyer->getRegisterNumber());
257
        $this->assertEquals($lawyerSecond->getFullName(), $lawyer->getFullName());
258
        $this->assertEquals($detailSecond, $lawyer);
259
    }
260
261
    protected function generateDetailLawyer(?Lawyer $lawyer = null): DetailLawyer
262
    {
263
        try {
264
            $id = md5(random_bytes(16));
265
        } catch (Exception $exception) {
266
            $id = md5(microtime(true));
267
        }
268
269
        $detailLawyer = (new DetailLawyer())
270
            ->setChamberOfLaw('Палата ' . $id)
271
            ->setLawFormation(
272
                (new LawFormation())
273
                    ->setPhone('88004443459')
274
                    ->setAddress('г. Москва, ул. Беговая, д. 2')
275
                    ->setName('ООО "Бреви Ману" ID: ' . $id)
276
                    ->setEmail('[email protected]')
277
            );
278
279
        return $lawyer !== null ? $detailLawyer->loadFromLawyer($lawyer) : $detailLawyer;
280
    }
281
282
    /**
283
     * Call protected/private method of a class.
284
     *
285
     * @param object &$object     Instantiated object that we will run method on.
286
     * @param string  $methodName Method name to call
287
     * @param array   $parameters Array of parameters to pass into method.
288
     *
289
     * @return mixed Method return.
290
     * @throws ReflectionException
291
     */
292
    public function invokeMethod(&$object, $methodName, array $parameters = [])
293
    {
294
        $reflection = new ReflectionClass(get_class($object));
295
        $method = $reflection->getMethod($methodName);
296
        $method->setAccessible(true);
297
298
        return $method->invokeArgs($object, $parameters);
299
    }
300
301
    public function testGetDetailLawyersGeneratorOnEmpty(): void
302
    {
303
        $client = $this->createMock(Client::class);
304
        $parser = $this->createMock(ParserInterface::class);
305
306
        $service = new Service($client, $parser);
307
308
        /**
309
         * @var Generator $generator
310
         */
311
        $generator = $this->invokeMethod($service, 'getDetailLawyersGenerator', [[]]);
312
        $this->assertInstanceOf(Generator::class, $generator);
313
        $this->assertFalse($generator->valid());
314
    }
315
}
316