Passed
Pull Request — master (#32)
by Anatoly
09:33
created

RouteCollectionTest::testGroup()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 37
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 22
nc 1
nop 0
dl 0
loc 37
rs 9.568
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Sunrise\Http\Router\Tests;
4
5
/**
6
 * Import classes
7
 */
8
use PHPUnit\Framework\TestCase;
9
use Sunrise\Http\Router\RouteInterface;
10
use Sunrise\Http\Router\RouteCollection;
11
use Sunrise\Http\Router\RouteCollectionInterface;
12
13
/**
14
 * Import functions
15
 */
16
use function end;
17
18
/**
19
 * RouteCollectionTest
20
 */
21
class RouteCollectionTest extends TestCase
22
{
23
24
    /**
25
     * @return void
26
     */
27
    public function testConstructor() : void
28
    {
29
        $collection = new RouteCollection();
30
31
        $this->assertInstanceOf(RouteCollectionInterface::class, $collection);
32
    }
33
34
    /**
35
     * @return void
36
     */
37
    public function testGetDefaultPrefix() : void
38
    {
39
        $collection = new RouteCollection();
40
41
        $this->assertNull($collection->getPrefix());
42
    }
43
44
    /**
45
     * @return void
46
     */
47
    public function testGetDefaultMiddlewares() : void
48
    {
49
        $collection = new RouteCollection();
50
51
        $this->assertSame([], $collection->getMiddlewares());
52
    }
53
54
    /**
55
     * @return void
56
     */
57
    public function testGetDefaultRoutes() : void
58
    {
59
        $collection = new RouteCollection();
60
61
        $this->assertSame([], $collection->getRoutes());
62
    }
63
64
    /**
65
     * @return void
66
     */
67
    public function testSetPrefix() : void
68
    {
69
        $collection = new RouteCollection();
70
71
        $this->assertSame($collection, $collection->setPrefix('/foo'));
72
        $this->assertSame('/foo', $collection->getPrefix());
73
74
        // override prefix...
75
        $collection->setPrefix('/bar');
76
        $this->assertSame('/bar', $collection->getPrefix());
77
78
        // https://github.com/sunrise-php/http-router/issues/26
79
        $collection->setPrefix('/baz/');
80
        $this->assertSame('/baz', $collection->getPrefix());
81
    }
82
83
    /**
84
     * @return void
85
     */
86
    public function testAddMiddlewares() : void
87
    {
88
        $middlewares = [
89
            new Fixture\BlankMiddleware(),
90
            new Fixture\BlankMiddleware(),
91
        ];
92
93
        $collection = new RouteCollection();
94
95
        $this->assertSame($collection, $collection->addMiddlewares(...$middlewares));
96
        $this->assertSame($middlewares, $collection->getMiddlewares());
97
98
        // extending...
99
        $middlewares[] = new Fixture\BlankMiddleware();
100
        $collection->addMiddlewares(end($middlewares));
101
        $this->assertSame($middlewares, $collection->getMiddlewares());
102
    }
103
104
    /**
105
     * @return void
106
     */
107
    public function testAddRoutes() : void
108
    {
109
        $routes = [
110
            new Fixture\TestRoute(),
111
            new Fixture\TestRoute(),
112
        ];
113
114
        $collection = new RouteCollection();
115
116
        $this->assertSame($collection, $collection->addRoutes(...$routes));
117
        $this->assertSame($routes, $collection->getRoutes());
118
119
        // extending...
120
        $routes[] = new Fixture\TestRoute();
121
        $collection->addRoutes(end($routes));
122
        $this->assertSame($routes, $collection->getRoutes());
123
    }
124
125
    /**
126
     * @return void
127
     */
128
    public function testMakeRoute() : void
129
    {
130
        $routeName = Fixture\TestRoute::getTestRouteName();
131
        $routePath = Fixture\TestRoute::getTestRoutePath();
132
        $routeMethods = Fixture\TestRoute::getTestRouteMethods();
133
        $routeRequestHandler = Fixture\TestRoute::getTestRouteRequestHandler();
134
135
        $collection = new RouteCollection();
136
137
        $route = $collection->route(
138
            $routeName,
139
            $routePath,
140
            $routeMethods,
141
            $routeRequestHandler
142
        );
143
144
        $this->assertInstanceOf(RouteInterface::class, $route);
145
        $this->assertSame($routeName, $route->getName());
146
        $this->assertSame($routePath, $route->getPath());
147
        $this->assertSame($routeMethods, $route->getMethods());
148
        $this->assertSame($routeRequestHandler, $route->getRequestHandler());
149
        $this->assertSame([], $route->getMiddlewares());
150
        $this->assertSame([], $route->getAttributes());
151
        $this->assertSame([$route], $collection->getRoutes());
152
    }
153
154
    /**
155
     * @return void
156
     */
157
    public function testMakeRouteWithOptionalParams() : void
158
    {
159
        $routeName = Fixture\TestRoute::getTestRouteName();
160
        $routePath = Fixture\TestRoute::getTestRoutePath();
161
        $routeMethods = Fixture\TestRoute::getTestRouteMethods();
162
        $routeRequestHandler = Fixture\TestRoute::getTestRouteRequestHandler();
163
        $routeMiddlewares = Fixture\TestRoute::getTestRouteMiddlewares();
164
        $routeAttributes = Fixture\TestRoute::getTestRouteAttributes();
165
166
        $collection = new RouteCollection();
167
168
        $route = $collection->route(
169
            $routeName,
170
            $routePath,
171
            $routeMethods,
172
            $routeRequestHandler,
173
            $routeMiddlewares,
174
            $routeAttributes
175
        );
176
177
        $this->assertInstanceOf(RouteInterface::class, $route);
178
        $this->assertSame($routeName, $route->getName());
179
        $this->assertSame($routePath, $route->getPath());
180
        $this->assertSame($routeMethods, $route->getMethods());
181
        $this->assertSame($routeRequestHandler, $route->getRequestHandler());
182
        $this->assertSame($routeMiddlewares, $route->getMiddlewares());
183
        $this->assertSame($routeAttributes, $route->getAttributes());
184
        $this->assertSame([$route], $collection->getRoutes());
185
    }
186
187
    /**
188
     * @return void
189
     */
190
    public function testMakeRouteWithTransferringPrefix() : void
191
    {
192
        $collection = new RouteCollection();
193
        $collection->setPrefix('/api');
194
195
        $route = $collection->route('foo', '/foo', ['GET'], new Fixture\BlankRequestHandler());
196
        $this->assertSame('/api/foo', $route->getPath());
197
    }
198
199
    /**
200
     * @return void
201
     */
202
    public function testMakeRouteWithTransferringMiddlewares() : void
203
    {
204
        $middlewares = [new Fixture\BlankMiddleware()];
205
206
        $collection = new RouteCollection();
207
        $collection->addMiddlewares(...$middlewares);
208
209
        $route = $collection->route('foo', '/foo', ['GET'], new Fixture\BlankRequestHandler());
210
        $this->assertSame($middlewares, $route->getMiddlewares());
211
212
        // merging...
213
        $middlewares[] = new Fixture\BlankMiddleware();
214
        $route = $collection->route('foo', '/foo', ['GET'], new Fixture\BlankRequestHandler(), [end($middlewares)]);
215
        $this->assertSame($middlewares, $route->getMiddlewares());
216
    }
217
218
    /**
219
     * @return void
220
     *
221
     * @dataProvider makeVerbableRoutesDataProvider
222
     */
223
    public function testMakeVerbableRoutes(string $calledMethod, string $expectedHttpMethod) : void
224
    {
225
        $routeName = Fixture\TestRoute::getTestRouteName();
226
        $routePath = Fixture\TestRoute::getTestRoutePath();
227
        $routeRequestHandler = Fixture\TestRoute::getTestRouteRequestHandler();
228
229
        $collection = new RouteCollection();
230
231
        $route = $collection->{$calledMethod}(
232
            $routeName,
233
            $routePath,
234
            $routeRequestHandler
235
        );
236
237
        $this->assertInstanceOf(RouteInterface::class, $route);
238
        $this->assertSame($routeName, $route->getName());
239
        $this->assertSame($routePath, $route->getPath());
240
        $this->assertSame([$expectedHttpMethod], $route->getMethods());
241
        $this->assertSame($routeRequestHandler, $route->getRequestHandler());
242
        $this->assertSame([], $route->getMiddlewares());
243
        $this->assertSame([], $route->getAttributes());
244
        $this->assertSame([$route], $collection->getRoutes());
245
    }
246
247
    /**
248
     * @return void
249
     *
250
     * @dataProvider makeVerbableRoutesDataProvider
251
     */
252
    public function testMakeVerbableRoutesWithOptionalParams(string $calledMethod, string $expectedHttpMethod) : void
253
    {
254
        $routeName = Fixture\TestRoute::getTestRouteName();
255
        $routePath = Fixture\TestRoute::getTestRoutePath();
256
        $routeRequestHandler = Fixture\TestRoute::getTestRouteRequestHandler();
257
        $routeMiddlewares = Fixture\TestRoute::getTestRouteMiddlewares();
258
        $routeAttributes = Fixture\TestRoute::getTestRouteAttributes();
259
260
        $collection = new RouteCollection();
261
262
        $route = $collection->{$calledMethod}(
263
            $routeName,
264
            $routePath,
265
            $routeRequestHandler,
266
            $routeMiddlewares,
267
            $routeAttributes
268
        );
269
270
        $this->assertInstanceOf(RouteInterface::class, $route);
271
        $this->assertSame($routeName, $route->getName());
272
        $this->assertSame($routePath, $route->getPath());
273
        $this->assertSame([$expectedHttpMethod], $route->getMethods());
274
        $this->assertSame($routeRequestHandler, $route->getRequestHandler());
275
        $this->assertSame($routeMiddlewares, $route->getMiddlewares());
276
        $this->assertSame($routeAttributes, $route->getAttributes());
277
        $this->assertSame([$route], $collection->getRoutes());
278
    }
279
280
    /**
281
     * @return void
282
     *
283
     * @dataProvider makeVerbableRoutesDataProvider
284
     */
285
    public function testMakeVerbableRoutesWithTransferringPrefix(string $calledMethod) : void
286
    {
287
        $collection = new RouteCollection();
288
        $collection->setPrefix('/api');
289
290
        $route = $collection->{$calledMethod}('foo', '/foo', new Fixture\BlankRequestHandler());
291
        $this->assertSame('/api/foo', $route->getPath());
292
    }
293
294
    /**
295
     * @return void
296
     *
297
     * @dataProvider makeVerbableRoutesDataProvider
298
     */
299
    public function testMakeVerbableRoutesWithTransferringMiddlewares(string $calledMethod) : void
300
    {
301
        $middlewares = [new Fixture\BlankMiddleware()];
302
303
        $collection = new RouteCollection();
304
        $collection->addMiddlewares(...$middlewares);
305
306
        $route = $collection->{$calledMethod}('foo', '/foo', new Fixture\BlankRequestHandler());
307
        $this->assertSame($middlewares, $route->getMiddlewares());
308
309
        // merging...
310
        $middlewares[] = new Fixture\BlankMiddleware();
311
        $route = $collection->{$calledMethod}('foo', '/foo', new Fixture\BlankRequestHandler(), [end($middlewares)]);
312
        $this->assertSame($middlewares, $route->getMiddlewares());
313
    }
314
315
    /**
316
     * @return void
317
     *
318
     * @todo This test needs to be improved...
319
     */
320
    public function testGroup() : void
321
    {
322
        $collection = new RouteCollection();
323
324
        $collection->get('qux', '/qux', new Fixture\BlankRequestHandler());
325
326
        $collection->group('/', function ($group) {
327
            $group->get('foo', '/foo', new Fixture\BlankRequestHandler());
328
329
            $group->group('/api', function ($group) {
330
                $group->group('/v1', function ($group) {
331
                    $group->group('/section', function ($group) {
332
                        $group->get('api.section.all', '/list', new Fixture\BlankRequestHandler());
333
                        $group->get('api.section.read', '/read/{id}', new Fixture\BlankRequestHandler());
334
                    });
335
336
                    $group->group('/entity', function ($group) {
337
                        $group->get('api.entity.all', '/list', new Fixture\BlankRequestHandler());
338
                        $group->get('api.entity.read', '/read/{id}', new Fixture\BlankRequestHandler());
339
                    });
340
                });
341
            });
342
343
            $group->get('bar', '/bar', new Fixture\BlankRequestHandler());
344
345
            $group->group('/admin', function ($group) {
346
                $group->group('/catalog', function ($group) {
347
                    $group->group('/section', function ($group) {
348
                        $group->get('admin.section.all', '/list', new Fixture\BlankRequestHandler());
349
                        $group->get('admin.section.read', '/read/{id}', new Fixture\BlankRequestHandler());
350
                    });
351
352
                    $group->group('/entity', function ($group) {
353
                        $group->get('admin.entity.all', '/list', new Fixture\BlankRequestHandler());
354
                        $group->get('admin.entity.read', '/read/{id}', new Fixture\BlankRequestHandler());
355
                    });
356
                });
357
            });
358
359
            $group->get('baz', '/baz', new Fixture\BlankRequestHandler());
360
        });
361
362
        $collection->get('quux', '/quux', new Fixture\BlankRequestHandler());
363
364
        $builtPaths = [];
365
        foreach ($collection->getRoutes() as $route) {
366
            $builtPaths[] = $route->getPath();
367
        }
368
369
        $expectedPaths = [
370
            '/qux',
371
            '/foo',
372
            '/api/v1/section/list',
373
            '/api/v1/section/read/{id}',
374
            '/api/v1/entity/list',
375
            '/api/v1/entity/read/{id}',
376
            '/bar',
377
            '/admin/catalog/section/list',
378
            '/admin/catalog/section/read/{id}',
379
            '/admin/catalog/entity/list',
380
            '/admin/catalog/entity/read/{id}',
381
            '/baz',
382
            '/quux',
383
        ];
384
385
        $this->assertSame($expectedPaths, $builtPaths);
386
    }
387
388
    /**
389
     * @return array
390
     */
391
    public function makeVerbableRoutesDataProvider() : array
392
    {
393
        return [
394
            [
395
                'head',
396
                'HEAD',
397
            ],
398
            [
399
                'get',
400
                'GET',
401
            ],
402
            [
403
                'post',
404
                'POST',
405
            ],
406
            [
407
                'put',
408
                'PUT',
409
            ],
410
            [
411
                'patch',
412
                'PATCH',
413
            ],
414
            [
415
                'delete',
416
                'DELETE',
417
            ],
418
            [
419
                'purge',
420
                'PURGE',
421
            ],
422
        ];
423
    }
424
}
425