Passed
Pull Request — main (#7)
by
unknown
02:07
created

RoutingTest::intProvider()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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

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