Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
13532 anikendra 1
<?php
2
/**
3
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
 *
6
 * Licensed under The MIT License
7
 * For full copyright and license information, please see the LICENSE.txt
8
 * Redistributions of files must retain the above copyright notice.
9
 *
10
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
11
 * @link          http://cakephp.org CakePHP(tm) Project
12
 * @package       Cake.Test.Case.Network
13
 * @since         CakePHP(tm) v 2.0
14
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
15
 */
16
 
17
App::uses('CakeResponse', 'Network');
18
App::uses('CakeRequest', 'Network');
19
 
20
/**
21
 * Class CakeResponseTest
22
 *
23
 * @package       Cake.Test.Case.Network
24
 */
25
class CakeResponseTest extends CakeTestCase {
26
 
27
/**
28
 * Setup for tests
29
 *
30
 * @return void
31
 */
32
	public function setUp() {
33
		parent::setUp();
34
		ob_start();
35
	}
36
 
37
/**
38
 * Cleanup after tests
39
 *
40
 * @return void
41
 */
42
	public function tearDown() {
43
		parent::tearDown();
44
		ob_end_clean();
45
	}
46
 
47
/**
48
 * Tests the request object constructor
49
 *
50
 */
51
	public function testConstruct() {
52
		$response = new CakeResponse();
53
		$this->assertNull($response->body());
54
		$this->assertEquals('UTF-8', $response->charset());
55
		$this->assertEquals('text/html', $response->type());
56
		$this->assertEquals(200, $response->statusCode());
57
 
58
		$options = array(
59
			'body' => 'This is the body',
60
			'charset' => 'my-custom-charset',
61
			'type' => 'mp3',
62
			'status' => '203'
63
		);
64
		$response = new CakeResponse($options);
65
		$this->assertEquals('This is the body', $response->body());
66
		$this->assertEquals('my-custom-charset', $response->charset());
67
		$this->assertEquals('audio/mpeg', $response->type());
68
		$this->assertEquals(203, $response->statusCode());
69
	}
70
 
71
/**
72
 * Tests the body method
73
 *
74
 */
75
	public function testBody() {
76
		$response = new CakeResponse();
77
		$this->assertNull($response->body());
78
		$response->body('Response body');
79
		$this->assertEquals('Response body', $response->body());
80
		$this->assertEquals('Changed Body', $response->body('Changed Body'));
81
	}
82
 
83
/**
84
 * Tests the charset method
85
 *
86
 */
87
	public function testCharset() {
88
		$response = new CakeResponse();
89
		$this->assertEquals('UTF-8', $response->charset());
90
		$response->charset('iso-8859-1');
91
		$this->assertEquals('iso-8859-1', $response->charset());
92
		$this->assertEquals('UTF-16', $response->charset('UTF-16'));
93
	}
94
 
95
/**
96
 * Tests the statusCode method
97
 *
98
 * @expectedException CakeException
99
 */
100
	public function testStatusCode() {
101
		$response = new CakeResponse();
102
		$this->assertEquals(200, $response->statusCode());
103
		$response->statusCode(404);
104
		$this->assertEquals(404, $response->statusCode());
105
		$this->assertEquals(500, $response->statusCode(500));
106
 
107
		//Throws exception
108
		$response->statusCode(1001);
109
	}
110
 
111
/**
112
 * Tests the type method
113
 *
114
 */
115
	public function testType() {
116
		$response = new CakeResponse();
117
		$this->assertEquals('text/html', $response->type());
118
		$response->type('pdf');
119
		$this->assertEquals('application/pdf', $response->type());
120
		$this->assertEquals('application/crazy-mime', $response->type('application/crazy-mime'));
121
		$this->assertEquals('application/json', $response->type('json'));
122
		$this->assertEquals('text/vnd.wap.wml', $response->type('wap'));
123
		$this->assertEquals('application/vnd.wap.xhtml+xml', $response->type('xhtml-mobile'));
124
		$this->assertEquals('text/csv', $response->type('csv'));
125
 
126
		$response->type(array('keynote' => 'application/keynote', 'bat' => 'application/bat'));
127
		$this->assertEquals('application/keynote', $response->type('keynote'));
128
		$this->assertEquals('application/bat', $response->type('bat'));
129
 
130
		$this->assertFalse($response->type('wackytype'));
131
	}
132
 
133
/**
134
 * Tests the header method
135
 *
136
 */
137
	public function testHeader() {
138
		$response = new CakeResponse();
139
		$headers = array();
140
		$this->assertEquals($headers, $response->header());
141
 
142
		$response->header('Location', 'http://example.com');
143
		$headers += array('Location' => 'http://example.com');
144
		$this->assertEquals($headers, $response->header());
145
 
146
		//Headers with the same name are overwritten
147
		$response->header('Location', 'http://example2.com');
148
		$headers = array('Location' => 'http://example2.com');
149
		$this->assertEquals($headers, $response->header());
150
 
151
		$response->header(array('WWW-Authenticate' => 'Negotiate'));
152
		$headers += array('WWW-Authenticate' => 'Negotiate');
153
		$this->assertEquals($headers, $response->header());
154
 
155
		$response->header(array('WWW-Authenticate' => 'Not-Negotiate'));
156
		$headers['WWW-Authenticate'] = 'Not-Negotiate';
157
		$this->assertEquals($headers, $response->header());
158
 
159
		$response->header(array('Age' => 12, 'Allow' => 'GET, HEAD'));
160
		$headers += array('Age' => 12, 'Allow' => 'GET, HEAD');
161
		$this->assertEquals($headers, $response->header());
162
 
163
		// String headers are allowed
164
		$response->header('Content-Language: da');
165
		$headers += array('Content-Language' => 'da');
166
		$this->assertEquals($headers, $response->header());
167
 
168
		$response->header('Content-Language: da');
169
		$headers += array('Content-Language' => 'da');
170
		$this->assertEquals($headers, $response->header());
171
 
172
		$response->header(array('Content-Encoding: gzip', 'Vary: *', 'Pragma' => 'no-cache'));
173
		$headers += array('Content-Encoding' => 'gzip', 'Vary' => '*', 'Pragma' => 'no-cache');
174
		$this->assertEquals($headers, $response->header());
175
 
176
		$response->header('Access-Control-Allow-Origin', array('domain1', 'domain2'));
177
		$headers += array('Access-Control-Allow-Origin' => array('domain1', 'domain2'));
178
		$this->assertEquals($headers, $response->header());
179
	}
180
 
181
/**
182
 * Tests the send method
183
 *
184
 */
185
	public function testSend() {
186
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', '_setCookies'));
187
		$response->header(array(
188
			'Content-Language' => 'es',
189
			'WWW-Authenticate' => 'Negotiate',
190
			'Access-Control-Allow-Origin' => array('domain1', 'domain2'),
191
		));
192
		$response->body('the response body');
193
		$response->expects($this->once())->method('_sendContent')->with('the response body');
194
		$response->expects($this->at(0))->method('_setCookies');
195
		$response->expects($this->at(1))
196
			->method('_sendHeader')->with('HTTP/1.1 200 OK');
197
		$response->expects($this->at(2))
198
			->method('_sendHeader')->with('Content-Language', 'es');
199
		$response->expects($this->at(3))
200
			->method('_sendHeader')->with('WWW-Authenticate', 'Negotiate');
201
		$response->expects($this->at(4))
202
			->method('_sendHeader')->with('Access-Control-Allow-Origin', 'domain1');
203
		$response->expects($this->at(5))
204
			->method('_sendHeader')->with('Access-Control-Allow-Origin', 'domain2');
205
		$response->expects($this->at(6))
206
			->method('_sendHeader')->with('Content-Length', 17);
207
		$response->expects($this->at(7))
208
			->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
209
		$response->send();
210
	}
211
 
212
/**
213
 * Data provider for content type tests.
214
 *
215
 * @return array
216
 */
217
	public static function charsetTypeProvider() {
218
		return array(
219
			array('mp3', 'audio/mpeg'),
220
			array('js', 'application/javascript; charset=UTF-8'),
221
			array('json', 'application/json; charset=UTF-8'),
222
			array('xml', 'application/xml; charset=UTF-8'),
223
			array('txt', 'text/plain; charset=UTF-8'),
224
		);
225
	}
226
 
227
/**
228
 * Tests the send method and changing the content type
229
 * @dataProvider charsetTypeProvider
230
 */
231
	public function testSendChangingContentType($original, $expected) {
232
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', '_setCookies'));
233
		$response->type($original);
234
		$response->body('the response body');
235
		$response->expects($this->once())->method('_sendContent')->with('the response body');
236
		$response->expects($this->at(0))->method('_setCookies');
237
		$response->expects($this->at(1))
238
			->method('_sendHeader')->with('HTTP/1.1 200 OK');
239
		$response->expects($this->at(2))
240
			->method('_sendHeader')->with('Content-Length', 17);
241
		$response->expects($this->at(3))
242
			->method('_sendHeader')->with('Content-Type', $expected);
243
		$response->send();
244
	}
245
 
246
/**
247
 * Tests the send method and changing the content type to JS without adding the charset
248
 *
249
 */
250
	public function testSendChangingContentTypeWithoutCharset() {
251
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', '_setCookies'));
252
		$response->type('js');
253
		$response->charset('');
254
 
255
		$response->body('var $foo = "bar";');
256
		$response->expects($this->once())->method('_sendContent')->with('var $foo = "bar";');
257
		$response->expects($this->at(0))->method('_setCookies');
258
		$response->expects($this->at(1))
259
			->method('_sendHeader')->with('HTTP/1.1 200 OK');
260
		$response->expects($this->at(2))
261
			->method('_sendHeader')->with('Content-Length', 17);
262
		$response->expects($this->at(3))
263
			->method('_sendHeader')->with('Content-Type', 'application/javascript');
264
		$response->send();
265
	}
266
 
267
/**
268
 * Tests the send method and changing the content type
269
 *
270
 */
271
	public function testSendWithLocation() {
272
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', '_setCookies'));
273
		$response->header('Location', 'http://www.example.com');
274
		$response->expects($this->at(0))->method('_setCookies');
275
		$response->expects($this->at(1))
276
			->method('_sendHeader')->with('HTTP/1.1 302 Found');
277
		$response->expects($this->at(2))
278
			->method('_sendHeader')->with('Location', 'http://www.example.com');
279
		$response->expects($this->at(3))
280
			->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
281
		$response->send();
282
	}
283
 
284
/**
285
 * Tests the disableCache method
286
 *
287
 */
288
	public function testDisableCache() {
289
		$response = new CakeResponse();
290
		$expected = array(
291
			'Expires' => 'Mon, 26 Jul 1997 05:00:00 GMT',
292
			'Last-Modified' => gmdate("D, d M Y H:i:s") . " GMT",
293
			'Cache-Control' => 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
294
		);
295
		$response->disableCache();
296
		$this->assertEquals($expected, $response->header());
297
	}
298
 
299
/**
300
 * Tests the cache method
301
 *
302
 */
303
	public function testCache() {
304
		$response = new CakeResponse();
305
		$since = time();
306
		$time = new DateTime('+1 day', new DateTimeZone('UTC'));
307
		$response->expires('+1 day');
308
		$expected = array(
309
			'Date' => gmdate("D, j M Y G:i:s ", $since) . 'GMT',
310
			'Last-Modified' => gmdate("D, j M Y H:i:s ", $since) . 'GMT',
311
			'Expires' => $time->format('D, j M Y H:i:s') . ' GMT',
312
			'Cache-Control' => 'public, max-age=' . ($time->format('U') - time())
313
		);
314
		$response->cache($since);
315
		$this->assertEquals($expected, $response->header());
316
 
317
		$response = new CakeResponse();
318
		$since = time();
319
		$time = '+5 day';
320
		$expected = array(
321
			'Date' => gmdate("D, j M Y G:i:s ", $since) . 'GMT',
322
			'Last-Modified' => gmdate("D, j M Y H:i:s ", $since) . 'GMT',
323
			'Expires' => gmdate("D, j M Y H:i:s", strtotime($time)) . " GMT",
324
			'Cache-Control' => 'public, max-age=' . (strtotime($time) - time())
325
		);
326
		$response->cache($since, $time);
327
		$this->assertEquals($expected, $response->header());
328
 
329
		$response = new CakeResponse();
330
		$since = time();
331
		$time = time();
332
		$expected = array(
333
			'Date' => gmdate("D, j M Y G:i:s ", $since) . 'GMT',
334
			'Last-Modified' => gmdate("D, j M Y H:i:s ", $since) . 'GMT',
335
			'Expires' => gmdate("D, j M Y H:i:s", $time) . " GMT",
336
			'Cache-Control' => 'public, max-age=0'
337
		);
338
		$response->cache($since, $time);
339
		$this->assertEquals($expected, $response->header());
340
	}
341
 
342
/**
343
 * Tests the compress method
344
 *
345
 * @return void
346
 */
347
	public function testCompress() {
348
		if (php_sapi_name() !== 'cli') {
349
			$this->markTestSkipped('The response compression can only be tested in cli.');
350
		}
351
 
352
		$response = new CakeResponse();
353
		if (ini_get("zlib.output_compression") === '1' || !extension_loaded("zlib")) {
354
			$this->assertFalse($response->compress());
355
			$this->markTestSkipped('Is not possible to test output compression');
356
		}
357
 
358
		$_SERVER['HTTP_ACCEPT_ENCODING'] = '';
359
		$result = $response->compress();
360
		$this->assertFalse($result);
361
 
362
		$_SERVER['HTTP_ACCEPT_ENCODING'] = 'gzip';
363
		$result = $response->compress();
364
		$this->assertTrue($result);
365
		$this->assertTrue(in_array('ob_gzhandler', ob_list_handlers()));
366
 
367
		ob_get_clean();
368
	}
369
 
370
/**
371
 * Tests the httpCodes method
372
 *
373
 * @expectedException CakeException
374
 */
375
	public function testHttpCodes() {
376
		$response = new CakeResponse();
377
		$result = $response->httpCodes();
378
		$this->assertEquals(40, count($result));
379
 
380
		$result = $response->httpCodes(100);
381
		$expected = array(100 => 'Continue');
382
		$this->assertEquals($expected, $result);
383
 
384
		$codes = array(
385
			381 => 'Unicorn Moved',
386
			555 => 'Unexpected Minotaur'
387
		);
388
 
389
		$result = $response->httpCodes($codes);
390
		$this->assertTrue($result);
391
		$this->assertEquals(42, count($response->httpCodes()));
392
 
393
		$result = $response->httpCodes(381);
394
		$expected = array(381 => 'Unicorn Moved');
395
		$this->assertEquals($expected, $result);
396
 
397
		$codes = array(404 => 'Sorry Bro');
398
		$result = $response->httpCodes($codes);
399
		$this->assertTrue($result);
400
		$this->assertEquals(42, count($response->httpCodes()));
401
 
402
		$result = $response->httpCodes(404);
403
		$expected = array(404 => 'Sorry Bro');
404
		$this->assertEquals($expected, $result);
405
 
406
		//Throws exception
407
		$response->httpCodes(array(
408
 
409
			-1 => 'Reverse Infinity',
410
			12345 => 'Universal Password',
411
			'Hello' => 'World'
412
		));
413
	}
414
 
415
/**
416
 * Tests the download method
417
 *
418
 */
419
	public function testDownload() {
420
		$response = new CakeResponse();
421
		$expected = array(
422
			'Content-Disposition' => 'attachment; filename="myfile.mp3"'
423
		);
424
		$response->download('myfile.mp3');
425
		$this->assertEquals($expected, $response->header());
426
	}
427
 
428
/**
429
 * Tests the mapType method
430
 *
431
 */
432
	public function testMapType() {
433
		$response = new CakeResponse();
434
		$this->assertEquals('wav', $response->mapType('audio/x-wav'));
435
		$this->assertEquals('pdf', $response->mapType('application/pdf'));
436
		$this->assertEquals('xml', $response->mapType('text/xml'));
437
		$this->assertEquals('html', $response->mapType('*/*'));
438
		$this->assertEquals('csv', $response->mapType('application/vnd.ms-excel'));
439
		$expected = array('json', 'xhtml', 'css');
440
		$result = $response->mapType(array('application/json', 'application/xhtml+xml', 'text/css'));
441
		$this->assertEquals($expected, $result);
442
	}
443
 
444
/**
445
 * Tests the outputCompressed method
446
 *
447
 */
448
	public function testOutputCompressed() {
449
		$response = new CakeResponse();
450
 
451
		$_SERVER['HTTP_ACCEPT_ENCODING'] = 'gzip';
452
		$result = $response->outputCompressed();
453
		$this->assertFalse($result);
454
 
455
		$_SERVER['HTTP_ACCEPT_ENCODING'] = '';
456
		$result = $response->outputCompressed();
457
		$this->assertFalse($result);
458
 
459
		if (!extension_loaded("zlib")) {
460
			$this->markTestSkipped('Skipping further tests for outputCompressed as zlib extension is not loaded');
461
		}
462
		if (php_sapi_name() !== 'cli') {
463
			$this->markTestSkipped('Testing outputCompressed method with compression enabled done only in cli');
464
		}
465
 
466
		if (ini_get("zlib.output_compression") !== '1') {
467
			ob_start('ob_gzhandler');
468
		}
469
		$_SERVER['HTTP_ACCEPT_ENCODING'] = 'gzip';
470
		$result = $response->outputCompressed();
471
		$this->assertTrue($result);
472
 
473
		$_SERVER['HTTP_ACCEPT_ENCODING'] = '';
474
		$result = $response->outputCompressed();
475
		$this->assertFalse($result);
476
		if (ini_get("zlib.output_compression") !== '1') {
477
			ob_get_clean();
478
		}
479
	}
480
 
481
/**
482
 * Tests the send and setting of Content-Length
483
 *
484
 */
485
	public function testSendContentLength() {
486
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
487
		$response->body('the response body');
488
		$response->expects($this->once())->method('_sendContent')->with('the response body');
489
		$response->expects($this->at(0))
490
			->method('_sendHeader')->with('HTTP/1.1 200 OK');
491
		$response->expects($this->at(2))
492
			->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
493
		$response->expects($this->at(1))
494
			->method('_sendHeader')->with('Content-Length', strlen('the response body'));
495
		$response->send();
496
 
497
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
498
		$body = '長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう?';
499
		$response->body($body);
500
		$response->expects($this->once())->method('_sendContent')->with($body);
501
		$response->expects($this->at(0))
502
			->method('_sendHeader')->with('HTTP/1.1 200 OK');
503
		$response->expects($this->at(2))
504
			->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
505
		$response->expects($this->at(1))
506
			->method('_sendHeader')->with('Content-Length', 116);
507
		$response->send();
508
 
509
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', 'outputCompressed'));
510
		$body = '長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう?';
511
		$response->body($body);
512
		$response->expects($this->once())->method('outputCompressed')->will($this->returnValue(true));
513
		$response->expects($this->once())->method('_sendContent')->with($body);
514
		$response->expects($this->exactly(2))->method('_sendHeader');
515
		$response->send();
516
 
517
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', 'outputCompressed'));
518
		$body = 'hwy';
519
		$response->body($body);
520
		$response->header('Content-Length', 1);
521
		$response->expects($this->never())->method('outputCompressed');
522
		$response->expects($this->once())->method('_sendContent')->with($body);
523
		$response->expects($this->at(1))
524
				->method('_sendHeader')->with('Content-Length', 1);
525
		$response->send();
526
 
527
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
528
		$body = 'content';
529
		$response->statusCode(301);
530
		$response->body($body);
531
		$response->expects($this->once())->method('_sendContent')->with($body);
532
		$response->expects($this->exactly(2))->method('_sendHeader');
533
		$response->send();
534
 
535
		ob_start();
536
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
537
		$goofyOutput = 'I am goofily sending output in the controller';
538
		echo $goofyOutput;
539
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
540
		$body = '長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう?';
541
		$response->body($body);
542
		$response->expects($this->once())->method('_sendContent')->with($body);
543
		$response->expects($this->at(0))
544
			->method('_sendHeader')->with('HTTP/1.1 200 OK');
545
		$response->expects($this->at(1))
546
			->method('_sendHeader')->with('Content-Length', strlen($goofyOutput) + 116);
547
		$response->expects($this->at(2))
548
			->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
549
		$response->send();
550
		ob_end_clean();
551
	}
552
 
553
/**
554
 * Tests getting/setting the protocol
555
 *
556
 * @return void
557
 */
558
	public function testProtocol() {
559
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
560
		$response->protocol('HTTP/1.0');
561
		$this->assertEquals('HTTP/1.0', $response->protocol());
562
		$response->expects($this->at(0))
563
			->method('_sendHeader')->with('HTTP/1.0 200 OK');
564
		$response->send();
565
	}
566
 
567
/**
568
 * Tests getting/setting the Content-Length
569
 *
570
 * @return void
571
 */
572
	public function testLength() {
573
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
574
		$response->length(100);
575
		$this->assertEquals(100, $response->length());
576
		$response->expects($this->at(1))
577
			->method('_sendHeader')->with('Content-Length', 100);
578
		$response->send();
579
 
580
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
581
		$response->length(false);
582
		$this->assertFalse($response->length());
583
		$response->expects($this->exactly(2))
584
			->method('_sendHeader');
585
		$response->send();
586
	}
587
 
588
/**
589
 * Tests that the response body is unset if the status code is 304 or 204
590
 *
591
 * @return void
592
 */
593
	public function testUnmodifiedContent() {
594
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
595
		$response->body('This is a body');
596
		$response->statusCode(204);
597
		$response->expects($this->once())
598
			->method('_sendContent')->with('');
599
		$response->send();
600
		$this->assertFalse(array_key_exists('Content-Type', $response->header()));
601
 
602
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
603
		$response->body('This is a body');
604
		$response->statusCode(304);
605
		$response->expects($this->once())
606
			->method('_sendContent')->with('');
607
		$response->send();
608
 
609
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
610
		$response->body('This is a body');
611
		$response->statusCode(200);
612
		$response->expects($this->once())
613
			->method('_sendContent')->with('This is a body');
614
		$response->send();
615
	}
616
 
617
/**
618
 * Tests setting the expiration date
619
 *
620
 * @return void
621
 */
622
	public function testExpires() {
623
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
624
		$now = new DateTime('now', new DateTimeZone('America/Los_Angeles'));
625
		$response->expires($now);
626
		$now->setTimeZone(new DateTimeZone('UTC'));
627
		$this->assertEquals($now->format('D, j M Y H:i:s') . ' GMT', $response->expires());
628
		$response->expects($this->at(1))
629
			->method('_sendHeader')->with('Expires', $now->format('D, j M Y H:i:s') . ' GMT');
630
		$response->send();
631
 
632
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
633
		$now = time();
634
		$response->expires($now);
635
		$this->assertEquals(gmdate('D, j M Y H:i:s', $now) . ' GMT', $response->expires());
636
		$response->expects($this->at(1))
637
			->method('_sendHeader')->with('Expires', gmdate('D, j M Y H:i:s', $now) . ' GMT');
638
		$response->send();
639
 
640
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
641
		$time = new DateTime('+1 day', new DateTimeZone('UTC'));
642
		$response->expires('+1 day');
643
		$this->assertEquals($time->format('D, j M Y H:i:s') . ' GMT', $response->expires());
644
		$response->expects($this->at(1))
645
			->method('_sendHeader')->with('Expires', $time->format('D, j M Y H:i:s') . ' GMT');
646
		$response->send();
647
	}
648
 
649
/**
650
 * Tests setting the modification date
651
 *
652
 * @return void
653
 */
654
	public function testModified() {
655
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
656
		$now = new DateTime('now', new DateTimeZone('America/Los_Angeles'));
657
		$response->modified($now);
658
		$now->setTimeZone(new DateTimeZone('UTC'));
659
		$this->assertEquals($now->format('D, j M Y H:i:s') . ' GMT', $response->modified());
660
		$response->expects($this->at(1))
661
			->method('_sendHeader')->with('Last-Modified', $now->format('D, j M Y H:i:s') . ' GMT');
662
		$response->send();
663
 
664
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
665
		$now = time();
666
		$response->modified($now);
667
		$this->assertEquals(gmdate('D, j M Y H:i:s', $now) . ' GMT', $response->modified());
668
		$response->expects($this->at(1))
669
			->method('_sendHeader')->with('Last-Modified', gmdate('D, j M Y H:i:s', $now) . ' GMT');
670
		$response->send();
671
 
672
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
673
		$time = new DateTime('+1 day', new DateTimeZone('UTC'));
674
		$response->modified('+1 day');
675
		$this->assertEquals($time->format('D, j M Y H:i:s') . ' GMT', $response->modified());
676
		$response->expects($this->at(1))
677
			->method('_sendHeader')->with('Last-Modified', $time->format('D, j M Y H:i:s') . ' GMT');
678
		$response->send();
679
	}
680
 
681
/**
682
 * Tests setting of public/private Cache-Control directives
683
 *
684
 * @return void
685
 */
686
	public function testSharable() {
687
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
688
		$this->assertNull($response->sharable());
689
		$response->sharable(true);
690
		$headers = $response->header();
691
		$this->assertEquals('public', $headers['Cache-Control']);
692
		$response->expects($this->at(1))
693
			->method('_sendHeader')->with('Cache-Control', 'public');
694
		$response->send();
695
 
696
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
697
		$response->sharable(false);
698
		$headers = $response->header();
699
		$this->assertEquals('private', $headers['Cache-Control']);
700
		$response->expects($this->at(1))
701
			->method('_sendHeader')->with('Cache-Control', 'private');
702
		$response->send();
703
 
704
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
705
		$response->sharable(true);
706
		$headers = $response->header();
707
		$this->assertEquals('public', $headers['Cache-Control']);
708
		$response->sharable(false);
709
		$headers = $response->header();
710
		$this->assertEquals('private', $headers['Cache-Control']);
711
		$response->expects($this->at(1))
712
			->method('_sendHeader')->with('Cache-Control', 'private');
713
		$response->send();
714
		$this->assertFalse($response->sharable());
715
		$response->sharable(true);
716
		$this->assertTrue($response->sharable());
717
 
718
		$response = new CakeResponse;
719
		$response->sharable(true, 3600);
720
		$headers = $response->header();
721
		$this->assertEquals('public, s-maxage=3600', $headers['Cache-Control']);
722
 
723
		$response = new CakeResponse;
724
		$response->sharable(false, 3600);
725
		$headers = $response->header();
726
		$this->assertEquals('private, max-age=3600', $headers['Cache-Control']);
727
		$response->send();
728
	}
729
 
730
/**
731
 * Tests setting of max-age Cache-Control directive
732
 *
733
 * @return void
734
 */
735
	public function testMaxAge() {
736
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
737
		$this->assertNull($response->maxAge());
738
		$response->maxAge(3600);
739
		$this->assertEquals(3600, $response->maxAge());
740
		$headers = $response->header();
741
		$this->assertEquals('max-age=3600', $headers['Cache-Control']);
742
		$response->expects($this->at(1))
743
			->method('_sendHeader')->with('Cache-Control', 'max-age=3600');
744
		$response->send();
745
 
746
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
747
		$response->maxAge(3600);
748
		$response->sharable(false);
749
		$headers = $response->header();
750
		$this->assertEquals('max-age=3600, private', $headers['Cache-Control']);
751
		$response->expects($this->at(1))
752
			->method('_sendHeader')->with('Cache-Control', 'max-age=3600, private');
753
		$response->send();
754
	}
755
 
756
/**
757
 * Tests setting of s-maxage Cache-Control directive
758
 *
759
 * @return void
760
 */
761
	public function testSharedMaxAge() {
762
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
763
		$this->assertNull($response->maxAge());
764
		$response->sharedMaxAge(3600);
765
		$this->assertEquals(3600, $response->sharedMaxAge());
766
		$headers = $response->header();
767
		$this->assertEquals('s-maxage=3600', $headers['Cache-Control']);
768
		$response->expects($this->at(1))
769
			->method('_sendHeader')->with('Cache-Control', 's-maxage=3600');
770
		$response->send();
771
 
772
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
773
		$response->sharedMaxAge(3600);
774
		$response->sharable(true);
775
		$headers = $response->header();
776
		$this->assertEquals('s-maxage=3600, public', $headers['Cache-Control']);
777
		$response->expects($this->at(1))
778
			->method('_sendHeader')->with('Cache-Control', 's-maxage=3600, public');
779
		$response->send();
780
	}
781
 
782
/**
783
 * Tests setting of must-revalidate Cache-Control directive
784
 *
785
 * @return void
786
 */
787
	public function testMustRevalidate() {
788
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
789
		$this->assertFalse($response->mustRevalidate());
790
		$response->mustRevalidate(true);
791
		$this->assertTrue($response->mustRevalidate());
792
		$headers = $response->header();
793
		$this->assertEquals('must-revalidate', $headers['Cache-Control']);
794
		$response->expects($this->at(1))
795
			->method('_sendHeader')->with('Cache-Control', 'must-revalidate');
796
		$response->send();
797
		$response->mustRevalidate(false);
798
		$this->assertFalse($response->mustRevalidate());
799
 
800
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
801
		$response->sharedMaxAge(3600);
802
		$response->mustRevalidate(true);
803
		$headers = $response->header();
804
		$this->assertEquals('s-maxage=3600, must-revalidate', $headers['Cache-Control']);
805
		$response->expects($this->at(1))
806
			->method('_sendHeader')->with('Cache-Control', 's-maxage=3600, must-revalidate');
807
		$response->send();
808
	}
809
 
810
/**
811
 * Tests getting/setting the Vary header
812
 *
813
 * @return void
814
 */
815
	public function testVary() {
816
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
817
		$response->vary('Accept-encoding');
818
		$this->assertEquals(array('Accept-encoding'), $response->vary());
819
		$response->expects($this->at(1))
820
			->method('_sendHeader')->with('Vary', 'Accept-encoding');
821
		$response->send();
822
 
823
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
824
		$response->vary(array('Accept-language', 'Accept-encoding'));
825
		$response->expects($this->at(1))
826
			->method('_sendHeader')->with('Vary', 'Accept-language, Accept-encoding');
827
		$response->send();
828
		$this->assertEquals(array('Accept-language', 'Accept-encoding'), $response->vary());
829
	}
830
 
831
/**
832
 * Tests getting/setting the Etag header
833
 *
834
 * @return void
835
 */
836
	public function testEtag() {
837
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
838
		$response->etag('something');
839
		$this->assertEquals('"something"', $response->etag());
840
		$response->expects($this->at(1))
841
			->method('_sendHeader')->with('Etag', '"something"');
842
		$response->send();
843
 
844
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
845
		$response->etag('something', true);
846
		$this->assertEquals('W/"something"', $response->etag());
847
		$response->expects($this->at(1))
848
			->method('_sendHeader')->with('Etag', 'W/"something"');
849
		$response->send();
850
	}
851
 
852
/**
853
 * Tests that the response is able to be marked as not modified
854
 *
855
 * @return void
856
 */
857
	public function testNotModified() {
858
		$response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
859
		$response->body('something');
860
		$response->statusCode(200);
861
		$response->length(100);
862
		$response->modified('now');
863
		$response->notModified();
864
 
865
		$this->assertEmpty($response->header());
866
		$this->assertEmpty($response->body());
867
		$this->assertEquals(304, $response->statusCode());
868
	}
869
 
870
/**
871
 * Test checkNotModified method
872
 *
873
 * @return void
874
 */
875
	public function testCheckNotModifiedByEtagStar() {
876
		$_SERVER['HTTP_IF_NONE_MATCH'] = '*';
877
		$response = $this->getMock('CakeResponse', array('notModified'));
878
		$response->etag('something');
879
		$response->expects($this->once())->method('notModified');
880
		$response->checkNotModified(new CakeRequest);
881
	}
882
 
883
/**
884
 * Test checkNotModified method
885
 *
886
 * @return void
887
 */
888
	public function testCheckNotModifiedByEtagExact() {
889
		$_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
890
		$response = $this->getMock('CakeResponse', array('notModified'));
891
		$response->etag('something', true);
892
		$response->expects($this->once())->method('notModified');
893
		$this->assertTrue($response->checkNotModified(new CakeRequest));
894
	}
895
 
896
/**
897
 * Test checkNotModified method
898
 *
899
 * @return void
900
 */
901
	public function testCheckNotModifiedByEtagAndTime() {
902
		$_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
903
		$_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
904
		$response = $this->getMock('CakeResponse', array('notModified'));
905
		$response->etag('something', true);
906
		$response->modified('2012-01-01 00:00:00');
907
		$response->expects($this->once())->method('notModified');
908
		$this->assertTrue($response->checkNotModified(new CakeRequest));
909
	}
910
 
911
/**
912
 * Test checkNotModified method
913
 *
914
 * @return void
915
 */
916
	public function testCheckNotModifiedByEtagAndTimeMismatch() {
917
		$_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
918
		$_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
919
		$response = $this->getMock('CakeResponse', array('notModified'));
920
		$response->etag('something', true);
921
		$response->modified('2012-01-01 00:00:01');
922
		$response->expects($this->never())->method('notModified');
923
		$this->assertFalse($response->checkNotModified(new CakeRequest));
924
	}
925
 
926
/**
927
 * Test checkNotModified method
928
 *
929
 * @return void
930
 */
931
	public function testCheckNotModifiedByEtagMismatch() {
932
		$_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something-else", "other"';
933
		$_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
934
		$response = $this->getMock('CakeResponse', array('notModified'));
935
		$response->etag('something', true);
936
		$response->modified('2012-01-01 00:00:00');
937
		$response->expects($this->never())->method('notModified');
938
		$this->assertFalse($response->checkNotModified(new CakeRequest));
939
	}
940
 
941
/**
942
 * Test checkNotModified method
943
 *
944
 * @return void
945
 */
946
	public function testCheckNotModifiedByTime() {
947
		$_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
948
		$response = $this->getMock('CakeResponse', array('notModified'));
949
		$response->modified('2012-01-01 00:00:00');
950
		$response->expects($this->once())->method('notModified');
951
		$this->assertTrue($response->checkNotModified(new CakeRequest));
952
	}
953
 
954
/**
955
 * Test checkNotModified method
956
 *
957
 * @return void
958
 */
959
	public function testCheckNotModifiedNoHints() {
960
		$_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
961
		$_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
962
		$response = $this->getMock('CakeResponse', array('notModified'));
963
		$response->expects($this->never())->method('notModified');
964
		$this->assertFalse($response->checkNotModified(new CakeRequest));
965
	}
966
 
967
/**
968
 * Test cookie setting
969
 *
970
 * @return void
971
 */
972
	public function testCookieSettings() {
973
		$response = new CakeResponse();
974
		$cookie = array(
975
			'name' => 'CakeTestCookie[Testing]'
976
		);
977
		$response->cookie($cookie);
978
		$expected = array(
979
			'name' => 'CakeTestCookie[Testing]',
980
			'value' => '',
981
			'expire' => 0,
982
			'path' => '/',
983
			'domain' => '',
984
			'secure' => false,
985
			'httpOnly' => false);
986
		$result = $response->cookie('CakeTestCookie[Testing]');
987
		$this->assertEquals($expected, $result);
988
 
989
		$cookie = array(
990
			'name' => 'CakeTestCookie[Testing2]',
991
			'value' => '[a,b,c]',
992
			'expire' => 1000,
993
			'path' => '/test',
994
			'secure' => true
995
		);
996
		$response->cookie($cookie);
997
		$expected = array(
998
			'CakeTestCookie[Testing]' => array(
999
				'name' => 'CakeTestCookie[Testing]',
1000
				'value' => '',
1001
				'expire' => 0,
1002
				'path' => '/',
1003
				'domain' => '',
1004
				'secure' => false,
1005
				'httpOnly' => false
1006
			),
1007
			'CakeTestCookie[Testing2]' => array(
1008
				'name' => 'CakeTestCookie[Testing2]',
1009
				'value' => '[a,b,c]',
1010
				'expire' => 1000,
1011
				'path' => '/test',
1012
				'domain' => '',
1013
				'secure' => true,
1014
				'httpOnly' => false
1015
			)
1016
		);
1017
 
1018
		$result = $response->cookie();
1019
		$this->assertEquals($expected, $result);
1020
 
1021
		$cookie = $expected['CakeTestCookie[Testing]'];
1022
		$cookie['value'] = 'test';
1023
		$response->cookie($cookie);
1024
		$expected = array(
1025
			'CakeTestCookie[Testing]' => array(
1026
				'name' => 'CakeTestCookie[Testing]',
1027
				'value' => 'test',
1028
				'expire' => 0,
1029
				'path' => '/',
1030
				'domain' => '',
1031
				'secure' => false,
1032
				'httpOnly' => false
1033
			),
1034
			'CakeTestCookie[Testing2]' => array(
1035
				'name' => 'CakeTestCookie[Testing2]',
1036
				'value' => '[a,b,c]',
1037
				'expire' => 1000,
1038
				'path' => '/test',
1039
				'domain' => '',
1040
				'secure' => true,
1041
				'httpOnly' => false
1042
			)
1043
		);
1044
 
1045
		$result = $response->cookie();
1046
		$this->assertEquals($expected, $result);
1047
	}
1048
 
1049
/**
1050
 * testFileNotFound
1051
 *
1052
 * @expectedException NotFoundException
1053
 * @return void
1054
 */
1055
	public function testFileNotFound() {
1056
		$response = new CakeResponse();
1057
		$response->file('/some/missing/folder/file.jpg');
1058
	}
1059
 
1060
/**
1061
 * testFile method
1062
 *
1063
 * @return void
1064
 */
1065
	public function testFile() {
1066
		$response = $this->getMock('CakeResponse', array(
1067
			'header',
1068
			'type',
1069
			'_sendHeader',
1070
			'_setContentType',
1071
			'_isActive',
1072
			'_clearBuffer',
1073
			'_flushBuffer'
1074
		));
1075
 
1076
		$response->expects($this->exactly(1))
1077
			->method('type')
1078
			->with('css')
1079
			->will($this->returnArgument(0));
1080
 
1081
		$response->expects($this->at(1))
1082
			->method('header')
1083
			->with('Content-Length', 38);
1084
 
1085
		$response->expects($this->once())->method('_clearBuffer');
1086
		$response->expects($this->once())->method('_flushBuffer');
1087
 
1088
		$response->expects($this->exactly(1))
1089
			->method('_isActive')
1090
			->will($this->returnValue(true));
1091
 
1092
		$response->file(CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'css' . DS . 'test_asset.css');
1093
 
1094
		ob_start();
1095
		$result = $response->send();
1096
		$output = ob_get_clean();
1097
		$this->assertEquals("/* this is the test asset css file */\n", $output);
1098
		$this->assertTrue($result !== false);
1099
	}
1100
 
1101
/**
1102
 * testFileWithUnknownFileTypeGeneric method
1103
 *
1104
 * @return void
1105
 */
1106
	public function testFileWithUnknownFileTypeGeneric() {
1107
		$currentUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
1108
		$_SERVER['HTTP_USER_AGENT'] = 'Some generic browser';
1109
 
1110
		$response = $this->getMock('CakeResponse', array(
1111
			'header',
1112
			'type',
1113
			'download',
1114
			'_sendHeader',
1115
			'_setContentType',
1116
			'_isActive',
1117
			'_clearBuffer',
1118
			'_flushBuffer'
1119
		));
1120
 
1121
		$response->expects($this->exactly(1))
1122
			->method('type')
1123
			->with('ini')
1124
			->will($this->returnValue(false));
1125
 
1126
		$response->expects($this->once())
1127
			->method('download')
1128
			->with('no_section.ini');
1129
 
1130
		$response->expects($this->at(2))
1131
			->method('header')
1132
			->with('Accept-Ranges', 'bytes');
1133
 
1134
		$response->expects($this->at(3))
1135
			->method('header')
1136
			->with('Content-Transfer-Encoding', 'binary');
1137
 
1138
		$response->expects($this->at(4))
1139
			->method('header')
1140
			->with('Content-Length', 35);
1141
 
1142
		$response->expects($this->once())->method('_clearBuffer');
1143
		$response->expects($this->once())->method('_flushBuffer');
1144
 
1145
		$response->expects($this->exactly(1))
1146
			->method('_isActive')
1147
			->will($this->returnValue(true));
1148
 
1149
		$response->file(CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS . 'no_section.ini');
1150
 
1151
		ob_start();
1152
		$result = $response->send();
1153
		$output = ob_get_clean();
1154
		$this->assertEquals("some_key = some_value\nbool_key = 1\n", $output);
1155
		$this->assertTrue($result !== false);
1156
		if ($currentUserAgent !== null) {
1157
			$_SERVER['HTTP_USER_AGENT'] = $currentUserAgent;
1158
		}
1159
	}
1160
 
1161
/**
1162
 * testFileWithUnknownFileTypeOpera method
1163
 *
1164
 * @return void
1165
 */
1166
	public function testFileWithUnknownFileTypeOpera() {
1167
		$currentUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
1168
		$_SERVER['HTTP_USER_AGENT'] = 'Opera/9.80 (Windows NT 6.0; U; en) Presto/2.8.99 Version/11.10';
1169
 
1170
		$response = $this->getMock('CakeResponse', array(
1171
			'header',
1172
			'type',
1173
			'download',
1174
			'_sendHeader',
1175
			'_setContentType',
1176
			'_isActive',
1177
			'_clearBuffer',
1178
			'_flushBuffer'
1179
		));
1180
 
1181
		$response->expects($this->at(0))
1182
			->method('type')
1183
			->with('ini')
1184
			->will($this->returnValue(false));
1185
 
1186
		$response->expects($this->at(1))
1187
			->method('type')
1188
			->with('application/octet-stream')
1189
			->will($this->returnValue(false));
1190
 
1191
		$response->expects($this->once())
1192
			->method('download')
1193
			->with('no_section.ini');
1194
 
1195
		$response->expects($this->at(3))
1196
			->method('header')
1197
			->with('Accept-Ranges', 'bytes');
1198
 
1199
		$response->expects($this->at(4))
1200
			->method('header')
1201
			->with('Content-Transfer-Encoding', 'binary');
1202
 
1203
		$response->expects($this->at(5))
1204
			->method('header')
1205
			->with('Content-Length', 35);
1206
 
1207
		$response->expects($this->once())->method('_clearBuffer');
1208
		$response->expects($this->once())->method('_flushBuffer');
1209
		$response->expects($this->exactly(1))
1210
			->method('_isActive')
1211
			->will($this->returnValue(true));
1212
 
1213
		$response->file(CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS . 'no_section.ini');
1214
 
1215
		ob_start();
1216
		$result = $response->send();
1217
		$output = ob_get_clean();
1218
		$this->assertEquals("some_key = some_value\nbool_key = 1\n", $output);
1219
		$this->assertTrue($result !== false);
1220
		if ($currentUserAgent !== null) {
1221
			$_SERVER['HTTP_USER_AGENT'] = $currentUserAgent;
1222
		}
1223
	}
1224
 
1225
/**
1226
 * testFileWithUnknownFileTypeIE method
1227
 *
1228
 * @return void
1229
 */
1230
	public function testFileWithUnknownFileTypeIE() {
1231
		$currentUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
1232
		$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320)';
1233
 
1234
		$response = $this->getMock('CakeResponse', array(
1235
			'header',
1236
			'type',
1237
			'download',
1238
			'_sendHeader',
1239
			'_setContentType',
1240
			'_isActive',
1241
			'_clearBuffer',
1242
			'_flushBuffer'
1243
		));
1244
 
1245
		$response->expects($this->at(0))
1246
			->method('type')
1247
			->with('ini')
1248
			->will($this->returnValue(false));
1249
 
1250
		$response->expects($this->at(1))
1251
			->method('type')
1252
			->with('application/force-download')
1253
			->will($this->returnValue(false));
1254
 
1255
		$response->expects($this->once())
1256
			->method('download')
1257
			->with('config.ini');
1258
 
1259
		$response->expects($this->at(3))
1260
			->method('header')
1261
			->with('Accept-Ranges', 'bytes');
1262
 
1263
		$response->expects($this->at(4))
1264
			->method('header')
1265
			->with('Content-Transfer-Encoding', 'binary');
1266
 
1267
		$response->expects($this->at(5))
1268
			->method('header')
1269
			->with('Content-Length', 35);
1270
 
1271
		$response->expects($this->once())->method('_clearBuffer');
1272
		$response->expects($this->once())->method('_flushBuffer');
1273
		$response->expects($this->exactly(1))
1274
			->method('_isActive')
1275
			->will($this->returnValue(true));
1276
 
1277
		$response->file(CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS . 'no_section.ini', array(
1278
			'name' => 'config.ini'
1279
		));
1280
 
1281
		ob_start();
1282
		$result = $response->send();
1283
		$output = ob_get_clean();
1284
		$this->assertEquals("some_key = some_value\nbool_key = 1\n", $output);
1285
		$this->assertTrue($result !== false);
1286
		if ($currentUserAgent !== null) {
1287
			$_SERVER['HTTP_USER_AGENT'] = $currentUserAgent;
1288
		}
1289
	}
