PageRenderTime 53ms CodeModel.GetById 2ms app.highlight 41ms RepoModel.GetById 1ms app.codeStats 0ms

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

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