Completed
Push — master ( 29a1f5...337ea5 )
by Harry
02:02
created

testShouldRespondOkWithoutTrailingSlashWithMountedControllers()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 41
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 41
rs 8.8571
cc 1
eloc 26
nc 1
nop 1
1
<?php
2
3
namespace Graze\Silex\Tests\ControllerProvider;
4
5
use Graze\Silex\ControllerProvider\TrailingSlashControllerProvider;
6
use Mockery;
7
use Silex\Application;
8
use Silex\ControllerProviderInterface;
9
use Silex\ServiceProviderInterface;
10
use Symfony\Component\HttpFoundation\Request;
11
use Symfony\Component\Routing\Matcher\UrlMatcher;
12
13
/**
14
 * TrailingSlashControllerProvider test cases.
15
 */
16
class TrailingSlashControllerProviderTest extends \PHPUnit_Framework_TestCase
17
{
18
    public function testShouldInitalize()
19
    {
20
        $provider = new TrailingSlashControllerProvider();
21
22
        $this->assertInstanceOf(ControllerProviderInterface::class, $provider);
23
        $this->assertInstanceOf(ServiceProviderInterface::class, $provider);
24
    }
25
26
    public function testShouldRegisterUrlMatcher()
27
    {
28
        $app = new Application();
29
30
        $app->register(new TrailingSlashControllerProvider());
31
32
        $this->assertInstanceOf(UrlMatcher::class, $app['url_matcher']);
33
    }
34
35
    public function testShouldMount()
36
    {
37
        $app = new Application();
38
39
        // `mount` should return the application.
40
        $this->assertSame(
41
            $app,
42
            $app->mount('/', new TrailingSlashControllerProvider())
43
        );
44
    }
45
46
    /**
47
     * @dataProvider requestMethodProvider
48
     *
49
     * @param string $method
50
     */
51 View Code Duplication
    public function testShouldRespondOkWithoutTrailingSlash($method)
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...
52
    {
53
        $app = new Application();
54
55
        $app->match('/foo/', function () {
56
            return 'hunter42';
57
        })->method($method);
58
59
        $app->match('/foo/bar/', function () {
60
            return 'What\'s the question?';
61
        })->method($method);
62
63
        $app->match('/foo/bar/baz/', function () {
64
            return 'Fizz Buzz';
65
        })->method($method);
66
67
        $app->register(new TrailingSlashControllerProvider());
68
        $app->mount('/', new TrailingSlashControllerProvider());
69
70
        $request = Request::create('/foo', $method);
71
        $response = $app->handle($request);
72
73
        $this->assertEquals(200, $response->getStatusCode());
74
75
        $request = Request::create('/foo/bar', $method);
76
        $response = $app->handle($request);
77
78
        $this->assertEquals(200, $response->getStatusCode());
79
80
        $request = Request::create('/foo/bar/baz', $method);
81
        $response = $app->handle($request);
82
83
        $this->assertEquals(200, $response->getStatusCode());
84
    }
85
86
    /**
87
     * This just shows that the mount order for the controller provider doesn't
88
     * matter when all routes are defined with a trailing slash.
89
     *
90
     * @dataProvider requestMethodProvider
91
     *
92
     * @param string $method
93
     */
94 View Code Duplication
    public function testShouldRespondOkWithoutTrailingSlashWhenMountedFirst($method)
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...
95
    {
96
        $app = new Application();
97
98
        $app->register(new TrailingSlashControllerProvider());
99
        $app->mount('/', new TrailingSlashControllerProvider());
100
101
        $app->match('/foo/', function () {
102
            return 'hunter42';
103
        })->method($method);
104
105
        $app->match('/foo/bar/', function () {
106
            return 'What\'s the question?';
107
        })->method($method);
108
109
        $app->match('/foo/bar/baz/', function () {
110
            return 'Fizz Buzz';
111
        })->method($method);
112
113
        $request = Request::create('/foo', $method);
114
        $response = $app->handle($request);
115
116
        $this->assertEquals(200, $response->getStatusCode());
117
118
        $request = Request::create('/foo/bar', $method);
119
        $response = $app->handle($request);
120
121
        $this->assertEquals(200, $response->getStatusCode());
122
123
        $request = Request::create('/foo/bar/baz', $method);
124
        $response = $app->handle($request);
125
126
        $this->assertEquals(200, $response->getStatusCode());
127
    }
128
129
    /**
130
     * This just shows that the controller provider is compatiable with other
131
     * controller providers.
132
     *
133
     * @dataProvider requestMethodProvider
134
     *
135
     * @param string $method
136
     */
137
    public function testShouldRespondOkWithoutTrailingSlashWithMountedControllers($method)
138
    {
139
        $app = new Application();
140
141
        $app->register(new TrailingSlashControllerProvider());
142
        $app->mount('/', new TrailingSlashControllerProvider());
143
144
        $controller = $app['controllers_factory'];
145
146
        $controller->match('/foo/', function () {
147
            return 'hunter42';
148
        })->method($method);
149
150
        $controller->match('/foo/bar/', function () {
151
            return 'hunter42';
152
        })->method($method);
153
154
        $controller->match('/foo/bar/baz/', function () {
155
            return 'hunter42';
156
        })->method($method);
157
158
        $provider = Mockery::mock(ControllerProviderInterface::class);
159
        $provider->shouldReceive('connect')->andReturn($controller);
160
161
        $app->mount('/', $provider);
162
163
        $request = Request::create('/foo', $method);
164
        $response = $app->handle($request);
165
166
        $this->assertEquals(200, $response->getStatusCode());
167
168
        $request = Request::create('/foo/bar', $method);
169
        $response = $app->handle($request);
170
171
        $this->assertEquals(200, $response->getStatusCode());
172
173
        $request = Request::create('/foo/bar/baz', $method);
174
        $response = $app->handle($request);
175
176
        $this->assertEquals(200, $response->getStatusCode());
177
    }
178
179
    /**
180
     * @return array
181
     */
182
    public function requestMethodProvider()
183
    {
184
        return [
185
            ['GET'],
186
            ['POST'],
187
            ['PUT'],
188
            ['PATCH'],
189
            ['DELETE'],
190
            ['PURGE'],
191
            ['OPTIONS'],
192
            ['TRACE'],
193
            ['CONNECT'],
194
        ];
195
    }
196
197
    public function testShouldRespondOkToHeadWithoutTrailingSlash()
198
    {
199
        $app = new Application();
200
201
        $app->get('/foo/', function () {
202
            return 'hunter42';
203
        });
204
205
        $app->get('/foo/bar/', function () {
206
            return 'What\'s the question?';
207
        });
208
209
        $app->get('/foo/bar/baz/', function () {
210
            return 'Fizz Buzz';
211
        });
212
213
        $app->register(new TrailingSlashControllerProvider());
214
        $app->mount('/', new TrailingSlashControllerProvider());
215
216
        $request = Request::create('/foo', 'HEAD');
217
        $response = $app->handle($request);
218
219
        $this->assertEquals(200, $response->getStatusCode());
220
221
        $request = Request::create('/foo/bar', 'HEAD');
222
        $response = $app->handle($request);
223
224
        $this->assertEquals(200, $response->getStatusCode());
225
226
        $request = Request::create('/foo/bar/baz', 'HEAD');
227
        $response = $app->handle($request);
228
229
        $this->assertEquals(200, $response->getStatusCode());
230
    }
231
232
    /**
233
     * This is just to show when defining routes that the trailing slash is
234
     * required when the controller provider is mounted before any other routes.
235
     *
236
     * @dataProvider requestMethodProvider
237
     *
238
     * @param string $method
239
     */
240 View Code Duplication
    public function testWillRespondWithNotFoundForRouteWithNoTrailingSlashWhenMountedFirst($method)
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...
241
    {
242
        $app = new Application();
243
244
        $app->register(new TrailingSlashControllerProvider());
245
        $app->mount('/', new TrailingSlashControllerProvider());
246
247
        $app->match('/foo', function () {
248
            return 'hunter42';
249
        })->method($method);
250
251
        $app->match('/foo/bar', function () {
252
            return 'hunter42';
253
        })->method($method);
254
255
        $request = Request::create('/foo', $method);
256
        $response = $app->handle($request);
257
258
        $this->assertEquals(404, $response->getStatusCode());
259
260
        $request = Request::create('/foo/bar', $method);
261
        $response = $app->handle($request);
262
263
        $this->assertEquals(404, $response->getStatusCode());
264
    }
265
266
    /**
267
     * This is just to show when defining routes with no trailing slash before
268
     * mounting the controller provider they should respond as expected.
269
     *
270
     * @dataProvider requestMethodProvider
271
     *
272
     * @param string $method
273
     */
274 View Code Duplication
    public function testWillRespondWithOkForRouteWithNoTrailingSlashWhenMountedLast($method)
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...
275
    {
276
        $app = new Application();
277
278
        $app->match('/foo', function () {
279
            return 'hunter42';
280
        })->method($method);
281
282
        $app->match('/foo/bar', function () {
283
            return 'hunter42';
284
        })->method($method);
285
286
        $app->register(new TrailingSlashControllerProvider());
287
        $app->mount('/', new TrailingSlashControllerProvider());
288
289
        $request = Request::create('/foo', $method);
290
        $response = $app->handle($request);
291
292
        $this->assertEquals(200, $response->getStatusCode());
293
294
        $request = Request::create('/foo/bar', $method);
295
        $response = $app->handle($request);
296
297
        $this->assertEquals(200, $response->getStatusCode());
298
    }
299
300
    /**
301
     * Test the case in which a request should have both query
302
     * string params and body params
303
     */
304
    public function testWillHandleQueryAndBodySeparately()
305
    {
306
        $app = new Application();
307
308
        $app->match('/foo/', function (Request $request) {
309
            $response = [
310
                'query' => $request->query->all(),
311
                'request' => $request->request->all()
312
            ];
313
            return json_encode($response, true);
314
        })->method('POST');
315
316
        $app->register(new TrailingSlashControllerProvider());
317
        $app->mount('/', new TrailingSlashControllerProvider());
318
319
        $request = Request::create('/foo?q=1', 'POST', ['r' => 2]);
320
        $response = $app->handle($request);
321
        $this->assertEquals(200, $response->getStatusCode());
322
        $body = json_decode($response->getContent(), true);
323
        $this->assertRequestQuery($body);
324
325
        $request = Request::create('/foo/?q=1', 'POST', ['r' => 2]);
326
        $response = $app->handle($request);
327
        $this->assertEquals(200, $response->getStatusCode());
328
        $body = json_decode($response->getContent(), true);
329
        $this->assertRequestQuery($body);
330
    }
331
332
    /**
333
     * @param array $body
334
     */
335
    private function assertRequestQuery(array $body)
336
    {
337
        $this->assertArrayHasKey('query', $body);
338
        $this->assertArrayHasKey('request', $body);
339
340
        $this->assertArrayHasKey('q', $body['query']);
341
        $this->assertEquals(1, $body['query']['q']);
342
343
        $this->assertArrayHasKey('r', $body['request']);
344
        $this->assertEquals(2, $body['request']['r']);
345
    }
346
}
347