1290
/**
1291
 * testFileWithUnknownFileNoDownload method
1292
 *
1293
 * @return void
1294
 */
1295
	public function testFileWithUnknownFileNoDownload() {
1296
		$currentUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
1297
		$_SERVER['HTTP_USER_AGENT'] = 'Some generic browser';
1298
 
1299
		$response = $this->getMock('CakeResponse', array(
1300
			'header',
1301
			'type',
1302
			'download',
1303
			'_sendHeader',
1304
			'_setContentType',
1305
			'_isActive',
1306
			'_clearBuffer',
1307
			'_flushBuffer'
1308
		));
1309
 
1310
		$response->expects($this->exactly(1))
1311
			->method('type')
1312
			->with('ini')
1313
			->will($this->returnValue(false));
1314
 
1315
		$response->expects($this->never())
1316
			->method('download');
1317
 
1318
		$response->file(CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS . 'no_section.ini', array(
1319
			'download' => false
1320
		));
1321
 
1322
		if ($currentUserAgent !== null) {
1323
			$_SERVER['HTTP_USER_AGENT'] = $currentUserAgent;
1324
		}
1325
	}
1326
 
1327
/**
1328
 * testConnectionAbortedOnBuffering method
1329
 *
1330
 * @return void
1331
 */
1332
	public function testConnectionAbortedOnBuffering() {
1333
		$response = $this->getMock('CakeResponse', array(
1334
			'header',
1335
			'type',
1336
			'download',
1337
			'_sendHeader',
1338
			'_setContentType',
1339
			'_isActive',
1340
			'_clearBuffer',
1341
			'_flushBuffer'
1342
		));
1343
 
1344
		$response->expects($this->any())
1345
			->method('type')
1346
			->with('css')
1347
			->will($this->returnArgument(0));
1348
 
1349
		$response->expects($this->at(0))
1350
			->method('_isActive')
1351
			->will($this->returnValue(false));
1352
 
1353
		$response->expects($this->once())->method('_clearBuffer');
1354
		$response->expects($this->never())->method('_flushBuffer');
1355
 
1356
		$response->file(CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'css' . DS . 'test_asset.css');
1357
 
1358
		$result = $response->send();
1359
		$this->assertNull($result);
1360
	}
