Passed
Pull Request — master (#17)
by Mihail
15:10
created

ServerRequestTest::test_defaults()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
cc 1
eloc 18
c 2
b 0
f 2
nc 1
nop 0
dl 0
loc 26
rs 9.6666
1
<?php
2
3
namespace Tests\Koded\Http;
4
5
use Koded\Http\Interfaces\HttpMethod;
6
use Koded\Http\ServerRequest;
7
use Koded\Http\Uri;
8
use Koded\Stdlib\Arguments;
9
use PHPUnit\Framework\TestCase;
10
use Psr\Http\Message\UriInterface;
11
12
class ServerRequestTest extends TestCase
13
{
14
    use AssertionTestSupportTrait;
15
16
    private ServerRequest $SUT;
17
18
    public function test_defaults()
19
    {
20
        $this->assertSame('POST', $this->SUT->getMethod());
21
22
        $serverSoftwareValue = $this->getObjectProperty($this->SUT, 'serverSoftware');
23
        $this->assertSame('', $serverSoftwareValue);
24
25
        // makes a difference
26
        $this->assertSame('/', $this->SUT->getPath(), 'Much useful and predictable for real life apps');
27
        $this->assertSame('', $this->SUT->getUri()->getPath(), 'Weird PSR-7 rule satisfied');
28
29
        $this->assertSame('http://example.org:8080', $this->SUT->getBaseUri());
30
        $this->assertFalse($this->SUT->isXHR());
31
        $this->assertSame('1.1', $this->SUT->getProtocolVersion());
32
33
        $this->assertSame([], $this->SUT->getAttributes());
34
        $this->assertSame([], $this->SUT->getQueryParams());
35
        $this->assertSame(['test' => 'fubar'], $this->SUT->getCookieParams());
36
        $this->assertSame([], $this->SUT->getUploadedFiles());
37
        $this->assertNull($this->SUT->getParsedBody());
38
        $this->assertTrue(count($this->SUT->getHeaders()) > 0);
39
        $this->assertSame($_SERVER, $this->SUT->getServerParams());
40
41
        $this->assertSame('', $this->SUT->getHeaderLine('Content-type'));
42
        $this->assertFalse($this->SUT->hasHeader('content-type'),
43
            'Content-type can be explicitly set in the request headers');
44
    }
45
46
    public function test_server_uri_value()
47
    {
48
        $_SERVER['REQUEST_URI'] = 'https://example.org';
49
50
        $request = new ServerRequest;
51
        $this->assertSame('https://example.org', (string)$request->getUri());
52
    }
53
54
    public function test_should_handle_arguments()
55
    {
56
        $this->assertNull($this->SUT->getAttribute('foo'));
57
58
        $request = $this->SUT->withAttribute('foo', 'bar');
59
        $this->assertSame('bar', $request->getAttribute('foo'));
60
        $this->assertNotSame($request, $this->SUT);
61
62
        $request = $request->withoutAttribute('foo');
63
        $this->assertNull($request->getAttribute('foo'));
64
    }
65
66
    public function test_query_array()
67
    {
68
        $request = $this->SUT->withQueryParams(['foo' => 'bar']);
69
        $this->assertSame(['foo' => 'bar'], $request->getQueryParams());
70
        $this->assertNotSame($request, $this->SUT);
71
72
        $request = $request->withQueryParams(['a' => 123]);
73
        $this->assertSame(['foo' => 'bar', 'a' => 123], $request->getQueryParams());
74
    }
75
76
    public function test_parsed_body_with_null_value()
77
    {
78
        $request = $this->SUT->withParsedBody(null);
79
        $this->assertNull($request->getParsedBody(), 'Indicates absence of body content');
80
    }
81
82
    public function test_parsed_body_with_array_data()
83
    {
84
        $request = $this->SUT->withParsedBody(['foo' => 'bar']);
85
        $this->assertSame(['foo' => 'bar'], $request->getParsedBody());
86
    }
87
88
    public function test_parsed_body_with_iterable_value()
89
    {
90
        $request = $this->SUT->withParsedBody(new Arguments(['foo' => 'bar']));
91
        $this->assertSame(['foo' => 'bar'], $request->getParsedBody());
92
93
        return $request;
94
    }
95
96
    /**
97
     * @depends test_parsed_body_with_iterable_value
98
     *
99
     * @param ServerRequest $request
100
     */
101
    public function test_parsed_body_with_post_and_content_type(ServerRequest $request)
102
    {
103
        $_POST   = ['accept', 'this'];
104
        $request = $request->withHeader('Content-type', 'application/x-www-form-urlencoded; charset=utf-8');
105
106
        $request = $request->withParsedBody(['ignored', 'values']);
107
        $this->assertSame($_POST, $request->getParsedBody(),
108
            'Supplied data is ignored per spec (Content-Type)');
109
    }
110
111
    public function test_parsed_body_throws_exception_on_unsupported_values()
112
    {
113
        $this->expectException(\InvalidArgumentException::class);
114
        $this->expectExceptionMessage('Unsupported data provided (string), Expects NULL, array or iterable');
115
        $this->SUT->withParsedBody('junk');
116
    }
117
118
    public function test_return_posted_body()
119
    {
120
        $_SERVER['HTTP_CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
121
        $_POST                        = ['key' => 'value'];
122
123
        $request = new ServerRequest;
124
        $this->assertSame($_POST, $request->getParsedBody(),
125
            'Returns the _POST array');
126
    }
127
128
    public function test_return_posted_body_with_parsed_body()
129
    {
130
        $_SERVER['HTTP_CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
131
        $_POST                        = ['key' => 'value'];
132
133
        $request  = new ServerRequest;
134
        $actual = $request->withParsedBody(['key' => 'value']);
135
136
        $this->assertNotSame($request, $actual,
137
            'Response objects are immutable');
138
    }
139
140
    public function test_put_method_should_parse_the_php_input()
141
    {
142
        $_SERVER['REQUEST_METHOD'] = 'PUT';
143
        $_POST                     = ['foo' => 'bar'];
144
145
        $request = new ServerRequest;
146
        $this->assertSame(['foo' => 'bar'], $request->getParsedBody());
147
    }
148
149
    public function test_extra_methods()
150
    {
151
        $this->assertFalse($this->SUT->isXHR());
152
        $this->assertFalse($this->SUT->isSafeMethod());
153
        $this->assertFalse($this->SUT->isSecure());
154
    }
155
156
    public function test_should_create_uri_instance_without_server_name_or_address()
157
    {
158
        unset($_SERVER['SERVER_NAME'], $_SERVER['SERVER_ADDR']);
159
        $request = new ServerRequest;
160
        $this->assertInstanceOf(UriInterface::class, $request->getUri());
161
    }
162
163
    public function test_should_set_host_header_from_uri_instance()
164
    {
165
        unset($_SERVER['SERVER_NAME'], $_SERVER['SERVER_ADDR'], $_SERVER['HTTP_HOST']);
166
167
        $request = new ServerRequest;
168
        $this->assertSame([], $request->getHeader('host'));
169
170
        $request = $request->withUri(new Uri('http://example.org/'));
171
        $this->assertSame(['example.org'], $request->getHeader('host'));
172
    }
173
174
    public function test_should_return_empty_baseuri_if_host_is_unknown()
175
    {
176
        unset($_SERVER['SERVER_NAME'], $_SERVER['SERVER_ADDR'], $_SERVER['HTTP_HOST']);
177
178
        $request = new ServerRequest;
179
        $this->assertSame('', $request->getBaseUri());
180
    }
181
182
    public function test_should_add_object_attributes()
183
    {
184
        $request = new ServerRequest(['foo' => 'bar']);
185
        $this->assertSame(['foo' => 'bar'], $request->getAttributes());
186
187
        $new = $request->withAttributes(['qux' => 'zim']);
188
        $this->assertSame(['foo' => 'bar', 'qux' => 'zim'], $new->getAttributes());
189
    }
190
191
    public function test_should_replace_cookies()
192
    {
193
        $_COOKIE = [
194
            'testcookie' => 'value',
195
            'logged'     => '0'
196
        ];
197
198
        $request = new ServerRequest;
199
        $this->assertSame($_COOKIE, $request->getCookieParams());
200
201
        $request = $request->withCookieParams(['logged' => '1']);
202
        $this->assertSame(['logged' => '1'], $request->getCookieParams());
203
    }
204
205
    public function test_parsed_body_if_method_is_post_with_provided_form_data()
206
    {
207
        $_POST = ['foo' => 'bar'];
208
        $this->setUp();
209
        $request = $this->SUT->withHeader('Content-Type', 'application/x-www-form-urlencoded');
210
211
        $this->assertSame($request->getParsedBody(), $_POST);
212
    }
213
214
    public function test_parsed_body_for_unsafe_method_with_json_data()
215
    {
216
        $_SERVER['REQUEST_METHOD'] = 'PUT';
217
218
        $request = new class extends ServerRequest
219
        {
220
            protected function getRawInput(): string
221
            {
222
                return '{"key":"value"}';
223
            }
224
        };
225
226
        $this->assertEquals(['key' => 'value'], $request->getParsedBody());
227
    }
228
229
    public function test_parsed_body_for_unsafe_method_with_urlencoded_data()
230
    {
231
        $_SERVER['REQUEST_METHOD'] = 'DELETE';
232
233
        $request = new class extends ServerRequest
234
        {
235
            protected function getRawInput(): string
236
            {
237
                return 'foo=bar';
238
            }
239
        };
240
241
        $this->assertEquals(['foo' => 'bar'], $request->getParsedBody());
242
    }
243
244
    public function test_parsed_body_for_unsafe_method_with_xml_data()
245
    {
246
        $_SERVER['REQUEST_METHOD'] = 'PATCH';
247
248
        $request = new class extends ServerRequest
249
        {
250
            protected function getRawInput(): string
251
            {
252
                return '<?xml version="1.0" encoding="UTF-8"?><doc><key>value</key></doc>';
253
            }
254
        };
255
256
        $this->assertEquals(['key' => 'value'], $request->getParsedBody());
257
    }
258
259
    public function test_headers_with_content_type_json()
260
    {
261
        $_SERVER['CONTENT_TYPE'] = 'application/json';
262
263
        $request = new ServerRequest;
264
        $this->assertEquals(
265
            'application/json',
266
            $request->getHeaderLine('content-type')
267
        );
268
    }
269
270
    protected function setUp(): void
271
    {
272
        $_SERVER['REQUEST_METHOD']  = 'POST';
273
        $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
274
        $_SERVER['SERVER_NAME']     = 'example.org';
275
        $_SERVER['SERVER_PORT']     = 8080;
276
        $_SERVER['REQUEST_URI']     = '';
277
        $_SERVER['SCRIPT_FILENAME'] = '/index.php';
278
279
        $_SERVER['HTTP_HOST']          = 'example.org';
280
        $_SERVER['HTTP_IF_NONE_MATCH'] = '0163b37c-08e0-46f8-9aec-f31991bf6078-gzip';
281
282
        $this->SUT = new ServerRequest;
283
    }
284
285
    protected function tearDown(): void
286
    {
287
        unset($_SERVER['HTTP_X_REQUESTED_WITH']);
288
        unset($_SERVER['HTTP_SEC_FETCH_MODE']);
289
290
        $_SERVER['REQUEST_METHOD'] = 'POST';
291
        $_SERVER['REQUEST_URI']    = '';
292
293
        $_POST     = [];
294
        unset($this->SUT);
295
    }
296
}
297