Completed
Push — master ( 677e94...463d73 )
by Gerrit
02:18
created

shouldNotHandleThrowables()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 29
rs 9.456
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * Copyright (C) 2017  Gerrit Addiks.
4
 * This package (including this file) was released under the terms of the GPL-3.0.
5
 * You should have received a copy of the GNU General Public License along with this program.
6
 * If not, see <http://www.gnu.org/licenses/> or send me a mail so i can send you a copy.
7
 * @license GPL-3.0
8
 * @author Gerrit Addiks <[email protected]>
9
 */
10
11
namespace Addiks\SymfonyGenerics\Tests\Unit\Controllers;
12
13
use PHPUnit\Framework\TestCase;
14
use Addiks\SymfonyGenerics\Controllers\GenericExceptionResponseController;
15
use Addiks\SymfonyGenerics\Controllers\ControllerHelperInterface;
16
use Serializable;
17
use Symfony\Component\HttpFoundation\Response;
18
use InvalidArgumentException;
19
use DivisionByZeroError;
20
use Addiks\SymfonyGenerics\Services\ArgumentCompilerInterface;
21
use Symfony\Component\HttpFoundation\Request;
22
use Symfony\Component\HttpFoundation\RedirectResponse;
23
use Symfony\Component\HttpFoundation\ParameterBag;
24
25
final class GenericExceptionResponseControllerTest extends TestCase
26
{
27
28
    /**
29
     * @var GenericExceptionResponseController
30
     */
31
    private $controller;
32
33
    /**
34
     * @var ControllerHelperInterface
35
     */
36
    private $controllerHelper;
37
38
    /**
39
     * @var Serializable
40
     */
41
    private $innerController;
42
43
    /**
44
     * @var ArgumentCompilerInterface
45
     */
46
    private $argumentBuilder;
47
48
    public function setUp()
49
    {
50
        $this->controllerHelper = $this->createMock(ControllerHelperInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\Addik...HelperInterface::class) of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Addiks\SymfonyGen...trollerHelperInterface> of property $controllerHelper.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
51
        $this->innerController = $this->createMock(Serializable::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\Serializable::class) of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Serializable> of property $innerController.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
52
        $this->argumentBuilder = $this->createMock(ArgumentCompilerInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\Addik...mpilerInterface::class) of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Addiks\SymfonyGen...umentCompilerInterface> of property $argumentBuilder.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
53
    }
54
55
    /**
56
     * @test
57
     */
58
    public function shouldexecuteInnerControllerSafely()
59
    {
60
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
61
            'inner-controller' => $this->innerController,
62
            'inner-controller-method' => "serialize",
63
        ]);
64
65
        $this->innerController->method("serialize")->willReturn(new Response("foo", 205));
66
67
        /** @var Request $request */
68
        $request = $this->createMock(Request::class);
69
70
        /** @var Response $response */
71
        $response = $controller->executeInnerControllerSafely($request);
72
73
        $this->assertEquals("foo", $response->getContent());
74
        $this->assertEquals(205, $response->getStatusCode());
75
    }
76
77
    /**
78
     * @test
79
     */
80 View Code Duplication
    public function shouldOverrideSuccessResponse()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
81
    {
82
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
83
            'inner-controller' => $this->innerController,
84
            'inner-controller-method' => "serialize",
85
            'success-response' => "Some success!",
86
            'success-response-code' => 234,
87
        ]);
88
89
        $this->innerController->method("serialize")->willReturn(new Response("foo", 205));
90
91
        /** @var Request $request */
92
        $request = $this->createMock(Request::class);
93
94
        /** @var Response $response */
95
        $response = $controller->executeInnerControllerSafely($request);
96
97
        $this->assertEquals("Some success!", $response->getContent());
98
        $this->assertEquals(234, $response->getStatusCode());
99
    }
100
101
    /**
102
     * @test
103
     */
104 View Code Duplication
    public function shouldOverrideSuccessResponseWithDefaultResponseCode()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
105
    {
106
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
107
            'inner-controller' => $this->innerController,
108
            'inner-controller-method' => "serialize",
109
            'success-response' => "Some success!",
110
        ]);
111
112
        $this->innerController->method("serialize")->willReturn(new Response("foo", 205));
113
114
        /** @var Request $request */
115
        $request = $this->createMock(Request::class);
116
117
        /** @var Response $response */
118
        $response = $controller->executeInnerControllerSafely($request);
119
120
        $this->assertEquals("Some success!", $response->getContent());
121
        $this->assertEquals(200, $response->getStatusCode());
122
    }
123
124
    /**
125
     * @test
126
     */
127
    public function shouldTriggerSuccessFlashMessage()
128
    {
129
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
130
            'inner-controller' => $this->innerController,
131
            'inner-controller-method' => "serialize",
132
            'success-flash-message' => 'Some Success Message!'
133
        ]);
134
135
        $this->controllerHelper->expects($this->once())->method('addFlashMessage')->with(
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Addiks\SymfonyGen...trollerHelperInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
136
            $this->equalTo('Some Success Message!'),
137
            $this->equalTo('success')
138
        );
