PageRenderTime 91ms CodeModel.GetById 14ms app.highlight 67ms RepoModel.GetById 1ms app.codeStats 1ms

/cake/tests/cases/libs/http_socket.test.php

https://bitbucket.org/sanjeevam/beug
PHP | 1407 lines | 1055 code | 157 blank | 195 comment | 8 complexity | 18691604382937f7870cdbafb45bc80e MD5 | raw file
   1<?php
   2/* SVN FILE: $Id$ */
   3/**
   4 * HttpSocketTest file
   5 *
   6 * Long description for file
   7 *
   8 * PHP versions 4 and 5
   9 *
  10 * CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
  11 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
  12 *
  13 *  Licensed under The Open Group Test Suite License
  14 *  Redistributions of files must retain the above copyright notice.
  15 *
  16 * @copyright     Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
  17 * @link          https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
  18 * @package       cake
  19 * @subpackage    cake.tests.cases.libs
  20 * @since         CakePHP(tm) v 1.2.0.4206
  21 * @version       $Revision$
  22 * @modifiedby    $LastChangedBy$
  23 * @lastmodified  $Date$
  24 * @license       http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
  25 */
  26App::import('Core', 'HttpSocket');
  27/**
  28 * HttpSocketTest class
  29 *
  30 * @package       cake
  31 * @subpackage    cake.tests.cases.libs
  32 */
  33class HttpSocketTest extends CakeTestCase {
  34/**
  35 * Socket property
  36 *
  37 * @var mixed null
  38 * @access public
  39 */
  40	var $Socket = null;
  41/**
  42 * RequestSocket property
  43 *
  44 * @var mixed null
  45 * @access public
  46 */
  47	var $RequestSocket = null;
  48/**
  49 * This function sets up a TestHttpSocket instance we are going to use for testing
  50 *
  51 * @access public
  52 * @return void
  53 */
  54	function setUp() {
  55		if (!class_exists('TestHttpSocket')) {
  56			Mock::generatePartial('HttpSocket', 'TestHttpSocket', array('read', 'write', 'connect'));
  57			Mock::generatePartial('HttpSocket', 'TestHttpSocketRequests', array('read', 'write', 'connect', 'request'));
  58		}
  59
  60		$this->Socket =& new TestHttpSocket();
  61		$this->RequestSocket =& new TestHttpSocketRequests();
  62	}
  63/**
  64 * We use this function to clean up after the test case was executed
  65 *
  66 * @access public
  67 * @return void
  68 */
  69	function tearDown() {
  70		unset($this->Socket, $this->RequestSocket);
  71	}
  72/**
  73 * Test that HttpSocket::__construct does what one would expect it to do
  74 *
  75 * @access public
  76 * @return void
  77 */
  78	function testConstruct() {
  79		$this->Socket->reset();
  80		$baseConfig = $this->Socket->config;
  81		$this->Socket->expectNever('connect');
  82		$this->Socket->__construct(array('host' => 'foo-bar'));
  83		$baseConfig['host']	 = 'foo-bar';
  84		$baseConfig['protocol'] = getprotobyname($baseConfig['protocol']);
  85		$this->assertIdentical($this->Socket->config, $baseConfig);
  86		$this->Socket->reset();
  87		$baseConfig = $this->Socket->config;
  88		$this->Socket->__construct('http://www.cakephp.org:23/');
  89		$baseConfig['host']	 = 'www.cakephp.org';
  90		$baseConfig['request']['uri']['host'] = 'www.cakephp.org';
  91		$baseConfig['port']	 = 23;
  92		$baseConfig['request']['uri']['port'] = 23;
  93		$baseConfig['protocol'] = getprotobyname($baseConfig['protocol']);
  94		$this->assertIdentical($this->Socket->config, $baseConfig);
  95
  96		$this->Socket->reset();
  97		$this->Socket->__construct(array('request' => array('uri' => 'http://www.cakephp.org:23/')));
  98		$this->assertIdentical($this->Socket->config, $baseConfig);
  99	}
 100/**
 101 * Test that HttpSocket::configUri works properly with different types of arguments
 102 *
 103 * @access public
 104 * @return void
 105 */
 106	function testConfigUri() {
 107		$this->Socket->reset();
 108		$r = $this->Socket->configUri('https://bob:secret@www.cakephp.org:23/?query=foo');
 109		$expected = array(
 110			'persistent' => false,
 111			'host' 		 => 'www.cakephp.org',
 112			'protocol'   => 'tcp',
 113			'port' 		 => 23,
 114			'timeout' 	 =>	30,
 115			'request' => array(
 116				'uri' => array(
 117					'scheme' => 'https'
 118					, 'host' => 'www.cakephp.org'
 119					, 'port' => 23
 120				),
 121				'auth' => array(
 122					'method' => 'Basic'
 123					, 'user' => 'bob'
 124					, 'pass' => 'secret'
 125				),
 126				'cookies' => array(),
 127			)
 128		);
 129		$this->assertIdentical($this->Socket->config, $expected);
 130		$this->assertIdentical($r, $expected);
 131		$r = $this->Socket->configUri(array('host' => 'www.foo-bar.org'));
 132		$expected['host'] = 'www.foo-bar.org';
 133		$expected['request']['uri']['host'] = 'www.foo-bar.org';
 134		$this->assertIdentical($this->Socket->config, $expected);
 135		$this->assertIdentical($r, $expected);
 136
 137		$r = $this->Socket->configUri('http://www.foo.com');
 138		$expected = array(
 139			'persistent' => false,
 140			'host' 		 => 'www.foo.com',
 141			'protocol'   => 'tcp',
 142			'port' 		 => 80,
 143			'timeout' 	 =>	30,
 144			'request' => array(
 145				'uri' => array(
 146					'scheme' => 'http'
 147					, 'host' => 'www.foo.com'
 148					, 'port' => 80
 149				),
 150				'auth' => array(
 151					'method' => 'Basic'
 152					, 'user' => null
 153					, 'pass' => null
 154				),
 155				'cookies' => array()
 156			)
 157		);
 158		$this->assertIdentical($this->Socket->config, $expected);
 159		$this->assertIdentical($r, $expected);
 160		$r = $this->Socket->configUri('/this-is-broken');
 161		$this->assertIdentical($this->Socket->config, $expected);
 162		$this->assertIdentical($r, false);
 163		$r = $this->Socket->configUri(false);
 164		$this->assertIdentical($this->Socket->config, $expected);
 165		$this->assertIdentical($r, false);
 166	}
 167/**
 168 * Tests that HttpSocket::request (the heart of the HttpSocket) is working properly.
 169 *
 170 * @access public
 171 * @return void
 172 */
 173	function testRequest() {
 174		$this->Socket->reset();
 175
 176		$this->Socket->reset();
 177		$response = $this->Socket->request(true);
 178		$this->assertFalse($response);
 179
 180		$tests = array(
 181			0 => array(
 182				'request' => 'http://www.cakephp.org/?foo=bar'
 183				, 'expectation' => array(
 184					'config' => array(
 185						'persistent' => false
 186						, 'host' => 'www.cakephp.org'
 187						, 'protocol' => 'tcp'
 188						, 'port' => 80
 189						, 'timeout' => 30
 190						, 'request' => array(
 191							'uri' => array (
 192								'scheme' => 'http'
 193								, 'host' => 'www.cakephp.org'
 194								, 'port' => 80,
 195							)
 196							, 'auth' => array(
 197								'method' => 'Basic'
 198								,'user' => null
 199								,'pass' => null
 200							),
 201							'cookies' => array(),
 202						),
 203					)
 204					, 'request' => array(
 205						'method' => 'GET'
 206						, 'uri' => array(
 207							'scheme' => 'http'
 208							, 'host' => 'www.cakephp.org'
 209							, 'port' => 80
 210							, 'user' => null
 211							, 'pass' => null
 212							, 'path' => '/'
 213							, 'query' => array('foo' => 'bar')
 214							, 'fragment' => null
 215						)
 216						, 'auth' => array(
 217							'method' => 'Basic'
 218							, 'user' => null
 219							, 'pass' => null
 220						)
 221						, 'version' => '1.1'
 222						, 'body' => ''
 223						, 'line' => "GET /?foo=bar HTTP/1.1\r\n"
 224						, 'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\n"
 225						, 'raw' => ""
 226						, 'cookies' => array(),
 227					)
 228				)
 229			)
 230			, 1 => array(
 231				'request' => array(
 232					'uri' => array(
 233						'host' => 'www.cakephp.org'
 234						, 'query' => '?foo=bar'
 235					)
 236				)
 237			)
 238			, 2 => array(
 239				'request' => 'www.cakephp.org/?foo=bar'
 240			)
 241			, 3 => array(
 242				'request' => array('host' => '192.168.0.1', 'uri' => 'http://www.cakephp.org/?foo=bar')
 243				, 'expectation' => array(
 244					'request' => array(
 245						'uri' => array('host' => 'www.cakephp.org')
 246					)
 247					, 'config' => array(
 248						'request' => array(
 249							'uri' => array('host' => 'www.cakephp.org')
 250						)
 251						, 'host' => '192.168.0.1'
 252					)
 253				)
 254			)
 255			, 'reset4' => array(
 256				'request.uri.query' => array()
 257			)
 258			, 4 => array(
 259				'request' => array('header' => array('Foo@woo' => 'bar-value'))
 260				, 'expectation' => array(
 261					'request' => array(
 262						'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nFoo\"@\"woo: bar-value\r\n"
 263						, 'line' => "GET / HTTP/1.1\r\n"
 264					)
 265				)
 266			)
 267			, 5 => array(
 268				'request' => array('header' => array('Foo@woo' => 'bar-value', 'host' => 'foo.com'), 'uri' => 'http://www.cakephp.org/')
 269				, 'expectation' => array(
 270					'request' => array(
 271						'header' => "Host: foo.com\r\nConnection: close\r\nUser-Agent: CakePHP\r\nFoo\"@\"woo: bar-value\r\n"
 272					)
 273					, 'config' => array(
 274						'host' => 'www.cakephp.org'
 275					)
 276				)
 277			)
 278			, 6 => array(
 279				'request' => array('header' => "Foo: bar\r\n")
 280				, 'expectation' => array(
 281					'request' => array(
 282						'header' => "Foo: bar\r\n"
 283					)
 284				)
 285			)
 286			, 7 => array(
 287				'request' => array('header' => "Foo: bar\r\n", 'uri' => 'http://www.cakephp.org/search?q=http_socket#ignore-me')
 288				, 'expectation' => array(
 289					'request' => array(
 290						'uri' => array(
 291							'path' => '/search'
 292							, 'query' => array('q' => 'http_socket')
 293							, 'fragment' => 'ignore-me'
 294						)
 295						, 'line' => "GET /search?q=http_socket HTTP/1.1\r\n"
 296					)
 297				)
 298			)
 299			, 'reset8' => array(
 300				'request.uri.query' => array()
 301			)
 302			, 8 => array(
 303				'request' => array('method' => 'POST', 'uri' => 'http://www.cakephp.org/posts/add', 'body' => array('name' => 'HttpSocket-is-released', 'date' => 'today'))
 304				, 'expectation' => array(
 305					'request' => array(
 306						'method' => 'POST'
 307						, 'uri' => array(
 308							'path' => '/posts/add'
 309							, 'fragment' => null
 310						)
 311						, 'body' => "name=HttpSocket-is-released&date=today"
 312						, 'line' => "POST /posts/add HTTP/1.1\r\n"
 313						, 'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 38\r\n"
 314						, 'raw' => "name=HttpSocket-is-released&date=today"
 315					)
 316				)
 317			)
 318			, 9 => array(
 319				'request' => array('method' => 'POST', 'uri' => 'http://www.cakephp.org:8080/posts/add', 'body' => array('name' => 'HttpSocket-is-released', 'date' => 'today'))
 320				, 'expectation' => array(
 321					'config' => array(
 322						'port' => 8080
 323						, 'request' => array(
 324							'uri' => array(
 325								'port' => 8080
 326							)
 327						)
 328					)
 329					, 'request' => array(
 330						'uri' => array(
 331							'port' => 8080
 332						)
 333						, 'header' => "Host: www.cakephp.org:8080\r\nConnection: close\r\nUser-Agent: CakePHP\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 38\r\n"
 334					)
 335				)
 336			)
 337			, 10 => array(
 338				'request' => array('method' => 'POST', 'uri' => 'https://www.cakephp.org/posts/add', 'body' => array('name' => 'HttpSocket-is-released', 'date' => 'today'))
 339				, 'expectation' => array(
 340					'config' => array(
 341						'port' => 443
 342						, 'request' => array(
 343							'uri' => array(
 344								'scheme' => 'https'
 345								, 'port' => 443
 346							)
 347						)
 348					)
 349					, 'request' => array(
 350						'uri' => array(
 351							'scheme' => 'https'
 352							, 'port' => 443
 353						)
 354						, 'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 38\r\n"
 355					)
 356				)
 357			)
 358			, 11 => array(
 359				'request' => array(
 360						'method' => 'POST',
 361						'uri' => 'https://www.cakephp.org/posts/add',
 362						'body' => array('name' => 'HttpSocket-is-released', 'date' => 'today'),
 363						'cookies' => array('foo' => array('value' => 'bar'))
 364				)
 365				, 'expectation' => array(
 366					'request' => array(
 367						'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 38\r\nCookie: foo=bar\r\n",
 368						'cookies' => array(
 369							'foo' => array('value' => 'bar'),
 370						)
 371					)
 372				)
 373			)
 374		);
 375
 376		$expectation = array();
 377		foreach ($tests as $i => $test) {
 378			if (strpos($i, 'reset') === 0) {
 379				foreach ($test as $path => $val) {
 380					$expectation = Set::insert($expectation, $path, $val);
 381				}
 382				continue;
 383			}
 384
 385			if (isset($test['expectation'])) {
 386				$expectation = Set::merge($expectation, $test['expectation']);
 387			}
 388			$this->Socket->request($test['request']);
 389
 390			$raw = $expectation['request']['raw'];
 391			$expectation['request']['raw'] = $expectation['request']['line'].$expectation['request']['header']."\r\n".$raw;
 392
 393			$r = array('config' => $this->Socket->config, 'request' => $this->Socket->request);
 394			$v = $this->assertIdentical($r, $expectation, '%s in test #'.$i.' ');
 395			if (!$v) {
 396				debug('Result:');
 397				debug($r);
 398				debug('Expected:');
 399				debug($expectation);
 400			}
 401			$expectation['request']['raw'] = $raw;
 402		}
 403
 404		$this->Socket->reset();
 405		$request = array('method' => 'POST', 'uri' => 'http://www.cakephp.org/posts/add', 'body' => array('name' => 'HttpSocket-is-released', 'date' => 'today'));
 406		$response = $this->Socket->request($request);
 407		$this->assertIdentical($this->Socket->request['body'], "name=HttpSocket-is-released&date=today");
 408
 409		$request = array('uri' => '*', 'method' => 'GET');
 410		$this->expectError(new PatternExpectation('/activate quirks mode/i'));
 411		$response = $this->Socket->request($request);
 412		$this->assertFalse($response);
 413		$this->assertFalse($this->Socket->response);
 414
 415		$this->Socket->reset();
 416		$request = array('uri' => 'htpp://www.cakephp.org/');
 417		$this->Socket->setReturnValue('connect', true);
 418		$this->Socket->setReturnValue('read', false);
 419		$this->Socket->_mock->_call_counts['read'] = 0;
 420		$number = mt_rand(0, 9999999);
 421		$serverResponse = "HTTP/1.x 200 OK\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>Hello, your lucky number is " . $number . "</h1>";
 422		$this->Socket->setReturnValueAt(0, 'read', $serverResponse);
 423		$this->Socket->expect('write', array("GET / HTTP/1.1\r\nHost: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\n\r\n"));
 424		$this->Socket->expectCallCount('read', 2);
 425		$response = $this->Socket->request($request);
 426		$this->assertIdentical($response, "<h1>Hello, your lucky number is " . $number . "</h1>");
 427
 428		$this->Socket->reset();
 429		$serverResponse = "HTTP/1.x 200 OK\r\nSet-Cookie: foo=bar\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>This is a cookie test!</h1>";
 430		unset($this->Socket->_mock->_actions->_at['read']);
 431		unset($this->Socket->_mock->_return_sequence['read']);
 432		$this->Socket->_mock->_call_counts['read'] = 0;
 433		$this->Socket->setReturnValueAt(0, 'read', $serverResponse);
 434
 435		$this->Socket->connected = true;
 436		$this->Socket->request($request);
 437		$result = $this->Socket->response['cookies'];
 438		$expect = array(
 439			'foo' => array(
 440				'value' => 'bar'
 441			)
 442		);
 443		$this->assertEqual($result, $expect);
 444		$this->assertEqual($this->Socket->config['request']['cookies'], $expect);
 445		$this->assertFalse($this->Socket->connected);
 446	}
 447/**
 448 * testUrl method
 449 *
 450 * @access public
 451 * @return void
 452 */
 453	function testUrl() {
 454		$this->Socket->reset(true);
 455
 456		$this->assertIdentical($this->Socket->url(true), false);
 457
 458		$url = $this->Socket->url('www.cakephp.org');
 459		$this->assertIdentical($url, 'http://www.cakephp.org/');
 460
 461		$url = $this->Socket->url('https://www.cakephp.org/posts/add');
 462		$this->assertIdentical($url, 'https://www.cakephp.org/posts/add');
 463		$url = $this->Socket->url('http://www.cakephp/search?q=socket', '/%path?%query');
 464		$this->assertIdentical($url, '/search?q=socket');
 465
 466		$this->Socket->config['request']['uri']['host'] = 'bakery.cakephp.org';
 467		$url = $this->Socket->url();
 468		$this->assertIdentical($url, 'http://bakery.cakephp.org/');
 469
 470		$this->Socket->configUri('http://www.cakephp.org');
 471		$url = $this->Socket->url('/search?q=bar');
 472		$this->assertIdentical($url, 'http://www.cakephp.org/search?q=bar');
 473
 474		$url = $this->Socket->url(array('host' => 'www.foobar.org', 'query' => array('q' => 'bar')));
 475		$this->assertIdentical($url, 'http://www.foobar.org/?q=bar');
 476
 477		$url = $this->Socket->url(array('path' => '/supersearch', 'query' => array('q' => 'bar')));
 478		$this->assertIdentical($url, 'http://www.cakephp.org/supersearch?q=bar');
 479
 480		$this->Socket->configUri('http://www.google.com');
 481		$url = $this->Socket->url('/search?q=socket');
 482		$this->assertIdentical($url, 'http://www.google.com/search?q=socket');
 483
 484		$url = $this->Socket->url();
 485		$this->assertIdentical($url, 'http://www.google.com/');
 486
 487		$this->Socket->configUri('https://www.google.com');
 488		$url = $this->Socket->url('/search?q=socket');
 489		$this->assertIdentical($url, 'https://www.google.com/search?q=socket');
 490
 491		$this->Socket->reset();
 492		$this->Socket->configUri('www.google.com:443');
 493		$url = $this->Socket->url('/search?q=socket');
 494		$this->assertIdentical($url, 'https://www.google.com/search?q=socket');
 495
 496		$this->Socket->reset();
 497		$this->Socket->configUri('www.google.com:8080');
 498		$url = $this->Socket->url('/search?q=socket');
 499		$this->assertIdentical($url, 'http://www.google.com:8080/search?q=socket');
 500	}
 501/**
 502 * testGet method
 503 *
 504 * @access public
 505 * @return void
 506 */
 507	function testGet() {
 508		$this->RequestSocket->reset();
 509
 510		$this->RequestSocket->expect('request', a(array('method' => 'GET', 'uri' => 'http://www.google.com/')));
 511		$this->RequestSocket->get('http://www.google.com/');
 512
 513		$this->RequestSocket->expect('request', a(array('method' => 'GET', 'uri' => 'http://www.google.com/?foo=bar')));
 514		$this->RequestSocket->get('http://www.google.com/', array('foo' => 'bar'));
 515
 516		$this->RequestSocket->expect('request', a(array('method' => 'GET', 'uri' => 'http://www.google.com/?foo=bar')));
 517		$this->RequestSocket->get('http://www.google.com/', 'foo=bar');
 518
 519		$this->RequestSocket->expect('request', a(array('method' => 'GET', 'uri' => 'http://www.google.com/?foo=23&foobar=42')));
 520		$this->RequestSocket->get('http://www.google.com/?foo=bar', array('foobar' => '42', 'foo' => '23'));
 521
 522		$this->RequestSocket->expect('request', a(array('method' => 'GET', 'uri' => 'http://www.google.com/', 'auth' => array('user' => 'foo', 'pass' => 'bar'))));
 523		$this->RequestSocket->get('http://www.google.com/', null, array('auth' => array('user' => 'foo', 'pass' => 'bar')));
 524	}
 525/**
 526 * test that two consecutive get() calls reset the authentication credentials.
 527 *
 528 * @return void
 529 */
 530	function testConsecutiveGetResetsAuthCredentials() {
 531		$socket = new TestHttpSocket();
 532		$socket->config['request']['auth'] = array(
 533			'method' => 'Basic',
 534			'user' => 'mark',
 535			'pass' => 'secret'
 536		);
 537		$socket->get('http://mark:secret@example.com/test');
 538		$this->assertEqual($socket->request['uri']['user'], 'mark');
 539		$this->assertEqual($socket->request['uri']['pass'], 'secret');
 540
 541		$socket->get('/test2');
 542		$this->assertEqual($socket->request['auth']['user'], 'mark');
 543		$this->assertEqual($socket->request['auth']['pass'], 'secret');
 544
 545		$socket->get('/test3');
 546		$this->assertEqual($socket->request['auth']['user'], 'mark');
 547		$this->assertEqual($socket->request['auth']['pass'], 'secret');
 548	}
 549
 550/**
 551 * testPostPutDelete method
 552 *
 553 * @access public
 554 * @return void
 555 */
 556	function testPostPutDelete() {
 557		$this->RequestSocket->reset();
 558
 559		foreach (array('POST', 'PUT', 'DELETE') as $method) {
 560			$this->RequestSocket->expect('request', a(array('method' => $method, 'uri' => 'http://www.google.com/', 'body' => array())));
 561			$this->RequestSocket->{low($method)}('http://www.google.com/');
 562
 563			$this->RequestSocket->expect('request', a(array('method' => $method, 'uri' => 'http://www.google.com/', 'body' => array('Foo' => 'bar'))));
 564			$this->RequestSocket->{low($method)}('http://www.google.com/', array('Foo' => 'bar'));
 565
 566			$this->RequestSocket->expect('request', a(array('method' => $method, 'uri' => 'http://www.google.com/', 'body' => null, 'line' => 'Hey Server')));
 567			$this->RequestSocket->{low($method)}('http://www.google.com/', null, array('line' => 'Hey Server'));
 568		}
 569	}
 570/**
 571 * testParseResponse method
 572 *
 573 * @access public
 574 * @return void
 575 */
 576	function testParseResponse() {
 577		$this->Socket->reset();
 578
 579		$r = $this->Socket->parseResponse(array('foo' => 'bar'));
 580		$this->assertIdentical($r, array('foo' => 'bar'));
 581
 582		$r = $this->Socket->parseResponse(true);
 583		$this->assertIdentical($r, false);
 584
 585		$r = $this->Socket->parseResponse("HTTP Foo\r\nBar: La");
 586		$this->assertIdentical($r, false);
 587
 588		$tests = array(
 589			'simple-request' => array(
 590				'response' => array(
 591					'status-line' => "HTTP/1.x 200 OK\r\n",
 592					'header' => "Date: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\n",
 593					'body' => "<h1>Hello World</h1>\r\n<p>It's good to be html</p>"
 594				)
 595				, 'expectations' => array(
 596					'status.http-version' => 'HTTP/1.x',
 597					'status.code' => 200,
 598					'status.reason-phrase' => 'OK',
 599					'header' => $this->Socket->parseHeader("Date: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\n"),
 600					'body' => "<h1>Hello World</h1>\r\n<p>It's good to be html</p>"
 601				)
 602			),
 603			'no-header' => array(
 604				'response' => array(
 605					'status-line' => "HTTP/1.x 404 OK\r\n",
 606					'header' => null,
 607				)
 608				, 'expectations' => array(
 609					'status.code' => 404,
 610					'header' => array()
 611				)
 612			),
 613			'chunked' => array(
 614				'response' => array(
 615					'header' => "Transfer-Encoding: chunked\r\n",
 616					'body' => "19\r\nThis is a chunked message\r\n0\r\n"
 617				),
 618				'expectations' => array(
 619					'body' => "This is a chunked message",
 620					'header' => $this->Socket->parseHeader("Transfer-Encoding: chunked\r\n")
 621				)
 622			),
 623			'enitity-header' => array(
 624				'response' => array(
 625					'body' => "19\r\nThis is a chunked message\r\n0\r\nFoo: Bar\r\n"
 626				),
 627				'expectations' => array(
 628					'header' => $this->Socket->parseHeader("Transfer-Encoding: chunked\r\nFoo: Bar\r\n")
 629				)
 630			),
 631			'enitity-header-combine' => array(
 632				'response' => array(
 633					'header' => "Transfer-Encoding: chunked\r\nFoo: Foobar\r\n"
 634				),
 635				'expectations' => array(
 636					'header' => $this->Socket->parseHeader("Transfer-Encoding: chunked\r\nFoo: Foobar\r\nFoo: Bar\r\n")
 637				)
 638			)
 639		);
 640
 641		$testResponse = array();
 642		$expectations = array();
 643
 644		foreach ($tests as $name => $test) {
 645
 646			$testResponse = array_merge($testResponse, $test['response']);
 647			$testResponse['response'] = $testResponse['status-line'].$testResponse['header']."\r\n".$testResponse['body'];
 648			$r = $this->Socket->parseResponse($testResponse['response']);
 649			$expectations = array_merge($expectations, $test['expectations']);
 650
 651			foreach ($expectations as $property => $expectedVal) {
 652				$val = Set::extract($r, $property);
 653				$this->assertIdentical($val, $expectedVal, 'Test "'.$name.'": response.'.$property.' - %s');
 654			}
 655
 656			foreach (array('status-line', 'header', 'body', 'response') as $field) {
 657				$this->assertIdentical($r['raw'][$field], $testResponse[$field], 'Test response.raw.'.$field.': %s');
 658			}
 659		}
 660	}
 661/**
 662 * testDecodeBody method
 663 *
 664 * @access public
 665 * @return void
 666 */
 667	function testDecodeBody() {
 668		$this->Socket->reset();
 669
 670		$r = $this->Socket->decodeBody(true);
 671		$this->assertIdentical($r, false);
 672
 673		$r = $this->Socket->decodeBody('Foobar', false);
 674		$this->assertIdentical($r, array('body' => 'Foobar', 'header' => false));
 675
 676		$encodings = array(
 677			'chunked' => array(
 678				'encoded' => "19\r\nThis is a chunked message\r\n0\r\n",
 679				'decoded' => array('body' => "This is a chunked message", 'header' => false)
 680			),
 681			'foo-coded' => array(
 682				'encoded' => '!Foobar!',
 683				'decoded' => array('body' => '!Foobar!', 'header' => false),
 684				'error' => new PatternExpectation('/unknown encoding: foo-coded/i')
 685			)
 686		);
 687
 688		foreach ($encodings as $encoding => $sample) {
 689			if (isset($sample['error'])) {
 690				$this->expectError($sample['error']);
 691			}
 692
 693			$r = $this->Socket->decodeBody($sample['encoded'], $encoding);
 694			$this->assertIdentical($r, $sample['decoded']);
 695
 696			if (isset($sample['error'])) {
 697				$this->Socket->quirksMode = true;
 698				$r = $this->Socket->decodeBody($sample['encoded'], $encoding);
 699				$this->assertIdentical($r, $sample['decoded']);
 700				$this->Socket->quirksMode = false;
 701			}
 702		}
 703	}
 704/**
 705 * testDecodeChunkedBody method
 706 *
 707 * @access public
 708 * @return void
 709 */
 710	function testDecodeChunkedBody() {
 711		$this->Socket->reset();
 712
 713		$r = $this->Socket->decodeChunkedBody(true);
 714		$this->assertIdentical($r, false);
 715
 716		$encoded = "19\r\nThis is a chunked message\r\n0\r\n";
 717		$decoded = "This is a chunked message";
 718		$r = $this->Socket->decodeChunkedBody($encoded);
 719		$this->assertIdentical($r['body'], $decoded);
 720		$this->assertIdentical($r['header'], false);
 721
 722		$encoded = "19 \r\nThis is a chunked message\r\n0\r\n";
 723		$r = $this->Socket->decodeChunkedBody($encoded);
 724		$this->assertIdentical($r['body'], $decoded);
 725
 726		$encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n0\r\n";
 727		$decoded = "This is a chunked message\nThat is cool\n";
 728		$r = $this->Socket->decodeChunkedBody($encoded);
 729		$this->assertIdentical($r['body'], $decoded);
 730		$this->assertIdentical($r['header'], false);
 731
 732		$encoded = "19\r\nThis is a chunked message\r\nE;foo-chunk=5\r\n\nThat is cool\n\r\n0\r\n";
 733		$r = $this->Socket->decodeChunkedBody($encoded);
 734		$this->assertIdentical($r['body'], $decoded);
 735		$this->assertIdentical($r['header'], false);
 736
 737		$encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n0\r\nfoo-header: bar\r\ncake: PHP\r\n\r\n";
 738		$r = $this->Socket->decodeChunkedBody($encoded);
 739		$this->assertIdentical($r['body'], $decoded);
 740		$this->assertIdentical($r['header'], array('Foo-Header' => 'bar', 'Cake' => 'PHP'));
 741
 742		$encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n";
 743		$this->expectError(new PatternExpectation('/activate quirks mode/i'));
 744		$r = $this->Socket->decodeChunkedBody($encoded);
 745		$this->assertIdentical($r, false);
 746
 747		$this->Socket->quirksMode = true;
 748		$r = $this->Socket->decodeChunkedBody($encoded);
 749		$this->assertIdentical($r['body'], $decoded);
 750		$this->assertIdentical($r['header'], false);
 751
 752		$encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\nfoo-header: bar\r\ncake: PHP\r\n\r\n";
 753		$r = $this->Socket->decodeChunkedBody($encoded);
 754		$this->assertIdentical($r['body'], $decoded);
 755		$this->assertIdentical($r['header'], array('Foo-Header' => 'bar', 'Cake' => 'PHP'));
 756	}
 757/**
 758 * testBuildRequestLine method
 759 *
 760 * @access public
 761 * @return void
 762 */
 763	function testBuildRequestLine() {
 764		$this->Socket->reset();
 765
 766		$this->expectError(new PatternExpectation('/activate quirks mode/i'));
 767		$r = $this->Socket->buildRequestLine('Foo');
 768		$this->assertIdentical($r, false);
 769
 770		$this->Socket->quirksMode = true;
 771		$r = $this->Socket->buildRequestLine('Foo');
 772		$this->assertIdentical($r, 'Foo');
 773		$this->Socket->quirksMode = false;
 774
 775		$r = $this->Socket->buildRequestLine(true);
 776		$this->assertIdentical($r, false);
 777
 778		$r = $this->Socket->buildRequestLine(array('foo' => 'bar', 'method' => 'foo'));
 779		$this->assertIdentical($r, false);
 780
 781		$r = $this->Socket->buildRequestLine(array('method' => 'GET', 'uri' => 'http://www.cakephp.org/search?q=socket'));
 782		$this->assertIdentical($r, "GET /search?q=socket HTTP/1.1\r\n");
 783
 784		$request = array(
 785			'method' => 'GET',
 786			'uri' => array(
 787				'path' => '/search',
 788				'query' => array('q' => 'socket')
 789			)
 790		);
 791		$r = $this->Socket->buildRequestLine($request);
 792		$this->assertIdentical($r, "GET /search?q=socket HTTP/1.1\r\n");
 793
 794		unset($request['method']);
 795		$r = $this->Socket->buildRequestLine($request);
 796		$this->assertIdentical($r, "GET /search?q=socket HTTP/1.1\r\n");
 797
 798		$r = $this->Socket->buildRequestLine($request, 'CAKE-HTTP/0.1');
 799		$this->assertIdentical($r, "GET /search?q=socket CAKE-HTTP/0.1\r\n");
 800
 801		$request = array('method' => 'OPTIONS', 'uri' => '*');
 802		$r = $this->Socket->buildRequestLine($request);
 803		$this->assertIdentical($r, "OPTIONS * HTTP/1.1\r\n");
 804
 805		$request['method'] = 'GET';
 806		$this->expectError(new PatternExpectation('/activate quirks mode/i'));
 807		$r = $this->Socket->buildRequestLine($request);
 808		$this->assertIdentical($r, false);
 809
 810		$this->expectError(new PatternExpectation('/activate quirks mode/i'));
 811		$r = $this->Socket->buildRequestLine("GET * HTTP/1.1\r\n");
 812		$this->assertIdentical($r, false);
 813
 814		$this->Socket->quirksMode = true;
 815		$r = $this->Socket->buildRequestLine($request);
 816		$this->assertIdentical($r,  "GET * HTTP/1.1\r\n");
 817
 818		$r = $this->Socket->buildRequestLine("GET * HTTP/1.1\r\n");
 819		$this->assertIdentical($r, "GET * HTTP/1.1\r\n");
 820	}
 821/**
 822 * Asserts that HttpSocket::parseUri is working properly
 823 *
 824 * @access public
 825 * @return void
 826 */
 827	function testParseUri() {
 828		$this->Socket->reset();
 829
 830		$uri = $this->Socket->parseUri(array('invalid' => 'uri-string'));
 831		$this->assertIdentical($uri, false);
 832
 833		$uri = $this->Socket->parseUri(array('invalid' => 'uri-string'), array('host' => 'somehost'));
 834		$this->assertIdentical($uri, array('host' => 'somehost', 'invalid' => 'uri-string'));
 835
 836		$uri = $this->Socket->parseUri(false);
 837		$this->assertIdentical($uri, false);
 838
 839		$uri = $this->Socket->parseUri('/my-cool-path');
 840		$this->assertIdentical($uri, array('path' => '/my-cool-path'));
 841
 842		$uri = $this->Socket->parseUri('http://bob:foo123@www.cakephp.org:40/search?q=dessert#results');
 843		$this->assertIdentical($uri, array(
 844			'scheme' => 'http',
 845			'host' => 'www.cakephp.org',
 846			'port' => 40,
 847			'user' => 'bob',
 848			'pass' => 'foo123',
 849			'path' => '/search',
 850			'query' => array('q' => 'dessert'),
 851			'fragment' => 'results'
 852		));
 853
 854		$uri = $this->Socket->parseUri('http://www.cakephp.org/');
 855		$this->assertIdentical($uri, array(
 856			'scheme' => 'http',
 857			'host' => 'www.cakephp.org',
 858			'path' => '/',
 859		));
 860
 861		$uri = $this->Socket->parseUri('http://www.cakephp.org', true);
 862		$this->assertIdentical($uri, array(
 863			'scheme' => 'http',
 864			'host' => 'www.cakephp.org',
 865			'port' => 80,
 866			'user' => null,
 867			'pass' => null,
 868			'path' => '/',
 869			'query' => array(),
 870			'fragment' => null
 871		));
 872
 873		$uri = $this->Socket->parseUri('https://www.cakephp.org', true);
 874		$this->assertIdentical($uri, array(
 875			'scheme' => 'https',
 876			'host' => 'www.cakephp.org',
 877			'port' => 443,
 878			'user' => null,
 879			'pass' => null,
 880			'path' => '/',
 881			'query' => array(),
 882			'fragment' => null
 883		));
 884
 885		$uri = $this->Socket->parseUri('www.cakephp.org:443/query?foo', true);
 886		$this->assertIdentical($uri, array(
 887			'scheme' => 'https',
 888			'host' => 'www.cakephp.org',
 889			'port' => 443,
 890			'user' => null,
 891			'pass' => null,
 892			'path' => '/query',
 893			'query' => array('foo' => ""),
 894			'fragment' => null
 895		));
 896
 897		$uri = $this->Socket->parseUri('http://www.cakephp.org', array('host' => 'piephp.org', 'user' => 'bob', 'fragment' => 'results'));
 898		$this->assertIdentical($uri, array(
 899			'host' => 'www.cakephp.org',
 900			'user' => 'bob',
 901			'fragment' => 'results',
 902			'scheme' => 'http'
 903		));
 904
 905		$uri = $this->Socket->parseUri('https://www.cakephp.org', array('scheme' => 'http', 'port' => 23));
 906		$this->assertIdentical($uri, array(
 907			'scheme' => 'https',
 908			'port' => 23,
 909			'host' => 'www.cakephp.org'
 910		));
 911
 912		$uri = $this->Socket->parseUri('www.cakephp.org:59', array('scheme' => array('http', 'https'), 'port' => 80));
 913		$this->assertIdentical($uri, array(
 914			'scheme' => 'http',
 915			'port' => 59,
 916			'host' => 'www.cakephp.org'
 917		));
 918
 919		$uri = $this->Socket->parseUri(array('scheme' => 'http', 'host' => 'www.google.com', 'port' => 8080), array('scheme' => array('http', 'https'), 'host' => 'www.google.com', 'port' => array(80, 443)));
 920		$this->assertIdentical($uri, array(
 921			'scheme' => 'http',
 922			'host' => 'www.google.com',
 923			'port' => 8080,
 924		));
 925
 926		$uri = $this->Socket->parseUri('http://www.cakephp.org/?param1=value1&param2=value2%3Dvalue3');
 927		$this->assertIdentical($uri, array(
 928			'scheme' => 'http',
 929			'host' => 'www.cakephp.org',
 930			'path' => '/',
 931			'query' => array(
 932				'param1' => 'value1',
 933				'param2' => 'value2=value3'
 934			)
 935		));
 936
 937		$uri = $this->Socket->parseUri('http://www.cakephp.org/?param1=value1&param2=value2=value3');
 938		$this->assertIdentical($uri, array(
 939			'scheme' => 'http',
 940			'host' => 'www.cakephp.org',
 941			'path' => '/',
 942			'query' => array(
 943				'param1' => 'value1',
 944				'param2' => 'value2=value3'
 945			)
 946		));
 947	}
 948/**
 949 * Tests that HttpSocket::buildUri can turn all kinds of uri arrays (and strings) into fully or partially qualified URI's
 950 *
 951 * @access public
 952 * @return void
 953 */
 954	function testBuildUri() {
 955		$this->Socket->reset();
 956
 957		$r = $this->Socket->buildUri(true);
 958		$this->assertIdentical($r, false);
 959
 960		$r = $this->Socket->buildUri('foo.com');
 961		$this->assertIdentical($r, 'http://foo.com/');
 962
 963		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org'));
 964		$this->assertIdentical($r, 'http://www.cakephp.org/');
 965
 966		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'scheme' => 'https'));
 967		$this->assertIdentical($r, 'https://www.cakephp.org/');
 968
 969		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'port' => 23));
 970		$this->assertIdentical($r, 'http://www.cakephp.org:23/');
 971
 972		$r = $this->Socket->buildUri(array('path' => 'www.google.com/search', 'query' => 'q=cakephp'));
 973		$this->assertIdentical($r, 'http://www.google.com/search?q=cakephp');
 974
 975		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'scheme' => 'https', 'port' => 79));
 976		$this->assertIdentical($r, 'https://www.cakephp.org:79/');
 977
 978		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'path' => 'foo'));
 979		$this->assertIdentical($r, 'http://www.cakephp.org/foo');
 980
 981		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'path' => '/foo'));
 982		$this->assertIdentical($r, 'http://www.cakephp.org/foo');
 983
 984		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'path' => '/search', 'query' => array('q' => 'HttpSocket')));
 985		$this->assertIdentical($r, 'http://www.cakephp.org/search?q=HttpSocket');
 986
 987		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'fragment' => 'bar'));
 988		$this->assertIdentical($r, 'http://www.cakephp.org/#bar');
 989
 990		$r = $this->Socket->buildUri(array(
 991			'scheme' => 'https',
 992			'host' => 'www.cakephp.org',
 993			'port' => 25,
 994			'user' => 'bob',
 995			'pass' => 'secret',
 996			'path' => '/cool',
 997			'query' => array('foo' => 'bar'),
 998			'fragment' => 'comment'
 999		));
