Completed
Push — master ( a4bca8...3f1e18 )
by Gerrit
27:14 queued 08:42
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
24
final class GenericExceptionResponseControllerTest extends TestCase
25
{
26
27
    /**
28
     * @var GenericExceptionResponseController
29
     */
30
    private $controller;
31
32
    /**
33
     * @var ControllerHelperInterface
34
     */
35
    private $controllerHelper;
36
37
    /**
38
     * @var Serializable
39
     */
40
    private $innerController;
41
42
    /**
43
     * @var ArgumentCompilerInterface
44
     */
45
    private $argumentBuilder;
46
47
    public function setUp()
48
    {
49
        $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...
50
        $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...
51
        $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...
52
    }
53
54
    /**
55
     * @test
56
     */
57 View Code Duplication
    public function shouldexecuteInnerControllerSafely()
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...
58
    {
59
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
60
            'inner-controller' => $this->innerController,
61
            'inner-controller-method' => "serialize",
62
        ]);
63
64
        $this->innerController->method("serialize")->willReturn(new Response("foo", 205));
65
66
        /** @var Request $request */
67
        $request = $this->createMock(Request::class);
68
69
        /** @var Response $response */
70
        $response = $controller->executeInnerControllerSafely($request);
71
72
        $this->assertEquals("foo", $response->getContent());
73
        $this->assertEquals(205, $response->getStatusCode());
74
    }
75
76
    /**
77
     * @test
78
     */
79 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...
80
    {
81
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
82
            'inner-controller' => $this->innerController,
83
            'inner-controller-method' => "serialize",
84
            'success-response' => "Some success!",
85
            'success-response-code' => 234,
86
        ]);
87
88
        $this->innerController->method("serialize")->willReturn(new Response("foo", 205));
89
90
        /** @var Request $request */
91
        $request = $this->createMock(Request::class);
92
93
        /** @var Response $response */
94
        $response = $controller->executeInnerControllerSafely($request);
95
96
        $this->assertEquals("Some success!", $response->getContent());
97
        $this->assertEquals(234, $response->getStatusCode());
98
    }
99
100
    /**
101
     * @test
102
     */
103 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...
104
    {
105
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
106
            'inner-controller' => $this->innerController,
107
            'inner-controller-method' => "serialize",
108
            'success-response' => "Some success!",
109
        ]);
110
111
        $this->innerController->method("serialize")->willReturn(new Response("foo", 205));
112
113
        /** @var Request $request */
114
        $request = $this->createMock(Request::class);
115
116
        /** @var Response $response */
117
        $response = $controller->executeInnerControllerSafely($request);
118
119
        $this->assertEquals("Some success!", $response->getContent());
120
        $this->assertEquals(200, $response->getStatusCode());
121
    }
122
123
    /**
124
     * @test
125
     */
126
    public function shouldTriggerSuccessFlashMessage()
127
    {
128
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
129
            'inner-controller' => $this->innerController,
130
            'inner-controller-method' => "serialize",
131
            'success-flash-message' => 'Some Success Message!'
132
        ]);
133
134
        $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...
135
            $this->equalTo('Some Success Message!'),
136
            $this->equalTo('success')
137
        );
138
139
        $this->innerController->method("serialize")->willReturn(new Response("foo", 200));
140
141
        /** @var Request $request */
142
        $request = $this->createMock(Request::class);
143
144
        $controller->executeInnerControllerSafely($request);
145
    }
146
147
    /**
148
     * @test
149
     */
150
    public function shouldAddFlashMessageUponException()
151
    {
152
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
153
            'inner-controller' => $this->innerController,
154
            'inner-controller-method' => "serialize",
155
            'exception-responses' => [
156
                InvalidArgumentException::class => [
157
                    'flash-type' => 'danger',
158
                    'flash-message' => 'Something happened: %s'
159
                ]
160
            ]
161
        ]);
162
163
        $this->innerController->method("serialize")->will($this->returnCallback(
164
            function () {
165
                throw new InvalidArgumentException("Lorem ipsum!");
166
            }
167
        ));
168
169
        $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...
170
        $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...
171
            $this->equalTo('Something happened: Lorem ipsum!'),
172
            $this->equalTo('danger')
173
        );
174
175
        /** @var Request $request */
176
        $request = $this->createMock(Request::class);
177
178
        /** @var Response $response */
179
        $response = $controller->executeInnerControllerSafely($request);
180
181
        $this->assertEquals("Lorem ipsum!", $response->getContent());
182
        $this->assertEquals(500, $response->getStatusCode());
183
    }
184
185
    /**
186
     * @test
187
     */
188
    public function shouldForwardThrowExceptionIfNotHandled()
189
    {
190
        /** @var mixed $controller */
191
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
192
            'inner-controller' => $this->innerController,
193
            'inner-controller-method' => "serialize",
194
        ]);
