Completed
Pull Request — master (#49)
by John
05:45
created

ExceptionListenerTest::setUp()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 32
rs 8.8571
cc 1
eloc 24
nc 1
nop 0
1
<?php
2
/*
3
 * This file is part of the KleijnWeb\SwaggerBundle package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace KleijnWeb\SwaggerBundle\Tests\EventListener;
10
11
use KleijnWeb\SwaggerBundle\EventListener\ExceptionListener;
12
use KleijnWeb\SwaggerBundle\Response\VndValidationErrorFactory;
13
use Psr\Log\LoggerInterface;
14
use Psr\Log\LogLevel;
15
use Symfony\Component\HttpFoundation\Request;
16
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
17
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
18
19
/**
20
 * @author John Kleijn <[email protected]>
21
 */
22
class ExceptionListenerTest extends \PHPUnit_Framework_TestCase
23
{
24
    /**
25
     * @var GetResponseForExceptionEvent
26
     */
27
    private $event;
28
29
    /**
30
     * @var \ReflectionProperty
31
     */
32
    private $codeProperty;
33
34
    /**
35
     * @var \Exception
36
     */
37
    private $exception;
38
39
    /**
40
     * @var Request
41
     */
42
    private $request;
43
44
    /**
45
     * @var ExceptionListener
46
     */
47
    private $exceptionListener;
48
49
    /**
50
     * Set up mocking
51
     */
52
    protected function setUp()
53
    {
54
        $this->event = $this
55
            ->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent')
56
            ->disableOriginalConstructor()
57
            ->setMethods(['getException', 'getRequest'])
58
            ->getMock();
59
60
        $this->exception = new \Exception("Mary had a little lamb");
61
        $reflection = new \ReflectionClass($this->exception);
62
        $codeProperty = $reflection->getProperty('code');
63
        $this->codeProperty = $codeProperty;
64
        $this->codeProperty->setAccessible(true);
65
        $attributes = [
66
            '_resource' => '/foo/bar'
67
        ];
68
        $this->request = new Request($query = [], $request = [], $attributes);
69
70
        $this->event
71
            ->expects($this->any())
72
            ->method('getException')
73
            ->willReturn($this->exception);
74
75
        $this->event
76
            ->expects($this->any())
77
            ->method('getRequest')
78
            ->willReturn($this->request);
79
80
        /** @var LoggerInterface $logger */
81
        $logger = $this->getMockForAbstractClass('Psr\Log\LoggerInterface');
82
        $this->exceptionListener = new ExceptionListener(new VndValidationErrorFactory(), $logger);
83
    }
84
85
    /**
86
     * @test
87
     */
88 View Code Duplication
    public function willLogExceptionsWith4xxCodesAsBadRequestNotices()
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...
89
    {
90
        for ($i = 0; $i < 99; $i++) {
91
            $logger = $this->getMockForAbstractClass('Psr\Log\LoggerInterface');
92
            $logger
93
                ->expects($this->once())
94
                ->method('log')
95
                ->with(LogLevel::NOTICE, $this->stringStartsWith('Bad Request'));
96
97
            /** @var LoggerInterface $logger */
98
            $this->exceptionListener->setLogger($logger);
99
            $this->codeProperty->setValue($this->exception, 400 + $i);
100
            $this->exceptionListener->onKernelException($this->event);
101
        }
102
    }
103
104
    /**
105
     * @test
106
     */
107 View Code Duplication
    public function willLogExceptionsWith5xxCodesAsRuntimeErrors()
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...
108
    {
109
        for ($i = 0; $i < 99; $i++) {
110
            $logger = $this->getMockForAbstractClass('Psr\Log\LoggerInterface');
111
            $logger
112
                ->expects($this->once())
113
                ->method('log')
114
                ->with(LogLevel::ERROR, $this->stringStartsWith('Internal Server Error'));
115
116
            /** @var LoggerInterface $logger */
117
            $this->exceptionListener->setLogger($logger);
118
            $this->codeProperty->setValue($this->exception, 500 + $i);
119
            $this->exceptionListener->onKernelException($this->event);
120
        }
121
    }
122
123
    /**
124
     * @test
125
     */
126
    public function willLogExceptionsWithUnexpectedCodesAsCriticalErrors()
127
    {
128
        $sample = [4096, 777, 22, 5, 0];
129
        foreach ($sample as $code) {
130
            $logger = $this->getMockForAbstractClass('Psr\Log\LoggerInterface');
131
            $logger
132
                ->expects($this->once())
133
                ->method('log')
134
                ->with(LogLevel::CRITICAL, $this->stringStartsWith('Internal Server Error'));
135
136
            /** @var LoggerInterface $logger */
137
            $this->exceptionListener->setLogger($logger);
138
            $this->codeProperty->setValue($this->exception, $code);
139
            $this->exceptionListener->onKernelException($this->event);
140
        }
141
    }
142
143
    /**
144
     * @test
145
     */
146 View Code Duplication
    public function willSetResponseWithVndErrorHeader()
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...
147
    {
148
        foreach ([400, 500] as $code) {
149
            $this->codeProperty->setValue($this->exception, $code);
150
            $this->exceptionListener->onKernelException($this->event);
151
            $response = $this->event->getResponse();
152
            $this->assertContains('application/vnd.error', $response->headers->get('Content-Type'));
153
        }
154
    }
155
156
    /**
157
     * @test
158
     */
159 View Code Duplication
    public function willSetResponseWithValidJsonContent()
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...
160
    {
161
        foreach ([400, 500] as $code) {
162
            $this->codeProperty->setValue($this->exception, $code);
163
            $this->exceptionListener->onKernelException($this->event);
164
            $response = $this->event->getResponse();
165
            $this->assertNotNull(json_decode($response->getContent()));
166
        }
167
    }
168
169
    /**
170
     * @test
171
     */
172 View Code Duplication
    public function willSetResponseWithSimpleMessage()
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...
173
    {
174
        foreach ([400 => 'Bad Request', 500 => 'Internal Server Error'] as $code => $message) {
175
            $this->codeProperty->setValue($this->exception, $code);
176
            $this->exceptionListener->onKernelException($this->event);
177
            $response = $this->event->getResponse();
178
            $this->assertEquals($message, json_decode($response->getContent())->message);
179
        }
180
    }
181
182
    /**
183
     * @test
184
     */
185 View Code Duplication
    public function willSetResponseWithLogRef()
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...
186
    {
187
        foreach ([400, 500] as $code) {
188
            $this->codeProperty->setValue($this->exception, $code);
189
            $this->exceptionListener->onKernelException($this->event);
190
            $response = $this->event->getResponse();
191
            $this->assertNotNull(json_decode($response->getContent())->logref);
192
        }
193
    }
194
195
    /**
196
     * @test
197
     */
198
    public function logrefInResponseAndLogMatch()
199
    {
200
        foreach ([400, 500] as $code) {
201
            $logref = null;
202
            $logger = $this->getMockForAbstractClass('Psr\Log\LoggerInterface');
203
            $logger
204
                ->expects($this->once())
205
                ->method('log')
206
                ->with($this->anything(), $this->callback(function ($message) use (&$logref) {
207
                    $matches = [];
208
                    if (preg_match('/logref ([a-z0-9]*)/', $message, $matches)) {
209
                        $logref = $matches[1];
210
211
                        return true;
212
                    }
213
214
                    return false;
215
                }));
216
217
            /** @var LoggerInterface $logger */
218
            $this->exceptionListener->setLogger($logger);
219
            $this->codeProperty->setValue($this->exception, $code);
220
            $this->exceptionListener->onKernelException($this->event);
221
            $response = $this->event->getResponse();
222
            $this->assertEquals($logref, json_decode($response->getContent())->logref);
223
        }
224
    }
225
226
    /**
227
     * @test
228
     */
229
    public function willReturn404Responses()
230
    {
231
        $event = $this
232
            ->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent')
233
            ->disableOriginalConstructor()
234
            ->setMethods(['getException', 'getRequest'])
235
            ->getMock();
236
237
        $event->expects($this->any())
238
            ->method('getException')
239
            ->willReturn(new NotFoundHttpException());
240
241
        $event->expects($this->any())
242
            ->method('getRequest')
243
            ->willReturn($this->request);
244
245
        $this->exceptionListener->onKernelException($event);
246
        $response = $event->getResponse();
247
        $this->assertSame(404, $response->getStatusCode());
248
    }
249
}
250