[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
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 21 class HttpfulTest extends \PHPUnit_Framework_TestCase 22 { 23 const TEST_SERVER = '127.0.0.1:8008'; 24 const TEST_URL = 'http://127.0.0.1:8008'; 25 const TEST_URL_400 = 'http://127.0.0.1:8008/400'; 26 27 const SAMPLE_JSON_HEADER = 28 "HTTP/1.1 200 OK 29 Content-Type: application/json 30 Connection: keep-alive 31 Transfer-Encoding: chunked\r\n"; 32 const SAMPLE_JSON_RESPONSE = '{"key":"value","object":{"key":"value"},"array":[1,2,3,4]}'; 33 const SAMPLE_CSV_HEADER = 34 "HTTP/1.1 200 OK 35 Content-Type: text/csv 36 Connection: keep-alive 37 Transfer-Encoding: chunked\r\n"; 38 const SAMPLE_CSV_RESPONSE = 39 "Key1,Key2 40 Value1,Value2 41 \"40.0\",\"Forty\""; 42 const SAMPLE_XML_RESPONSE = '<stdClass><arrayProp><array><k1><myClass><intProp>2</intProp></myClass></k1></array></arrayProp><stringProp>a string</stringProp><boolProp>TRUE</boolProp></stdClass>'; 43 const SAMPLE_XML_HEADER = 44 "HTTP/1.1 200 OK 45 Content-Type: application/xml 46 Connection: keep-alive 47 Transfer-Encoding: chunked\r\n"; 48 const SAMPLE_VENDOR_HEADER = 49 "HTTP/1.1 200 OK 50 Content-Type: application/vnd.nategood.message+xml 51 Connection: keep-alive 52 Transfer-Encoding: chunked\r\n"; 53 const SAMPLE_VENDOR_TYPE = "application/vnd.nategood.message+xml"; 54 const SAMPLE_MULTI_HEADER = 55 "HTTP/1.1 200 OK 56 Content-Type: application/json 57 Connection: keep-alive 58 Transfer-Encoding: chunked 59 X-My-Header:Value1 60 X-My-Header:Value2\r\n"; 61 function testInit() 62 { 63 $r = Request::init(); 64 // Did we get a 'Request' object? 65 $this->assertEquals('Httpful\Request', get_class($r)); 66 } 67 68 function testMethods() 69 { 70 $valid_methods = array('get', 'post', 'delete', 'put', 'options', 'head'); 71 $url = 'http://example.com/'; 72 foreach ($valid_methods as $method) { 73 $r = call_user_func(array('Httpful\Request', $method), $url); 74 $this->assertEquals('Httpful\Request', get_class($r)); 75 $this->assertEquals(strtoupper($method), $r->method); 76 } 77 } 78 79 function testDefaults() 80 { 81 // Our current defaults are as follows 82 $r = Request::init(); 83 $this->assertEquals(Http::GET, $r->method); 84 $this->assertFalse($r->strict_ssl); 85 } 86 87 function testShortMime() 88 { 89 // Valid short ones 90 $this->assertEquals(Mime::JSON, Mime::getFullMime('json')); 91 $this->assertEquals(Mime::XML, Mime::getFullMime('xml')); 92 $this->assertEquals(Mime::HTML, Mime::getFullMime('html')); 93 $this->assertEquals(Mime::CSV, Mime::getFullMime('csv')); 94 95 // Valid long ones 96 $this->assertEquals(Mime::JSON, Mime::getFullMime(Mime::JSON)); 97 $this->assertEquals(Mime::XML, Mime::getFullMime(Mime::XML)); 98 $this->assertEquals(Mime::HTML, Mime::getFullMime(Mime::HTML)); 99 $this->assertEquals(Mime::CSV, Mime::getFullMime(Mime::CSV)); 100 101 // No false positives 102 $this->assertNotEquals(Mime::XML, Mime::getFullMime(Mime::HTML)); 103 $this->assertNotEquals(Mime::JSON, Mime::getFullMime(Mime::XML)); 104 $this->assertNotEquals(Mime::HTML, Mime::getFullMime(Mime::JSON)); 105 $this->assertNotEquals(Mime::XML, Mime::getFullMime(Mime::CSV)); 106 } 107 108 function testSettingStrictSsl() 109 { 110 $r = Request::init() 111 ->withStrictSsl(); 112 113 $this->assertTrue($r->strict_ssl); 114 115 $r = Request::init() 116 ->withoutStrictSsl(); 117 118 $this->assertFalse($r->strict_ssl); 119 } 120 121 function testSendsAndExpectsType() 122 { 123 $r = Request::init() 124 ->sendsAndExpectsType(Mime::JSON); 125 $this->assertEquals(Mime::JSON, $r->expected_type); 126 $this->assertEquals(Mime::JSON, $r->content_type); 127 128 $r = Request::init() 129 ->sendsAndExpectsType('html'); 130 $this->assertEquals(Mime::HTML, $r->expected_type); 131 $this->assertEquals(Mime::HTML, $r->content_type); 132 133 $r = Request::init() 134 ->sendsAndExpectsType('form'); 135 $this->assertEquals(Mime::FORM, $r->expected_type); 136 $this->assertEquals(Mime::FORM, $r->content_type); 137 138 $r = Request::init() 139 ->sendsAndExpectsType('application/x-www-form-urlencoded'); 140 $this->assertEquals(Mime::FORM, $r->expected_type); 141 $this->assertEquals(Mime::FORM, $r->content_type); 142 143 $r = Request::init() 144 ->sendsAndExpectsType(Mime::CSV); 145 $this->assertEquals(Mime::CSV, $r->expected_type); 146 $this->assertEquals(Mime::CSV, $r->content_type); 147 } 148 149 function testIni() 150 { 151 // Test setting defaults/templates 152 153 // Create the template 154 $template = Request::init() 155 ->method(Http::POST) 156 ->withStrictSsl() 157 ->expectsType(Mime::HTML) 158 ->sendsType(Mime::FORM); 159 160 Request::ini($template); 161 162 $r = Request::init(); 163 164 $this->assertTrue($r->strict_ssl); 165 $this->assertEquals(Http::POST, $r->method); 166 $this->assertEquals(Mime::HTML, $r->expected_type); 167 $this->assertEquals(Mime::FORM, $r->content_type); 168 169 // Test the default accessor as well 170 $this->assertTrue(Request::d('strict_ssl')); 171 $this->assertEquals(Http::POST, Request::d('method')); 172 $this->assertEquals(Mime::HTML, Request::d('expected_type')); 173 $this->assertEquals(Mime::FORM, Request::d('content_type')); 174 175 Request::resetIni(); 176 } 177 178 function testAccept() 179 { 180 $r = Request::get('http://example.com/') 181 ->expectsType(Mime::JSON); 182 183 $this->assertEquals(Mime::JSON, $r->expected_type); 184 $r->_curlPrep(); 185 $this->assertContains('application/json', $r->raw_headers); 186 } 187 188 function testCustomAccept() 189 { 190 $accept = 'application/api-1.0+json'; 191 $r = Request::get('http://example.com/') 192 ->addHeader('Accept', $accept); 193 194 $r->_curlPrep(); 195 $this->assertContains($accept, $r->raw_headers); 196 $this->assertEquals($accept, $r->headers['Accept']); 197 } 198 199 function testUserAgent() 200 { 201 $r = Request::get('http://example.com/') 202 ->withUserAgent('ACME/1.2.3'); 203 204 $this->assertArrayHasKey('User-Agent', $r->headers); 205 $r->_curlPrep(); 206 $this->assertContains('User-Agent: ACME/1.2.3', $r->raw_headers); 207 $this->assertNotContains('User-Agent: HttpFul/1.0', $r->raw_headers); 208 209 $r = Request::get('http://example.com/') 210 ->withUserAgent(''); 211 212 $this->assertArrayHasKey('User-Agent', $r->headers); 213 $r->_curlPrep(); 214 $this->assertContains('User-Agent:', $r->raw_headers); 215 $this->assertNotContains('User-Agent: HttpFul/1.0', $r->raw_headers); 216 } 217 218 function testAuthSetup() 219 { 220 $username = 'nathan'; 221 $password = 'opensesame'; 222 223 $r = Request::get('http://example.com/') 224 ->authenticateWith($username, $password); 225 226 $this->assertEquals($username, $r->username); 227 $this->assertEquals($password, $r->password); 228 $this->assertTrue($r->hasBasicAuth()); 229 } 230 231 function testDigestAuthSetup() 232 { 233 $username = 'nathan'; 234 $password = 'opensesame'; 235 236 $r = Request::get('http://example.com/') 237 ->authenticateWithDigest($username, $password); 238 239 $this->assertEquals($username, $r->username); 240 $this->assertEquals($password, $r->password); 241 $this->assertTrue($r->hasDigestAuth()); 242 } 243 244 function testJsonResponseParse() 245 { 246 $req = Request::init()->sendsAndExpects(Mime::JSON); 247 $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req); 248 249 $this->assertEquals("value", $response->body->key); 250 $this->assertEquals("value", $response->body->object->key); 251 $this->assertInternalType('array', $response->body->array); 252 $this->assertEquals(1, $response->body->array[0]); 253 } 254 255 function testXMLResponseParse() 256 { 257 $req = Request::init()->sendsAndExpects(Mime::XML); 258 $response = new Response(self::SAMPLE_XML_RESPONSE, self::SAMPLE_XML_HEADER, $req); 259 $sxe = $response->body; 260 $this->assertEquals("object", gettype($sxe)); 261 $this->assertEquals("SimpleXMLElement", get_class($sxe)); 262 $bools = $sxe->xpath('/stdClass/boolProp'); 263 list( , $bool ) = each($bools); 264 $this->assertEquals("TRUE", (string) $bool); 265 $ints = $sxe->xpath('/stdClass/arrayProp/array/k1/myClass/intProp'); 266 list( , $int ) = each($ints); 267 $this->assertEquals("2", (string) $int); 268 $strings = $sxe->xpath('/stdClass/stringProp'); 269 list( , $string ) = each($strings); 270 $this->assertEquals("a string", (string) $string); 271 } 272 273 function testCsvResponseParse() 274 { 275 $req = Request::init()->sendsAndExpects(Mime::CSV); 276 $response = new Response(self::SAMPLE_CSV_RESPONSE, self::SAMPLE_CSV_HEADER, $req); 277 278 $this->assertEquals("Key1", $response->body[0][0]); 279 $this->assertEquals("Value1", $response->body[1][0]); 280 $this->assertInternalType('string', $response->body[2][0]); 281 $this->assertEquals("40.0", $response->body[2][0]); 282 } 283 284 function testParsingContentTypeCharset() 285 { 286 $req = Request::init()->sendsAndExpects(Mime::JSON); 287 // $response = new Response(SAMPLE_JSON_RESPONSE, "", $req); 288 // // Check default content type of iso-8859-1 289 $response = new Response(self::SAMPLE_JSON_RESPONSE, "HTTP/1.1 200 OK 290 Content-Type: text/plain; charset=utf-8\r\n", $req); 291 $this->assertInstanceOf('Httpful\Response\Headers', $response->headers); 292 $this->assertEquals($response->headers['Content-Type'], 'text/plain; charset=utf-8'); 293 $this->assertEquals($response->content_type, 'text/plain'); 294 $this->assertEquals($response->charset, 'utf-8'); 295 } 296 297 function testEmptyResponseParse() 298 { 299 $req = Request::init()->sendsAndExpects(Mime::JSON); 300 $response = new Response("", self::SAMPLE_JSON_HEADER, $req); 301 $this->assertEquals(null, $response->body); 302 303 $reqXml = Request::init()->sendsAndExpects(Mime::XML); 304 $responseXml = new Response("", self::SAMPLE_XML_HEADER, $reqXml); 305 $this->assertEquals(null, $responseXml->body); 306 } 307 308 function testNoAutoParse() 309 { 310 $req = Request::init()->sendsAndExpects(Mime::JSON)->withoutAutoParsing(); 311 $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req); 312 $this->assertInternalType('string', $response->body); 313 $req = Request::init()->sendsAndExpects(Mime::JSON)->withAutoParsing(); 314 $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req); 315 $this->assertInternalType('object', $response->body); 316 } 317 318 function testParseHeaders() 319 { 320 $req = Request::init()->sendsAndExpects(Mime::JSON); 321 $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req); 322 $this->assertEquals('application/json', $response->headers['Content-Type']); 323 } 324 325 function testRawHeaders() 326 { 327 $req = Request::init()->sendsAndExpects(Mime::JSON); 328 $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req); 329 $this->assertContains('Content-Type: application/json', $response->raw_headers); 330 } 331 332 function testHasErrors() 333 { 334 $req = Request::init()->sendsAndExpects(Mime::JSON); 335 $response = new Response('', "HTTP/1.1 100 Continue\r\n", $req); 336 $this->assertFalse($response->hasErrors()); 337 $response = new Response('', "HTTP/1.1 200 OK\r\n", $req); 338 $this->assertFalse($response->hasErrors()); 339 $response = new Response('', "HTTP/1.1 300 Multiple Choices\r\n", $req); 340 $this->assertFalse($response->hasErrors()); 341 $response = new Response('', "HTTP/1.1 400 Bad Request\r\n", $req); 342 $this->assertTrue($response->hasErrors()); 343 $response = new Response('', "HTTP/1.1 500 Internal Server Error\r\n", $req); 344 $this->assertTrue($response->hasErrors()); 345 } 346 347 function test_parseCode() 348 { 349 $req = Request::init()->sendsAndExpects(Mime::JSON); 350 $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req); 351 $code = $response->_parseCode("HTTP/1.1 406 Not Acceptable\r\n"); 352 $this->assertEquals(406, $code); 353 } 354 355 function testToString() 356 { 357 $req = Request::init()->sendsAndExpects(Mime::JSON); 358 $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req); 359 $this->assertEquals(self::SAMPLE_JSON_RESPONSE, (string)$response); 360 } 361 362 function test_parseHeaders() 363 { 364 $parse_headers = Response\Headers::fromString(self::SAMPLE_JSON_HEADER); 365 $this->assertCount(3, $parse_headers); 366 $this->assertEquals('application/json', $parse_headers['Content-Type']); 367 $this->assertTrue(isset($parse_headers['Connection'])); 368 } 369 370 function testMultiHeaders() 371 { 372 $req = Request::init(); 373 $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_MULTI_HEADER, $req); 374 $parse_headers = $response->_parseHeaders(self::SAMPLE_MULTI_HEADER); 375 $this->assertEquals('Value1,Value2', $parse_headers['X-My-Header']); 376 } 377 378 function testDetectContentType() 379 { 380 $req = Request::init(); 381 $response = new Response(self::SAMPLE_JSON_RESPONSE, self::SAMPLE_JSON_HEADER, $req); 382 $this->assertEquals('application/json', $response->headers['Content-Type']); 383 } 384 385 function testMissingBodyContentType() 386 { 387 $body = 'A string'; 388 $request = Request::post(HttpfulTest::TEST_URL, $body)->_curlPrep(); 389 $this->assertEquals($body, $request->serialized_payload); 390 } 391 392 function testParentType() 393 { 394 // Parent type 395 $request = Request::init()->sendsAndExpects(Mime::XML); 396 $response = new Response('<xml><name>Nathan</name></xml>', self::SAMPLE_VENDOR_HEADER, $request); 397 398 $this->assertEquals("application/xml", $response->parent_type); 399 $this->assertEquals(self::SAMPLE_VENDOR_TYPE, $response->content_type); 400 $this->assertTrue($response->is_mime_vendor_specific); 401 402 // Make sure we still parsed as if it were plain old XML 403 $this->assertEquals("Nathan", $response->body->name->__toString()); 404 } 405 406 function testMissingContentType() 407 { 408 // Parent type 409 $request = Request::init()->sendsAndExpects(Mime::XML); 410 $response = new Response('<xml><name>Nathan</name></xml>', 411 "HTTP/1.1 200 OK 412 Connection: keep-alive 413 Transfer-Encoding: chunked\r\n", $request); 414 415 $this->assertEquals("", $response->content_type); 416 } 417 418 function testCustomMimeRegistering() 419 { 420 // Register new mime type handler for "application/vnd.nategood.message+xml" 421 Httpful::register(self::SAMPLE_VENDOR_TYPE, new DemoMimeHandler()); 422 423 $this->assertTrue(Httpful::hasParserRegistered(self::SAMPLE_VENDOR_TYPE)); 424 425 $request = Request::init(); 426 $response = new Response('<xml><name>Nathan</name></xml>', self::SAMPLE_VENDOR_HEADER, $request); 427 428 $this->assertEquals(self::SAMPLE_VENDOR_TYPE, $response->content_type); 429 $this->assertEquals('custom parse', $response->body); 430 } 431 432 public function testShorthandMimeDefinition() 433 { 434 $r = Request::init()->expects('json'); 435 $this->assertEquals(Mime::JSON, $r->expected_type); 436 437 $r = Request::init()->expectsJson(); 438 $this->assertEquals(Mime::JSON, $r->expected_type); 439 } 440 441 public function testOverrideXmlHandler() 442 { 443 // Lazy test... 444 $prev = \Httpful\Httpful::get(\Httpful\Mime::XML); 445 $this->assertEquals($prev, new \Httpful\Handlers\XmlHandler()); 446 $conf = array('namespace' => 'http://example.com'); 447 \Httpful\Httpful::register(\Httpful\Mime::XML, new \Httpful\Handlers\XmlHandler($conf)); 448 $new = \Httpful\Httpful::get(\Httpful\Mime::XML); 449 $this->assertNotEquals($prev, $new); 450 } 451 } 452 453 class DemoMimeHandler extends \Httpful\Handlers\MimeHandlerAdapter { 454 public function parse($body) { 455 return 'custom parse'; 456 } 457 } 458
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |