Passed
Pull Request — master (#59)
by Raúl
04:04
created

HttpfulTest::testRawHeaders()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 5
rs 10
1
<?php
2
/**
3
 * Port over the original tests into a more traditional PHPUnit
4
 * format.  Still need to hook into a lightweight HTTP server to
5
 * better test some things (e.g. obscure cURL settings).  I've moved
6
 * the old tests and node.js server to the tests/.legacy directory.
7
 *
8
 * @author Nate Good <[email protected]>
9
 */
10
namespace Httpful\Test;
11
12
require(dirname(dirname(dirname(__FILE__))) . '/bootstrap.php');
13
\Httpful\Bootstrap::init();
14
15
use Httpful\Httpful;
16
use Httpful\Request;
17
use Httpful\Mime;
18
use Httpful\Http;
19
use Httpful\Response;
20
use Httpful\Handlers\JsonHandler;
21
22
define('TEST_SERVER', WEB_SERVER_HOST . ':' . WEB_SERVER_PORT);
0 ignored issues
show
Bug introduced by
The constant Httpful\Test\WEB_SERVER_HOST was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant Httpful\Test\WEB_SERVER_PORT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
23
24
class HttpfulTest extends \PHPUnit_Framework_TestCase
25
{
26
    const TEST_SERVER = TEST_SERVER;
27
    const TEST_URL = 'http://127.0.0.1:8008';
28
    const TEST_URL_400 = 'http://127.0.0.1:8008/400';
29
30
    const SAMPLE_JSON_HEADER =
31
"HTTP/1.1 200 OK
32
Content-Type: application/json
33
Connection: keep-alive
34
Transfer-Encoding: chunked\r\n";
35
    const SAMPLE_JSON_RESPONSE = '{"key":"value","object":{"key":"value"},"array":[1,2,3,4]}';
36
    const SAMPLE_CSV_HEADER =
37
"HTTP/1.1 200 OK
38
Content-Type: text/csv
39
Connection: keep-alive
40
Transfer-Encoding: chunked\r\n";
41
    const SAMPLE_CSV_RESPONSE =
42
"Key1,Key2
43
Value1,Value2
44
\"40.0\",\"Forty\"";
45
    const SAMPLE_XML_RESPONSE = '<stdClass><arrayProp><array><k1><myClass><intProp>2</intProp></myClass></k1></array></arrayProp><stringProp>a string</stringProp><boolProp>TRUE</boolProp></stdClass>';
46
    const SAMPLE_XML_HEADER =
47
"HTTP/1.1 200 OK
48
Content-Type: application/xml
49
Connection: keep-alive
50
Transfer-Encoding: chunked\r\n";
51
    const SAMPLE_VENDOR_HEADER =
52
"HTTP/1.1 200 OK
53
Content-Type: application/vnd.nategood.message+xml
54
Connection: keep-alive
55
Transfer-Encoding: chunked\r\n";
56
    const SAMPLE_VENDOR_TYPE = "application/vnd.nategood.message+xml";
57
    const SAMPLE_MULTI_HEADER =
58
"HTTP/1.1 200 OK
59
Content-Type: application/json
60
Connection: keep-alive
61
Transfer-Encoding: chunked
62
X-My-Header:Value1
63
X-My-Header:Value2\r\n";
64
65
    function testInit()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
66
    {
67
      $r = Request::init();
68
      // Did we get a 'Request' object?
69
      $this->assertEquals('Httpful\Request', get_class($r));
70
    }
71
72
    function testDetermineLength()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
73
    {
74
      $r = Request::init();
75
      $this->assertEquals(1, $r->_determineLength('A'));
76
      $this->assertEquals(2, $r->_determineLength('À'));
77
      $this->assertEquals(2, $r->_determineLength('Ab'));
78
      $this->assertEquals(3, $r->_determineLength('Àb'));
79
      $this->assertEquals(6, $r->_determineLength('世界'));
80
    }
81
82
    function testMethods()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
83
    {
84
      $valid_methods = array('get', 'post', 'delete', 'put', 'options', 'head');
85
      $url = 'http://example.com/';
86
      foreach ($valid_methods as $method) {
87
        $r = call_user_func(array('Httpful\Request', $method), $url);
88
        $this->assertEquals('Httpful\Request', get_class($r));
89
        $this->assertEquals(strtoupper($method), $r->method);
90
      }
91
    }
92
93
    function testDefaults()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
94
    {
95
        // Our current defaults are as follows
96
        $r = Request::init();
97
        $this->assertEquals(Http::GET, $r->method);
98
        $this->assertFalse($r->strict_ssl);
99
    }
100
101
    function testShortMime()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
102
    {
103
        // Valid short ones
104
        $this->assertEquals(Mime::JSON,  Mime::getFullMime('json'));
105
        $this->assertEquals(Mime::XML,   Mime::getFullMime('xml'));
106
        $this->assertEquals(Mime::HTML,  Mime::getFullMime('html'));
107
        $this->assertEquals(Mime::CSV,  Mime::getFullMime('csv'));
108
        $this->assertEquals(Mime::UPLOAD,  Mime::getFullMime('upload'));
109
110
        // Valid long ones
111
        $this->assertEquals(Mime::JSON, Mime::getFullMime(Mime::JSON));
112
        $this->assertEquals(Mime::XML,  Mime::getFullMime(Mime::XML));
113
        $this->assertEquals(Mime::HTML, Mime::getFullMime(Mime::HTML));
114
        $this->assertEquals(Mime::CSV, Mime::getFullMime(Mime::CSV));
115
        $this->assertEquals(Mime::UPLOAD, Mime::getFullMime(Mime::UPLOAD));
116
117
        // No false positives
118
        $this->assertNotEquals(Mime::XML,  Mime::getFullMime(Mime::HTML));
119
        $this->assertNotEquals(Mime::JSON, Mime::getFullMime(Mime::XML));
120
        $this->assertNotEquals(Mime::HTML, Mime::getFullMime(Mime::JSON));
121
        $this->assertNotEquals(Mime::XML, Mime::getFullMime(Mime::CSV));
122
    }
123
124
    function testSettingStrictSsl()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
125
    {
126
        $r = Request::init()
127
             ->withStrictSsl();
128
129
        $this->assertTrue($r->strict_ssl);
130
131
        $r = Request::init()
132
             ->withoutStrictSsl();
133
134
        $this->assertFalse($r->strict_ssl);
135
    }
136
137
    function testSendsAndExpectsType()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
138
    {
139
        $r = Request::init()
140
            ->sendsAndExpectsType(Mime::JSON);
141
        $this->assertEquals(Mime::JSON, $r->expected_type);
142
        $this->assertEquals(Mime::JSON, $r->content_type);
143
144
        $r = Request::init()
145
            ->sendsAndExpectsType('html');
146
        $this->assertEquals(Mime::HTML, $r->expected_type);
147
        $this->assertEquals(Mime::HTML, $r->content_type);
148
149
        $r = Request::init()
150
            ->sendsAndExpectsType('form');
151
        $this->assertEquals(Mime::FORM, $r->expected_type);
152
        $this->assertEquals(Mime::FORM, $r->content_type);
153
154
        $r = Request::init()
155
            ->sendsAndExpectsType('application/x-www-form-urlencoded');
156
        $this->assertEquals(Mime::FORM, $r->expected_type);
157
        $this->assertEquals(Mime::FORM, $r->content_type);
158
159
        $r = Request::init()
160
            ->sendsAndExpectsType(Mime::CSV);
161
        $this->assertEquals(Mime::CSV, $r->expected_type);
162
        $this->assertEquals(Mime::CSV, $r->content_type);
163
    }
164
165
    function testIni()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
166
    {
167
        // Test setting defaults/templates
168
169
        // Create the template
170
        $template = Request::init()
171
            ->method(Http::POST)
172
            ->withStrictSsl()
173
            ->expectsType(Mime::HTML)
174
            ->sendsType(Mime::FORM);
175
176
        Request::ini($template);
177
178
        $r = Request::init();
179
180
        $this->assertTrue($r->strict_ssl);
181
        $this->assertEquals(Http::POST, $r->method);
182
        $this->assertEquals(Mime::HTML, $r->expected_type);
183
        $this->assertEquals(Mime::FORM, $r->content_type);
184
185
        // Test the default accessor as well
186
        $this->assertTrue(Request::d('strict_ssl'));
187
        $this->assertEquals(Http::POST, Request::d('method'));
188
        $this->assertEquals(Mime::HTML, Request::d('expected_type'));
189
        $this->assertEquals(Mime::FORM, Request::d('content_type'));
190
191
        Request::resetIni();
192
    }
193
194
    function testAccept()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
195
    {
196
        $r = Request::get('http://example.com/')
197
            ->expectsType(Mime::JSON);
198
199
        $this->assertEquals(Mime::JSON, $r->expected_type);
200
        $r->_curlPrep();
201
        $this->assertContains('application/json', $r->raw_headers);
202
    }
203
204
    function testCustomAccept()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
205
    {
206
        $accept = 'application/api-1.0+json';
207
        $r = Request::get('http://example.com/')
208
            ->addHeader('Accept', $accept);
209
210
        $r->_curlPrep();
211
        $this->assertContains($accept, $r->raw_headers);
212
        $this->assertEquals($accept, $r->headers['Accept']);
213
    }
214
215
    function testUserAgent()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
216
    {
217
        $r = Request::get('http://example.com/')
218
            ->withUserAgent('ACME/1.2.3');
219
220
        $this->assertArrayHasKey('User-Agent', $r->headers);
221
        $r->_curlPrep();
222
        $this->assertContains('User-Agent: ACME/1.2.3', $r->raw_headers);
223
        $this->assertNotContains('User-Agent: HttpFul/1.0', $r->raw_headers);
224
225
        $r = Request::get('http://example.com/')
226
            ->withUserAgent('');
227
228
        $this->assertArrayHasKey('User-Agent', $r->headers);
229
        $r->_curlPrep();
230
        $this->assertContains('User-Agent:', $r->raw_headers);
231
        $this->assertNotContains('User-Agent: HttpFul/1.0', $r->raw_headers);
232
    }
233
234
    function testAuthSetup()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
235
    {
236
        $username = 'nathan';
237
        $password = 'opensesame';
238
239
        $r = Request::get('http://example.com/')
240
            ->authenticateWith($username, $password);
241
242
        $this->assertEquals($username, $r->username);
243
        $this->assertEquals($password, $r->password);
244
        $this->assertTrue($r->hasBasicAuth());
245
    }
246
247
    function testDigestAuthSetup()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
248
    {
249
        $username = 'nathan';
250
        $password = 'opensesame';
251
252
        $r = Request::get('http://example.com/')
253
            ->authenticateWithDigest($username, $password);
254
255
        $this->assertEquals($username, $r->username);
256
        $this->assertEquals($password, $r->password);
257
        $this->assertTrue($r->hasDigestAuth());
258
    }
259
260
    function testJsonResponseParse()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
261
    {
262
        $req = Request::init()->sendsAndExpects(Mime::JSON);
263
        $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req);
264
265
        $this->assertEquals("value", $response->body->key);
266
        $this->assertEquals("value", $response->body->object->key);
267
        $this->assertInternalType('array', $response->body->array);
268
        $this->assertEquals(1, $response->body->array[0]);
269
    }
270
271
    function testXMLResponseParse()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
272
    {
273
        $req = Request::init()->sendsAndExpects(Mime::XML);
274
        $response = new Response(self::SAMPLE_XML_RESPONSE, self::SAMPLE_XML_HEADER, $req);
275
        $sxe = $response->body;
276
        $this->assertEquals("object", gettype($sxe));
277
        $this->assertEquals("SimpleXMLElement", get_class($sxe));
278
        $bools = $sxe->xpath('/stdClass/boolProp');
279
        list( , $bool ) = each($bools);
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

279
        list( , $bool ) = /** @scrutinizer ignore-deprecated */ each($bools);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
280
        $this->assertEquals("TRUE", (string) $bool);
281
        $ints = $sxe->xpath('/stdClass/arrayProp/array/k1/myClass/intProp');
282
        list( , $int ) = each($ints);
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

282
        list( , $int ) = /** @scrutinizer ignore-deprecated */ each($ints);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
283
        $this->assertEquals("2", (string) $int);
284
        $strings = $sxe->xpath('/stdClass/stringProp');
285
        list( , $string ) = each($strings);
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

285
        list( , $string ) = /** @scrutinizer ignore-deprecated */ each($strings);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
286
        $this->assertEquals("a string", (string) $string);
287
    }
288
289
    function testCsvResponseParse()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
290
    {
291
        $req = Request::init()->sendsAndExpects(Mime::CSV);
292
        $response = new Response(self::SAMPLE_CSV_RESPONSE, self::SAMPLE_CSV_HEADER, $req);
293
294
        $this->assertEquals("Key1", $response->body[0][0]);
295
        $this->assertEquals("Value1", $response->body[1][0]);
296
        $this->assertInternalType('string', $response->body[2][0]);
297
        $this->assertEquals("40.0", $response->body[2][0]);
298
    }
299
300
    function testParsingContentTypeCharset()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
301
    {
302
        $req = Request::init()->sendsAndExpects(Mime::JSON);
303
        // $response = new Response(SAMPLE_JSON_RESPONSE, "", $req);
304
        // // Check default content type of iso-8859-1
305
        $response = new Response(self::SAMPLE_JSON_RESPONSE, "HTTP/1.1 200 OK
306
Content-Type: text/plain; charset=utf-8\r\n", $req);
307
        $this->assertInstanceOf('Httpful\Response\Headers', $response->headers);
308
        $this->assertEquals($response->headers['Content-Type'], 'text/plain; charset=utf-8');
309
        $this->assertEquals($response->content_type, 'text/plain');
310
        $this->assertEquals($response->charset, 'utf-8');
311
    }
312
313
    function testParsingContentTypeUpload()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
314
    {
315
        $req = Request::init();
316
317
        $req->sendsType(Mime::UPLOAD);
318
        // $response = new Response(SAMPLE_JSON_RESPONSE, "", $req);
319
        // // Check default content type of iso-8859-1
320
        $this->assertEquals($req->content_type, 'multipart/form-data');
321
    }
322
323
    function testAttach() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
324
        $req = Request::init();
325
        $testsPath = realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..');
326
        $filename = $testsPath . DIRECTORY_SEPARATOR . 'test_image.jpg';
327
        $req->attach(array('index' => $filename));
328
        $payload = $req->payload['index'];
329
        // PHP 5.5  + will take advantage of CURLFile while previous
330
        // versions just use the string syntax
331
        if (is_string($payload)) {
332
            $this->assertEquals($payload, '@' . $filename . ';type=image/jpeg');
333
        } else {
334
            $this->assertInstanceOf('CURLFile', $payload);
335
        }
336
337
        $this->assertEquals($req->content_type, Mime::UPLOAD);
338
        $this->assertEquals($req->serialize_payload_method, Request::SERIALIZE_PAYLOAD_NEVER);
339
    }
340
341
    function testIsUpload() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
342
        $req = Request::init();
343
344
        $req->sendsType(Mime::UPLOAD);
345
346
        $this->assertTrue($req->isUpload());
347
    }
