Issues (47)

tests/Feature/Router/MiddlewareGroupTest.php (8 issues)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GacelaTest\Feature\Router;
6
7
use Closure;
8
use Gacela\Router\Configure\Middlewares;
9
use Gacela\Router\Configure\Routes;
10
use Gacela\Router\Entities\Request;
11
use Gacela\Router\Middleware\MiddlewareInterface;
12
use Gacela\Router\Router;
13
use GacelaTest\Feature\HeaderTestCase;
14
use GacelaTest\Feature\Router\Fixtures\FakeMiddleware;
15
use Override;
16
17
final class MiddlewareGroupTest extends HeaderTestCase
18
{
19
    public function test_can_define_middleware_group(): void
20
    {
21
        $router = new Router(static function (Routes $routes, Middlewares $middlewares): void {
22
            $middlewares->group('test', [self::createAnonMiddleware('GROUP')]);
23
24
            $routes->get('/', static fn () => 'CONTENT')->middleware('test');
0 ignored issues
show
function(...) { /* ... */ } of type callable is incompatible with the type object|string expected by parameter $controller of Gacela\Router\Configure\Routes::get(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

24
            $routes->get('/', /** @scrutinizer ignore-type */ static fn () => 'CONTENT')->middleware('test');
Loading history...
25
        });
26
27
        $_SERVER['REQUEST_METHOD'] = 'GET';
28
        $_SERVER['REQUEST_URI'] = '/';
29
30
        ob_start();
31
        $router->run();
32
        $output = ob_get_clean();
33
34
        self::assertSame('[GROUP]CONTENT[/GROUP]', $output);
35
    }
36
37
    public function test_middleware_group_with_multiple_middlewares(): void
38
    {
39
        $router = new Router(static function (Routes $routes, Middlewares $middlewares): void {
40
            $middlewares->group('web', [
41
                self::createAnonMiddleware('FIRST'),
42
                self::createAnonMiddleware('SECOND'),
43
            ]);
44
45
            $routes->get('/', static fn () => 'CONTENT')->middleware('web');
0 ignored issues
show
function(...) { /* ... */ } of type callable is incompatible with the type object|string expected by parameter $controller of Gacela\Router\Configure\Routes::get(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

45
            $routes->get('/', /** @scrutinizer ignore-type */ static fn () => 'CONTENT')->middleware('web');
Loading history...
46
        });
47
48
        $_SERVER['REQUEST_METHOD'] = 'GET';
49
        $_SERVER['REQUEST_URI'] = '/';
50
51
        ob_start();
52
        $router->run();
53
        $output = ob_get_clean();
54
55
        self::assertSame('[FIRST][SECOND]CONTENT[/SECOND][/FIRST]', $output);
56
    }
57
58
    public function test_multiple_groups_can_be_applied_to_route(): void
59
    {
60
        $router = new Router(static function (Routes $routes, Middlewares $middlewares): void {
61
            $middlewares->group('group1', [
62
                self::createAnonMiddleware('G1'),
63
            ]);
64
65
            $middlewares->group('group2', [
66
                self::createAnonMiddleware('G2'),
67
            ]);
68
69
            $routes
70
                ->get('/', static fn () => 'CONTENT')
0 ignored issues
show
function(...) { /* ... */ } of type callable is incompatible with the type object|string expected by parameter $controller of Gacela\Router\Configure\Routes::get(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

70
                ->get('/', /** @scrutinizer ignore-type */ static fn () => 'CONTENT')
Loading history...
71
                ->middleware('group1')
72
                ->middleware('group2');
73
        });
74
75
        $_SERVER['REQUEST_METHOD'] = 'GET';
76
        $_SERVER['REQUEST_URI'] = '/';
77
78
        ob_start();
79
        $router->run();
80
        $output = ob_get_clean();
81
82
        self::assertSame('[G1][G2]CONTENT[/G2][/G1]', $output);
83
    }
84
85
    public function test_can_mix_groups_and_individual_middleware(): void
86
    {
87
        $router = new Router(static function (Routes $routes, Middlewares $middlewares): void {
88
            $middlewares->group('auth', [
89
                self::createAnonMiddleware('AUTH'),
90
            ]);
91
92
            $routes
93
                ->get('/', static fn () => 'CONTENT')
0 ignored issues
show
function(...) { /* ... */ } of type callable is incompatible with the type object|string expected by parameter $controller of Gacela\Router\Configure\Routes::get(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

93
                ->get('/', /** @scrutinizer ignore-type */ static fn () => 'CONTENT')
Loading history...
94
                ->middleware('auth')
95
                ->middleware(self::createAnonMiddleware('CUSTOM'));
96
        });
97
98
        $_SERVER['REQUEST_METHOD'] = 'GET';
99
        $_SERVER['REQUEST_URI'] = '/';
100
101
        ob_start();
102
        $router->run();
103
        $output = ob_get_clean();
104
105
        self::assertSame('[AUTH][CUSTOM]CONTENT[/CUSTOM][/AUTH]', $output);
106
    }
107
108
    public function test_global_middleware_groups(): void
109
    {
110
        $router = new Router(static function (Routes $routes, Middlewares $middlewares): void {
111
            $middlewares->group('global', [self::createAnonMiddleware('GLOBAL')]);
112
113
            // Add group to global middleware
114
            $middlewares->add('global');
115
116
            $routes->get('/', static fn () => 'CONTENT');
0 ignored issues
show
function(...) { /* ... */ } of type callable is incompatible with the type object|string expected by parameter $controller of Gacela\Router\Configure\Routes::get(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

116
            $routes->get('/', /** @scrutinizer ignore-type */ static fn () => 'CONTENT');
Loading history...
117
        });
118
119
        $_SERVER['REQUEST_METHOD'] = 'GET';
120
        $_SERVER['REQUEST_URI'] = '/';
121
122
        ob_start();
123
        $router->run();
124
        $output = ob_get_clean();
125
126
        self::assertSame('[GLOBAL]CONTENT[/GLOBAL]', $output);
127
    }
128
129
    public function test_middleware_group_with_class_strings(): void
130
    {
131
        $router = new Router(static function (Routes $routes, Middlewares $middlewares): void {
132
            $middlewares->group('test', [
133
                FakeMiddleware::class,
134
            ]);
135
136
            $routes->get('/', static fn () => 'CONTENT')->middleware('test');
0 ignored issues
show
function(...) { /* ... */ } of type callable is incompatible with the type object|string expected by parameter $controller of Gacela\Router\Configure\Routes::get(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

136
            $routes->get('/', /** @scrutinizer ignore-type */ static fn () => 'CONTENT')->middleware('test');
Loading history...
137
        });
138
139
        $_SERVER['REQUEST_METHOD'] = 'GET';
140
        $_SERVER['REQUEST_URI'] = '/';
141
142
        ob_start();
143
        $router->run();
144
        $output = ob_get_clean();
145
146
        self::assertSame('[TEST]CONTENT[/TEST]', $output);
147
    }
148
149
    public function test_undefined_group_uses_name_as_class_string(): void
150
    {
151
        $router = new Router(static function (Routes $routes): void {
152
            // Use class name directly without defining as group
153
            $routes
154
                ->get('/', static fn () => 'CONTENT')
0 ignored issues
show
function(...) { /* ... */ } of type callable is incompatible with the type object|string expected by parameter $controller of Gacela\Router\Configure\Routes::get(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

154
                ->get('/', /** @scrutinizer ignore-type */ static fn () => 'CONTENT')
Loading history...
155
                ->middleware(FakeMiddleware::class);
156
        });
157
158
        $_SERVER['REQUEST_METHOD'] = 'GET';
159
        $_SERVER['REQUEST_URI'] = '/';
160
161
        ob_start();
162
        $router->run();
163
        $output = ob_get_clean();
164
165
        self::assertSame('[TEST]CONTENT[/TEST]', $output);
166
    }
167
168
    public function test_can_retrieve_defined_groups(): void
169
    {
170
        $middlewares = new Middlewares();
171
172
        $middleware1 = new class() implements MiddlewareInterface {
173
            #[Override]
174
            public function handle(Request $request, Closure $next): string
175
            {
176
                return $next($request);
177
            }
178
        };
179
180
        $middlewares->group('test', [$middleware1]);
181
182
        $groups = $middlewares->getGroups();
183
184
        self::assertArrayHasKey('test', $groups);
185
        self::assertSame([$middleware1], $groups['test']);
186
    }
187
188
    public function test_empty_group_does_nothing(): void
189
    {
190
        $router = new Router(static function (Routes $routes, Middlewares $middlewares): void {
191
            $middlewares->group('empty', []);
192
            $routes->get('/', static fn () => 'CONTENT')->middleware('empty');
0 ignored issues
show
function(...) { /* ... */ } of type callable is incompatible with the type object|string expected by parameter $controller of Gacela\Router\Configure\Routes::get(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

192
            $routes->get('/', /** @scrutinizer ignore-type */ static fn () => 'CONTENT')->middleware('empty');
Loading history...
193
        });
194
195
        $_SERVER['REQUEST_METHOD'] = 'GET';
196
        $_SERVER['REQUEST_URI'] = '/';
197
198
        ob_start();
199
        $router->run();
200
        $output = ob_get_clean();
201
202
        self::assertSame('CONTENT', $output);
203
    }
204
205
    private static function createAnonMiddleware(string $tag): MiddlewareInterface
206
    {
207
        return new class($tag) implements MiddlewareInterface {
208
            public function __construct(
209
                private readonly string $tag,
210
            ) {
211
            }
212
213
            #[Override]
214
            public function handle(Request $request, Closure $next): string
215
            {
216
                return "[{$this->tag}]" . $next($request) . "[/{$this->tag}]";
217
            }
218
        };
219
    }
220
}
221