1361
 
1362
/**
1363
 * Test downloading files with UPPERCASE extensions.
1364
 *
1365
 * @return void
1366
 */
1367
	public function testFileUpperExtension() {
1368
		$response = $this->getMock('CakeResponse', array(
1369
			'header',
1370
			'type',
1371
			'download',
1372
			'_sendHeader',
1373
			'_setContentType',
1374
			'_isActive',
1375
			'_clearBuffer',
1376
			'_flushBuffer'
1377
		));
1378
 
1379
		$response->expects($this->any())
1380
			->method('type')
1381
			->with('jpg')
1382
			->will($this->returnArgument(0));
1383
 
1384
		$response->expects($this->at(0))
1385
			->method('_isActive')
1386
			->will($this->returnValue(true));
1387
 
1388
		$response->file(CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'img' . DS . 'test_2.JPG');
1389
	}
1390
 
1391
/**
1392
 * Test downloading files with extension not explicitly set.
1393
 *
1394
 * @return void
1395
 */
1396
	public function testFileExtensionNotSet() {
1397
		$response = $this->getMock('CakeResponse', array(
1398
			'header',
1399
			'type',
1400
			'download',
1401
			'_sendHeader',
1402
			'_setContentType',
1403
			'_isActive',
1404
			'_clearBuffer',
1405
			'_flushBuffer'
1406
		));
1407
 
1408
		$response->expects($this->any())
1409
			->method('type')
1410
			->with('jpg')
1411
			->will($this->returnArgument(0));
1412
 
1413
		$response->expects($this->at(0))
1414
			->method('_isActive')
1415
			->will($this->returnValue(true));
1416
 
1417
		$response->file(CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'img' . DS . 'test_2.JPG');
1418
	}