348
349
    function testEmptyResponseParse()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
350
    {
351
        $req = Request::init()->sendsAndExpects(Mime::JSON);
352
        $response = new Response("", self::SAMPLE_JSON_HEADER, $req);
353
        $this->assertEquals(null, $response->body);
354
355
        $reqXml = Request::init()->sendsAndExpects(Mime::XML);
356
        $responseXml = new Response("", self::SAMPLE_XML_HEADER, $reqXml);
357
        $this->assertEquals(null, $responseXml->body);
358
    }
359
360
    function testNoAutoParse()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
361
    {
362
        $req = Request::init()->sendsAndExpects(Mime::JSON)->withoutAutoParsing();
363
        $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req);
364
        $this->assertInternalType('string', $response->body);
365
        $req = Request::init()->sendsAndExpects(Mime::JSON)->withAutoParsing();
366
        $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req);
367
        $this->assertInternalType('object', $response->body);
368
    }
369
370
    function testParseHeaders()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
371
    {
372
        $req = Request::init()->sendsAndExpects(Mime::JSON);
373
        $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req);
374
        $this->assertEquals('application/json', $response->headers['Content-Type']);
375
    }
376
377
    function testRawHeaders()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
378
    {
379
        $req = Request::init()->sendsAndExpects(Mime::JSON);
380
        $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req);