195
196
        $this->innerController->method("serialize")->will($this->returnCallback(
197
            function () {
198
                throw new InvalidArgumentException("Lorem ipsum!");
199
            }
200
        ));
201
202
        $this->expectException(InvalidArgumentException::class);
203
204
        /** @var Request $request */
205
        $request = $this->createMock(Request::class);
206
207
        $controller->executeInnerControllerSafely($request);
208
    }
209
210
    /**
211
     * @test
212
     */
213
    public function shouldThrowExceptionIfInnerControllerDidNotReturnAResponse()
214
    {
215
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
216
            'inner-controller' => $this->innerController,
217
            'inner-controller-method' => "serialize",
218
        ]);
219
220
        $this->expectException(InvalidArgumentException::class);
221
222
        /** @var Request $request */
223
        $request = $this->createMock(Request::class);
224
225
        $controller->executeInnerControllerSafely($request);
226
    }
227
228
    /**
229
     * @test
230
     */
231
    public function shouldThrowExceptionIfHandledExceptionClassIsNotException()
232
    {
233
        $this->expectException(InvalidArgumentException::class);
234
235
        $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...
236
            'inner-controller' => $this->innerController,
237
            'inner-controller-method' => "serialize",
238
            'exception-responses' => [
239
                "TotallyNotAnException" => [
240
                    'flash-type' => 'danger',
241
                    'flash-message' => 'Something happened: %s'
242
                ]
243
            ]
244
        ]);
245
    }
246
247
    /**
248
     * @test
249
     */
250
    public function shouldNotHandleThrowables()
251
    {
252
        $this->expectException(DivisionByZeroError::class);
253
254
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
255
            'inner-controller' => $this->innerController,
256
            'inner-controller-method' => "serialize",
257
            'exception-responses' => [
258
                DivisionByZeroError::class => [
259
                    'flash-type' => 'danger',
260
                    'flash-message' => 'Something happened: %s'
261
                ]
262
            ]
263
        ]);
264
265
        $this->innerController->method("serialize")->will($this->returnCallback(
266
            function () {
267
                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...
268
            }
269
        ));
270
271
        /** @var Request $request */
272
        $request = $this->createMock(Request::class);
273
274
        /** @var Response $response */
275
        $response = $controller->executeInnerControllerSafely($request);
276
277
        $this->assertEquals("Lorem ipsum", $response->getContent());
278
    }
279
280
    /**
281
     * @test
282
     */
283 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...
284
    {
285
        $this->expectException(InvalidArgumentException::class);
286
287
        $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...
288
            'inner-controller' => false,
289
            'inner-controller-method' => "serialize",
290
        ]);
291
    }
292
293
    /**
294
     * @test
295
     */
296 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...
297
    {
298
        $this->expectException(InvalidArgumentException::class);
299
300
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
301
            'inner-controller' => $this->innerController,
302
            'inner-controller-method' => "serialize",
303
        ]);
304
305
        $controller->__construct($this->controllerHelper, $this->argumentBuilder, [
306
            'inner-controller' => $this->innerController,
307
            'inner-controller-method' => "serialize",
308
        ]);
309
    }
310
311
    /**
312
     * @test
313
     */
314 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...
315
    {
316
        $this->expectException(InvalidArgumentException::class);
317
318
        $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...
319
            'inner-controller' => $this->innerController,
320
            'inner-controller-method' => "serialize",
321
            'arguments' => "Lorem ipsum",
322
        ]);
323
    }
324
325
    /**
326
     * @test
327
     */
328
    public function shouldRedirectFromException()
329
    {
330
        /** @var mixed $controller */
331
        $controller = new GenericExceptionResponseController($this->controllerHelper, $this->argumentBuilder, [
332
            'inner-controller' => $this->innerController,
333
            'inner-controller-method' => "serialize",
334
            'exception-responses' => [
335
                InvalidArgumentException::class => [
336
                    'redirect-route' => 'some_redirect_route',
337
                    'redirect-route-parameters' => [
338
                        'foo' => 'bar'
339
                    ]
340
                ]
341
            ]
342
        ]);
343
344
        $this->innerController->method("serialize")->will($this->returnCallback(
345
            function () {
346
                throw new InvalidArgumentException("Lorem ipsum!");
347
            }
348
        ));
349
350
        /** @var RedirectResponse $redirectResponse */
351
        $redirectResponse = $this->createMock(RedirectResponse::class);
352
353
        $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...
354
        $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...
355
            $this->equalTo('some_redirect_route'),
356
            $this->equalTo([]),
357
            $this->equalTo(301)
358
        )->willReturn($redirectResponse);
359
360
        /** @var Request $request */
361
        $request = $this->createMock(Request::class);
362
363
        /** @var Response $response */
364
        $response = $controller->executeInnerControllerSafely($request);
365
366
        $this->assertSame($redirectResponse, $response);
367
    }
368
369
}
370