Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
12345 anikendra 1
<?php
2
/**
3
 * HttpResponseTest file
4
 *
5
 * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
14
 * @package       Cake.Test.Case.Network.Http
15
 * @since         CakePHP(tm) v 1.2.0.4206
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18
 
19
App::uses('HttpResponse', 'Network/Http');
20
 
21
/**
22
 * TestHttpResponse class
23
 *
24
 * @package       Cake.Test.Case.Network.Http
25
 */
26
class TestHttpResponse extends HttpResponse {
27
 
28
/**
29
 * Convenience method for testing protected method
30
 *
31
 * @param array $header Header as an indexed array (field => value)
32
 * @return array Parsed header
33
 */
34
	public function parseHeader($header) {
35
		return parent::_parseHeader($header);
36
	}
37
 
38
/**
39
 * Convenience method for testing protected method
40
 *
41
 * @param string $body A string containing the body to decode
42
 * @param bool|string $encoding Can be false in case no encoding is being used, or a string representing the encoding
43
 * @return mixed Array or false
44
 */
45
	public function decodeBody($body, $encoding = 'chunked') {
46
		return parent::_decodeBody($body, $encoding);
47
	}
48
 
49
/**
50
 * Convenience method for testing protected method
51
 *
52
 * @param string $body A string containing the chunked body to decode
53
 * @return mixed Array or false
54
 */
55
	public function decodeChunkedBody($body) {
56
		return parent::_decodeChunkedBody($body);
57
	}
58
 
59
/**
60
 * Convenience method for testing protected method
61
 *
62
 * @param string $token Token to unescape
63
 * @return string Unescaped token
64
 */
65
	public function unescapeToken($token, $chars = null) {
66
		return parent::_unescapeToken($token, $chars);
67
	}
68
 
69
/**
70
 * Convenience method for testing protected method
71
 *
72
 * @param bool $hex true to get them as HEX values, false otherwise
73
 * @return array Escape chars
74
 */
75
	public function tokenEscapeChars($hex = true, $chars = null) {
76
		return parent::_tokenEscapeChars($hex, $chars);
77
	}
78
 
79
}
80
 
81
/**
82
 * HttpResponseTest class
83
 *
84
 * @package       Cake.Test.Case.Network.Http
85
 */
