Passed
Pull Request — main (#11)
by Chema
02:44
created

RouterMatchTest::test_multiple_optional_argument()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 9
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GacelaTest\Feature\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\Feature\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_method_does_not_matches(): void
30
    {
31
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
32
        $_SERVER['REQUEST_METHOD'] = 'GET';
33
34
        $this->expectOutputString('');
35
36
        Router::configure(static function (Routes $routes): void {
37
            $routes->post('expected/uri', FakeController::class, 'basicAction');
38
        });
39
    }
40
41
    public function test_respond_only_the_first_match(): void
42
    {
43
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
44
        $_SERVER['REQUEST_METHOD'] = 'GET';
45
46
        $this->expectOutputString('Expected!');
47
48
        Router::configure(static function (Routes $routes): void {
49
            $routes->get('expected/uri', FakeController::class, 'basicAction');
50
            $routes->get('expected/{param}', FakeController::class, 'stringParamAction');
51
        });
52
    }
53
54
    public function test_optional_argument(): void
55
    {
56
        $_SERVER['REQUEST_URI'] = 'https://example.org/optional';
57
        $_SERVER['REQUEST_METHOD'] = 'GET';
58
59
        $this->expectOutputString('Expected!');
60
61
        Router::configure(static function (Routes $routes): void {
62
            $routes->get('optional/{param?}', FakeController::class, 'basicAction');
63
        });
64
    }
65
66
    public function test_multiple_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/{param1?}/{param2?}', FakeController::class, 'basicAction');
75
        });
76
    }
77
78
    public function test_thrown_exception_when_method_does_not_exist(): void
79
    {
80
        $this->expectException(UnsupportedHttpMethodException::class);
81
82
        Router::configure(static function (Routes $routes): void {
83
            $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

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