139
140
        $this->innerController->method("serialize")->willReturn(new Response("foo", 200));
141
142
        /** @var Request $request */
143
        $request = $this->createMock(Request::class);
144
145
        $controller->executeInnerControllerSafely($request);
146
    }
147
148
    /**
149
     * @test
150
     */
151
    public function shouldAddFlashMessageUponException()
152
    {
153
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
154
            'inner-controller' => $this->innerController,
155
            'inner-controller-method' => "serialize",
156
            'exception-responses' => [
157
                InvalidArgumentException::class => [
158
                    'flash-type' => 'danger',
159
                    'flash-message' => 'Something happened: %s'
160
                ]
161
            ]
162
        ]);
163
164
        $this->innerController->method("serialize")->will($this->returnCallback(
165
            function () {
166
                throw new InvalidArgumentException("Lorem ipsum!");
167
            }
168
        ));
169
170
        $this->controllerHelper->expects($this->once())->method('handleException');
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Addiks\SymfonyGen...trollerHelperInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
171
        $this->controllerHelper->expects($this->once())->method('addFlashMessage')->with(
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Addiks\SymfonyGen...trollerHelperInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
172
            $this->equalTo('Something happened: Lorem ipsum!'),
173
            $this->equalTo('danger')
174
        );
175
176
        /** @var Request $request */
177
        $request = $this->createMock(Request::class);
178
179
        /** @var Response $response */
180
        $response = $controller->executeInnerControllerSafely($request);
181
182
        $this->assertEquals("Lorem ipsum!", $response->getContent());
183
        $this->assertEquals(500, $response->getStatusCode());
184
    }
185
186
    /**
187
     * @test
188
     */
189
    public function shouldForwardThrowExceptionIfNotHandled()
190
    {
191
        /** @var mixed $controller */
192
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
193
            'inner-controller' => $this->innerController,
194
            'inner-controller-method' => "serialize",
195
        ]);
196
197
        $this->innerController->method("serialize")->will($this->returnCallback(
198
            function () {
199
                throw new InvalidArgumentException("Lorem ipsum!");
200
            }
201
        ));
202
203
        $this->expectException(InvalidArgumentException::class);
204
205
        /** @var Request $request */
206
        $request = $this->createMock(Request::class);
207
208
        $controller->executeInnerControllerSafely($request);
209
    }
210
211
    /**
212
     * @test
213
     */
214
    public function shouldThrowExceptionIfInnerControllerDidNotReturnAResponse()
215
    {
216
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
217
            'inner-controller' => $this->innerController,
218
            'inner-controller-method' => "serialize",
219
        ]);
220
221
        $this->expectException(InvalidArgumentException::class);
222
223
        /** @var Request $request */
224
        $request = $this->createMock(Request::class);
225
226
        $controller->executeInnerControllerSafely($request);
227
    }
228
229
    /**
230
     * @test
231
     */
232
    public function shouldThrowExceptionIfHandledExceptionClassIsNotException()
233
    {
234
        $this->expectException(InvalidArgumentException::class);
235
236
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
0 ignored issues
show
Unused Code introduced by
$controller is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
237
            'inner-controller' => $this->innerController,
238
            'inner-controller-method' => "serialize",
239
            'exception-responses' => [
240
                "TotallyNotAnException" => [
241
                    'flash-type' => 'danger',
242
                    'flash-message' => 'Something happened: %s'
243
                ]
244
            ]
245
        ]);
246
    }
247
248
    /**
249
     * @test
250
     */
251
    public function shouldHandleThrowables()
252
    {
253
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
254
            'inner-controller' => $this->innerController,
255
            'inner-controller-method' => "serialize",
256
            'exception-responses' => [
257
                DivisionByZeroError::class => [
258
                    'flash-type' => 'danger',
259
                    'flash-message' => 'Something happened: %s'
260
                ]
261
            ]
262
        ]);
263
264
        $this->innerController->method("serialize")->will($this->returnCallback(
265
            function () {
266
                throw new DivisionByZeroError("Lorem ipsum");
0 ignored issues
show
Unused Code introduced by
The call to DivisionByZeroError::__construct() has too many arguments starting with 'Lorem ipsum'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
267
            }
268
        ));
269
270
        /** @var Request $request */
271
        $request = $this->createMock(Request::class);
272
273
        /** @var Response $response */
274
        $response = $controller->executeInnerControllerSafely($request);
275
276
        $this->assertEquals("Lorem ipsum", $response->getContent());
277
    }
278
279
    /**
280
     * @test
281
     */
282 View Code Duplication
    public function shouldRejectNonObjectInnerController()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
283
    {
284
        $this->expectException(InvalidArgumentException::class);
285
286
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
0 ignored issues
show
Unused Code introduced by
$controller is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
287
            'inner-controller' => false,
288
            'inner-controller-method' => "serialize",
289
        ]);
290
    }
291
292
    /**
293
     * @test
294
     */
295 View Code Duplication
    public function shouldRejectControllerBeingCalledAgain()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
