Passed
Pull Request — master (#1)
by Igor
02:41
created

ServiceTest   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 253
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 143
dl 0
loc 253
rs 10
c 2
b 0
f 0
wmc 12

9 Methods

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