Passed
Push — master ( f44faa...c2d2bb )
by Alexander
05:29
created

UrlMatcherTest::testNoCache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 12
nc 1
nop 0
dl 0
loc 17
rs 9.8666
c 1
b 0
f 0
1
<?php
2
3
4
namespace Yiisoft\Router\FastRoute\Tests;
5
6
use Nyholm\Psr7\ServerRequest;
7
use PHPUnit\Framework\TestCase;
8
use Psr\SimpleCache\CacheInterface;
9
use Yiisoft\Router\RouteCollection;
10
use Yiisoft\Router\FastRoute\UrlMatcher;
11
use Yiisoft\Router\Group;
12
use Yiisoft\Router\Route;
13
use Yiisoft\Router\UrlMatcherInterface;
14
15
final class UrlMatcherTest extends TestCase
16
{
17
    private function createUrlMatcher(array $routes, CacheInterface $cache = null): UrlMatcherInterface
18
    {
19
        $container = new DummyContainer();
20
        $collector = Group::create();
21
        $rootGroup = Group::create(null, $routes, $container);
22
        $collector->addGroup($rootGroup);
23
        return new UrlMatcher(new RouteCollection($collector), $cache, ['cache_key' => 'route-cache']);
24
    }
25
26
    public function testDefaultsAreInResult(): void
27
    {
28
        $routes = [
29
            Route::get('/[{name}]')->defaults(['name' => 'test']),
30
        ];
31
32
        $urlMatcher = $this->createUrlMatcher($routes);
33
34
        $request = new ServerRequest('GET', '/');
35
36
        $result = $urlMatcher->match($request);
37
        $parameters = $result->parameters();
38
39
        $this->assertTrue($result->isSuccess());
40
        $this->assertArrayHasKey('name', $parameters);
41
        $this->assertSame('test', $parameters['name']);
42
    }
43
44
    public function testSimpleRoute(): void
45
    {
46
        $routes = [
47
            Route::get('/site/index'),
48
        ];
49
50
        $urlMatcher = $this->createUrlMatcher($routes);
51
52
        $request = new ServerRequest('GET', '/site/index');
53
54
        $result = $urlMatcher->match($request);
55
        $this->assertTrue($result->isSuccess());
56
    }
57
58
    public function testSimpleRouteWithDifferentMethods(): void
59
    {
60
        $routes = [
61
            Route::methods(['GET', 'POST'], '/site/index'),
62
        ];
63
64
        $urlMatcher = $this->createUrlMatcher($routes);
65
66
        $request1 = new ServerRequest('GET', '/site/index');
67
        $request2 = new ServerRequest('POST', '/site/index');
68
69
        $result1 = $urlMatcher->match($request1);
70
        $result2 = $urlMatcher->match($request2);
71
        $this->assertTrue($result1->isSuccess());
72
        $this->assertTrue($result2->isSuccess());
73
    }
74
75
    public function testSimpleRouteWithParam(): void
76
    {
77
        $routes = [
78
            Route::get('/site/post/{id}'),
79
        ];
80
81
        $urlMatcher = $this->createUrlMatcher($routes);
82
83
        $request = new ServerRequest('GET', '/site/post/23');
84
85
        $result = $urlMatcher->match($request);
86
        $parameters = $result->parameters();
87
88
        $this->assertTrue($result->isSuccess());
89
        $this->assertArrayHasKey('id', $parameters);
90
        $this->assertSame('23', $parameters['id']);
91
    }
92
93
    public function testSimpleRouteWithOptionalPartSuccess(): void
94
    {
95
        $routes = [
96
            Route::get('/site/post[/view]'),
97
        ];
98
99
        $urlMatcher = $this->createUrlMatcher($routes);
100
101
        $request1 = new ServerRequest('GET', '/site/post/view');
102
        $request2 = new ServerRequest('GET', '/site/post');
103
104
        $result1 = $urlMatcher->match($request1);
105
        $result2 = $urlMatcher->match($request2);
106
107
        $this->assertTrue($result1->isSuccess());
108
        $this->assertTrue($result2->isSuccess());
109
    }
110
111
    public function testSimpleRouteWithOptionalPartFailed(): void
112
    {
113
        $routes = [
114
            Route::get('/site/post[/view]'),
115
        ];
116
117
        $urlMatcher = $this->createUrlMatcher($routes);
118
119
        $request = new ServerRequest('GET', '/site/post/index');
120
121
        $result = $urlMatcher->match($request);
122
123
        $this->assertFalse($result->isSuccess());
124
    }
125
126
    public function testSimpleRouteWithOptionalParam(): void
127
    {
128
        $routes = [
129
            Route::get('/site/post[/{id}]'),
130
        ];
131
132
        $urlMatcher = $this->createUrlMatcher($routes);
133
134
        $request1 = new ServerRequest('GET', '/site/post/23');
135
        $request2 = new ServerRequest('GET', '/site/post');
136
137
        $result1 = $urlMatcher->match($request1);
138
        $parameters1 = $result1->parameters();
139
        $result2 = $urlMatcher->match($request2);
140
        $parameters2 = $result2->parameters();
141
142
        $this->assertTrue($result1->isSuccess());
143
        $this->assertArrayHasKey('id', $parameters1);
144
        $this->assertSame('23', $parameters1['id']);
145
        $this->assertTrue($result2->isSuccess());
146
        $this->assertArrayNotHasKey('id', $parameters2);
147
    }
148
149
    public function testSimpleRouteWithNestedOptionalParts(): void
150
    {
151
        $routes = [
152
            Route::get('/site[/post[/view]]'),
153
        ];
154
155
        $urlMatcher = $this->createUrlMatcher($routes);
156
157
        $request1 = new ServerRequest('GET', '/site/post/view');
158
        $request2 = new ServerRequest('GET', '/site/post');
159
        $request3 = new ServerRequest('GET', '/site');
160
161
        $result1 = $urlMatcher->match($request1);
162
        $result2 = $urlMatcher->match($request2);
163
        $result3 = $urlMatcher->match($request3);
164
165
        $this->assertTrue($result1->isSuccess());
166
        $this->assertTrue($result2->isSuccess());
167
        $this->assertTrue($result3->isSuccess());
168
    }
169
170
    public function testSimpleRouteWithNestedOptionalParamsSuccess(): void
171
    {
172
        $routes = [
173
            Route::get('/site[/{name}[/{id}]]'),
174
        ];
175
176
        $urlMatcher = $this->createUrlMatcher($routes);
177
178
        $request1 = new ServerRequest('GET', '/site/post/23');
179
        $request2 = new ServerRequest('GET', '/site/post');
180
        $request3 = new ServerRequest('GET', '/site');
181
182
        $result1 = $urlMatcher->match($request1);
183
        $parameters1 = $result1->parameters();
184
        $result2 = $urlMatcher->match($request2);
185
        $parameters2 = $result2->parameters();
186
        $result3 = $urlMatcher->match($request3);
187
        $parameters3 = $result3->parameters();
188
189
        $this->assertTrue($result1->isSuccess());
190
        $this->assertArrayHasKey('id', $parameters1);
191
        $this->assertArrayHasKey('name', $parameters1);
192
        $this->assertSame('23', $parameters1['id']);
193
        $this->assertSame('post', $parameters1['name']);
194
        $this->assertTrue($result2->isSuccess());
195
        $this->assertArrayHasKey('name', $parameters2);
196
        $this->assertSame('post', $parameters2['name']);
197
        $this->assertTrue($result3->isSuccess());
198
        $this->assertArrayNotHasKey('id', $parameters3);
199
        $this->assertArrayNotHasKey('name', $parameters3);
200
    }
201
202
    public function testDisallowedMethod(): void
203
    {
204
        $routes = [
205
            Route::get('/site/index'),
206
        ];
207
208
        $urlMatcher = $this->createUrlMatcher($routes);
209
210
        $request = new ServerRequest('POST', '/site/index');
211
212
        $result = $urlMatcher->match($request);
213
        $this->assertFalse($result->isSuccess());
214
        $this->assertTrue($result->isMethodFailure());
215
        $this->assertSame(['GET'], $result->methods());
216
    }
217
218
    public function testDisallowedHEADMethod(): void
219
    {
220
        $routes = [
221
            Route::post('/site/post/view'),
222
            Route::get('/site/index'),
223
            Route::post('/site/index'),
224
        ];
225
226
        $urlMatcher = $this->createUrlMatcher($routes);
227
228
        $request = new ServerRequest('HEAD', '/site/index');
229
230
        $result = $urlMatcher->match($request);
231
        $this->assertFalse($result->isSuccess());
232
        $this->assertTrue($result->isMethodFailure());
233
        $this->assertSame(['GET', 'POST'], $result->methods());
234
    }
235
236
    public function testGetCurrentRoute(): void
237
    {
238
        $routes = [
239
            Route::get('/site/index')->name('request1'),
240
            Route::post('/site/index')->name('request2'),
241
        ];
242
243
        $urlMatcher = $this->createUrlMatcher($routes);
244
245
        $request = new ServerRequest('GET', '/site/index');
246
247
        $urlMatcher->match($request);
248
        $this->assertSame($routes[0]->getName(), $urlMatcher->getCurrentRoute()->getName());
249
    }
250
251
    public function testGetLastMatchedRequest(): void
252
    {
253
        $routes = [
254
            Route::get('/site/index')->name('request1'),
255
            Route::post('/site/index')->name('request2'),
256
        ];
257
258
        $urlMatcher = $this->createUrlMatcher($routes);
259
260
        $request = new ServerRequest('GET', '/site/index');
261
262
        $urlMatcher->match($request);
263
        $this->assertSame($request, $urlMatcher->getLastMatchedRequest());
264
    }
265
266
    public function testGetRouteCollection(): void
267
    {
268
        $routes = [
269
            Route::get('/site/index')->name('request1'),
270
            Route::post('/site/index')->name('request2'),
271
        ];
272
273
        $collector = Group::create();
274
        $collector->addGroup(Group::create(null, $routes));
275
        $routeCollection = new RouteCollection($collector);
276
        $urlMatcher = new UrlMatcher($routeCollection);
277
278
        $this->assertSame($routeCollection, $urlMatcher->getRouteCollection());
279
    }
280
281
    public function testNoCache(): void
282
    {
283
        $routes = [
284
            Route::get('/')
285
                ->name('site/index'),
286
            Route::methods(['GET', 'POST'], '/contact')
287
                ->name('site/contact'),
288
        ];
289
290
        $request = new ServerRequest('GET', '/contact');
291
292
        $cache = $this->createMock(CacheInterface::class);
293
        $cache->method('has')
294
            ->willReturn(false);
295
        $matcher = $this->createUrlMatcher($routes, $cache);
296
        $result = $matcher->match($request);
297
        $this->assertTrue($result->isSuccess());
298
    }
299
300
    public function testHasCache(): void
301
    {
302
        $routes = [
303
            Route::get('/')
304
                ->name('site/index'),
305
            Route::methods(['GET', 'POST'], '/contact')
306
                ->name('site/contact'),
307
        ];
308
309
        $cacheArray = [
310
            0 => [
311
                'GET' => [
312
                    '/' => 'site/index',
313
                    '/contact' => 'site/contact',
314
                ],
315
                'POST' => [
316
                    '/contact' => 'site/contact',
317
                ],
318
            ],
319
            1 => []
320
        ];
321
322
        $request = new ServerRequest('GET', '/contact');
323
324
        $cache = $this->createMock(CacheInterface::class);
325
        $cache->method('has')
326
            ->willReturn(true);
327
        $cache->method('get')
328
            ->willReturn($cacheArray);
329
        $matcher = $this->createUrlMatcher($routes, $cache);
330
        $result = $matcher->match($request);
331
        $this->assertTrue($result->isSuccess());
332
    }
333
334
    public function testCacheError(): void
335
    {
336
        $routes = [
337
            Route::get('/')
338
                ->name('site/index'),
339
            Route::methods(['GET', 'POST'], '/contact')
340
                ->name('site/contact'),
341
        ];
342
343
        $request = new ServerRequest('GET', '/contact');
344
345
        $cache = $this->createMock(CacheInterface::class);
346
        $cache->method('get')
347
            ->will($this->throwException(new \RuntimeException()));
348
        $matcher = $this->createUrlMatcher($routes, $cache);
349
        $result = $matcher->match($request);
350
        $this->assertTrue($result->isSuccess());
351
    }
352
}
353