Completed
Push — master ( 116dd8...98663d )
by Al3x
02:26
created

testDispatchRequestApiException()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 34
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 34
c 0
b 0
f 0
rs 8.8571
cc 1
eloc 25
nc 1
nop 0
1
<?php
2
3
namespace InvoiceNinjaModuleTest\Service;
4
5
use InvoiceNinjaModule\Model\Interfaces\RequestOptionsInterface;
6
use InvoiceNinjaModule\Model\Interfaces\SettingsInterface;
7
use InvoiceNinjaModule\Service\Interfaces\RequestServiceInterface;
8
use InvoiceNinjaModule\Service\RequestService;
9
use Zend\Http\Client;
10
use Zend\Http\Header\HeaderInterface;
11
use Zend\Http\Headers;
12
use Zend\Http\Request;
13
use Zend\Http\Response;
14
use Zend\Stdlib\RequestInterface;
15
use PHPUnit\Framework\TestCase;
16
17
class RequestServiceTest extends TestCase
18
{
19
    /** @var  RequestServiceInterface */
20
    private $manager;
21
    /** @var  \PHPUnit_Framework_MockObject_MockObject */
22
    private $settingsMock;
23
    /** @var  \PHPUnit_Framework_MockObject_MockObject */
24
    private $httpClientMock;
25
    /** @var  string */
26
    private $reqMethod;
27
    /** @var  \PHPUnit_Framework_MockObject_MockObject */
28
    private $requestOptions;
29
30
    protected function setUp()
31
    {
32
        parent::setUp();
33
        $this->settingsMock = $this->createMock(SettingsInterface::class);
34
        $this->httpClientMock = $this->createMock(Client::class);
35
        $this->reqMethod = Request::METHOD_GET;
36
        $this->requestOptions = $this->createMock(RequestOptionsInterface::class);
37
38
39
        $this->manager = new RequestService($this->settingsMock, $this->httpClientMock);
40
    }
41
42
    public function testCreate()
43
    {
44
        self::assertInstanceOf(RequestServiceInterface::class, $this->manager);
45
    }
46
47
    public function testDispatchRequest()
48
    {
49
        $testTokenType = 'testtokentype';
50
        $testToken = 'testtoken';
51
        $testReqRoute = 'testroute';
52
53
        $headers = $this->createMock(Headers::class);
54
        $headers->expects(self::once())
55
            ->method('get')
56
            ->with(self::stringContains('Content-disposition'))
57
            ->willReturn(false);
58
59
        $response = $this->createMock(Response::class);
60
        $response->expects(self::once())
61
            ->method('getStatusCode')
62
            ->willReturn(Response::STATUS_CODE_200);
63
64
        $response->expects(self::once())
65
            ->method('getHeaders')
66
            ->willReturn($headers);
67
68
        $response->expects(self::once())
69
            ->method('getBody')
70
            ->willReturn('{"data": [0]}');
71
72
        $this->settingsMock->expects(self::once())
73
            ->method('getTimeout')
74
            ->willReturn(10);
75
76
        $this->settingsMock->expects(self::once())
77
            ->method('getTokenType')
78
            ->willReturn($testTokenType);
79
80
        $this->settingsMock->expects(self::once())
81
            ->method('getToken')
82
            ->willReturn($testToken);
83
84
        $this->httpClientMock->expects(self::once())
85
            ->method('send')
86
            ->with(
87
                self::logicalAnd(
88
                    self::isInstanceOf(RequestInterface::class),
89
                    self::callback(function ($request) {
90
                        /** @var Request $request */
91
                        return $request->getAllowCustomMethods() === false;
92
                    })
93
                )
94
            )
95
            ->willReturn($response);
96
97
98
        $this->manager = new RequestService($this->settingsMock, $this->httpClientMock);
99
100
        self::assertInternalType(
101
            'array',
102
            $this->manager->dispatchRequest($this->reqMethod, $testReqRoute, $this->requestOptions)
103
        );
104
    }
105
106
107
    public function testDispatchRequestFile()
108
    {
109
        $testTokenType = 'testtokentype';
110
        $testToken = 'testtoken';
111
        $testReqRoute = 'testroute';
112
113
        $header = $this->createMock(HeaderInterface::class);
114
        $header->expects(self::once())
115
            ->method('getFieldValue')
116
            ->willReturn('attachment; filename="test.pdf"');
117
118
        $headers = $this->createMock(Headers::class);
119
        $headers->expects(self::once())
120
            ->method('get')
121
            ->with(self::stringContains('Content-disposition'))
122
            ->willReturn($header);
123
124
        $response = $this->createMock(Response::class);
125
        $response->expects(self::once())
126
            ->method('getStatusCode')
127
            ->willReturn(Response::STATUS_CODE_200);
128
129
        $response->expects(self::once())
130
            ->method('getHeaders')
131
            ->willReturn($headers);
132
133
        $response->expects(self::once())
134
            ->method('getBody')
135
            ->willReturn('testfilecontent');
136
137
        $this->settingsMock->expects(self::once())
138
            ->method('getTimeout')
139
            ->willReturn(10);
140
141
        $this->settingsMock->expects(self::once())
142
            ->method('getTokenType')
143
            ->willReturn($testTokenType);
144
145
        $this->settingsMock->expects(self::once())
146
            ->method('getToken')
147
            ->willReturn($testToken);
148
149
        $this->httpClientMock->expects(self::once())
150
            ->method('send')
151
            ->with(
152
                self::logicalAnd(
153
                    self::isInstanceOf(RequestInterface::class),
154
                    self::callback(function ($request) {
155
                        /** @var Request $request*/
156
                        return $request->getAllowCustomMethods() === false;
157
                    })
158
                )
159
            )
160
            ->willReturn($response);
161
162
        $this->manager = new RequestService($this->settingsMock, $this->httpClientMock);
163
        $result = $this->manager->dispatchRequest($this->reqMethod, $testReqRoute, $this->requestOptions);
164
        self::assertInternalType('array', $result);
165
        self::assertArrayHasKey('test.pdf', $result);
166
        self::assertEquals('testfilecontent', $result['test.pdf']);
167
    }
168
169
    public function testDispatchRequestFileInvalidHeader()
170
    {
171
        $testTokenType = 'testtokentype';
172
        $testToken = 'testtoken';
173
        $testReqRoute = 'testroute';
174
175
        $header = $this->createMock(HeaderInterface::class);
176
        $header->expects(self::once())
177
            ->method('getFieldValue')
178
            ->willReturn('attachTESTment; filename="test.pdf"');
179
180
        $headers = $this->createMock(Headers::class);
181
        $headers->expects(self::once())
182
            ->method('get')
183
            ->with(self::stringContains('Content-disposition'))
184
            ->willReturn($header);
185
186
        $response = $this->createMock(Response::class);
187
        $response->expects(self::once())
188
            ->method('getStatusCode')
189
            ->willReturn(Response::STATUS_CODE_200);
190
191
        $response->expects(self::once())
192
            ->method('getHeaders')
193
            ->willReturn($headers);
194
195
        $response->expects(self::never())
196
            ->method('getBody')
197
            ->willReturn('testfilecontent');
198
199
        $this->settingsMock->expects(self::once())
200
            ->method('getTimeout')
201
            ->willReturn(10);
202
203
        $this->settingsMock->expects(self::once())
204
            ->method('getTokenType')
205
            ->willReturn($testTokenType);
206
207
        $this->settingsMock->expects(self::once())
208
            ->method('getToken')
209
            ->willReturn($testToken);
210
211
        $this->httpClientMock->expects(self::once())
212
            ->method('send')
213
            ->with(
214
                self::logicalAnd(
215
                    self::isInstanceOf(RequestInterface::class),
216
                    self::callback(function ($request) {
217
                        /** @var Request $request*/
218
                        return $request->getAllowCustomMethods() === false;
219
                    })
220
                )
221
            )
222
            ->willReturn($response);
223
224
        $this->manager = new RequestService($this->settingsMock, $this->httpClientMock);
225
        $result = $this->manager->dispatchRequest($this->reqMethod, $testReqRoute, $this->requestOptions);
226
        self::assertInternalType('array', $result);
227
        self::assertEmpty($result);
228
    }
229
230
    public function testDispatchRequestWithOptions()
231
    {
232
        $testTokenType = 'testtokentype';
233
        $testToken = 'testtoken';
234
        $testReqRoute = 'testroute';
235
236
        $this->requestOptions->expects(self::once())
237
            ->method('getQueryArray')
238
            ->willReturn([]);
239
240
        $headers = $this->createMock(Headers::class);
241
        $headers->expects(self::once())
242
            ->method('get')
243
            ->with(self::stringContains('Content-disposition'))
244
            ->willReturn(false);
245
246
        $response = $this->createMock(Response::class);
247
        $response->expects(self::once())
248
            ->method('getStatusCode')
249
            ->willReturn(Response::STATUS_CODE_200);
250
251
        $response->expects(self::once())
252
            ->method('getHeaders')
253
            ->willReturn($headers);
254
255
        $response->expects(self::once())
256
            ->method('getBody')
257
            ->willReturn('{"data": [0]}');
258
259
        $this->settingsMock->expects(self::once())
260
            ->method('getTimeout')
261
            ->willReturn(10);
262
263
        $this->settingsMock->expects(self::once())
264
            ->method('getTokenType')
265
            ->willReturn($testTokenType);
266
267
        $this->settingsMock->expects(self::once())
268
            ->method('getToken')
269
            ->willReturn($testToken);
270
271
        $this->httpClientMock->expects(self::once())
272
            ->method('send')
273
            ->with(
274
                self::logicalAnd(
275
                    self::isInstanceOf(RequestInterface::class),
276
                    self::callback(function ($request) {
277
                        /** @var Request $request*/
278
                        return $request->getAllowCustomMethods() === false;
279
                    })
280
                )
281
            )
282
            ->willReturn($response);
283
284
285
        $this->manager = new RequestService($this->settingsMock, $this->httpClientMock);
286
        self::assertInternalType(
287
            'array',
288
            $this->manager->dispatchRequest($this->reqMethod, $testReqRoute, $this->requestOptions)
289
        );
290
    }
291
292
293
    /**
294
     * @expectedException  \InvoiceNinjaModule\Exception\EmptyResponseException
295
     */
296
    public function testDispatchRequestEmptyExceptionEmptyData()
297
    {
298
        $testTokenType = 'testtokentype';
299
        $testToken = 'testtoken';
300
        $testReqRoute = 'testroute';
301
302
        $headers = $this->createMock(Headers::class);
303
        $headers->expects(self::once())
304
            ->method('get')
305
            ->with(self::stringContains('Content-disposition'))
306
            ->willReturn(false);
307
308
        $response = $this->createMock(Response::class);
309
        $response->expects(self::once())
310
            ->method('getStatusCode')
311
            ->willReturn(Response::STATUS_CODE_200);
312
313
        $response->expects(self::once())
314
            ->method('getHeaders')
315
            ->willReturn($headers);
316
317
        $response->expects(self::once())
318
            ->method('getBody')
319
            ->willReturn('{"data": []}');
320
321
        $this->settingsMock->expects(self::once())
322
            ->method('getTimeout')
323
            ->willReturn(10);
324
325
        $this->settingsMock->expects(self::once())
326
            ->method('getTokenType')
327
            ->willReturn($testTokenType);
328
329
        $this->settingsMock->expects(self::once())
330
            ->method('getToken')
331
            ->willReturn($testToken);
332
333
        $this->httpClientMock->expects(self::once())
334
            ->method('send')
335
            ->with(self::isInstanceOf(RequestInterface::class))
336
            ->willReturn($response);
337
338
        $this->manager = new RequestService($this->settingsMock, $this->httpClientMock);
339
        self::assertInternalType(
340
            'array',
341
            $this->manager->dispatchRequest($this->reqMethod, $testReqRoute, $this->requestOptions)
342
        );
343
    }
344
345
    /**
346
     * @expectedException  \InvoiceNinjaModule\Exception\EmptyResponseException
347
     */
348
    public function testDispatchRequestEmptyExceptionMissingData()
349
    {
350
        $testTokenType = 'testtokentype';
351
        $testToken = 'testtoken';
352
        $testReqRoute = 'testroute';
353
354
        $headers = $this->createMock(Headers::class);
355
        $headers->expects(self::once())
356
            ->method('get')
357
            ->with(self::stringContains('Content-disposition'))
358
            ->willReturn(false);
359
360
        $response = $this->createMock(Response::class);
361
        $response->expects(self::once())
362
            ->method('getStatusCode')
363
            ->willReturn(Response::STATUS_CODE_200);
364
365
        $response->expects(self::once())
366
            ->method('getHeaders')
367
            ->willReturn($headers);
368
369
        $response->expects(self::once())
370
            ->method('getBody')
371
            ->willReturn('{}');
372
373
        $this->settingsMock->expects(self::once())
374
            ->method('getTimeout')
375
            ->willReturn(10);
376
377
        $this->settingsMock->expects(self::once())
378
            ->method('getTokenType')
379
            ->willReturn($testTokenType);
380
381
        $this->settingsMock->expects(self::once())
382
            ->method('getToken')
383
            ->willReturn($testToken);
384
385
        $this->httpClientMock->expects(self::once())
386
            ->method('send')
387
            ->with(self::isInstanceOf(RequestInterface::class))
388
            ->willReturn($response);
389
390
        $this->manager = new RequestService($this->settingsMock, $this->httpClientMock);
391
        self::assertInternalType(
392
            'array',
393
            $this->manager->dispatchRequest($this->reqMethod, $testReqRoute, $this->requestOptions)
394
        );
395
    }
396
397
    /**
398
     * @expectedException  \InvoiceNinjaModule\Exception\ApiException
399
     */
400
    public function testDispatchRequestApiException()
401
    {
402
        $testTokenType = 'testtokentype';
403
        $testToken = 'testtoken';
404
        $testReqRoute = 'testroute';
405
406
        $response = $this->createMock(Response::class);
407
        $response->expects(self::exactly(2))
408
            ->method('getStatusCode')
409
            ->willReturn(Response::STATUS_CODE_500);
410
411
        $this->settingsMock->expects(self::once())
412
            ->method('getTimeout')
413
            ->willReturn(10);
414
415
        $this->settingsMock->expects(self::once())
416
            ->method('getTokenType')
417
            ->willReturn($testTokenType);
418
419
        $this->settingsMock->expects(self::once())
420
            ->method('getToken')
421
            ->willReturn($testToken);
422
423
        $this->httpClientMock->expects(self::once())
424
            ->method('send')
425
            ->with(self::isInstanceOf(RequestInterface::class))
426
            ->willReturn($response);
427
428
        $this->manager = new RequestService($this->settingsMock, $this->httpClientMock);
429
        self::assertInternalType(
430
            'array',
431
            $this->manager->dispatchRequest($this->reqMethod, $testReqRoute, $this->requestOptions)
432
        );
433
    }
434
435
    /**
436
     * @expectedException  \InvoiceNinjaModule\Exception\ApiException
437
     */
438
    public function testDispatchRequestApiExceptionInvalidArgument()
439
    {
440
        $this->reqMethod = 'TESTPUT';
441
        $testReqRoute = 'testroute';
442
443
        self::assertInternalType(
444
            'array',
445
            $this->manager->dispatchRequest($this->reqMethod, $testReqRoute, $this->requestOptions)
446
        );
447
    }
448
449
    /**
450
     * @expectedException  \InvoiceNinjaModule\Exception\ApiException
451
     */
452
    public function testDispatchRequestApiExceptionInvalidRuntime()
453
    {
454
        $testTokenType = 'testtokentype';
455
        $testToken = 'testtoken';
456
        $testReqRoute = 'testroute';
457
458
        $this->settingsMock->expects(self::once())
459
            ->method('getTimeout')
460
            ->willReturn(10);
461
462
        $this->settingsMock->expects(self::once())
463
            ->method('getTokenType')
464
            ->willReturn($testTokenType);
465
466
        $this->settingsMock->expects(self::once())
467
            ->method('getToken')
468
            ->willReturn($testToken);
469
470
        $this->httpClientMock->expects(self::once())
471
            ->method('send')
472
            ->with(self::isInstanceOf(RequestInterface::class))
473
            ->willThrowException(new Client\Exception\RuntimeException());
474
475
        $this->manager = new RequestService($this->settingsMock, $this->httpClientMock);
476
        self::assertInternalType(
477
            'array',
478
            $this->manager->dispatchRequest($this->reqMethod, $testReqRoute, $this->requestOptions)
479
        );
480
    }
481
482
    public function testDispatchRequestEmpty()
483
    {
484
        $testTokenType = 'testtokentype';
485
        $testToken = 'testtoken';
486
        $testReqRoute = 'testroute';
487
488
        $headers = $this->createMock(Headers::class);
489
        $headers->expects(self::once())
490
            ->method('get')
491
            ->with(self::stringContains('Content-disposition'))
492
            ->willReturn(false);
493
494
        $response = $this->createMock(Response::class);
495
        $response->expects(self::once())
496
            ->method('getStatusCode')
497
            ->willReturn(Response::STATUS_CODE_200);
498
499
        $response->expects(self::once())
500
            ->method('getHeaders')
501
            ->willReturn($headers);
502
503
        $response->expects(self::once())
504
            ->method('getBody')
505
            ->willReturn('');
506
507
        $this->settingsMock->expects(self::once())
508
            ->method('getTimeout')
509
            ->willReturn(10);
510
511
        $this->settingsMock->expects(self::once())
512
            ->method('getTokenType')
513
            ->willReturn($testTokenType);
514
515
        $this->settingsMock->expects(self::once())
516
            ->method('getToken')
517
            ->willReturn($testToken);
518
519
        $this->httpClientMock->expects(self::once())
520
            ->method('send')
521
            ->with(self::isInstanceOf(RequestInterface::class))
522
            ->willReturn($response);
523
524
        $this->manager = new RequestService($this->settingsMock, $this->httpClientMock);
525
        self::assertInternalType(
526
            'array',
527
            $this->manager->dispatchRequest($this->reqMethod, $testReqRoute, $this->requestOptions)
528
        );
529
    }
530
531
    public function testDispatchRequestPost()
532
    {
533
        $testTokenType = 'testtokentype';
534
        $testToken = 'testtoken';
535
        $testReqRoute = 'testroute';
536
537
538
        $this->requestOptions = $this->createMock(RequestOptionsInterface::class);
539
        $this->requestOptions->expects(self::once())
540
            ->method('getPostArray')
541
            ->willReturn(['test']);
542
543
        $headers = $this->createMock(Headers::class);
544
        $headers->expects(self::once())
545
            ->method('get')
546
            ->with(self::stringContains('Content-disposition'))
547
            ->willReturn(false);
548
549
        $response = $this->createMock(Response::class);
550
        $response->expects(self::once())
551
            ->method('getStatusCode')
552
            ->willReturn(Response::STATUS_CODE_200);
553
554
        $response->expects(self::once())
555
            ->method('getHeaders')
556
            ->willReturn($headers);
557
558
        $response->expects(self::once())
559
            ->method('getBody')
560
            ->willReturn('');
561
562
        $this->settingsMock->expects(self::once())
563
            ->method('getTimeout')
564
            ->willReturn(10);
565
566
        $this->settingsMock->expects(self::once())
567
            ->method('getTokenType')
568
            ->willReturn($testTokenType);
569
570
        $this->settingsMock->expects(self::once())
571
            ->method('getToken')
572
            ->willReturn($testToken);
573
574
        $this->httpClientMock->expects(self::once())
575
            ->method('send')
576
            ->with(
577
                self::logicalAnd(
578
                    self::isInstanceOf(RequestInterface::class),
579
                    self::callback(function ($request) {
580
                        $return = true;
581
                        /** @var Request $request */
582
                        if ($request->getContent() === '') {
583
                            $return = false;
584
                        }
585
586
                        if ($request->getAllowCustomMethods() === true) {
587
                            $return = false;
588
                        }
589
590
                        return $return;
591
                    })
592
                )
593
            )
594
            ->willReturn($response);
595
596
        $this->manager = new RequestService($this->settingsMock, $this->httpClientMock);
597
        self::assertInternalType(
598
            'array',
599
            $this->manager->dispatchRequest($this->reqMethod, $testReqRoute, $this->requestOptions)
600
        );
601
    }
602
}
603