Completed
Push — master ( 15f476...52f8b5 )
by Alex
07:26
created

testOneComponentRouterClassMethod()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 13
rs 10
1
<?php
2
namespace Mezon\Router\Tests;
3
4
class RouterUnitTest extends \PHPUnit\Framework\TestCase
5
{
6
7
    const DELETE_REQUEST_METHOD = 'DELETE';
8
9
    /**
10
     * Function sets $_SERVER['REQUEST_METHOD']
11
     *
12
     * @param string $requestMethod
13
     *            request method
14
     */
15
    public static function setRequestMethod(string $requestMethod): void
16
    {
17
        $_SERVER['REQUEST_METHOD'] = $requestMethod;
18
    }
19
20
    /**
21
     * Default setup
22
     *
23
     * {@inheritdoc}
24
     * @see \PHPUnit\Framework\TestCase::setUp()
25
     */
26
    public function setUp(): void
27
    {
28
        RouterUnitTest::setRequestMethod('GET');
29
    }
30
31
    /**
32
     * Function simply returns string.
33
     */
34
    public function helloWorldOutput(): string
35
    {
36
        return 'Hello world!';
37
    }
38
39
    /**
40
     * Testing action #1.
41
     */
42
    public function actionA1(): string
43
    {
44
        return 'action #1';
45
    }
46
47
    /**
48
     * Testing action #2.
49
     */
50
    public function actionA2(): string
51
    {
52
        return 'action #2';
53
    }
54
55
    public function actionDoubleWord(): string
56
    {
57
        return 'action double word';
58
    }
59
60
    /**
61
     * Testing one component router.
62
     */
63
    public function testOneComponentRouterClassMethod(): void
64
    {
65
        // TODO join this test with the next one via data provider
66
        $router = new \Mezon\Router\Router();
67
68
        $router->addRoute('/one-component-class-method/', [
69
            $this,
70
            'helloWorldOutput'
71
        ]);
72
73
        $content = $router->callRoute('/one-component-class-method/');
74
75
        $this->assertEquals('Hello world!', $content);
76
    }
77
78
    /**
79
     * Testing one component router.
80
     */
81
    public function testOneComponentRouterLambda(): void
82
    {
83
        $router = new \Mezon\Router\Router();
84
85
        $router->addRoute('/one-comonent-lambda/', function () {
86
            return 'Hello world!';
87
        });
88
89
        $content = $router->callRoute('/one-comonent-lambda/');
90
91
        $this->assertEquals('Hello world!', $content);
92
    }
93
94
    /**
95
     * Testing unexisting route behaviour.
96
     */
97
    public function testUnexistingRoute(): void
98
    {
99
        $exception = '';
100
        $router = new \Mezon\Router\Router();
101
        $router->addRoute('/existing-route/', [
102
            $this,
103
            'helloWorldOutput'
104
        ]);
105
106
        try {
107
            $router->callRoute('/unexisting-route/');
108
        } catch (\Exception $e) {
109
            $exception = $e->getMessage();
110
        }
111
112
        $msg = "The processor was not found for the route";
113
114
        $this->assertNotFalse(strpos($exception, $msg), 'Valid error handling expected');
115
    }
116
117
    /**
118
     * Data provider for the test testClassAction
119
     *
120
     * @return array test data
121
     */
122
    public function classActionDataProvider(): array
123
    {
124
        $testData = [];
125
126
        foreach ([
127
            'GET',
128
            'POST'
129
        ] as $requestMethod) {
130
            $testData[] = [
131
                $requestMethod,
132
                '/a1/',
133
                'action #1'
134
            ];
135
136
            $testData[] = [
137
                $requestMethod,
138
                '/a2/',
139
                'action #2'
140
            ];
141
142
            $testData[] = [
143
                $requestMethod,
144
                '/double-word/',
145
                'action double word'
146
            ];
147
        }
148
149
        return $testData;
150
    }
151
152
    /**
153
     * Method tests class actions
154
     *
155
     * @param string $requestMethod
156
     *            request method
157
     * @param string $route
158
     *            requesting route
159
     * @param string $expectedResult
160
     *            expected result of route processing
161
     * @dataProvider classActionDataProvider
162
     */
163
    public function testClassAction(string $requestMethod, string $route, string $expectedResult): void
164
    {
165
        RouterUnitTest::setRequestMethod($requestMethod);
166
167
        $router = new \Mezon\Router\Router();
168
        $router->fetchActions($this);
169
        $result = $router->callRoute($route);
170
        $this->assertEquals($expectedResult, $result);
171
    }
172
173
    /**
174
     * Testing case when all processors exist
175
     */
176
    public function testRequestMethodsConcurrency(): void
177
    {
178
        $route = '/catalog/';
179
        $router = new \Mezon\Router\Router();
180
        $router->addRoute($route, function () {
181
            return 'POST';
182
        }, 'POST');
183
        $router->addRoute($route, function () {
184
            return 'GET';
185
        }, 'GET');
186
        $router->addRoute($route, function () {
187
            return 'PUT';
188
        }, 'PUT');
189
        $router->addRoute($route, function () {
190
            return RouterUnitTest::DELETE_REQUEST_METHOD;
191
        }, RouterUnitTest::DELETE_REQUEST_METHOD);
192
193
        RouterUnitTest::setRequestMethod('POST');
194
        $result = $router->callRoute($route);
195
        $this->assertEquals($result, 'POST');
196
197
        RouterUnitTest::setRequestMethod('GET');
198
        $result = $router->callRoute($route);
199
        $this->assertEquals($result, 'GET');
200
201
        RouterUnitTest::setRequestMethod('PUT');
202
        $result = $router->callRoute($route);
203
        $this->assertEquals($result, 'PUT');
204
205
        RouterUnitTest::setRequestMethod(RouterUnitTest::DELETE_REQUEST_METHOD);
206
        $result = $router->callRoute($route);
207
        $this->assertEquals($result, RouterUnitTest::DELETE_REQUEST_METHOD);
208
    }
209
210
    /**
211
     * Data provider
212
     *
213
     * @return array
214
     */
215
    public function clearMethodTestDataProvider(): array
216
    {
217
        // TODO user getListOfSupportedRequestMethods() to fetch supported request methods
218
        return [
219
            [
220
                'POST'
221
            ],
222
            [
223
                'GET'
224
            ],
225
            [
226
                'PUT'
227
            ],
228
            [
229
                RouterUnitTest::DELETE_REQUEST_METHOD
230
            ],
231
            [
232
                'OPTION'
233
            ]
234
        ];
235
    }
236
237
    /**
238
     * Testing 'clear' method
239
     *
240
     * @param string $method
241
     *            request method
242
     * @dataProvider clearMethodTestDataProvider
243
     */
244
    public function testClearMethod(string $method): void
245
    {
246
        $router = new \Mezon\Router\Router();
247
        $router->addRoute('/route-to-clear/', function () use ($method) {
248
            return $method;
249
        }, $method);
250
        $router->clear();
251
252
        try {
253
            RouterUnitTest::setRequestMethod($method);
254
            $router->callRoute('/route-to-clear/');
255
            $flag = 'not cleared';
256
        } catch (\Exception $e) {
257
            $flag = 'cleared';
258
        }
259
        $this->assertEquals($flag, 'cleared', 'Data was not cleared');
260
    }
261
262
    /**
263
     * Method increments assertion count
264
     */
265
    protected function errorHandler(): void
266
    {
267
        $this->addToAssertionCount(1);
268
    }
269
270
    /**
271
     * Test validate custom error handlers.
272
     */
273
    public function testSetErrorHandler(): void
274
    {
275
        // setup
276
        $router = new \Mezon\Router\Router();
277
        $router->setNoProcessorFoundErrorHandler(function () {
278
            $this->errorHandler();
279
        });
280
281
        // test body and assertions
282
        RouterUnitTest::setRequestMethod('POST');
283
        $router->callRoute('/unexisting/');
284
    }
285
286
    /**
287
     * Data provider for the
288
     *
289
     * @return array testing dataset
290
     */
291
    public function getCallbackDataProvider(): array
292
    {
293
        return [
294
            [
295
                'some-static-route',
296
                'some-static-route'
297
            ],
298
            [
299
                'some/non-static/route/[i:id]',
300
                'some/non-static/route/1'
301
            ]
302
        ];
303
    }
304
305
    /**
306
     * Testing getting callback
307
     *
308
     * @param string $route
309
     *            route
310
     * @param string $url
311
     *            concrete URL
312
     * @dataProvider getCallbackDataProvider
313
     */
314
    public function testGetCallback(string $route, string $url): void
315
    {
316
        // setup
317
        $router = new \Mezon\Router\Router();
318
        $router->addRoute($route, function () {
319
            return 'route result';
320
        });
321
322
        // test body
323
        $callback = $router->getCallback($url);
324
325
        // assertions
326
        $this->assertEquals('route result', $callback());
327
    }
328
329
    /**
330
     * Testing case with unexisting callback
331
     */
332
    public function testGetCallbackWithUnexistingRoute(): void
333
    {
334
        // setup
335
        $router = new \Mezon\Router\Router();
336
        $router->addRoute('existing-route', function () {
337
            return 'existing route result';
338
        });
339
340
        // assertions
341
        $this->expectException(\Exception::class);
342
343
        // test body
344
        $router->getCallback('unexisting-route');
345
    }
346
347
    /**
348
     * Data provider for the test testReverseRouteByName
349
     *
350
     * @return array test data
351
     */
352
    public function reverseRouteByNameDataProvider(): array
353
    {
354
        return [
355
            [
356
                'named-route-url',
357
                [],
358
                'named-route-url'
359
            ],
360
            [
361
                'route-with-params/[i:id]',
362
                [
363
                    'id' => 123
364
                ],
365
                'route-with-params/123',
366
            ],
367
            [
368
                'route-with-foo/[i:id]',
369
                [
370
                    'foo' => 123
371
                ],
372
                'route-with-foo/[i:id]',
373
            ],
374
            [
375
                'route-no-params/[i:id]',
376
                [],
377
                'route-no-params/[i:id]',
378
            ]
379
        ];
380
    }
381
382
    /**
383
     * Testing reverse route by it's name
384
     *
385
     * @param string $route
386
     *            route
387
     * @param array $parameters
388
     *            parameters to be substituted
389
     * @param string $extectedResult
390
     *            quite obviuous to describe it here )
391
     * @dataProvider reverseRouteByNameDataProvider
392
     */
393
    public function testReverseRouteByName(string $route, array $parameters = [], string $extectedResult): void
394
    {
395
        // setup
396
        $router = new \Mezon\Router\Router();
397
        $router->addRoute($route, function () {
398
            return 'named route result';
399
        }, 'GET', 'named-route');
400
401
        // test body
402
        $url = $router->reverse('named-route', $parameters);
403
404
        // assertions
405
        $this->assertEquals($extectedResult, $url);
406
    }
407
408
    /**
409
     * Trying to fetch unexisting route by name
410
     */
411
    public function testFetchUnexistingRouteByName(): void
412
    {
413
        // setup
414
        $router = new \Mezon\Router\Router();
415
416
        // assertions
417
        $this->expectException(\Exception::class);
418
419
        // test body
420
        $router->getRouteByName('unexisting-name');
421
    }
422
}
423