Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 liveuser 1
<?php
2
 
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <fabien@symfony.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
namespace Symfony\Component\HttpFoundation\Tests;
13
 
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\HttpFoundation\Response;
16
 
17
/**
18
 * @group time-sensitive
19
 */
20
class ResponseTest extends ResponseTestCase
21
{
22
    public function testCreate()
23
    {
24
        $response = Response::create('foo', 301, array('Foo' => 'bar'));
25
 
26
        $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
27
        $this->assertEquals(301, $response->getStatusCode());
28
        $this->assertEquals('bar', $response->headers->get('foo'));
29
    }
30
 
31
    public function testToString()
32
    {
33
        $response = new Response();
34
        $response = explode("\r\n", $response);
35
        $this->assertEquals('HTTP/1.0 200 OK', $response[0]);
36
        $this->assertEquals('Cache-Control: no-cache', $response[1]);
37
    }
38
 
39
    public function testClone()
40
    {
41
        $response = new Response();
42
        $responseClone = clone $response;
43
        $this->assertEquals($response, $responseClone);
44
    }
45
 
46
    public function testSendHeaders()
47
    {
48
        $response = new Response();
49
        $headers = $response->sendHeaders();
50
        $this->assertObjectHasAttribute('headers', $headers);
51
        $this->assertObjectHasAttribute('content', $headers);
52
        $this->assertObjectHasAttribute('version', $headers);
53
        $this->assertObjectHasAttribute('statusCode', $headers);
54
        $this->assertObjectHasAttribute('statusText', $headers);
55
        $this->assertObjectHasAttribute('charset', $headers);
56
    }
57
 
58
    public function testSend()
59
    {
60
        $response = new Response();
61
        $responseSend = $response->send();
62
        $this->assertObjectHasAttribute('headers', $responseSend);
63
        $this->assertObjectHasAttribute('content', $responseSend);
64
        $this->assertObjectHasAttribute('version', $responseSend);
65
        $this->assertObjectHasAttribute('statusCode', $responseSend);
66
        $this->assertObjectHasAttribute('statusText', $responseSend);
67
        $this->assertObjectHasAttribute('charset', $responseSend);
68
    }
69
 
70
    public function testGetCharset()
71
    {
72
        $response = new Response();
73
        $charsetOrigin = 'UTF-8';
74
        $response->setCharset($charsetOrigin);
75
        $charset = $response->getCharset();
76
        $this->assertEquals($charsetOrigin, $charset);
77
    }
78
 
79
    public function testIsCacheable()
80
    {
81
        $response = new Response();
82
        $this->assertFalse($response->isCacheable());
83
    }
84
 
85
    public function testIsCacheableWithErrorCode()
86
    {
87
        $response = new Response('', 500);
88
        $this->assertFalse($response->isCacheable());
89
    }
90
 
91
    public function testIsCacheableWithNoStoreDirective()
92
    {
93
        $response = new Response();
94
        $response->headers->set('cache-control', 'private');
95
        $this->assertFalse($response->isCacheable());
96
    }
97
 
98
    public function testIsCacheableWithSetTtl()
99
    {
100
        $response = new Response();
101
        $response->setTtl(10);
102
        $this->assertTrue($response->isCacheable());
103
    }
104
 
105
    public function testMustRevalidate()
106
    {
107
        $response = new Response();
108
        $this->assertFalse($response->mustRevalidate());
109
    }
110
 
111
    public function testMustRevalidateWithMustRevalidateCacheControlHeader()
112
    {
113
        $response = new Response();
114
        $response->headers->set('cache-control', 'must-revalidate');
115
 
116
        $this->assertTrue($response->mustRevalidate());
117
    }
118
 
119
    public function testMustRevalidateWithProxyRevalidateCacheControlHeader()
120
    {
121
        $response = new Response();
122
        $response->headers->set('cache-control', 'proxy-revalidate');
123
 
124
        $this->assertTrue($response->mustRevalidate());
125
    }
126
 
127
    public function testSetNotModified()
128
    {
129
        $response = new Response();
130
        $modified = $response->setNotModified();
131
        $this->assertObjectHasAttribute('headers', $modified);
132
        $this->assertObjectHasAttribute('content', $modified);
133
        $this->assertObjectHasAttribute('version', $modified);
134
        $this->assertObjectHasAttribute('statusCode', $modified);
135
        $this->assertObjectHasAttribute('statusText', $modified);
136
        $this->assertObjectHasAttribute('charset', $modified);
137
        $this->assertEquals(304, $modified->getStatusCode());
138
    }
139
 
140
    public function testIsSuccessful()
141
    {
142
        $response = new Response();
143
        $this->assertTrue($response->isSuccessful());
144
    }
145
 
146
    public function testIsNotModified()
147
    {
148
        $response = new Response();
149
        $modified = $response->isNotModified(new Request());
150
        $this->assertFalse($modified);
151
    }
152
 
153
    public function testIsNotModifiedNotSafe()
154
    {
155
        $request = Request::create('/homepage', 'POST');
156
 
157
        $response = new Response();
158
        $this->assertFalse($response->isNotModified($request));
159
    }
160
 
161
    public function testIsNotModifiedLastModified()
162
    {
163
        $before = 'Sun, 25 Aug 2013 18:32:31 GMT';
164
        $modified = 'Sun, 25 Aug 2013 18:33:31 GMT';
165
        $after = 'Sun, 25 Aug 2013 19:33:31 GMT';
166
 
167
        $request = new Request();
168
        $request->headers->set('If-Modified-Since', $modified);
169
 
170
        $response = new Response();
171
 
172
        $response->headers->set('Last-Modified', $modified);
173
        $this->assertTrue($response->isNotModified($request));
174
 
175
        $response->headers->set('Last-Modified', $before);
176
        $this->assertTrue($response->isNotModified($request));
177
 
178
        $response->headers->set('Last-Modified', $after);
179
        $this->assertFalse($response->isNotModified($request));
180
 
181
        $response->headers->set('Last-Modified', '');
182
        $this->assertFalse($response->isNotModified($request));
183
    }
184
 
185
    public function testIsNotModifiedEtag()
186
    {
187
        $etagOne = 'randomly_generated_etag';
188
        $etagTwo = 'randomly_generated_etag_2';
189
 
190
        $request = new Request();
191
        $request->headers->set('if_none_match', sprintf('%s, %s, %s', $etagOne, $etagTwo, 'etagThree'));
192
 
193
        $response = new Response();
194
 
195
        $response->headers->set('ETag', $etagOne);
196
        $this->assertTrue($response->isNotModified($request));
197
 
198
        $response->headers->set('ETag', $etagTwo);
199
        $this->assertTrue($response->isNotModified($request));
200
 
201
        $response->headers->set('ETag', '');
202
        $this->assertFalse($response->isNotModified($request));
203
    }
204
 
205
    public function testIsNotModifiedLastModifiedAndEtag()
206
    {
207
        $before = 'Sun, 25 Aug 2013 18:32:31 GMT';
208
        $modified = 'Sun, 25 Aug 2013 18:33:31 GMT';
209
        $after = 'Sun, 25 Aug 2013 19:33:31 GMT';
210
        $etag = 'randomly_generated_etag';
211
 
212
        $request = new Request();
213
        $request->headers->set('if_none_match', sprintf('%s, %s', $etag, 'etagThree'));
214
        $request->headers->set('If-Modified-Since', $modified);
215
 
216
        $response = new Response();
217
 
218
        $response->headers->set('ETag', $etag);
219
        $response->headers->set('Last-Modified', $after);
220
        $this->assertFalse($response->isNotModified($request));
221
 
222
        $response->headers->set('ETag', 'non-existent-etag');
223
        $response->headers->set('Last-Modified', $before);
224
        $this->assertFalse($response->isNotModified($request));
225
 
226
        $response->headers->set('ETag', $etag);
227
        $response->headers->set('Last-Modified', $modified);
228
        $this->assertTrue($response->isNotModified($request));
229
    }
230
 
231
    public function testIsNotModifiedIfModifiedSinceAndEtagWithoutLastModified()
232
    {
233
        $modified = 'Sun, 25 Aug 2013 18:33:31 GMT';
234
        $etag = 'randomly_generated_etag';
235
 
236
        $request = new Request();
237
        $request->headers->set('if_none_match', sprintf('%s, %s', $etag, 'etagThree'));
238
        $request->headers->set('If-Modified-Since', $modified);
239
 
240
        $response = new Response();
241
 
242
        $response->headers->set('ETag', $etag);
243
        $this->assertTrue($response->isNotModified($request));
244
 
245
        $response->headers->set('ETag', 'non-existent-etag');
246
        $this->assertFalse($response->isNotModified($request));
247
    }
248
 
249
    public function testIsValidateable()
250
    {
251
        $response = new Response('', 200, array('Last-Modified' => $this->createDateTimeOneHourAgo()->format(DATE_RFC2822)));
252
        $this->assertTrue($response->isValidateable(), '->isValidateable() returns true if Last-Modified is present');
253
 
254
        $response = new Response('', 200, array('ETag' => '"12345"'));
255
        $this->assertTrue($response->isValidateable(), '->isValidateable() returns true if ETag is present');
256
 
257
        $response = new Response();
258
        $this->assertFalse($response->isValidateable(), '->isValidateable() returns false when no validator is present');
259
    }
260
 
261
    public function testGetDate()
262
    {
263
        $oneHourAgo = $this->createDateTimeOneHourAgo();
264
        $response = new Response('', 200, array('Date' => $oneHourAgo->format(DATE_RFC2822)));
265
        $date = $response->getDate();
266
        $this->assertEquals($oneHourAgo->getTimestamp(), $date->getTimestamp(), '->getDate() returns the Date header if present');
267
 
268
        $response = new Response();
269
        $date = $response->getDate();
270
        $this->assertEquals(time(), $date->getTimestamp(), '->getDate() returns the current Date if no Date header present');
271
 
272
        $response = new Response('', 200, array('Date' => $this->createDateTimeOneHourAgo()->format(DATE_RFC2822)));
273
        $now = $this->createDateTimeNow();
274
        $response->headers->set('Date', $now->format(DATE_RFC2822));
275
        $date = $response->getDate();
276
        $this->assertEquals($now->getTimestamp(), $date->getTimestamp(), '->getDate() returns the date when the header has been modified');
277
 
278
        $response = new Response('', 200);
279
        $response->headers->remove('Date');
280
        $this->assertInstanceOf('\DateTime', $response->getDate());
281
    }
282
 
283
    public function testGetMaxAge()
284
    {
285
        $response = new Response();
286
        $response->headers->set('Cache-Control', 's-maxage=600, max-age=0');
287
        $this->assertEquals(600, $response->getMaxAge(), '->getMaxAge() uses s-maxage cache control directive when present');
288
 
289
        $response = new Response();
290
        $response->headers->set('Cache-Control', 'max-age=600');
291
        $this->assertEquals(600, $response->getMaxAge(), '->getMaxAge() falls back to max-age when no s-maxage directive present');
292
 
293
        $response = new Response();
294
        $response->headers->set('Cache-Control', 'must-revalidate');
295
        $response->headers->set('Expires', $this->createDateTimeOneHourLater()->format(DATE_RFC2822));
296
        $this->assertEquals(3600, $response->getMaxAge(), '->getMaxAge() falls back to Expires when no max-age or s-maxage directive present');
297
 
298
        $response = new Response();
299
        $response->headers->set('Cache-Control', 'must-revalidate');
300
        $response->headers->set('Expires', -1);
301
        $this->assertEquals('Sat, 01 Jan 00 00:00:00 +0000', $response->getExpires()->format(DATE_RFC822));
302
 
303
        $response = new Response();
304
        $this->assertNull($response->getMaxAge(), '->getMaxAge() returns null if no freshness information available');
305
    }
306
 
307
    public function testSetSharedMaxAge()
308
    {
309
        $response = new Response();
310
        $response->setSharedMaxAge(20);
311
 
312
        $cacheControl = $response->headers->get('Cache-Control');
313
        $this->assertEquals('public, s-maxage=20', $cacheControl);
314
    }
315
 
316
    public function testIsPrivate()
317
    {
318
        $response = new Response();
319
        $response->headers->set('Cache-Control', 'max-age=100');
320
        $response->setPrivate();
321
        $this->assertEquals(100, $response->headers->getCacheControlDirective('max-age'), '->isPrivate() adds the private Cache-Control directive when set to true');
322
        $this->assertTrue($response->headers->getCacheControlDirective('private'), '->isPrivate() adds the private Cache-Control directive when set to true');
323
 
324
        $response = new Response();
325
        $response->headers->set('Cache-Control', 'public, max-age=100');
326
        $response->setPrivate();
327
        $this->assertEquals(100, $response->headers->getCacheControlDirective('max-age'), '->isPrivate() adds the private Cache-Control directive when set to true');
328
        $this->assertTrue($response->headers->getCacheControlDirective('private'), '->isPrivate() adds the private Cache-Control directive when set to true');
329
        $this->assertFalse($response->headers->hasCacheControlDirective('public'), '->isPrivate() removes the public Cache-Control directive');
330
    }
331
 
332
    public function testExpire()
333
    {
334
        $response = new Response();
335
        $response->headers->set('Cache-Control', 'max-age=100');
336
        $response->expire();
337
        $this->assertEquals(100, $response->headers->get('Age'), '->expire() sets the Age to max-age when present');
338
 
339
        $response = new Response();
340
        $response->headers->set('Cache-Control', 'max-age=100, s-maxage=500');
341
        $response->expire();
342
        $this->assertEquals(500, $response->headers->get('Age'), '->expire() sets the Age to s-maxage when both max-age and s-maxage are present');
343
 
344
        $response = new Response();
345
        $response->headers->set('Cache-Control', 'max-age=5, s-maxage=500');
346
        $response->headers->set('Age', '1000');
347
        $response->expire();
348
        $this->assertEquals(1000, $response->headers->get('Age'), '->expire() does nothing when the response is already stale/expired');
349
 
350
        $response = new Response();
351
        $response->expire();
352
        $this->assertFalse($response->headers->has('Age'), '->expire() does nothing when the response does not include freshness information');
353
 
354
        $response = new Response();
355
        $response->headers->set('Expires', -1);
356
        $response->expire();
357
        $this->assertNull($response->headers->get('Age'), '->expire() does not set the Age when the response is expired');
358
    }
359
 
360
    public function testGetTtl()
361
    {
362
        $response = new Response();
363
        $this->assertNull($response->getTtl(), '->getTtl() returns null when no Expires or Cache-Control headers are present');
364
 
365
        $response = new Response();
366
        $response->headers->set('Expires', $this->createDateTimeOneHourLater()->format(DATE_RFC2822));
367
        $this->assertEquals(3600, $response->getTtl(), '->getTtl() uses the Expires header when no max-age is present');
368
 
369
        $response = new Response();
370
        $response->headers->set('Expires', $this->createDateTimeOneHourAgo()->format(DATE_RFC2822));
371
        $this->assertLessThan(0, $response->getTtl(), '->getTtl() returns negative values when Expires is in past');
372
 
373
        $response = new Response();
374
        $response->headers->set('Expires', $response->getDate()->format(DATE_RFC2822));
375
        $response->headers->set('Age', 0);
376
        $this->assertSame(0, $response->getTtl(), '->getTtl() correctly handles zero');
377
 
378
        $response = new Response();
379
        $response->headers->set('Cache-Control', 'max-age=60');
380
        $this->assertEquals(60, $response->getTtl(), '->getTtl() uses Cache-Control max-age when present');
381
    }
382
 
383
    public function testSetClientTtl()
384
    {
385
        $response = new Response();
386
        $response->setClientTtl(10);
387
 
388
        $this->assertEquals($response->getMaxAge(), $response->getAge() + 10);
389
    }
390
 
391
    public function testGetSetProtocolVersion()
392
    {
393
        $response = new Response();
394
 
395
        $this->assertEquals('1.0', $response->getProtocolVersion());
396
 
397
        $response->setProtocolVersion('1.1');
398
 
399
        $this->assertEquals('1.1', $response->getProtocolVersion());
400
    }
401
 
402
    public function testGetVary()
403
    {
404
        $response = new Response();
405
        $this->assertEquals(array(), $response->getVary(), '->getVary() returns an empty array if no Vary header is present');
406
 
407
        $response = new Response();
408
        $response->headers->set('Vary', 'Accept-Language');
409
        $this->assertEquals(array('Accept-Language'), $response->getVary(), '->getVary() parses a single header name value');
410
 
411
        $response = new Response();
412
        $response->headers->set('Vary', 'Accept-Language User-Agent    X-Foo');
413
        $this->assertEquals(array('Accept-Language', 'User-Agent', 'X-Foo'), $response->getVary(), '->getVary() parses multiple header name values separated by spaces');
414
 
415
        $response = new Response();
416
        $response->headers->set('Vary', 'Accept-Language,User-Agent,    X-Foo');
417
        $this->assertEquals(array('Accept-Language', 'User-Agent', 'X-Foo'), $response->getVary(), '->getVary() parses multiple header name values separated by commas');
418
 
419
        $vary = array('Accept-Language', 'User-Agent', 'X-foo');
420
 
421
        $response = new Response();
422
        $response->headers->set('Vary', $vary);
423
        $this->assertEquals($vary, $response->getVary(), '->getVary() parses multiple header name values in arrays');
424
 
425
        $response = new Response();
426
        $response->headers->set('Vary', 'Accept-Language, User-Agent, X-foo');
427
        $this->assertEquals($vary, $response->getVary(), '->getVary() parses multiple header name values in arrays');
428
    }
429
 
430
    public function testSetVary()
431
    {
432
        $response = new Response();
433
        $response->setVary('Accept-Language');
434
        $this->assertEquals(array('Accept-Language'), $response->getVary());
435
 
436
        $response->setVary('Accept-Language, User-Agent');
437
        $this->assertEquals(array('Accept-Language', 'User-Agent'), $response->getVary(), '->setVary() replace the vary header by default');
438
 
439
        $response->setVary('X-Foo', false);
440
        $this->assertEquals(array('Accept-Language', 'User-Agent', 'X-Foo'), $response->getVary(), '->setVary() doesn\'t wipe out earlier Vary headers if replace is set to false');
441
    }
442
 
443
    public function testDefaultContentType()
444
    {
445
        $headerMock = $this->getMock('Symfony\Component\HttpFoundation\ResponseHeaderBag', array('set'));
446
        $headerMock->expects($this->at(0))
447
            ->method('set')
448
            ->with('Content-Type', 'text/html');
449
        $headerMock->expects($this->at(1))
450
            ->method('set')
451
            ->with('Content-Type', 'text/html; charset=UTF-8');
452
 
453
        $response = new Response('foo');
454
        $response->headers = $headerMock;
455
 
456
        $response->prepare(new Request());
457
    }
458
 
459
    public function testContentTypeCharset()
460
    {
461
        $response = new Response();
462
        $response->headers->set('Content-Type', 'text/css');
463
 
464
        // force fixContentType() to be called
465
        $response->prepare(new Request());
466
 
467
        $this->assertEquals('text/css; charset=UTF-8', $response->headers->get('Content-Type'));
468
    }
469
 
470
    public function testPrepareDoesNothingIfContentTypeIsSet()
471
    {
472
        $response = new Response('foo');
473
        $response->headers->set('Content-Type', 'text/plain');
474
 
475
        $response->prepare(new Request());
476
 
477
        $this->assertEquals('text/plain; charset=UTF-8', $response->headers->get('content-type'));
478
    }
479
 
480
    public function testPrepareDoesNothingIfRequestFormatIsNotDefined()
481
    {
482
        $response = new Response('foo');
483
 
484
        $response->prepare(new Request());
485
 
486
        $this->assertEquals('text/html; charset=UTF-8', $response->headers->get('content-type'));
487
    }
488
 
489
    public function testPrepareSetContentType()
490
    {
491
        $response = new Response('foo');
492
        $request = Request::create('/');
493
        $request->setRequestFormat('json');
494
 
495
        $response->prepare($request);
496
 
497
        $this->assertEquals('application/json', $response->headers->get('content-type'));
498
    }
499
 
500
    public function testPrepareRemovesContentForHeadRequests()
501
    {
502
        $response = new Response('foo');
503
        $request = Request::create('/', 'HEAD');
504
 
505
        $length = 12345;
506
        $response->headers->set('Content-Length', $length);
507
        $response->prepare($request);
508
 
509
        $this->assertEquals('', $response->getContent());
510
        $this->assertEquals($length, $response->headers->get('Content-Length'), 'Content-Length should be as if it was GET; see RFC2616 14.13');
511
    }
512
 
513
    public function testPrepareRemovesContentForInformationalResponse()
514
    {
515
        $response = new Response('foo');
516
        $request = Request::create('/');
517
 
518
        $response->setContent('content');
519
        $response->setStatusCode(101);
520
        $response->prepare($request);
521
        $this->assertEquals('', $response->getContent());
522
        $this->assertFalse($response->headers->has('Content-Type'));
523
        $this->assertFalse($response->headers->has('Content-Type'));
524
 
525
        $response->setContent('content');
526
        $response->setStatusCode(304);
527
        $response->prepare($request);
528
        $this->assertEquals('', $response->getContent());
529
        $this->assertFalse($response->headers->has('Content-Type'));
530
        $this->assertFalse($response->headers->has('Content-Length'));
531
    }
532
 
533
    public function testPrepareRemovesContentLength()
534
    {
535
        $response = new Response('foo');
536
        $request = Request::create('/');
537
 
538
        $response->headers->set('Content-Length', 12345);
539
        $response->prepare($request);
540
        $this->assertEquals(12345, $response->headers->get('Content-Length'));
541
 
542
        $response->headers->set('Transfer-Encoding', 'chunked');
543
        $response->prepare($request);
544
        $this->assertFalse($response->headers->has('Content-Length'));
545
    }
546
 
547
    public function testPrepareSetsPragmaOnHttp10Only()
548
    {
549
        $request = Request::create('/', 'GET');
550
        $request->server->set('SERVER_PROTOCOL', 'HTTP/1.0');
551
 
552
        $response = new Response('foo');
553
        $response->prepare($request);
554
        $this->assertEquals('no-cache', $response->headers->get('pragma'));
555
        $this->assertEquals('-1', $response->headers->get('expires'));
556
 
557
        $request->server->set('SERVER_PROTOCOL', 'HTTP/1.1');
558
        $response = new Response('foo');
559
        $response->prepare($request);
560
        $this->assertFalse($response->headers->has('pragma'));
561
        $this->assertFalse($response->headers->has('expires'));
562
    }
563
 
564
    public function testSetCache()
565
    {
566
        $response = new Response();
567
        //array('etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public')
568
        try {
569
            $response->setCache(array('wrong option' => 'value'));
570
            $this->fail('->setCache() throws an InvalidArgumentException if an option is not supported');
571
        } catch (\Exception $e) {
572
            $this->assertInstanceOf('InvalidArgumentException', $e, '->setCache() throws an InvalidArgumentException if an option is not supported');
573
            $this->assertContains('"wrong option"', $e->getMessage());
574
        }
575
 
576
        $options = array('etag' => '"whatever"');
577
        $response->setCache($options);
578
        $this->assertEquals($response->getEtag(), '"whatever"');
579
 
580
        $now = $this->createDateTimeNow();
581
        $options = array('last_modified' => $now);
582
        $response->setCache($options);
583
        $this->assertEquals($response->getLastModified()->getTimestamp(), $now->getTimestamp());
584
 
585
        $options = array('max_age' => 100);
586
        $response->setCache($options);
587
        $this->assertEquals($response->getMaxAge(), 100);
588
 
589
        $options = array('s_maxage' => 200);
590
        $response->setCache($options);
591
        $this->assertEquals($response->getMaxAge(), 200);
592
 
593
        $this->assertTrue($response->headers->hasCacheControlDirective('public'));
594
        $this->assertFalse($response->headers->hasCacheControlDirective('private'));
595
 
596
        $response->setCache(array('public' => true));
597
        $this->assertTrue($response->headers->hasCacheControlDirective('public'));
598
        $this->assertFalse($response->headers->hasCacheControlDirective('private'));
599
 
600
        $response->setCache(array('public' => false));
601
        $this->assertFalse($response->headers->hasCacheControlDirective('public'));
602
        $this->assertTrue($response->headers->hasCacheControlDirective('private'));
603
 
604
        $response->setCache(array('private' => true));
605
        $this->assertFalse($response->headers->hasCacheControlDirective('public'));
606
        $this->assertTrue($response->headers->hasCacheControlDirective('private'));
607
 
608
        $response->setCache(array('private' => false));
609
        $this->assertTrue($response->headers->hasCacheControlDirective('public'));
610
        $this->assertFalse($response->headers->hasCacheControlDirective('private'));
611
    }
612
 
613
    public function testSendContent()
614
    {
615
        $response = new Response('test response rendering', 200);
616
 
617
        ob_start();
618
        $response->sendContent();
619
        $string = ob_get_clean();
620
        $this->assertContains('test response rendering', $string);
621
    }
622
 
623
    public function testSetPublic()
624
    {
625
        $response = new Response();
626
        $response->setPublic();
627
 
628
        $this->assertTrue($response->headers->hasCacheControlDirective('public'));
629
        $this->assertFalse($response->headers->hasCacheControlDirective('private'));
630
    }
631
 
632
    public function testSetExpires()
633
    {
634
        $response = new Response();
635
        $response->setExpires(null);
636
 
637
        $this->assertNull($response->getExpires(), '->setExpires() remove the header when passed null');
638
 
639
        $now = $this->createDateTimeNow();
640
        $response->setExpires($now);
641
 
642
        $this->assertEquals($response->getExpires()->getTimestamp(), $now->getTimestamp());
643
    }
644
 
645
    public function testSetLastModified()
646
    {
647
        $response = new Response();
648
        $response->setLastModified($this->createDateTimeNow());
649
        $this->assertNotNull($response->getLastModified());
650
 
651
        $response->setLastModified(null);
652
        $this->assertNull($response->getLastModified());
653
    }
654
 
655
    public function testIsInvalid()
656
    {
657
        $response = new Response();
658
 
659
        try {
660
            $response->setStatusCode(99);
661
            $this->fail();
662
        } catch (\InvalidArgumentException $e) {
663
            $this->assertTrue($response->isInvalid());
664
        }
665
 
666
        try {
667
            $response->setStatusCode(650);
668
            $this->fail();
669
        } catch (\InvalidArgumentException $e) {
670
            $this->assertTrue($response->isInvalid());
671
        }
672
 
673
        $response = new Response('', 200);
674
        $this->assertFalse($response->isInvalid());
675
    }
676
 
677
    /**
678
     * @dataProvider getStatusCodeFixtures
679
     */
680
    public function testSetStatusCode($code, $text, $expectedText)
681
    {
682
        $response = new Response();
683
 
684
        $response->setStatusCode($code, $text);
685
 
686
        $statusText = new \ReflectionProperty($response, 'statusText');
687
        $statusText->setAccessible(true);
688
 
689
        $this->assertEquals($expectedText, $statusText->getValue($response));
690
    }
691
 
692
    public function getStatusCodeFixtures()
693
    {
694
        return array(
695
            array('200', null, 'OK'),
696
            array('200', false, ''),
697
            array('200', 'foo', 'foo'),
698
            array('199', null, 'unknown status'),
699
            array('199', false, ''),
700
            array('199', 'foo', 'foo'),
701
        );
702
    }
703
 
704
    public function testIsInformational()
705
    {
706
        $response = new Response('', 100);
707
        $this->assertTrue($response->isInformational());
708
 
709
        $response = new Response('', 200);
710
        $this->assertFalse($response->isInformational());
711
    }
712
 
713
    public function testIsRedirectRedirection()
714
    {
715
        foreach (array(301, 302, 303, 307) as $code) {
716
            $response = new Response('', $code);
717
            $this->assertTrue($response->isRedirection());
718
            $this->assertTrue($response->isRedirect());
719
        }
720
 
721
        $response = new Response('', 304);
722
        $this->assertTrue($response->isRedirection());
723
        $this->assertFalse($response->isRedirect());
724
 
725
        $response = new Response('', 200);
726
        $this->assertFalse($response->isRedirection());
727
        $this->assertFalse($response->isRedirect());
728
 
729
        $response = new Response('', 404);
730
        $this->assertFalse($response->isRedirection());
731
        $this->assertFalse($response->isRedirect());
732
 
733
        $response = new Response('', 301, array('Location' => '/good-uri'));
734
        $this->assertFalse($response->isRedirect('/bad-uri'));
735
        $this->assertTrue($response->isRedirect('/good-uri'));
736
    }
737
 
738
    public function testIsNotFound()
739
    {
740
        $response = new Response('', 404);
741
        $this->assertTrue($response->isNotFound());
742
 
743
        $response = new Response('', 200);
744
        $this->assertFalse($response->isNotFound());
745
    }
746
 
747
    public function testIsEmpty()
748
    {
749
        foreach (array(204, 304) as $code) {
750
            $response = new Response('', $code);
751
            $this->assertTrue($response->isEmpty());
752
        }
753
 
754
        $response = new Response('', 200);
755
        $this->assertFalse($response->isEmpty());
756
    }
757
 
758
    public function testIsForbidden()
759
    {
760
        $response = new Response('', 403);
761
        $this->assertTrue($response->isForbidden());
762
 
763
        $response = new Response('', 200);
764
        $this->assertFalse($response->isForbidden());
765
    }
766
 
767
    public function testIsOk()
768
    {
769
        $response = new Response('', 200);
770
        $this->assertTrue($response->isOk());
771
 
772
        $response = new Response('', 404);
773
        $this->assertFalse($response->isOk());
774
    }
775
 
776
    public function testIsServerOrClientError()
777
    {
778
        $response = new Response('', 404);
779
        $this->assertTrue($response->isClientError());
780
        $this->assertFalse($response->isServerError());
781
 
782
        $response = new Response('', 500);
783
        $this->assertFalse($response->isClientError());
784
        $this->assertTrue($response->isServerError());
785
    }
786
 
787
    public function testHasVary()
788
    {
789
        $response = new Response();
790
        $this->assertFalse($response->hasVary());
791
 
792
        $response->setVary('User-Agent');
793
        $this->assertTrue($response->hasVary());
794
    }
795
 
796
    public function testSetEtag()
797
    {
798
        $response = new Response('', 200, array('ETag' => '"12345"'));
799
        $response->setEtag();
800
 
801
        $this->assertNull($response->headers->get('Etag'), '->setEtag() removes Etags when call with null');
802
    }
803
 
804
    /**
805
     * @dataProvider validContentProvider
806
     */
807
    public function testSetContent($content)
808
    {
809
        $response = new Response();
810
        $response->setContent($content);
811
        $this->assertEquals((string) $content, $response->getContent());
812
    }
813
 
814
    /**
815
     * @expectedException \UnexpectedValueException
816
     * @dataProvider invalidContentProvider
817
     */
818
    public function testSetContentInvalid($content)
819
    {
820
        $response = new Response();
821
        $response->setContent($content);
822
    }
823
 
824
    public function testSettersAreChainable()
825
    {
826
        $response = new Response();
827
 
828
        $setters = array(
829
            'setProtocolVersion' => '1.0',
830
            'setCharset' => 'UTF-8',
831
            'setPublic' => null,
832
            'setPrivate' => null,
833
            'setDate' => $this->createDateTimeNow(),
834
            'expire' => null,
835
            'setMaxAge' => 1,
836
            'setSharedMaxAge' => 1,
837
            'setTtl' => 1,
838
            'setClientTtl' => 1,
839
        );
840
 
841
        foreach ($setters as $setter => $arg) {
842
            $this->assertEquals($response, $response->{$setter}($arg));
843
        }
844
    }
845
 
846
    public function validContentProvider()
847
    {
848
        return array(
849
            'obj' => array(new StringableObject()),
850
            'string' => array('Foo'),
851
            'int' => array(2),
852
        );
853
    }
854
 
855
    public function invalidContentProvider()
856
    {
857
        return array(
858
            'obj' => array(new \stdClass()),
859
            'array' => array(array()),
860
            'bool' => array(true, '1'),
861
        );
862
    }
863
 
864
    protected function createDateTimeOneHourAgo()
865
    {
866
        return $this->createDateTimeNow()->sub(new \DateInterval('PT1H'));
867
    }
868
 
869
    protected function createDateTimeOneHourLater()
870
    {
871
        return $this->createDateTimeNow()->add(new \DateInterval('PT1H'));
872
    }
873
 
874
    protected function createDateTimeNow()
875
    {
876
        $date = new \DateTime();
877
 
878
        return $date->setTimestamp(time());
879
    }
880
 
881
    protected function provideResponse()
882
    {
883
        return new Response();
884
    }
885
}
886
 
887
class StringableObject
888
{
889
    public function __toString()
890
    {
891
        return 'Foo';
892
    }
893
}