86
class HttpResponseTest extends CakeTestCase {
87
 
88
/**
89
 * This function sets up a HttpResponse
90
 *
91
 * @return void
92
 */
93
	public function setUp() {
94
		parent::setUp();
95
		$this->HttpResponse = new TestHttpResponse();
96
	}
97
 
98
/**
99
 * testBody
100
 *
101
 * @return void
102
 */
103
	public function testBody() {
104
		$this->HttpResponse->body = 'testing';
105
		$this->assertEquals('testing', $this->HttpResponse->body());
106
 
107
		$this->HttpResponse->body = null;
108
		$this->assertSame($this->HttpResponse->body(), '');
109
	}
110
 
111
/**
112
 * testToString
113
 *
114
 * @return void
115
 */
116
	public function testToString() {
117
		$this->HttpResponse->body = 'other test';
118
		$this->assertEquals('other test', $this->HttpResponse->body());
119
		$this->assertEquals('other test', (string)$this->HttpResponse);
120
		$this->assertTrue(strpos($this->HttpResponse, 'test') > 0);
121
 
122
		$this->HttpResponse->body = null;
123
		$this->assertEquals('', (string)$this->HttpResponse);
124
	}
125
 
126
/**
127
 * testGetHeader
128
 *
129
 * @return void
130
 */
131
	public function testGetHeader() {
132
		$this->HttpResponse->headers = array(
133
			'foo' => 'Bar',
134
			'Some' => 'ok',
135
			'HeAdEr' => 'value',
136
			'content-Type' => 'text/plain'
137
		);
138
 
139
		$this->assertEquals('Bar', $this->HttpResponse->getHeader('foo'));
140
		$this->assertEquals('Bar', $this->HttpResponse->getHeader('Foo'));
141
		$this->assertEquals('Bar', $this->HttpResponse->getHeader('FOO'));
142
		$this->assertEquals('value', $this->HttpResponse->getHeader('header'));
143
		$this->assertEquals('text/plain', $this->HttpResponse->getHeader('Content-Type'));
144
		$this->assertNull($this->HttpResponse->getHeader(0));
145
 
146
		$this->assertEquals('Bar', $this->HttpResponse->getHeader('foo', false));
147
		$this->assertEquals('not from class', $this->HttpResponse->getHeader('foo', array('foo' => 'not from class')));
148
	}
149
 
150
/**
151
 * testIsOk
152
 *
153
 * @return void
154
 */
155
	public function testIsOk() {
156
		$this->HttpResponse->code = 0;
157
		$this->assertFalse($this->HttpResponse->isOk());
158
		$this->HttpResponse->code = -1;
159
		$this->assertFalse($this->HttpResponse->isOk());
160
		$this->HttpResponse->code = 'what?';
161
		$this->assertFalse($this->HttpResponse->isOk());
162
		$this->HttpResponse->code = 200;
163
		$this->assertTrue($this->HttpResponse->isOk());
164
		$this->HttpResponse->code = 201;
165
		$this->assertTrue($this->HttpResponse->isOk());
166
		$this->HttpResponse->code = 202;
167
		$this->assertTrue($this->HttpResponse->isOk());
168
		$this->HttpResponse->code = 203;
169
		$this->assertTrue($this->HttpResponse->isOk());
170
		$this->HttpResponse->code = 204;
171
		$this->assertTrue($this->HttpResponse->isOk());
172
		$this->HttpResponse->code = 205;
173
		$this->assertTrue($this->HttpResponse->isOk());
174
		$this->HttpResponse->code = 206;
175
		$this->assertTrue($this->HttpResponse->isOk());
176
		$this->HttpResponse->code = 207;
177
		$this->assertFalse($this->HttpResponse->isOk());
178
		$this->HttpResponse->code = 208;
179
		$this->assertFalse($this->HttpResponse->isOk());
180
		$this->HttpResponse->code = 209;
181
		$this->assertFalse($this->HttpResponse->isOk());
182
		$this->HttpResponse->code = 210;
183
		$this->assertFalse($this->HttpResponse->isOk());
184
		$this->HttpResponse->code = 226;
185
		$this->assertFalse($this->HttpResponse->isOk());
186
		$this->HttpResponse->code = 288;
187
		$this->assertFalse($this->HttpResponse->isOk());
188
		$this->HttpResponse->code = 301;
189
		$this->assertFalse($this->HttpResponse->isOk());
190
	}
191
 
192
/**
193
 * testIsRedirect
194
 *
195
 * @return void
196
 */
197
	public function testIsRedirect() {
198
		$this->HttpResponse->code = 0;
199
		$this->assertFalse($this->HttpResponse->isRedirect());
200
		$this->HttpResponse->code = -1;
201
		$this->assertFalse($this->HttpResponse->isRedirect());
202
		$this->HttpResponse->code = 201;
203
		$this->assertFalse($this->HttpResponse->isRedirect());
204
		$this->HttpResponse->code = 'what?';
205
		$this->assertFalse($this->HttpResponse->isRedirect());
206
		$this->HttpResponse->code = 301;
207
		$this->assertFalse($this->HttpResponse->isRedirect());
208
		$this->HttpResponse->code = 302;
209
		$this->assertFalse($this->HttpResponse->isRedirect());
210
		$this->HttpResponse->code = 303;
211
		$this->assertFalse($this->HttpResponse->isRedirect());
212
		$this->HttpResponse->code = 307;
213
		$this->assertFalse($this->HttpResponse->isRedirect());
214
		$this->HttpResponse->code = 301;
215
		$this->HttpResponse->headers['Location'] = 'http://somewhere/';
216
		$this->assertTrue($this->HttpResponse->isRedirect());
217
		$this->HttpResponse->code = 302;
218
		$this->HttpResponse->headers['Location'] = 'http://somewhere/';
219
		$this->assertTrue($this->HttpResponse->isRedirect());
220
		$this->HttpResponse->code = 303;
221
		$this->HttpResponse->headers['Location'] = 'http://somewhere/';
222
		$this->assertTrue($this->HttpResponse->isRedirect());
223
		$this->HttpResponse->code = 307;
224
		$this->HttpResponse->headers['Location'] = 'http://somewhere/';
225
		$this->assertTrue($this->HttpResponse->isRedirect());
226
	}
227
 
228
/**
229
 * Test that HttpSocket::parseHeader can take apart a given (and valid) $header string and turn it into an array.
230
 *
231
 * @return void
232
 */
233
	public function testParseHeader() {
234
		$r = $this->HttpResponse->parseHeader(array('foo' => 'Bar', 'fOO-bAr' => 'quux'));
235
		$this->assertEquals(array('foo' => 'Bar', 'fOO-bAr' => 'quux'), $r);
236
 
237
		$r = $this->HttpResponse->parseHeader(true);
238
		$this->assertEquals(false, $r);
239
 
240
		$header = "Host: cakephp.org\t\r\n";
241
		$r = $this->HttpResponse->parseHeader($header);
242
		$expected = array(
243
			'Host' => 'cakephp.org'
244
		);
245
		$this->assertEquals($expected, $r);
246
 
247
		$header = "Date:Sat, 07 Apr 2007 10:10:25 GMT\r\nX-Powered-By: PHP/5.1.2\r\n";
248
		$r = $this->HttpResponse->parseHeader($header);
249
		$expected = array(
250
			'Date' => 'Sat, 07 Apr 2007 10:10:25 GMT',
251
			'X-Powered-By' => 'PHP/5.1.2'
252
		);
253
		$this->assertEquals($expected, $r);
254
 
255
		$header = "people: Jim,John\r\nfoo-LAND: Bar\r\ncAKe-PHP: rocks\r\n";
256
		$r = $this->HttpResponse->parseHeader($header);
257
		$expected = array(
258
			'people' => 'Jim,John',
259
			'foo-LAND' => 'Bar',
260
			'cAKe-PHP' => 'rocks'
261
		);
262
		$this->assertEquals($expected, $r);
263
 
264
		$header = "People: Jim,John,Tim\r\nPeople: Lisa,Tina,Chelsea\r\n";
265
		$r = $this->HttpResponse->parseHeader($header);
266
		$expected = array(
267
			'People' => array('Jim,John,Tim', 'Lisa,Tina,Chelsea')
268
		);
269
		$this->assertEquals($expected, $r);
270
 
271
		$header = "Multi-Line: I am a \r\nmulti line\t\r\nfield value.\r\nSingle-Line: I am not\r\n";
272
		$r = $this->HttpResponse->parseHeader($header);
273
		$expected = array(
274
			'Multi-Line' => "I am a\r\nmulti line\r\nfield value.",
275
			'Single-Line' => 'I am not'
276
		);
277
		$this->assertEquals($expected, $r);
278
 
279
		$header = "Esc\"@\"ped: value\r\n";
280
		$r = $this->HttpResponse->parseHeader($header);
281
		$expected = array(
282
			'Esc@ped' => 'value'
283
		);
284
		$this->assertEquals($expected, $r);
285
	}
286
 
287
/**
288
 * testParseResponse method
289
 *
290
 * @return void
291
 */
292
	public function testParseResponse() {
293
		$tests = array(
294
			'simple-request' => array(
295
				'response' => array(
296
					'status-line' => "HTTP/1.x 200 OK\r\n",
297
					'header' => "Date: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\n",
298
					'body' => "<h1>Hello World</h1>\r\n<p>It's good to be html</p>"
299
				),
300
				'expectations' => array(
301
					'httpVersion' => 'HTTP/1.x',
302
					'code' => 200,
303
					'reasonPhrase' => 'OK',
304
					'headers' => array('Date' => 'Mon, 16 Apr 2007 04:14:16 GMT', 'Server' => 'CakeHttp Server'),
305
					'body' => "<h1>Hello World</h1>\r\n<p>It's good to be html</p>"
306
				)
307
			),
308
			'no-header' => array(
309
				'response' => array(
310
					'status-line' => "HTTP/1.x 404 OK\r\n",
311
					'header' => null
312
				),
313
				'expectations' => array(
314
					'code' => 404,
315
					'headers' => array()
316
				)
317
			)
318
		);
319
 
320
		$testResponse = array();
321
		$expectations = array();
322
 
323
		foreach ($tests as $name => $test) {
324
			$testResponse = array_merge($testResponse, $test['response']);
325
			$testResponse['response'] = $testResponse['status-line'] . $testResponse['header'] . "\r\n" . $testResponse['body'];
326
			$this->HttpResponse->parseResponse($testResponse['response']);
327
			$expectations = array_merge($expectations, $test['expectations']);
328
 
329
			foreach ($expectations as $property => $expectedVal) {
330
				$this->assertEquals($expectedVal, $this->HttpResponse->{$property}, 'Test "' . $name . '": response.' . $property . ' - %s');
331
			}
332
 
333
			foreach (array('status-line', 'header', 'body', 'response') as $field) {
334
				$this->assertEquals($this->HttpResponse['raw'][$field], $testResponse[$field], 'Test response.raw.' . $field . ': %s');
335
			}
336
		}
337
	}
338
 
339
/**
340
 * data provider function for testInvalidParseResponseData
341
 *
342
 * @return array
343
 */
344
	public static function invalidParseResponseDataProvider() {
345
		return array(
346
			array(array('foo' => 'bar')),
347
			array(true),
348
			array("HTTP Foo\r\nBar: La"),
349
			array('HTTP/1.1 TEST ERROR')
350
		);
351
	}
352
 
353
/**
354
 * testInvalidParseResponseData
355
 *
356
 * @dataProvider invalidParseResponseDataProvider
357
 * @expectedException SocketException
358
 * @return void
359
 */
360
	public function testInvalidParseResponseData($value) {
361
		$this->HttpResponse->parseResponse($value);
362
	}
363
 
364
/**
365
 * testDecodeBody method
366
 *
367
 * @return void
368
 */
369
	public function testDecodeBody() {
370
		$r = $this->HttpResponse->decodeBody(true);
371
		$this->assertEquals(false, $r);
372
 
373
		$r = $this->HttpResponse->decodeBody('Foobar', false);
374
		$this->assertEquals(array('body' => 'Foobar', 'header' => false), $r);
375
 
376
		$encoding = 'chunked';
377
		$sample = array(
378
			'encoded' => "19\r\nThis is a chunked message\r\n0\r\n",
379
			'decoded' => array('body' => "This is a chunked message", 'header' => false)
380
		);
381
 
382
		$r = $this->HttpResponse->decodeBody($sample['encoded'], $encoding);
383
		$this->assertEquals($r, $sample['decoded']);
384
 
385
		$encoding = 'chunked';
386
		$sample = array(
387
			'encoded' => "19\nThis is a chunked message\r\n0\n",
388
			'decoded' => array('body' => "This is a chunked message", 'header' => false)
389
		);
390
 
391
		$r = $this->HttpResponse->decodeBody($sample['encoded'], $encoding);
392
		$this->assertEquals($r, $sample['decoded'], 'Inconsistent line terminators should be tolerated.');
393
	}
394
 
395
/**
396
 * testDecodeFooCoded
397
 *
398
 * @return void
399
 */
400
	public function testDecodeFooCoded() {
401
		$r = $this->HttpResponse->decodeBody(true);
402
		$this->assertEquals(false, $r);
403
 
404
		$r = $this->HttpResponse->decodeBody('Foobar', false);
405
		$this->assertEquals(array('body' => 'Foobar', 'header' => false), $r);
406
 
407
		$encoding = 'foo-bar';
408
		$sample = array(
409
			'encoded' => '!Foobar!',
410
			'decoded' => array('body' => '!Foobar!', 'header' => false),
411
		);
412
 
413
		$r = $this->HttpResponse->decodeBody($sample['encoded'], $encoding);
414
		$this->assertEquals($r, $sample['decoded']);
415
	}
416
 
417
/**
418
 * testDecodeChunkedBody method
419
 *
420
 * @return void
421
 */
422
	public function testDecodeChunkedBody() {
423
		$r = $this->HttpResponse->decodeChunkedBody(true);
424
		$this->assertEquals(false, $r);
425
 
426
		$encoded = "19\r\nThis is a chunked message\r\n0\r\n";
427
		$decoded = "This is a chunked message";
428
		$r = $this->HttpResponse->decodeChunkedBody($encoded);
429
		$this->assertEquals($r['body'], $decoded);
430
		$this->assertEquals(false, $r['header']);
431
 
432
		$encoded = "19 \r\nThis is a chunked message\r\n0\r\n";
433
		$r = $this->HttpResponse->decodeChunkedBody($encoded);
434
		$this->assertEquals($r['body'], $decoded);
435
 
436
		$encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n0\r\n";
437
		$decoded = "This is a chunked message\nThat is cool\n";
438
		$r = $this->HttpResponse->decodeChunkedBody($encoded);
439
		$this->assertEquals($r['body'], $decoded);
440
		$this->assertEquals(false, $r['header']);
441
 
442
		$encoded = "19\r\nThis is a chunked message\r\nE;foo-chunk=5\r\n\nThat is cool\n\r\n0\r\n";
443
		$r = $this->HttpResponse->decodeChunkedBody($encoded);
444
		$this->assertEquals($r['body'], $decoded);
445
		$this->assertEquals(false, $r['header']);
446
 
447
		$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";
448
		$r = $this->HttpResponse->decodeChunkedBody($encoded);
449
		$this->assertEquals($r['body'], $decoded);
450
		$this->assertEquals(array('foo-header' => 'bar', 'cake' => 'PHP'), $r['header']);
451
	}
452
 
453
/**
454
 * testDecodeChunkedBodyError method
455
 *
456
 * @expectedException SocketException
457
 * @return void
458
 */
459
	public function testDecodeChunkedBodyError() {
460
		$encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n";
461
		$this->HttpResponse->decodeChunkedBody($encoded);
462
	}
463
 
464
/**
465
 * testParseCookies method
466
 *
467
 * @return void
468
 */
469
	public function testParseCookies() {
470
		$header = array(
471
			'Set-Cookie' => array(
472
				'foo=bar',
473
				'people=jim,jack,johnny";";Path=/accounts',
474
				'google=not=nice'
475
			),
476
			'Transfer-Encoding' => 'chunked',
477
			'Date' => 'Sun, 18 Nov 2007 18:57:42 GMT',
478
		);
479
		$cookies = $this->HttpResponse->parseCookies($header);
480
		$expected = array(
481
			'foo' => array(
482
				'value' => 'bar'
483
			),
484
			'people' => array(
485
				'value' => 'jim,jack,johnny";"',
486
				'path' => '/accounts',
487
			),
488
			'google' => array(
489
				'value' => 'not=nice',
490
			)
491
		);
492
		$this->assertEquals($expected, $cookies);
493
 
494
		$header['Set-Cookie'][] = 'cakephp=great; Secure';
495
		$expected['cakephp'] = array('value' => 'great', 'secure' => true);
496
		$cookies = $this->HttpResponse->parseCookies($header);
497
		$this->assertEquals($expected, $cookies);
498
 
499
		$header['Set-Cookie'] = 'foo=bar';
500
		unset($expected['people'], $expected['cakephp'], $expected['google']);
501
		$cookies = $this->HttpResponse->parseCookies($header);
502
		$this->assertEquals($expected, $cookies);
503
	}
504
 
505
/**
506
 * Test that escaped token strings are properly unescaped by HttpSocket::unescapeToken
507
 *
508
 * @return void
509
 */
510
	public function testUnescapeToken() {
511
		$this->assertEquals('Foo', $this->HttpResponse->unescapeToken('Foo'));
512
 
513
		$escape = $this->HttpResponse->tokenEscapeChars(false);
514
		foreach ($escape as $char) {
515
			$token = 'My-special-"' . $char . '"-Token';
516
			$unescapedToken = $this->HttpResponse->unescapeToken($token);
517
			$expectedToken = 'My-special-' . $char . '-Token';
518
 
519
			$this->assertEquals($expectedToken, $unescapedToken, 'Test token unescaping for ASCII ' . ord($char));
520
		}
521
 
522
		$token = 'Extreme-":"Token-"	"-""""@"-test';
523
		$escapedToken = $this->HttpResponse->unescapeToken($token);
524
		$expectedToken = 'Extreme-:Token-	-"@-test';
525
		$this->assertEquals($expectedToken, $escapedToken);
526
	}
527
 
528
/**
529
 * testArrayAccess
530
 *
531
 * @return void
532
 */
533
	public function testArrayAccess() {
534
		$this->HttpResponse->httpVersion = 'HTTP/1.1';
535
		$this->HttpResponse->code = 200;
536
		$this->HttpResponse->reasonPhrase = 'OK';
537
		$this->HttpResponse->headers = array(
538
			'Server' => 'CakePHP',
539
			'ContEnt-Type' => 'text/plain'
540
		);
541
		$this->HttpResponse->cookies = array(
542
			'foo' => array('value' => 'bar'),
543
			'bar' => array('value' => 'foo')
544
		);
545
		$this->HttpResponse->body = 'This is a test!';
546
		$this->HttpResponse->raw = "HTTP/1.1 200 OK\r\nServer: CakePHP\r\nContEnt-Type: text/plain\r\n\r\nThis is a test!";
547
		$expectedOne = "HTTP/1.1 200 OK\r\n";
548
		$this->assertEquals($expectedOne, $this->HttpResponse['raw']['status-line']);
549
		$expectedTwo = "Server: CakePHP\r\nContEnt-Type: text/plain\r\n";
550
		$this->assertEquals($expectedTwo, $this->HttpResponse['raw']['header']);
551
		$expectedThree = 'This is a test!';
552
		$this->assertEquals($expectedThree, $this->HttpResponse['raw']['body']);
553
		$expected = $expectedOne . $expectedTwo . "\r\n" . $expectedThree;
554
		$this->assertEquals($expected, $this->HttpResponse['raw']['response']);
555
 
556
		$expected = 'HTTP/1.1';
557
		$this->assertEquals($expected, $this->HttpResponse['status']['http-version']);
558
		$expected = 200;
559
		$this->assertEquals($expected, $this->HttpResponse['status']['code']);
560
		$expected = 'OK';
561
		$this->assertEquals($expected, $this->HttpResponse['status']['reason-phrase']);
562
 
563
		$expected = array(
564
			'Server' => 'CakePHP',
565
			'ContEnt-Type' => 'text/plain'
566
		);
567
		$this->assertEquals($expected, $this->HttpResponse['header']);
568
 
569
		$expected = 'This is a test!';
570
		$this->assertEquals($expected, $this->HttpResponse['body']);
571
 
572
		$expected = array(
573
			'foo' => array('value' => 'bar'),
574
			'bar' => array('value' => 'foo')
575
		);
576
		$this->assertEquals($expected, $this->HttpResponse['cookies']);
577
 
578
		$this->HttpResponse->raw = "HTTP/1.1 200 OK\r\n\r\nThis is a test!";
579
		$this->assertNull($this->HttpResponse['raw']['header']);
580
	}
581
 
582
}