381
        $this->assertContains('Content-Type: application/json', $response->raw_headers);
382
    }
383
384
    function testHasErrors()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
385
    {
386
        $req = Request::init()->sendsAndExpects(Mime::JSON);
387
        $response = new Response('', "HTTP/1.1 100 Continue\r\n", $req);
388
        $this->assertFalse($response->hasErrors());
389
        $response = new Response('', "HTTP/1.1 200 OK\r\n", $req);
390
        $this->assertFalse($response->hasErrors());
391
        $response = new Response('', "HTTP/1.1 300 Multiple Choices\r\n", $req);
392
        $this->assertFalse($response->hasErrors());
393
        $response = new Response('', "HTTP/1.1 400 Bad Request\r\n", $req);
394
        $this->assertTrue($response->hasErrors());
395
        $response = new Response('', "HTTP/1.1 500 Internal Server Error\r\n", $req);
396
        $this->assertTrue($response->hasErrors());
397
    }
398
399
    function testWhenError() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
400
        $caught = false;
401
402
        try {
403
            Request::get('malformed:url')
404
                ->whenError(function($error) use(&$caught) {
405
                    $caught = true;
406
                })
407
                ->timeoutIn(0.1)
408
                ->send();
409
        } catch (\Httpful\Exception\ConnectionErrorException $e) {}
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
410
411
        $this->assertTrue($caught);