1419
 
1420
/**
1421
 * A data provider for testing various ranges
1422
 *
1423
 * @return array
1424
 */
1425
	public static function rangeProvider() {
1426
		return array(
1427
			// suffix-byte-range
1428
			array(
1429
				'bytes=-25', 25, 'bytes 13-37/38'
1430
			),
1431
 
1432
			array(
1433
				'bytes=0-', 38, 'bytes 0-37/38'
1434
			),
1435
			array(
1436
				'bytes=10-', 28, 'bytes 10-37/38'
1437
			),
1438
			array(
1439
				'bytes=10-20', 11, 'bytes 10-20/38'
1440
			),
1441
		);
1442
	}
1443
 
1444
/**
1445
 * Test the various range offset types.
1446
 *
1447
 * @dataProvider rangeProvider
1448
 * @return void
1449
 */
1450
	public function testFileRangeOffsets($range, $length, $offsetResponse) {
1451
		$_SERVER['HTTP_RANGE'] = $range;
1452
		$response = $this->getMock('CakeResponse', array(
1453
			'header',
1454
			'type',
1455
			'_sendHeader',
1456
			'_isActive',
1457
			'_clearBuffer',
1458
			'_flushBuffer'
1459
		));
1460
 
1461
		$response->expects($this->at(1))
1462
			->method('header')
1463
			->with('Content-Disposition', 'attachment; filename="test_asset.css"');
1464
 
1465
		$response->expects($this->at(2))
1466
			->method('header')
1467
			->with('Accept-Ranges', 'bytes');
1468
 
1469
		$response->expects($this->at(3))
1470
			->method('header')
1471
			->with('Content-Transfer-Encoding', 'binary');
1472
 
1473
		$response->expects($this->at(4))
1474
			->method('header')
1475
			->with(array(
1476
				'Content-Length' => $length,
1477
				'Content-Range' => $offsetResponse,
1478
			));
1479
 
1480
		$response->expects($this->any())
1481
			->method('_isActive')
1482
			->will($this->returnValue(true));
1483
 
1484
		$response->file(
1485
			CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'css' . DS . 'test_asset.css',
1486
			array('download' => true)
1487
		);
1488
 
1489
		ob_start();
1490
		$result = $response->send();
1491
		ob_get_clean();
1492
	}
