Completed
Push — master ( 2dfe17...2fbb48 )
by Alex
01:53
created

RouterUnitTest::testClassAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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