Passed
Push — main ( 13bcd8...97d8ea )
by Chema
54s queued 14s
created

ErrorHandlingTest.php$0 ➔ __invoke()   A

Complexity

Conditions 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
dl 0
loc 4
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GacelaTest\Feature\Router;
6
7
use Exception;
8
use Gacela\Router\Entities\Request;
9
use Gacela\Router\Exceptions\NotFound404Exception;
10
use Gacela\Router\Handlers;
11
use Gacela\Router\Router;
12
use Gacela\Router\Routes;
13
use GacelaTest\Feature\HeaderTestCase;
14
use GacelaTest\Feature\Router\Fixtures\FakeController;
15
use GacelaTest\Feature\Router\Fixtures\FakeControllerWithUnhandledException;
16
use GacelaTest\Feature\Router\Fixtures\UnhandledException;
17
use Generator;
18
19
final class ErrorHandlingTest extends HeaderTestCase
20
{
21
    public function test_respond_404_status_when_uri_does_not_match(): void
22
    {
23
        $_SERVER['REQUEST_URI'] = 'https://example.org/optional/uri';
24
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_OPTIONS;
25
26
        Router::configure(static function (): void {
27
        });
28
29
        self::assertSame([
30
            [
31
                'header' => 'HTTP/1.0 404 Not Found',
32
                'replace' => true,
33
                'response_code' => 0,
34
            ],
35
        ], $this->headers());
36
    }
37
38
    public function test_respond_404_status_when_method_does_not_match(): void
39
    {
40
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
41
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
42
43
        Router::configure(static function (Routes $routes): void {
44
            $routes->post('expected/uri', FakeController::class, 'basicAction');
45
        });
46
47
        self::assertSame([
48
            [
49
                'header' => 'HTTP/1.0 404 Not Found',
50
                'replace' => true,
51
                'response_code' => 0,
52
            ],
53
        ], $this->headers());
54
    }
55
56
    /**
57
     * @dataProvider notMatchesMethodsProvider
58
     */
59
    public function test_respond_404_status_when_not_matches_match_methods(string $testMethod, array $givenMethods): void
60
    {
61
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
62
        $_SERVER['REQUEST_METHOD'] = $testMethod;
63
64
        Router::configure(static function (Routes $routes) use ($givenMethods): void {
65
            $routes->match($givenMethods, 'expected/uri', FakeController::class, 'basicAction');
66
        });
67
68
        self::assertSame([
69
            [
70
                'header' => 'HTTP/1.0 404 Not Found',
71
                'replace' => true,
72
                'response_code' => 0,
73
            ],
74
        ], $this->headers());
75
    }
76
77
    public function notMatchesMethodsProvider(): Generator
78
    {
79
        yield [Request::METHOD_PUT, [Request::METHOD_GET, Request::METHOD_POST]];
80
        yield [Request::METHOD_OPTIONS, [Request::METHOD_GET, Request::METHOD_POST]];
81
        yield [Request::METHOD_GET, [Request::METHOD_PATCH, Request::METHOD_PUT, Request::METHOD_DELETE, Request::METHOD_POST]];
82
        yield [Request::METHOD_CONNECT, [
83
            Request::METHOD_GET, Request::METHOD_DELETE, Request::METHOD_HEAD, Request::METHOD_OPTIONS,
84
            Request::METHOD_PATCH, Request::METHOD_POST, Request::METHOD_PUT, Request::METHOD_TRACE,
85
        ]];
86
    }
87
88
    public function test_respond_500_status_when_unhandled_exception(): void
89
    {
90
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
91
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
92
93
        Router::configure(static function (Routes $routes): void {
94
            $routes->get('expected/uri', FakeControllerWithUnhandledException::class);
95
        });
96
97
        self::assertSame([
98
            [
99
                'header' => 'HTTP/1.1 500 Internal Server Error',
100
                'replace' => true,
101
                'response_code' => 0,
102
            ],
103
        ], $this->headers());
104
    }
105
106
    public function test_handle_handled_exception_with_anonymous_function(): void
107
    {
108
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
109
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
110
111
        Router::configure(static function (Routes $routes, Handlers $handlers): void {
112
            $routes->get('expected/uri', FakeControllerWithUnhandledException::class);
113
114
            $handlers->handle(UnhandledException::class, static function (): string {
115
                \Gacela\Router\header('HTTP/1.1 418 I\'m a teapot');
116
                return 'Handled!';
117
            });
118
        });
119
120
        $this->expectOutputString('Handled!');
121
        self::assertSame([
122
            [
123
                'header' => 'HTTP/1.1 418 I\'m a teapot',
124
                'replace' => true,
125
                'response_code' => 0,
126
            ],
127
        ], $this->headers());
128
    }
129
130
    public function test_custom_404_handler(): void
131
    {
132
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
133
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
134
135
        Router::configure(static function (Handlers $handlers): void {
136
            $handlers->handle(NotFound404Exception::class, static function (): string {
137
                \Gacela\Router\header('HTTP/1.1 418 I\'m a teapot');
138
                return 'Handled!';
139
            });
140
        });
141
142
        $this->expectOutputString('Handled!');
143
        self::assertSame([
144
            [
145
                'header' => 'HTTP/1.1 418 I\'m a teapot',
146
                'replace' => true,
147
                'response_code' => 0,
148
            ],
149
        ], $this->headers());
150
    }
151
152
    public function test_custom_fallback_handler(): void
153
    {
154
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
155
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
156
157
        Router::configure(static function (Handlers $handlers, Routes $routes): void {
158
            $routes->get('expected/uri', FakeControllerWithUnhandledException::class);
159
160
            $handlers->handle(Exception::class, static function (): string {
161
                \Gacela\Router\header('HTTP/1.1 418 I\'m a teapot');
162
                return 'Handled!';
163
            });
164
        });
165
166
        $this->expectOutputString('Handled!');
167
        self::assertSame([
168
            [
169
                'header' => 'HTTP/1.1 418 I\'m a teapot',
170
                'replace' => true,
171
                'response_code' => 0,
172
            ],
173
        ], $this->headers());
174
    }
175
176
    public function test_handle_handled_exception_with_anonymous_class(): void
177
    {
178
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
179
        $_SERVER['REQUEST_METHOD'] = Request::METHOD_GET;
180
181
        Router::configure(static function (Handlers $handlers, Routes $routes): void {
182
            $routes->get('expected/uri', FakeControllerWithUnhandledException::class);
183
184
            $handlers->handle(UnhandledException::class, new class() {
185
                public function __invoke(): string
186
                {
187
                    \Gacela\Router\header('HTTP/1.1 418 I\'m a teapot');
188
                    return 'Handled!';
189
                }
190
            });
191
        });
192
193
        $this->expectOutputString('Handled!');
194
        self::assertSame([
195
            [
196
                'header' => 'HTTP/1.1 418 I\'m a teapot',
197
                'replace' => true,
198
                'response_code' => 0,
199
            ],
200
        ], $this->headers());
201
    }
202
}
203