412
    }
413
414
    function testBeforeSend() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
415
        $invoked = false;
416
        $changed = false;
417
        $self = $this;
418
419
        try {
420
            Request::get('malformed://url')
421
                ->beforeSend(function($request) use(&$invoked,$self) {
422
                    $self->assertEquals('malformed://url', $request->uri);
423
                    $self->assertEquals('A payload', $request->serialized_payload);
424
                    $request->uri('malformed2://url');
425
                    $invoked = true;
426
                })
427
                ->whenError(function($error) { /* Be silent */ })
428
                ->body('A payload')
429
                ->send();
430
        } catch (\Httpful\Exception\ConnectionErrorException $e) {
431
            $this->assertTrue(strpos($e->getMessage(), 'malformed2') !== false);
432
            $changed = true;
433
        }
434
435
        $this->assertTrue($invoked);
436
        $this->assertTrue($changed);
437
    }
438
439
    function test_parseCode()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
440
    {
441
        $req = Request::init()->sendsAndExpects(Mime::JSON);
442
        $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req);
443
        $code = $response->_parseCode("HTTP/1.1 406 Not Acceptable\r\n");
444
        $this->assertEquals(406, $code);
445
    }
446
447
    function testToString()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
448
    {
449
        $req = Request::init()->sendsAndExpects(Mime::JSON);
450
        $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req);
