Passed
Push — main ( 0a89cd...ee99b4 )
by Chema
54s queued 14s
created

RouterMatchTest::test_optional_argument()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 9
rs 10
cc 1
nc 1
nop 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\Routes;
11
use GacelaTest\Unit\Router\Fixtures\FakeController;
12
use Generator;
13
use PHPUnit\Framework\TestCase;
14
15
final class RouterMatchTest extends TestCase
16
{
17
    public function test_respond_when_everything_matches(): void
18
    {
19
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
20
        $_SERVER['REQUEST_METHOD'] = 'GET';
21
22
        $this->expectOutputString('Expected!');
23
24
        Router::configure(static function (Routes $routes): void {
25
            $routes->get('expected/uri', FakeController::class, 'basicAction');
26
        });
27
    }
28
29
    public function test_not_respond_when_the_uri_does_not_matches(): void
30
    {
31
        $_SERVER['REQUEST_URI'] = 'https://example.org/unexpected/uri';
32
        $_SERVER['REQUEST_METHOD'] = 'GET';
33
34
        $this->expectOutputString('');
35
36
        Router::configure(static function (Routes $routes): void {
37
            $routes->get('other/uri', FakeController::class, 'basicAction');
38
        });
39
    }
40
41
    public function test_not_respond_when_the_method_does_not_matches(): void
42
    {
43
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
44
        $_SERVER['REQUEST_METHOD'] = 'GET';
45
46
        $this->expectOutputString('');
47
48
        Router::configure(static function (Routes $routes): void {
49
            $routes->post('expected/uri', FakeController::class, 'basicAction');
50
        });
51
    }
52
53
    public function test_respond_only_the_first_match(): void
54
    {
55
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
56
        $_SERVER['REQUEST_METHOD'] = 'GET';
57
58
        $this->expectOutputString('Expected!');
59
60
        Router::configure(static function (Routes $routes): void {
61
            $routes->get('expected/uri', FakeController::class, 'basicAction');
62
            $routes->get('expected/{param}', FakeController::class, 'stringParamAction');
63
        });
64
    }
65
66
    public function test_optional_argument(): void
67
    {
68
        $_SERVER['REQUEST_URI'] = 'https://example.org/optional';
69
        $_SERVER['REQUEST_METHOD'] = 'GET';
70
71
        $this->expectOutputString('Expected!');
72
73
        Router::configure(static function (Routes $routes): void {
74
            $routes->get('optional/{param?}', FakeController::class, 'basicAction');
75
        });
76
    }
77
78
    public function test_multiple_optional_argument(): void
79
    {
80
        $_SERVER['REQUEST_URI'] = 'https://example.org/optional';
81
        $_SERVER['REQUEST_METHOD'] = 'GET';
82
83
        $this->expectOutputString('Expected!');
84
85
        Router::configure(static function (Routes $routes): void {
86
            $routes->get('optional/{param1?}/{param2?}', FakeController::class, 'basicAction');
87
        });
88
    }
89
90
    public function test_thrown_exception_when_method_does_not_exist(): void
91
    {
92
        $this->expectException(UnsupportedHttpMethodException::class);
93
94
        Router::configure(static function (Routes $routes): void {
95
            $routes->invalidName('', FakeController::class);
0 ignored issues
show
Bug introduced by
The method invalidName() does not exist on Gacela\Router\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

95
            $routes->/** @scrutinizer ignore-call */ 
96
                     invalidName('', FakeController::class);
Loading history...
96
        });
97
    }
98
99
    /**
100
     * @dataProvider anyHttpMethodProvider
101
     */
102
    public function test_any_http_method(string $httpMethod): void
103
    {
104
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
105
        $_SERVER['REQUEST_METHOD'] = $httpMethod;
106
107
        $this->expectOutputString('Expected!');
108
109
        Router::configure(static function (Routes $routes): void {
110
            $routes->any('expected/uri', FakeController::class, 'basicAction');
111
        });
112
    }
113
114
    public function anyHttpMethodProvider(): Generator
115
    {
116
        yield ['METHOD_GET' => Request::METHOD_GET];
117
        yield ['METHOD_CONNECT' => Request::METHOD_CONNECT];
118
        yield ['METHOD_DELETE' => Request::METHOD_DELETE];
119
        yield ['METHOD_HEAD' => Request::METHOD_HEAD];
120
        yield ['METHOD_OPTIONS' => Request::METHOD_OPTIONS];
121
        yield ['METHOD_PATCH' => Request::METHOD_PATCH];
122
        yield ['METHOD_POST' => Request::METHOD_POST];
123
        yield ['METHOD_PUT' => Request::METHOD_PUT];
124
        yield ['METHOD_TRACE' => Request::METHOD_TRACE];
125
    }
126
127
    /**
128
     * @dataProvider matchesMethodsProvider
129
     */
130
    public function test_match_matches_all_its_methods(string $testMethod, array $givenMethods): void
131
    {
132
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
133
        $_SERVER['REQUEST_METHOD'] = $testMethod;
134
135
        $this->expectOutputString('Expected!');
136
137
        Router::configure(static function (Routes $routes) use ($givenMethods): void {
138
            $routes->match($givenMethods, 'expected/uri', FakeController::class, 'basicAction');
139
        });
140
    }
141
142
    public function matchesMethodsProvider(): Generator
143
    {
144
        yield [Request::METHOD_GET, [Request::METHOD_GET, Request::METHOD_POST]];
145
        yield [Request::METHOD_POST, [Request::METHOD_GET, Request::METHOD_POST]];
146
        yield [Request::METHOD_PATCH, [Request::METHOD_PATCH, Request::METHOD_PUT]];
147
        yield [Request::METHOD_PUT, [Request::METHOD_PATCH, Request::METHOD_PUT]];
148
    }
149
150
    /**
151
     * @dataProvider notMatchesMethodsProvider
152
     */
153
    public function test_match_does_not_matches_other_methods(string $testMethod, array $givenMethods): void
154
    {
155
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
156
        $_SERVER['REQUEST_METHOD'] = $testMethod;
157
158
        $this->expectOutputString('');
159
160
        Router::configure(static function (Routes $routes) use ($givenMethods): void {
161
            $routes->match($givenMethods, 'expected/uri', FakeController::class, 'basicAction');
162
        });
163
    }
164
165
    public function notMatchesMethodsProvider(): Generator
166
    {
167
        yield [Request::METHOD_PUT, [Request::METHOD_GET, Request::METHOD_POST]];
168
        yield [Request::METHOD_OPTIONS, [Request::METHOD_GET, Request::METHOD_POST]];
169
        yield [Request::METHOD_GET, [Request::METHOD_PATCH, Request::METHOD_PUT, Request::METHOD_DELETE, Request::METHOD_POST]];
170
        yield [Request::METHOD_CONNECT, [
171
            Request::METHOD_GET, Request::METHOD_DELETE, Request::METHOD_HEAD, Request::METHOD_OPTIONS,
172
            Request::METHOD_PATCH, Request::METHOD_POST, Request::METHOD_PUT, Request::METHOD_TRACE,
173
        ]];
174
    }
175
}
176