1493
 
1494
/**
1495
 * Test fetching ranges from a file.
1496
 *
1497
 * @return void
1498
 */
1499
	public function testFileRange() {
1500
		$_SERVER['HTTP_RANGE'] = 'bytes=8-25';
1501
		$response = $this->getMock('CakeResponse', array(
1502
			'header',
1503
			'type',
1504
			'_sendHeader',
1505
			'_setContentType',
1506
			'_isActive',
1507
			'_clearBuffer',
1508
			'_flushBuffer'
1509
		));
1510
 
1511
		$response->expects($this->exactly(1))
1512
			->method('type')
1513
			->with('css')
1514
			->will($this->returnArgument(0));
1515
 
1516
		$response->expects($this->at(1))
1517
			->method('header')
1518
			->with('Content-Disposition', 'attachment; filename="test_asset.css"');
1519
 
1520
		$response->expects($this->at(2))
1521
			->method('header')
1522
			->with('Accept-Ranges', 'bytes');
1523
 
1524
		$response->expects($this->at(3))
1525
			->method('header')
1526
			->with('Content-Transfer-Encoding', 'binary');
1527
 
1528
		$response->expects($this->at(4))
1529
			->method('header')
1530
			->with(array(
1531
				'Content-Length' => 18,
1532
				'Content-Range' => 'bytes 8-25/38',
1533
			));
1534
 
1535
		$response->expects($this->once())->method('_clearBuffer');
1536
 
1537
		$response->expects($this->any())
1538
			->method('_isActive')
1539
			->will($this->returnValue(true));
1540
 
1541
		$response->file(
1542
			CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'css' . DS . 'test_asset.css',
1543
			array('download' => true)
1544
		);
1545
 
1546
		ob_start();
1547
		$result = $response->send();
1548
		$output = ob_get_clean();
1549
		$this->assertEquals(206, $response->statusCode());
1550
		$this->assertEquals("is the test asset ", $output);
1551
		$this->assertTrue($result !== false);
1552
	}