296
    {
297
        $this->expectException(InvalidArgumentException::class);
298
299
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
300
            'inner-controller' => $this->innerController,
301
            'inner-controller-method' => "serialize",
302
        ]);
303
304
        $controller->__construct($this->controllerHelper, $this->argumentBuilder, [
305
            'inner-controller' => $this->innerController,
306
            'inner-controller-method' => "serialize",
307
        ]);
308
    }
309
310
    /**
311
     * @test
312
     */
313 View Code Duplication
    public function shouldRejectNonArrayGivenAsInnerControllerArguments()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
314
    {
315
        $this->expectException(InvalidArgumentException::class);
316
317
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
0 ignored issues
show
Unused Code introduced by
$controller is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
318
            'inner-controller' => $this->innerController,
319
            'inner-controller-method' => "serialize",
320
            'arguments' => "Lorem ipsum",
321
        ]);
322
    }
323
324
    /**
325
     * @test
326
     */
327 View Code Duplication
    public function shouldRedirectFromException()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
328
    {
329
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
330
            'inner-controller' => $this->innerController,
331
            'inner-controller-method' => "serialize",
332
            'exception-responses' => [
333
                InvalidArgumentException::class => [
334
                    'redirect-route' => 'some_redirect_route',
335
                    'redirect-route-parameters' => [
336
                        'foo' => 'bar'
337
                    ]
338
                ]
339
            ]
340
        ]);
341
342
        $this->innerController->method("serialize")->will($this->returnCallback(
343
            function () {
344
                throw new InvalidArgumentException("Lorem ipsum!");
345
            }
346
        ));
347
348
        /** @var RedirectResponse $redirectResponse */
349
        $redirectResponse = $this->createMock(RedirectResponse::class);
350
351
        $this->controllerHelper->expects($this->once())->method('handleException');
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Addiks\SymfonyGen...trollerHelperInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
352
        $this->controllerHelper->expects($this->once())->method('redirectToRoute')->with(
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Addiks\SymfonyGen...trollerHelperInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
353
            $this->equalTo('some_redirect_route'),
354
            $this->equalTo([]),
355
            $this->equalTo(301)
356
        )->willReturn($redirectResponse);
357
358
        /** @var Request $request */
359
        $request = $this->createMock(Request::class);
360
        $request->attributes = $this->createMock(ParameterBag::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\Symfo...on\ParameterBag::class) of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Symfony\Component...oundation\ParameterBag> of property $attributes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
361
        $request->attributes->method('get')->willReturn([]);
362
363
        /** @var Response $response */
364
        $response = $controller->executeInnerControllerSafely($request);
365
366
        $this->assertSame($redirectResponse, $response);
367
    }
368
369
    /**
370
     * @test
371
     */
372 View Code Duplication
    public function shouldBeCallableByInvokingController()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
373
    {
374
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
375
            'inner-controller' => $this->innerController,
376
            'inner-controller-method' => "serialize",
377
            'exception-responses' => [
378
                InvalidArgumentException::class => [
379
                    'redirect-route' => 'some_redirect_route',
380
                    'redirect-route-parameters' => [
381
                        'foo' => 'bar'
382
                    ]
383
                ]
384
            ]
385
        ]);
386
387
        $this->innerController->method("serialize")->will($this->returnCallback(
388
            function () {
389
                throw new InvalidArgumentException("Lorem ipsum!");
390
            }
391
        ));
392
393
        /** @var RedirectResponse $redirectResponse */
394
        $redirectResponse = $this->createMock(RedirectResponse::class);
395
396
        $this->controllerHelper->expects($this->once())->method('handleException');
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Addiks\SymfonyGen...trollerHelperInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
397
        $this->controllerHelper->expects($this->once())->method('redirectToRoute')->with(
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Addiks\SymfonyGen...trollerHelperInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
398
            $this->equalTo('some_redirect_route'),
399
            $this->equalTo([]),
400
            $this->equalTo(301)
401
        )->willReturn($redirectResponse);
402
403
        /** @var Request $request */
404
        $request = $this->createMock(Request::class);
405
        $request->attributes = $this->createMock(ParameterBag::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\Symfo...on\ParameterBag::class) of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Symfony\Component...oundation\ParameterBag> of property $attributes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
406
        $request->attributes->method('get')->willReturn([]);
407
408
        $this->controllerHelper->method('getCurrentRequest')->willReturn($request);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Addiks\SymfonyGen...trollerHelperInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
409
410
        /** @var Response $response */
411
        $response = $controller();
412
413
        $this->assertSame($redirectResponse, $response);
414
    }
415
416
    /**
417
     * @test
418
     */
419
    public function shouldRejectCallWithoutRequest()
420
    {
421
        $this->expectException(InvalidArgumentException::class);
422
423
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
424
            'inner-controller' => $this->innerController,
425
            'inner-controller-method' => "serialize",
426
        ]);
427
428
        $this->controllerHelper->method('getCurrentRequest')->willReturn(null);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Addiks\SymfonyGen...trollerHelperInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
429
430
        $controller();
431
    }
432
433
}
434