451
        $this->assertEquals(self::SAMPLE_JSON_RESPONSE, (string)$response);
452
    }
453
454
    function test_parseHeaders()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
455
    {
456
        $parse_headers = Response\Headers::fromString(self::SAMPLE_JSON_HEADER);
457
        $this->assertCount(3, $parse_headers);
458
        $this->assertEquals('application/json', $parse_headers['Content-Type']);
459
        $this->assertTrue(isset($parse_headers['Connection']));
460
    }
461
462
    function testMultiHeaders()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
463
    {
464
        $req = Request::init();
465
        $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_MULTI_HEADER, $req);
466
        $parse_headers = $response->_parseHeaders(self::SAMPLE_MULTI_HEADER);
467
        $this->assertEquals('Value1,Value2', $parse_headers['X-My-Header']);
468
    }
469
470
    function testDetectContentType()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
471
    {
472
        $req = Request::init();
473
        $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req);
474
        $this->assertEquals('application/json', $response->headers['Content-Type']);
475
    }
476
477
    function testMissingBodyContentType()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
478
    {
479
        $body = 'A string';
480
        $request = Request::post(HttpfulTest::TEST_URL, $body)->_curlPrep();
481
        $this->assertEquals($body, $request->serialized_payload);
482
    }
483
484
    function testParentType()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
485
    {
486
        // Parent type
487
        $request = Request::init()->sendsAndExpects(Mime::XML);
488
        $response = new Response('<xml><name>Nathan</name></xml>', self::SAMPLE_VENDOR_HEADER, $request);
489
490
        $this->assertEquals("application/xml", $response->parent_type);
491
        $this->assertEquals(self::SAMPLE_VENDOR_TYPE, $response->content_type);
492
        $this->assertTrue($response->is_mime_vendor_specific);
493
494
        // Make sure we still parsed as if it were plain old XML
495
        $this->assertEquals("Nathan", $response->body->name->__toString());
496
    }