1553
 
1554
/**
1555
 * Test invalid file ranges.
1556
 *
1557
 * @return void
1558
 */
1559
	public function testFileRangeInvalid() {
1560
		$_SERVER['HTTP_RANGE'] = 'bytes=30-2';
1561
		$response = $this->getMock('CakeResponse', array(
1562
			'header',
1563
			'type',
1564
			'_sendHeader',
1565
			'_setContentType',
1566
			'_isActive',
1567
			'_clearBuffer',
1568
			'_flushBuffer'
1569
		));
1570
 
1571
		$response->expects($this->at(1))
1572
			->method('header')
1573
			->with('Content-Disposition', 'attachment; filename="test_asset.css"');
1574
 
1575
		$response->expects($this->at(2))
1576
			->method('header')
1577
			->with('Accept-Ranges', 'bytes');
1578
 
1579
		$response->expects($this->at(3))
1580
			->method('header')
1581
			->with('Content-Transfer-Encoding', 'binary');
1582
 
1583
		$response->expects($this->at(4))
1584
			->method('header')
1585
			->with(array(
1586
				'Content-Range' => 'bytes 0-37/38',
1587
			));
1588
 
1589
		$response->file(
1590
			CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'css' . DS . 'test_asset.css',
1591
			array('download' => true)
1592
		);
1593
 
1594
		$this->assertEquals(416, $response->statusCode());
1595
		$result = $response->send();
1596
	}
1597
 
1598
/**
1599
 * Test the location method.
1600
 *
1601
 * @return void
1602
 */
1603
	public function testLocation() {
1604
		$response = new CakeResponse();
1605
		$this->assertNull($response->location(), 'No header should be set.');
1606
		$this->assertNull($response->location('http://example.org'), 'Setting a location should return null');
1607
		$this->assertEquals('http://example.org', $response->location(), 'Reading a location should return the value.');
1608
	}
1609
 
1610
}