Passed
Pull Request — main (#35)
by
unknown
02:25
created

RouterMatchTest::test_mandatory_argument()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
nc 1
nop 0
dl 0
loc 11
rs 10
c 2
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GacelaTest\Feature\Router;
6
7
use Gacela\Router\Configure\Routes;
8
use Gacela\Router\Entities\Request;
9
use Gacela\Router\Exceptions\MalformedPathException;
10
use Gacela\Router\Exceptions\UnsupportedHttpMethodException;
11
use Gacela\Router\Router;
12
use GacelaTest\Feature\Router\Fixtures\FakeController;
13
use Generator;
14
use PHPUnit\Framework\TestCase;
15
16
final class RouterMatchTest extends TestCase
17
{
18
    public function test_respond_when_everything_matches(): void
19
    {
20
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
21
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
22
23
        $this->expectOutputString('Expected!');
24
25
        $router = new Router(static function (Routes $routes): void {
26
            $routes->get('expected/uri', FakeController::class, 'basicAction');
27
        });
28
        $router->run();
29
    }
30
31
    public function test_respond_only_the_first_match(): void
32
    {
33
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
34
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
35
36
        $this->expectOutputString('Expected!');
37
38
        $router = new Router(static function (Routes $routes): void {
39
            $routes->get('expected/uri', FakeController::class, 'basicAction');
40
            $routes->get('expected/{param}', FakeController::class, 'stringParamAction');
41
        });
42
        $router->run();
43
    }
44
45
    public function test_optional_argument(): void
46
    {
47
        $_SERVER['REQUEST_URI'] = 'https://example.org/optional';
48
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
49
50
        $this->expectOutputString('Expected!');
51
52
        $router = new Router(static function (Routes $routes): void {
53
            $routes->get('optional/{param?}', FakeController::class, 'basicAction');
54
        });
55
        $router->run();
56
    }
57
58
    public function test_multiple_optional_argument(): void
59
    {
60
        $_SERVER['REQUEST_URI'] = 'https://example.org/optional';
61
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
62
63
        $this->expectOutputString('Expected!');
64
65
        $router = new Router(static function (Routes $routes): void {
66
            $routes->get('optional/{param1?}/{param2?}', FakeController::class, 'basicAction');
67
        });
68
        $router->run();
69
    }
70
71
    public function test_multiple_optional_argument_with_only_first_provided(): void
72
    {
73
        $_SERVER['REQUEST_URI'] = 'https://example.org/optional/bob1';
74
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
75
76
        $this->expectOutputString('Expected!');
77
78
        $router = new Router(static function (Routes $routes): void {
79
            $routes->get('optional/{param1?}/{param2?}', FakeController::class, 'basicAction');
80
        });
81
        $router->run();
82
    }
83
84
    public function test_multiple_optional_argument_with_both_provided(): void
85
    {
86
        $_SERVER['REQUEST_URI'] = 'https://example.org/optional/bob1/bob2';
87
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
88
89
        $this->expectOutputString('Expected!');
90
91
        $router = new Router(static function (Routes $routes): void {
92
            $routes->get('optional/{param1?}/{param2?}', FakeController::class, 'basicAction');
93
        });
94
        $router->run();
95
    }
96
97
    public function test_throw_malformed_path_exception_due_mandatory_argument_after_optional_argument(): void
98
    {
99
        $this->expectException(MalformedPathException::class);
100
101
        $router = new Router(static function (Routes $routes): void {
102
            $routes->get('uri/{param1?}/{param2}', FakeController::class);
103
        });
104
        $router->run();
105
    }
106
107
    public function test_throw_malformed_path_exception_due_static_part_after_optional_argument(): void
108
    {
109
        $this->expectException(MalformedPathException::class);
110
111
        $router = new Router(static function (Routes $routes): void {
112
            $routes->get('uri/{param1?}/alice', FakeController::class);
113
        });
114
        $router->run();
115
    }
116
117
    public function test_mandatory_argument(): void
118
    {
119
        $_SERVER['REQUEST_URI'] = 'https://example.org/mandatory/alice';
120
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
121
122
        $this->expectOutputString('Expected!');
123
124
        $router = new Router(static function (Routes $routes): void {
125
            $routes->get('mandatory/{param1}', FakeController::class, 'basicAction');
126
        });
127
        $router->run();
128
    }
129
130
    public function test_mandatory_and_not_provided_optional_argument(): void
131
    {
132
        $_SERVER['REQUEST_URI'] = 'https://example.org/mandatory_and_not_provided_optional/alice';
133
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
134
135
        $this->expectOutputString('Expected!');
136
137
        $router = new Router(static function (Routes $routes): void {
138
            $routes->get('mandatory_and_not_provided_optional/{param1}/{param2?}', FakeController::class, 'basicAction');
139
        });
140
        $router->run();
141
    }
142
143
    public function test_mandatory_and_provided_optional_argument(): void
144
    {
145
        $_SERVER['REQUEST_URI'] = 'https://example.org/mandatory_and_provided_optional/alice/bob';
146
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
147
148
        $this->expectOutputString('Expected!');
149
150
        $router = new Router(static function (Routes $routes): void {
151
            $routes->get('mandatory_and_provided_optional/{param1}/{param2?}', FakeController::class, 'basicAction');
152
        });
153
        $router->run();
154
    }
155
156
    public function test_thrown_exception_when_method_does_not_exist(): void
157
    {
158
        $this->expectException(UnsupportedHttpMethodException::class);
159
160
        $router = new Router(static function (Routes $routes): void {
161
            $routes->invalidName('', FakeController::class);
0 ignored issues
show
Bug introduced by
The method invalidName() does not exist on Gacela\Router\Configure\Routes. 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

161
            $routes->/** @scrutinizer ignore-call */ 
162
                     invalidName('', FakeController::class);
Loading history...
162
        });
163
        $router->run();
164
    }
165
166
    /**
167
     * @dataProvider anyHttpMethodProvider
168
     */
169
    public function test_any_http_method(string $httpMethod): void
170
    {
171
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
172
        $_SERVER['REQUEST_METHOD'] = $httpMethod;
173
174
        $this->expectOutputString('Expected!');
175
176
        $router = new Router(static function (Routes $routes): void {
177
            $routes->any('expected/uri', FakeController::class, 'basicAction');
178
        });
179
        $router->run();
180
    }
181
182
    public function anyHttpMethodProvider(): Generator
183
    {
184
        yield ['METHOD_GET' => Request::METHOD_GET];
185
        yield ['METHOD_CONNECT' => Request::METHOD_CONNECT];
186
        yield ['METHOD_DELETE' => Request::METHOD_DELETE];
187
        yield ['METHOD_HEAD' => Request::METHOD_HEAD];
188
        yield ['METHOD_OPTIONS' => Request::METHOD_OPTIONS];
189
        yield ['METHOD_PATCH' => Request::METHOD_PATCH];
190
        yield ['METHOD_POST' => Request::METHOD_POST];
191
        yield ['METHOD_PUT' => Request::METHOD_PUT];
192
        yield ['METHOD_TRACE' => Request::METHOD_TRACE];
193
    }
194
195
    /**
196
     * @dataProvider matchesMethodsProvider
197
     */
198
    public function test_match_matches_all_its_methods(string $testMethod, array $givenMethods): void
199
    {
200
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
201
        $_SERVER['REQUEST_METHOD'] = $testMethod;
202
203
        $this->expectOutputString('Expected!');
204
205
        $router = new Router(static function (Routes $routes) use ($givenMethods): void {
206
            $routes->match($givenMethods, 'expected/uri', FakeController::class, 'basicAction');
207
        });
208
        $router->run();
209
    }
210
211
    public function matchesMethodsProvider(): Generator
212
    {
213
        yield [Request::METHOD_GET, [Request::METHOD_GET, Request::METHOD_POST]];
214
        yield [Request::METHOD_POST, [Request::METHOD_GET, Request::METHOD_POST]];
215
        yield [Request::METHOD_PATCH, [Request::METHOD_PATCH, Request::METHOD_PUT]];
216
        yield [Request::METHOD_PUT, [Request::METHOD_PATCH, Request::METHOD_PUT]];
217
    }
218
}
219