Test Failed
Pull Request — main (#6)
by Chema
05:22 queued 03:08
created

RoutingTest::test_any_http_method()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GacelaTest\Unit\Router;
6
7
use Gacela\Router\Request;
8
use Gacela\Router\Routing;
9
use Gacela\Router\RoutingConfigurator;
10
use Gacela\Router\UnsupportedHttpMethodException;
11
use GacelaTest\Unit\Router\Fake\Name;
12
use GacelaTest\Unit\Router\Fake\NameInterface;
13
use Generator;
14
use PHPUnit\Framework\TestCase;
15
16
final class RoutingTest extends TestCase
17
{
18
    private const PROVIDER_TRIES = 10;
19
20
    protected function setUp(): void
21
    {
22
        Request::resetCache();
23
    }
24
25
    public function test_it_should_respond_if_everything_matches(): void
26
    {
27
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
28
        $_SERVER['REQUEST_METHOD'] = 'GET';
29
30
        $this->expectOutputString('Expected!');
31
32
        Routing::configure(static function (RoutingConfigurator $routes): void {
33
            $routes->get('expected/uri', FakeController::class, 'basicAction');
34
        });
35
    }
36
37
    public function test_it_should_not_respond_if_the_uri_does_not_matches(): void
38
    {
39
        $_SERVER['REQUEST_URI'] = 'https://example.org/unexpected/uri';
40
        $_SERVER['REQUEST_METHOD'] = 'GET';
41
42
        $this->expectOutputString('');
43
44
        Routing::configure(static function (RoutingConfigurator $routes): void {
45
            $routes->get('other/uri', FakeController::class, 'basicAction');
46
        });
47
    }
48
49
    public function test_it_should_not_respond_if_the_method_does_not_matches(): void
50
    {
51
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
52
        $_SERVER['REQUEST_METHOD'] = 'GET';
53
54
        $this->expectOutputString('');
55
56
        Routing::configure(static function (RoutingConfigurator $routes): void {
57
            $routes->post('expected/uri', FakeController::class, 'basicAction');
58
        });
59
    }
60
61
    public function test_it_should_pass_many_params_to_the_action(): void
62
    {
63
        /** @var list<string> $params */
64
        $params = ['foo', 'bar', 'baz'];
65
66
        $_SERVER['REQUEST_URI'] = "https://example.org/{$params[0]}/{$params[1]}/{$params[2]}";
67
        $_SERVER['REQUEST_METHOD'] = 'GET';
68
69
        $this->expectOutputString("The params are '{$params[0]}', '{$params[1]}' and '{$params[2]}'!");
70
71
        Routing::configure(static function (RoutingConfigurator $routes): void {
72
            $routes->get('{firstParam}/{secondParam}/{thirdParam}', FakeController::class, 'manyParamsAction');
73
        });
74
    }
75
76
    public function test_it_should_pass_associated_params_by_name_to_the_action(): void
77
    {
78
        /** @var list<string> $params */
79
        $params = ['foo', 'bar', 'baz'];
80
81
        $_SERVER['REQUEST_URI'] = "https://example.org/{$params[0]}/{$params[1]}/{$params[2]}";
82
        $_SERVER['REQUEST_METHOD'] = 'GET';
83
84
        $this->expectOutputString("The params are '{$params[1]}', '{$params[0]}' and '{$params[2]}'!");
85
86
        Routing::configure(static function (RoutingConfigurator $routes): void {
87
            $routes->get('{secondParam}/{firstParam}/{thirdParam}', FakeController::class, 'manyParamsAction');
88
        });
89
    }
90
91
    /**
92
     * @dataProvider stringProvider
93
     */
94
    public function test_it_should_pass_string_params_to_the_action(string $string): void
95
    {
96
        $_SERVER['REQUEST_URI'] = "https://example.org/expected/string/is/{$string}";
97
        $_SERVER['REQUEST_METHOD'] = 'GET';
98
99
        $this->expectOutputString("The 'string' param is '{$string}'!");
100
101
        Routing::configure(static function (RoutingConfigurator $routes): void {
102
            $routes->get('expected/string/is/{param}', FakeController::class, 'stringParamAction');
103
        });
104
    }
105
106
    public function stringProvider(): Generator
107
    {
108
        for ($try = 0; $try < self::PROVIDER_TRIES; ++$try) {
109
            $randomString = (string)'word-' . mt_rand();
110
            yield $randomString => ['string' => $randomString];
111
        }
112
    }
113
114
    /**
115
     * @dataProvider intProvider
116
     */
117
    public function test_it_should_pass_int_params_to_the_action(string $int): void
118
    {
119
        $_SERVER['REQUEST_URI'] = "https://example.org/expected/integer/is/{$int}";
120
        $_SERVER['REQUEST_METHOD'] = 'GET';
121
122
        $this->expectOutputString("The 'int' param is '{$int}'!");
123
124
        Routing::configure(static function (RoutingConfigurator $routes): void {
125
            $routes->get('expected/integer/is/{param}', FakeController::class, 'intParamAction');
126
        });
127
    }
128
129
    public function intProvider(): Generator
130
    {
131
        for ($try = 0; $try < self::PROVIDER_TRIES; ++$try) {
132
            $randomInt = (string)random_int(1, 9999);
133
            yield "#{$randomInt}" => ['int' => $randomInt];
134
        }
135
    }
136
137
    /**
138
     * @dataProvider floatProvider
139
     */
140
    public function test_it_should_pass_float_params_to_the_action(string $float): void
141
    {
142
        $_SERVER['REQUEST_URI'] = "https://example.org/expected/float/is/{$float}";
143
        $_SERVER['REQUEST_METHOD'] = 'GET';
144
145
        $this->expectOutputString("The 'float' param is '{$float}'!");
146
147
        Routing::configure(static function (RoutingConfigurator $routes): void {
148
            $routes->get('expected/float/is/{param}', FakeController::class, 'floatParamAction');
149
        });
150
    }
151
152
    public function floatProvider(): Generator
153
    {
154
        for ($try = 0; $try < self::PROVIDER_TRIES; ++$try) {
155
            $randomFloat = (string)mt_rand();
156
            yield "#{$randomFloat}" => ['float' => $randomFloat];
157
        }
158
    }
159
160
    /**
161
     * @dataProvider boolProvider
162
     */
163
    public function test_it_should_pass_bool_params_to_the_action(string $given, string $expected): void
164
    {
165
        $_SERVER['REQUEST_URI'] = "https://example.org/expected/bool/is/{$given}";
166
        $_SERVER['REQUEST_METHOD'] = 'GET';
167
168
        $this->expectOutputString("The 'bool' param is '{$expected}'!");
169
170
        Routing::configure(static function (RoutingConfigurator $routes): void {
171
            $routes->get('expected/bool/is/{param}', FakeController::class, 'boolParamAction');
172
        });
173
    }
174
175
    public function boolProvider(): iterable
176
    {
177
        yield 'true' => ['given' => 'true', 'expected' => 'true'];
178
        yield 'false' => ['given' => 'false', 'expected' => 'false'];
179
        yield '1' => ['given' => '1', 'expected' => 'true'];
180
        yield '0' => ['given' => '0', 'expected' => 'false'];
181
    }
182
183
    public function test_it_should_respond_only_the_first_match(): void
184
    {
185
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
186
        $_SERVER['REQUEST_METHOD'] = 'GET';
187
188
        $this->expectOutputString('Expected!');
189
190
        Routing::configure(static function (RoutingConfigurator $routes): void {
191
            $routes->get('expected/uri', FakeController::class, 'basicAction');
192
            $routes->get('expected/{param}', FakeController::class, 'stringParamAction');
193
        });
194
    }
195
196
    public function test_optional_argument(): void
197
    {
198
        $_SERVER['REQUEST_URI'] = 'https://example.org/optional';
199
        $_SERVER['REQUEST_METHOD'] = 'GET';
200
201
        $this->expectOutputString('Expected!');
202
203
        Routing::configure(static function (RoutingConfigurator $routes): void {
204
            $routes->get('optional/{param?}', FakeController::class, 'basicAction');
205
        });
206
    }
207
208
    public function test_multiple_optional_argument(): void
209
    {
210
        $_SERVER['REQUEST_URI'] = 'https://example.org/optional';
211
        $_SERVER['REQUEST_METHOD'] = 'GET';
212
213
        $this->expectOutputString('Expected!');
214
215
        Routing::configure(static function (RoutingConfigurator $routes): void {
216
            $routes->get('optional/{param1?}/{param2?}', FakeController::class, 'basicAction');
217
        });
218
    }
219
220
    public function test_it_should_thrown_exception_if_method_does_not_exist(): void
221
    {
222
        $this->expectException(UnsupportedHttpMethodException::class);
223
224
        Routing::configure(static function (RoutingConfigurator $routes): void {
225
            $routes->invalidName('', FakeController::class);
0 ignored issues
show
Bug introduced by
The method invalidName() does not exist on Gacela\Router\RoutingConfigurator. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

225
            $routes->/** @scrutinizer ignore-call */ 
226
                     invalidName('', FakeController::class);
Loading history...
226
        });
227
    }
228
229
    /**
230
     * @dataProvider anyHttpMethodProvider
231
     */
232
    public function test_any_http_method(string $httpMethod): void
233
    {
234
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
235
        $_SERVER['REQUEST_METHOD'] = $httpMethod;
236
237
        $this->expectOutputString('Expected!');
238
239
        Routing::configure(static function (RoutingConfigurator $routes): void {
240
            $routes->any('expected/uri', FakeController::class, 'basicAction');
241
        });
242
    }
243
244
    public function anyHttpMethodProvider(): Generator
245
    {
246
        yield ['METHOD_GET' => Request::METHOD_GET];
247
        yield ['METHOD_CONNECT' => Request::METHOD_CONNECT];
248
        yield ['METHOD_DELETE' => Request::METHOD_DELETE];
249
        yield ['METHOD_HEAD' => Request::METHOD_HEAD];
250
        yield ['METHOD_OPTIONS' => Request::METHOD_OPTIONS];
251
        yield ['METHOD_PATCH' => Request::METHOD_PATCH];
252
        yield ['METHOD_POST' => Request::METHOD_POST];
253
        yield ['METHOD_PUT' => Request::METHOD_PUT];
254
        yield ['METHOD_TRACE' => Request::METHOD_TRACE];
255
    }
256
257
    public function test_inject_dependencies_in_controllers(): void
258
    {
259
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
260
        $_SERVER['REQUEST_METHOD'] = 'GET';
261
262
        $this->expectOutputString('default-Expected!');
263
264
        Routing::configure(static function (RoutingConfigurator $routes): void {
265
            $routes->get('expected/uri', FakeControllerWithDependencies::class);
266
            $routes->setMappingInterfaces([NameInterface::class => new Name('Expected!')]);
267
        });
268
    }
269
}
270