Passed
Push — master ( 7fc855...fc8ef2 )
by Alexander
13:50
created

GroupTest::testAddGroup()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 44
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 30
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 44
rs 9.44
1
<?php
2
3
namespace Yiisoft\Router\Tests;
4
5
use Nyholm\Psr7\ServerRequest;
6
use Nyholm\Psr7\Response;
7
use PHPUnit\Framework\TestCase;
8
use Psr\Container\ContainerInterface;
9
use Psr\Http\Server\MiddlewareInterface;
10
use Psr\Http\Message\ResponseInterface;
11
use Psr\Http\Message\ServerRequestInterface;
12
use Psr\Http\Server\RequestHandlerInterface;
13
use Yiisoft\Router\Group;
14
use Yiisoft\Router\Route;
15
use Yiisoft\Router\RouteCollection;
16
use Yiisoft\Router\RouteCollectorInterface;
17
use Yiisoft\Router\Tests\Support\Container;
18
19
class GroupTest extends TestCase
20
{
21
    public function testAddRoute(): void
22
    {
23
        $listRoute = Route::get('/');
24
        $viewRoute = Route::get('/{id}');
25
26
        $group = Group::create();
27
        $group->addRoute($listRoute);
28
        $group->addRoute($viewRoute);
29
30
        $this->assertCount(2, $group->getItems());
31
        $this->assertSame($listRoute, $group->getItems()[0]);
32
        $this->assertSame($viewRoute, $group->getItems()[1]);
33
    }
34
35
    public function testAddMiddleware(): void
36
    {
37
        $group = Group::create();
38
39
        $middleware1 = static function () {
40
            return new Response();
41
        };
42
        $middleware2 = static function () {
43
            return new Response();
44
        };
45
46
        $group
47
            ->addMiddleware($middleware1)
48
            ->addMiddleware($middleware2);
49
50
        $this->assertCount(2, $group->getMiddlewares());
51
        $this->assertSame($middleware1, $group->getMiddlewares()[0]);
52
        $this->assertSame($middleware2, $group->getMiddlewares()[1]);
53
    }
54
55
    public function testAddNestedMiddleware(): void
56
    {
57
        $request = new ServerRequest('GET', '/outergroup/innergroup/test1');
58
59
        $middleware1 = static function (ServerRequestInterface $request, RequestHandlerInterface $handler) {
60
            $request = $request->withAttribute('middleware', 'middleware1');
61
            return $handler->handle($request);
62
        };
63
64
        $middleware2 = static function (ServerRequestInterface $request) {
65
            return new Response(200, [], null, '1.1', implode($request->getAttributes()));
66
        };
67
68
        $group = Group::create('/outergroup', [
69
            Group::create('/innergroup', [
70
                Route::get('/test1')->name('request1')
71
            ])->addMiddleware($middleware2),
72
        ], $this->getContainer())->addMiddleware($middleware1);
73
74
        $collector = Group::create();
75
        $collector->addGroup($group);
76
77
        $routeCollection = new RouteCollection($collector);
78
        $route = $routeCollection->getRoute('request1');
79
        $response = $route->process($request, $this->getRequestHandler());
80
        $this->assertSame(200, $response->getStatusCode());
81
        $this->assertSame('middleware1', $response->getReasonPhrase());
82
    }
83
84
    public function testGroupMiddlewareFullStackCalled(): void
85
    {
86
        $group = Group::create('/group', function (RouteCollectorInterface $r) {
87
            $r->addRoute(Route::get('/test1')->name('request1'));
88
        }, $this->getContainer());
89
90
        $request = new ServerRequest('GET', '/group/test1');
91
        $middleware1 = function (ServerRequestInterface $request, RequestHandlerInterface $handler) {
92
            $request = $request->withAttribute('middleware', 'middleware1');
93
            return $handler->handle($request);
94
        };
95
        $middleware2 = function (ServerRequestInterface $request) {
96
            return new Response(200, [], null, '1.1', implode($request->getAttributes()));
97
        };
98
99
        $group->addMiddleware($middleware2)->addMiddleware($middleware1);
100
        $collector = Group::create();
101
        $collector->addGroup($group);
102
103
        $routeCollection = new RouteCollection($collector);
104
        $route = $routeCollection->getRoute('request1');
105
        $response = $route->process($request, $this->getRequestHandler());
106
        $this->assertSame(200, $response->getStatusCode());
107
        $this->assertSame('middleware1', $response->getReasonPhrase());
108
    }
109
110
    public function testGroupMiddlewareStackInterrupted(): void
111
    {
112
        $group = Group::create('/group', function (RouteCollectorInterface $r) {
113
            $r->addRoute(Route::get('/test1')->name('request1'));
114
        }, $this->getContainer());
115
116
        $request = new ServerRequest('GET', '/group/test1');
117
        $middleware1 = function () {
118
            return new Response(403);
119
        };
120
        $middleware2 = function () {
121
            return new Response(200);
122
        };
123
124
        $group->addMiddleware($middleware2)->addMiddleware($middleware1);
125
        $collector = Group::create();
126
        $collector->addGroup($group);
127
128
        $routeCollection = new RouteCollection($collector);
129
        $route = $routeCollection->getRoute('request1');
130
        $response = $route->process($request, $this->getRequestHandler());
131
        $this->assertSame(403, $response->getStatusCode());
132
    }
133
134
    public function testAddGroup(): void
135
    {
136
        $logoutRoute = Route::post('/logout');
137
        $listRoute = Route::get('/');
138
        $viewRoute = Route::get('/{id}');
139
140
        $middleware1 = static function () {
141
            return new Response();
142
        };
143
        $middleware2 = static function () {
144
            return new Response();
145
        };
146
147
        $root = Group::create();
148
        $root->addGroup(Group::create('/api', static function (Group $group) use ($logoutRoute, $listRoute, $viewRoute, $middleware1, $middleware2) {
149
            $group->addRoute($logoutRoute);
150
            $group->addGroup(Group::create('/post', static function (Group $group) use ($listRoute, $viewRoute) {
151
                $group->addRoute($listRoute);
152
                $group->addRoute($viewRoute);
153
            }));
154
155
            $group->addMiddleware($middleware1);
156
            $group->addMiddleware($middleware2);
157
        }));
158
159
        $this->assertCount(1, $root->getItems());
160
        $api = $root->getItems()[0];
161
162
        $this->assertSame('/api', $api->getPrefix());
163
        $this->assertCount(2, $api->getItems());
164
        $this->assertSame($logoutRoute, $api->getItems()[0]);
165
166
        /** @var Group $postGroup */
167
        $postGroup = $api->getItems()[1];
168
        $this->assertInstanceOf(Group::class, $postGroup);
169
        $this->assertCount(2, $api->getMiddlewares());
170
        $this->assertSame($middleware1, $api->getMiddlewares()[0]);
171
        $this->assertSame($middleware2, $api->getMiddlewares()[1]);
172
173
        $this->assertSame('/post', $postGroup->getPrefix());
174
        $this->assertCount(2, $postGroup->getItems());
175
        $this->assertSame($listRoute, $postGroup->getItems()[0]);
176
        $this->assertSame($viewRoute, $postGroup->getItems()[1]);
177
        $this->assertEmpty($postGroup->getMiddlewares());
178
    }
179
180
    public function testAddGroupSecondWay(): void
181
    {
182
        $logoutRoute = Route::post('/logout');
183
        $listRoute = Route::get('/');
184
        $viewRoute = Route::get('/{id}');
185
186
        $middleware1 = static function () {
187
            return new Response();
188
        };
189
        $middleware2 = static function () {
190
            return new Response();
191
        };
192
193
        $root = Group::create(null, [
194
            Group::create('/api', [
195
                $logoutRoute,
196
                Group::create('/post', [
197
                    $listRoute,
198
                    $viewRoute
199
                ])
200
            ])->addMiddleware($middleware1)->addMiddleware($middleware2)
201
        ]);
202
203
        $this->assertCount(1, $root->getItems());
204
        $api = $root->getItems()[0];
205
206
        $this->assertSame('/api', $api->getPrefix());
207
        $this->assertCount(2, $api->getItems());
208
        $this->assertSame($logoutRoute, $api->getItems()[0]);
209
210
        /** @var Group $postGroup */
211
        $postGroup = $api->getItems()[1];
212
        $this->assertInstanceOf(Group::class, $postGroup);
213
        $this->assertCount(2, $api->getMiddlewares());
214
        $this->assertSame($middleware1, $api->getMiddlewares()[0]);
215
        $this->assertSame($middleware2, $api->getMiddlewares()[1]);
216
217
        $this->assertSame('/post', $postGroup->getPrefix());
218
        $this->assertCount(2, $postGroup->getItems());
219
        $this->assertSame($listRoute, $postGroup->getItems()[0]);
220
        $this->assertSame($viewRoute, $postGroup->getItems()[1]);
221
        $this->assertEmpty($postGroup->getMiddlewares());
222
    }
223
224
    public function testContainerInjected(): void
225
    {
226
        $container = $this->getContainer();
227
228
        $apiGroup = Group::create(
229
            '/api',
230
            static function (Group $group) {
231
                $group->addRoute(Route::get('/info')->name('api-info'));
232
                $group->addGroup(
233
                    Group::create(
234
                        '/v1',
235
                        static function (Group $group) {
236
                            $group->addRoute(Route::get('/user')->name('api-v1-user/index'));
237
                            $group->addRoute(Route::get('/user/{id}')->name('api-v1-user/view'));
238
                            $group->addGroup(
239
                                Group::create(
240
                                    '/news',
241
                                    static function (Group $group) {
242
                                        $group->addRoute(Route::get('/post')->name('api-v1-news-post/index'));
243
                                        $group->addRoute(Route::get('/post/{id}')->name('api-v1-news-post/view'));
244
                                    }
245
                                )
246
                            );
247
                            $group->addGroup(
248
                                Group::create(
249
                                    '/blog',
250
                                    static function (Group $group) {
251
                                        $group->addRoute(Route::get('/post')->name('api-v1-blog-post/index'));
252
                                        $group->addRoute(Route::get('/post/{id}')->name('api-v1-blog-post/view'));
253
                                    }
254
                                )
255
                            );
256
                            $group->addRoute(Route::get('/note')->name('api-v1-note/index'));
257
                            $group->addRoute(Route::get('/note/{id}')->name('api-v1-note/view'));
258
                        }
259
                    )
260
                );
261
                $group->addGroup(
262
                    Group::create(
263
                        '/v2',
264
                        static function (Group $group) {
265
                            $group->addRoute(Route::get('/user')->name('api-v2-user/index'));
266
                            $group->addRoute(Route::get('/user/{id}')->name('api-v2-user/view'));
267
                            $group->addGroup(
268
                                Group::create(
269
                                    '/news',
270
                                    static function (Group $group) {
271
                                        $group->addRoute(Route::get('/post')->name('api-v2-news-post/index'));
272
                                        $group->addRoute(Route::get('/post/{id}')->name('api-v2-news-post/view'));
273
                                    }
274
                                )
275
                            );
276
                            $group->addGroup(
277
                                Group::create(
278
                                    '/blog',
279
                                    static function (Group $group) {
280
                                        $group->addRoute(Route::get('/post')->name('api-v2-blog-post/index'));
281
                                        $group->addRoute(Route::get('/post/{id}')->name('api-v2-blog-post/view'));
282
                                    }
283
                                )
284
                            );
285
                            $group->addRoute(Route::get('/note')->name('api-v2-note/index'));
286
                            $group->addRoute(Route::get('/note/{id}')->name('api-v2-note/view'));
287
                        }
288
                    )
289
                );
290
            },
291
            $container
292
        );
293
294
        $items = $apiGroup->getItems();
295
296
        $this->assertAllRoutesAndGroupsHaveContainer($items);
297
    }
298
299
    private function getRequestHandler(): RequestHandlerInterface
300
    {
301
        return new class() implements RequestHandlerInterface {
302
            public function handle(ServerRequestInterface $request): ResponseInterface
303
            {
304
                return new Response(404);
305
            }
306
        };
307
    }
308
309
    private function getContainer(array $instances = []): ContainerInterface
310
    {
311
        return new Container($instances);
312
    }
313
314
    private function assertAllRoutesAndGroupsHaveContainer(array $items): void
315
    {
316
        $func = function ($item) use (&$func) {
317
            $this->assertTrue($item->hasContainer());
318
            if ($item instanceof Group) {
319
                $items = $item->getItems();
320
                array_walk($items, $func);
321
            }
322
        };
323
        array_walk($items, $func);
324
    }
325
}
326