1000		$this->assertIdentical($r, 'https://bob:secret@www.cakephp.org:25/cool?foo=bar#comment');
1001
1002		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'fragment' => 'bar'), '%fragment?%host');
1003		$this->assertIdentical($r, 'bar?www.cakephp.org');
1004
1005		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org'), '%fragment???%host');
1006		$this->assertIdentical($r, '???www.cakephp.org');
1007
1008		$r = $this->Socket->buildUri(array('path' => '*'), '/%path?%query');
1009		$this->assertIdentical($r, '*');
1010
1011		$r = $this->Socket->buildUri(array('scheme' => 'foo', 'host' => 'www.cakephp.org'));
1012		$this->assertIdentical($r, 'foo://www.cakephp.org:80/');
1013	}
1014/**
1015 * Asserts that HttpSocket::parseQuery is working properly
1016 *
1017 * @access public
1018 * @return void
1019 */
1020	function testParseQuery() {
1021		$this->Socket->reset();
1022
1023		$query = $this->Socket->parseQuery(array('framework' => 'cakephp'));
1024		$this->assertIdentical($query, array('framework' => 'cakephp'));
1025
1026		$query = $this->Socket->parseQuery('');
1027		$this->assertIdentical($query, array());
1028
1029		$query = $this->Socket->parseQuery('framework=cakephp');
1030		$this->assertIdentical($query, array('framework' => 'cakephp'));
1031
1032		$query = $this->Socket->parseQuery('?framework=cakephp');
1033		$this->assertIdentical($query, array('framework' => 'cakephp'));
1034
1035		$query = $this->Socket->parseQuery('a&b&c');
1036		$this->assertIdentical($query, array('a' => '', 'b' => '', 'c' => ''));
1037
1038		$query = $this->Socket->parseQuery('value=12345');
1039		$this->assertIdentical($query, array('value' => '12345'));
1040
1041		$query = $this->Socket->parseQuery('a[0]=foo&a[1]=bar&a[2]=cake');
1042		$this->assertIdentical($query, array('a' => array(0 => 'foo', 1 => 'bar', 2 => 'cake')));
1043
1044		$query = $this->Socket->parseQuery('a[]=foo&a[]=bar&a[]=cake');
1045		$this->assertIdentical($query, array('a' => array(0 => 'foo', 1 => 'bar', 2 => 'cake')));
1046
1047		$query = $this->Socket->parseQuery('a]][[=foo&[]=bar&]]][]=cake');
1048		$this->assertIdentical($query, array('a]][[' => 'foo', 0 => 'bar', ']]]' => array('cake')));
1049
1050		$query = $this->Socket->parseQuery('a[][]=foo&a[][]=bar&a[][]=cake');
1051		$expectedQuery = array(
1052			'a' => array(
1053				0 => array(
1054					0 => 'foo'
1055				),
1056				1 => array(
1057					0 => 'bar'
1058				),
1059				array(
1060					0 => 'cake'
1061				)
1062			)
1063		);
1064		$this->assertIdentical($query, $expectedQuery);
1065
1066		$query = $this->Socket->parseQuery('a[][]=foo&a[bar]=php&a[][]=bar&a[][]=cake');
1067		$expectedQuery = array(
1068			'a' => array(
1069				0 => array(
1070					0 => 'foo'
1071				),
1072				'bar' => 'php',
1073				1 => array(
1074					0 => 'bar'
1075				),
1076				array(
1077					0 => 'cake'
1078				)
1079			)
1080		);
1081		$this->assertIdentical($query, $expectedQuery);
1082
1083		$query = $this->Socket->parseQuery('user[]=jim&user[3]=tom&user[]=bob');
1084		$expectedQuery = array(
1085			'user' => array(
1086				0 => 'jim',
1087				3 => 'tom',
1088				4 => 'bob'
1089			)
1090		);
1091		$this->assertIdentical($query, $expectedQuery);
1092
1093		$queryStr = 'user[0]=foo&user[0][items][]=foo&user[0][items][]=bar&user[][name]=jim&user[1][items][personal][]=book&user[1][items][personal][]=pen&user[1][items][]=ball&user[count]=2&empty';
1094		$query = $this->Socket->parseQuery($queryStr);
1095		$expectedQuery = array(
1096			'user' => array(
1097				0 => array(
1098					'items' => array(
1099						'foo',
1100						'bar'
1101					)
1102				),
1103				1 => array(
1104					'name' => 'jim',
1105					'items' => array(
1106						'personal' => array(
1107							'book'
1108							, 'pen'
1109						),
1110						'ball'
1111					)
1112				),
1113				'count' => '2'
1114			),
1115			'empty' => ''
1116		);
1117		$this->assertIdentical($query, $expectedQuery);
1118	}
1119/**
1120 * Tests that HttpSocket::buildHeader can turn a given $header array into a proper header string according to
1121 * HTTP 1.1 specs.
1122 *
1123 * @access public
1124 * @return void
1125 */
1126	function testBuildHeader() {
1127		$this->Socket->reset();
1128
1129		$r = $this->Socket->buildHeader(true);
1130		$this->assertIdentical($r, false);
1131
1132		$r = $this->Socket->buildHeader('My raw header');
1133		$this->assertIdentical($r, 'My raw header');
1134
1135		$r = $this->Socket->buildHeader(array('Host' => 'www.cakephp.org'));
1136		$this->assertIdentical($r, "Host: www.cakephp.org\r\n");
1137
1138		$r = $this->Socket->buildHeader(array('Host' => 'www.cakephp.org', 'Connection' => 'Close'));
1139		$this->assertIdentical($r, "Host: www.cakephp.org\r\nConnection: Close\r\n");
1140
1141		$r = $this->Socket->buildHeader(array('People' => array('Bob', 'Jim', 'John')));
1142		$this->assertIdentical($r, "People: Bob,Jim,John\r\n");
1143
1144		$r = $this->Socket->buildHeader(array('Multi-Line-Field' => "This is my\r\nMulti Line field"));
1145		$this->assertIdentical($r, "Multi-Line-Field: This is my\r\n Multi Line field\r\n");
1146
1147		$r = $this->Socket->buildHeader(array('Multi-Line-Field' => "This is my\r\n Multi Line field"));
1148		$this->assertIdentical($r, "Multi-Line-Field: This is my\r\n Multi Line field\r\n");
1149
1150		$r = $this->Socket->buildHeader(array('Multi-Line-Field' => "This is my\r\n\tMulti Line field"));
1151		$this->assertIdentical($r, "Multi-Line-Field: This is my\r\n\tMulti Line field\r\n");
1152
1153		$r = $this->Socket->buildHeader(array('Test@Field' => "My value"));
1154		$this->assertIdentical($r, "Test\"@\"Field: My value\r\n");
1155
1156	}
1157/**
1158 * Test that HttpSocket::parseHeader can take apart a given (and valid) $header string and turn it into an array.
1159 *
1160 * @access public
1161 * @return void
1162 */
1163	function testParseHeader() {
1164		$this->Socket->reset();
1165
1166		$r = $this->Socket->parseHeader(array('foo' => 'Bar', 'fOO-bAr' => 'quux'));
1167		$this->assertIdentical($r, array('Foo' => 'Bar', 'Foo-Bar' => 'quux'));
1168
1169		$r = $this->Socket->parseHeader(true);
1170		$this->assertIdentical($r, false);
1171
1172		$header = "Host: cakephp.org\t\r\n";
1173		$r = $this->Socket->parseHeader($header);
1174		$expected = array(
1175			'Host' => 'cakephp.org'
1176		);
1177		$this->assertIdentical($r, $expected);
1178
1179		$header = "Date:Sat, 07 Apr 2007 10:10:25 GMT\r\nX-Powered-By: PHP/5.1.2\r\n";
1180		$r = $this->Socket->parseHeader($header);
1181		$expected = array(
1182			'Date' => 'Sat, 07 Apr 2007 10:10:25 GMT'
1183			, 'X-Powered-By' =>  'PHP/5.1.2'
1184		);
1185		$this->assertIdentical($r, $expected);
1186
1187		$header = "people: Jim,John\r\nfoo-LAND: Bar\r\ncAKe-PHP: rocks\r\n";
1188		$r = $this->Socket->parseHeader($header);
1189		$expected = array(
1190			'People' => 'Jim,John'
1191			, 'Foo-Land' => 'Bar'
1192			, 'Cake-Php' =>  'rocks'
1193		);
1194		$this->assertIdentical($r, $expected);
1195
1196		$header = "People: Jim,John,Tim\r\nPeople: Lisa,Tina,Chelsea\r\n";
1197		$r = $this->Socket->parseHeader($header);
1198		$expected = array(
1199			'People' =>  array('Jim,John,Tim', 'Lisa,Tina,Chelsea')
1200		);
1201		$this->assertIdentical($r, $expected);
1202
1203		$header = "Multi-Line: I am a \r\nmulti line\t\r\nfield value.\r\nSingle-Line: I am not\r\n";
1204		$r = $this->Socket->parseHeader($header);
1205		$expected = array(
1206			'Multi-Line' => "I am a\r\nmulti line\r\nfield value."
1207			, 'Single-Line' => 'I am not'
1208		);
1209		$this->assertIdentical($r, $expected);
1210
1211		$header = "Esc\"@\"ped: value\r\n";
1212		$r = $this->Socket->parseHeader($header);
1213		$expected = array(
1214			'Esc@ped' => 'value'
1215		);
1216		$this->assertIdentical($r, $expected);
1217	}
1218/**
1219 * testParseCookies method
1220 *
1221 * @access public
1222 * @return void
1223 */
1224	function testParseCookies() {
1225		$header = array(
1226			'Set-Cookie' => array(
1227				'foo=bar',
1228				'people=jim,jack,johnny";";Path=/accounts',
1229				'google=not=nice'
1230			),
1231			'Transfer-Encoding' => 'chunked',
1232			'Date' => 'Sun, 18 Nov 2007 18:57:42 GMT',
1233		);
1234		$cookies = $this->Socket->parseCookies($header);
1235		$expected = array(
1236			'foo' => array(
1237				'value' => 'bar'
1238			),
1239			'people' => array(
1240				'value' => 'jim,jack,johnny";"',
1241				'path' => '/accounts',
1242			),
1243			'google' => array(
1244				'value' => 'not=nice',
1245			)
1246		);
1247		$this->assertEqual($cookies, $expected);
1248
1249		$header['Set-Cookie'][] = 'cakephp=great; Secure';
1250		$expected['cakephp'] = array('value' => 'great', 'secure' => true);
1251		$cookies = $this->Socket->parseCookies($header);
1252		$this->assertEqual($cookies, $expected);
1253
1254		$header['Set-Cookie'] = 'foo=bar';
1255		unset($expected['people'], $expected['cakephp'], $expected['google']);
1256		$cookies = $this->Socket->parseCookies($header);
1257		$this->assertEqual($cookies, $expected);
1258	}
1259/**
1260 * testBuildCookies method
1261 *
1262 * @return void
1263 * @access public
1264 * @todo Test more scenarios
1265 */
1266	function testBuildCookies() {
1267		$cookies = array(
1268			'foo' => array(
1269				'value' => 'bar'
1270			),
1271			'people' => array(
1272				'value' => 'jim,jack,johnny;',
1273				'path' => '/accounts'
1274			)
1275		);
1276		$expect = "Cookie: foo=bar; people=jim,jack,johnny\";\"\r\n";
1277		$result = $this->Socket->buildCookies($cookies);
1278		$this->assertEqual($result, $expect);
1279	}
1280/**
1281 * Tests that HttpSocket::__tokenEscapeChars() returns the right characters.
1282 *
1283 * @access public
1284 * @return void
1285 */
1286	function testTokenEscapeChars() {
1287		$this->Socket->reset();
1288
1289		$expected = array(
1290			'\x22','\x28','\x29','\x3c','\x3e','\x40','\x2c','\x3b','\x3a','\x5c','\x2f','\x5b','\x5d','\x3f','\x3d','\x7b',
1291			'\x7d','\x20','\x00','\x01','\x02','\x03','\x04','\x05','\x06','\x07','\x08','\x09','\x0a','\x0b','\x0c','\x0d',
1292			'\x0e','\x0f','\x10','\x11','\x12','\x13','\x14','\x15','\x16','\x17','\x18','\x19','\x1a','\x1b','\x1c','\x1d',
1293			'\x1e','\x1f','\x7f'
1294		);
1295		$r = $this->Socket->__tokenEscapeChars();
1296		$this->assertEqual($r, $expected);
1297
1298		foreach ($expected as $key => $char) {
1299			$expected[$key] = chr(hexdec(substr($char, 2)));
1300		}
1301
1302		$r = $this->Socket->__tokenEscapeChars(false);
1303		$this->assertEqual($r, $expected);
1304	}
1305/**
1306 * Test that HttpSocket::escapeToken is escaping all characters as descriped in RFC 2616 (HTTP 1.1 specs)
1307 *
1308 * @access public
1309 * @return void
1310 */
1311	function testEscapeToken() {
1312		$this->Socket->reset();
1313
1314		$this->assertIdentical($this->Socket->escapeToken('Foo'), 'Foo');
1315
1316		$escape = $this->Socket->__tokenEscapeChars(false);
1317		foreach ($escape as $char) {
1318			$token = 'My-special-'.$char.'-Token';
1319			$escapedToken = $this->Socket->escapeToken($token);
1320			$expectedToken = 'My-special-"'.$char.'"-Token';
1321
1322			$this->assertIdentical($escapedToken, $expectedToken, 'Test token escaping for ASCII '.ord($char));
1323		}
1324
1325		$token = 'Extreme-:Token-	-"@-test';
1326		$escapedToken = $this->Socket->escapeToken($token);
1327		$expectedToken = 'Extreme-":"Token-"	"-""""@"-test';
1328		$this->assertIdentical($expectedToken, $escapedToken);
1329	}
1330/**
1331 * Test that escaped token strings are properly unescaped by HttpSocket::unescapeToken
1332 *
1333 * @access public
1334 * @return void
1335 */
1336	function testUnescapeToken() {
1337		$this->Socket->reset();
1338
1339		$this->assertIdentical($this->Socket->unescapeToken('Foo'), 'Foo');
1340
1341		$escape = $this->Socket->__tokenEscapeChars(false);
1342		foreach ($escape as $char) {
1343			$token = 'My-special-"'.$char.'"-Token';
1344			$unescapedToken = $this->Socket->unescapeToken($token);
1345			$expectedToken = 'My-special-'.$char.'-Token';
1346
1347			$this->assertIdentical($unescapedToken, $expectedToken, 'Test token unescaping for ASCII '.ord($char));
1348		}
1349
1350		$token = 'Extreme-":"Token-"	"-""""@"-test';
1351		$escapedToken = $this->Socket->unescapeToken($token);
1352		$expectedToken = 'Extreme-:Token-	-"@-test';
1353		$this->assertIdentical($expectedToken, $escapedToken);
1354	}
1355/**
1356 * This tests asserts HttpSocket::reset() resets a HttpSocket instance to it's initial state (before Object::__construct
1357 * got executed)
1358 *
1359 * @access public
1360 * @return void
1361 */
1362	function testReset() {
1363		$this->Socket->reset();
1364
1365		$initialState = get_class_vars('HttpSocket');
1366		foreach ($initialState as $property => $value) {
1367			$this->Socket->{$property} = 'Overwritten';
1368		}
1369
1370		$return = $this->Socket->reset();
1371
1372		foreach ($initialState as $property => $value) {
1373			$this->assertIdentical($this->Socket->{$property}, $value);
1374		}
1375
1376		$this->assertIdentical($return, true);
1377	}
1378/**
1379 * This tests asserts HttpSocket::reset(false) resets certain HttpSocket properties to their initial state (before
1380 * Object::__construct got executed).
1381 *
1382 * @access public
1383 * @return void
1384 */
1385	function testPartialReset() {
1386		$this->Socket->reset();
1387
1388		$partialResetProperties = array('request', 'response');
1389		$initialState = get_class_vars('HttpSocket');
1390
1391		foreach ($initialState as $property => $value) {
1392			$this->Socket->{$property} = 'Overwritten';
1393		}
1394
1395		$return = $this->Socket->reset(false);
1396
1397		foreach ($initialState as $property => $originalValue) {
1398			if (in_array($property, $partialResetProperties)) {
1399				$this->assertIdentical($this->Socket->{$property}, $originalValue);
1400			} else {
1401				$this->assertIdentical($this->Socket->{$property}, 'Overwritten');
1402			}
1403		}
1404		$this->assertIdentical($return, true);
1405	}
1406}
1407?>