497
498
    function testMissingContentType()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
499
    {
500
        // Parent type
501
        $request = Request::init()->sendsAndExpects(Mime::XML);
502
        $response = new Response('<xml><name>Nathan</name></xml>',
503
"HTTP/1.1 200 OK
504
Connection: keep-alive
505
Transfer-Encoding: chunked\r\n", $request);
506
507
        $this->assertEquals("", $response->content_type);
508
    }
509
510
    function testCustomMimeRegistering()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
511
    {
512
        // Register new mime type handler for "application/vnd.nategood.message+xml"
513
        Httpful::register(self::SAMPLE_VENDOR_TYPE, new DemoMimeHandler());
514
515
        $this->assertTrue(Httpful::hasParserRegistered(self::SAMPLE_VENDOR_TYPE));
516
517
        $request = Request::init();
518
        $response = new Response('<xml><name>Nathan</name></xml>', self::SAMPLE_VENDOR_HEADER, $request);
519
520
        $this->assertEquals(self::SAMPLE_VENDOR_TYPE, $response->content_type);
521
        $this->assertEquals('custom parse', $response->body);
522
    }
523
524
    public function testShorthandMimeDefinition()
525
    {
526
        $r = Request::init()->expects('json');
527
        $this->assertEquals(Mime::JSON, $r->expected_type);
528
529
        $r = Request::init()->expectsJson();
530
        $this->assertEquals(Mime::JSON, $r->expected_type);
531
    }
532
533
    public function testOverrideXmlHandler()
534
    {
535
        // Lazy test...
536
        $prev = \Httpful\Httpful::get(\Httpful\Mime::XML);
537
        $this->assertEquals($prev, new \Httpful\Handlers\XmlHandler());
538
        $conf = array('namespace' => 'http://example.com');
539
        \Httpful\Httpful::register(\Httpful\Mime::XML, new \Httpful\Handlers\XmlHandler($conf));
540
        $new = \Httpful\Httpful::get(\Httpful\Mime::XML);
541
        $this->assertNotEquals($prev, $new);
542
    }
543
544
    public function testHasProxyWithoutProxy()
545
    {
546
        $r = Request::get('someUrl');
547
        $this->assertFalse($r->hasProxy());
548
    }
549
550
    public function testHasProxyWithProxy()
551
    {
552
        $r = Request::get('some_other_url');
553
        $r->useProxy('proxy.com');
554
        $this->assertTrue($r->hasProxy());
555
    }
556
557
    public function testParseJSON()
558
    {
559
        $handler = new JsonHandler();
560
561
        $bodies = array(
562
            'foo',
563
            array(),
564
            array('foo', 'bar'),
565
            null
566
        );
567
        foreach ($bodies as $body) {
568
            $this->assertEquals($body, $handler->parse(json_encode($body)));
569
        }
570
571
        try {
572
            $result = $handler->parse('invalid{json');
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
573
        } catch(\Exception $e) {
574
            $this->assertEquals('Unable to parse response as JSON', $e->getMessage());
575
            return;
576
        }
577
        $this->fail('Expected an exception to be thrown due to invalid json');
578
    }
579
580
    // /**
581
    //  * Skeleton for testing against the 5.4 baked in server
582
    //  */
583
    // public function testLocalServer()
584
    // {
585
    //     if (!defined('WITHOUT_SERVER') || (defined('WITHOUT_SERVER') && !WITHOUT_SERVER)) {
586
    //         // PHP test server seems to always set content type to application/octet-stream
587
    //         // so force parsing as JSON here
588
    //         Httpful::register('application/octet-stream', new \Httpful\Handlers\JsonHandler());
589
    //         $response = Request::get(TEST_SERVER . '/test.json')
590
    //             ->sendsAndExpects(MIME::JSON);
591
    //         $response->send();
592
    //         $this->assertTrue(...);
593
    //     }
594
    // }
595
}
596
597
class DemoMimeHandler extends \Httpful\Handlers\MimeHandlerAdapter
598
{
599
    public function parse($body)
600
    {
601
        return 'custom parse';
602
    }
603
}
604
605