Passed
Pull Request — master (#26)
by Dmitriy
06:22 queued 03:41
created

testSimpleRouteWithOptionalPartSuccess()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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