Completed
Pull Request — master (#275)
by
unknown
06:37
created

CacheControlSubscriberTest::testDefaultHeaders()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 22
rs 9.2
cc 1
eloc 16
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the FOSHttpCacheBundle package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.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 FOS\HttpCacheBundle\Tests\Unit\EventListener;
13
14
use FOS\HttpCacheBundle\EventListener\CacheControlSubscriber;
15
use Symfony\Component\HttpFoundation\Request;
16
use Symfony\Component\HttpFoundation\Response;
17
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
18
19
class CacheControlSubscriberTest extends \PHPUnit_Framework_TestCase
20
{
21
    public function testDefaultHeaders()
22
    {
23
        $event = $this->buildEvent();
24
        $headers = array(
25
            'overwrite' => false,
26
            'last_modified' => '13.07.2003',
27
            'cache_control' => array(
28
                'max_age' => '900',
29
                's_maxage' => '300',
30
                'public' => true,
31
                'private' => false,
32
            ),
33
        );
34
        $subscriber = $this->getCacheControl($headers);
35
36
        $subscriber->onKernelResponse($event);
37
        $newHeaders = $event->getResponse()->headers->all();
38
39
        $this->assertEquals('max-age=900, public, s-maxage=300', $newHeaders['cache-control'][0]);
40
        $this->assertArrayHasKey('last-modified', $newHeaders, implode(',', array_keys($newHeaders)));
41
        $this->assertEquals(strtotime('13.07.2003'), strtotime($newHeaders['last-modified'][0]));
42
    }
43
44 View Code Duplication
    public function testExtraHeaders()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
45
    {
46
        $event = $this->buildEvent();
47
        $headers = array(
48
            'overwrite' => false,
49
            'cache_control' => array(
50
                'must_revalidate' => true,
51
                'proxy_revalidate' => true,
52
                'no_transform' => true,
53
                'stale_if_error' => '300',
54
                'stale_while_revalidate' => '400',
55
            ),
56
        );
57
        $subscriber = $this->getCacheControl($headers);
58
59
        $subscriber->onKernelResponse($event);
60
        $newHeaders = $event->getResponse()->headers->all();
61
62
        $this->assertEquals('must-revalidate, no-transform, proxy-revalidate, stale-if-error=300, stale-while-revalidate=400, private', $newHeaders['cache-control'][0]);
63
    }
64
65
    public function testCompoundHeaders()
66
    {
67
        $event = $this->buildEvent();
68
        $headers = array(
69
            'overwrite' => false,
70
            'cache_control' => array(
71
                'max_age' => '900',
72
                's_maxage' => '300',
73
                'public' => true,
74
                'private' => false,
75
                'must_revalidate' => true,
76
                'proxy_revalidate' => true,
77
                'no_transform' => true,
78
                'stale_if_error' => '300',
79
                'stale_while_revalidate' => '400',
80
            ),
81
        );
82
        $subscriber = $this->getCacheControl($headers);
83
84
        $subscriber->onKernelResponse($event);
85
        $newHeaders = $event->getResponse()->headers->all();
86
87
        $this->assertEquals('max-age=900, must-revalidate, no-transform, proxy-revalidate, public, s-maxage=300, stale-if-error=300, stale-while-revalidate=400', $newHeaders['cache-control'][0]);
88
    }
89
90 View Code Duplication
    public function testSetNoCacheHeaders()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91
    {
92
        $event = $this->buildEvent();
93
        $headers = array(
94
            'overwrite'     => false,
95
            'cache_control' => array(
96
                'max_age' => '0',
97
                's_maxage' => '0',
98
                'private' => true,
99
                'no_cache' => true,
100
                'must_revalidate' => true,
101
            ),
102
            'last_modified' => '13.07.2003',
103
        );
104
        $subscriber = $this->getCacheControl($headers);
105
106
        $subscriber->onKernelResponse($event);
107
        $newHeaders = $event->getResponse()->headers->all();
108
109
        $this->assertEquals('max-age=0, must-revalidate, no-cache, private, s-maxage=0', $newHeaders['cache-control'][0]);
110
    }
111
112
    public function testMergeHeaders()
113
    {
114
        $event = $this->buildEvent();
115
        $headers = array(
116
            'overwrite' => false,
117
            'cache_control' => array(
118
                'max_age' => '900',
119
                's_maxage' => '300',
120
                'public' => true,
121
                'private' => false,
122
                'must_revalidate' => true,
123
                'proxy_revalidate' => true,
124
                'no_transform' => true,
125
                'stale_if_error' => '300',
126
                'stale_while_revalidate' => '400',
127
            ),
128
            'vary' => array(
129
                'Cookie',
130
            ),
131
            'etag' => true,
132
            'last_modified' => '2014-10-10 GMT',
133
        );
134
        $subscriber = $this->getCacheControl($headers);
135
        $response = $event->getResponse();
136
        $response->setPublic();
137
        $response->setCache(array('max_age' => 0));
138
        $response->headers->addCacheControlDirective('stale-if-error', 0);
139
        $response->setVary('Encoding');
140
        $response->setEtag('foo');
141
        $response->setLastModified(new \DateTime('2013-09-09 GMT'));
142
143
        $subscriber->onKernelResponse($event);
144
        $newHeaders = $event->getResponse()->headers->all();
145
146
        $this->assertEquals('max-age=0, must-revalidate, no-transform, proxy-revalidate, public, s-maxage=300, stale-if-error=0, stale-while-revalidate=400', $newHeaders['cache-control'][0]);
147
        $this->assertEquals(array('Encoding', 'Cookie'), $newHeaders['vary']);
148
        $this->assertEquals('"foo"', $newHeaders['etag'][0]);
149
        $this->assertEquals('Mon, 09 Sep 2013 00:00:00 GMT', $newHeaders['last-modified'][0]);
150
    }
151
152
    public function testOverwriteHeaders()
153
    {
154
        $event = $this->buildEvent();
155
        $headers = array(
156
            'overwrite' => true,
157
            'cache_control' => array(
158
                'max_age' => '900',
159
                's_maxage' => '300',
160
                'public' => true,
161
                'private' => false,
162
                'must_revalidate' => true,
163
                'proxy_revalidate' => true,
164
                'no_transform' => true,
165
                'stale_if_error' => '300',
166
                'stale_while_revalidate' => '400',
167
            ),
168
            'vary' => array(
169
                'Cookie',
170
            ),
171
            'etag' => true,
172
            'last_modified' => '2014-10-10 GMT',
173
        );
174
        $subscriber = $this->getCacheControl($headers);
175
        $response = $event->getResponse();
176
        $response->setPublic();
177
        $response->setCache(array('max_age' => 0));
178
        $response->headers->addCacheControlDirective('stale-if-error', 0);
179
        $response->setVary('Encoding');
180
        $response->setEtag('foo');
181
        $response->setLastModified(new \DateTime('2013-09-09 GMT'));
182
183
        $subscriber->onKernelResponse($event);
184
        $newHeaders = $event->getResponse()->headers->all();
185
186
        $this->assertEquals('max-age=900, must-revalidate, no-transform, proxy-revalidate, public, s-maxage=300, stale-if-error=300, stale-while-revalidate=400', $newHeaders['cache-control'][0]);
187
        $this->assertEquals(array('Cookie'), $newHeaders['vary']);
188
        $this->assertEquals('"'.md5('').'"', $response->getEtag());
189
        $this->assertEquals('Fri, 10 Oct 2014 00:00:00 GMT', $newHeaders['last-modified'][0]);
190
    }
191
192
    public function testMergePublicPrivate()
193
    {
194
        $event = $this->buildEvent();
195
        $headers = array(
196
            'overwrite' => false,
197
            'cache_control' => array(
198
                'private' => true,
199
        ), );
200
        $subscriber = $this->getCacheControl($headers);
201
        $response = $event->getResponse();
202
        $response->setPublic();
203
204
        $subscriber->onKernelResponse($event);
205
        $newHeaders = $response->headers->all();
206
207
        $this->assertEquals('public', $newHeaders['cache-control'][0]);
208
    }
209
210
    /**
211
     * The no_cache header is never actually called as its already set.
212
     */
213
    public function testSetOnlyNoCacheHeader()
214
    {
215
        $event = $this->buildEvent();
216
        $headers = array(
217
            'overwrite' => false,
218
            'cache_control' => array(
219
                'no_cache' => true,
220
            ),
221
        );
222
        $subscriber = $this->getCacheControl($headers);
223
224
        $subscriber->onKernelResponse($event);
225
        $newHeaders = $event->getResponse()->headers->all();
226
227
        $this->assertEquals('no-cache', $newHeaders['cache-control'][0]);
228
    }
229
230
    public function testSkip()
231
    {
232
        $event = $this->buildEvent();
233
        $subscriber = $this->getMockBuilder('FOS\HttpCacheBundle\EventListener\CacheControlSubscriber')
234
            ->setMethods(array('matchRule'))
235
            ->getMock()
236
        ;
237
        $subscriber->expects($this->never())
238
            ->method('matchRule')
239
        ;
240
241
        $subscriber->setSkip();
242
        $subscriber->onKernelResponse($event);
243
        $newHeaders = $event->getResponse()->headers->all();
244
245
        $this->assertEquals('no-cache', $newHeaders['cache-control'][0]);
246
    }
247
248
    public function testVary()
249
    {
250
        $event = $this->buildEvent();
251
        $headers = array(
252
            'overwrite' => false,
253
            'vary' => array(
254
                'Cookie',
255
                'Accept-Language',
256
                'Encoding',
257
            ),
258
        );
259
        $subscriber = $this->getCacheControl($headers);
260
261
        $subscriber->onKernelResponse($event);
262
        $newHeaders = $event->getResponse()->headers->all();
263
264
        $this->assertTrue(isset($newHeaders['vary']), implode(',', array_keys($newHeaders)));
265
        $this->assertEquals($headers['vary'], $newHeaders['vary']);
266
    }
267
268
    public function testReverseProxyTtl()
269
    {
270
        $event = $this->buildEvent();
271
        $headers = array(
272
            'reverse_proxy_ttl' => 600,
273
        );
274
        $subscriber = $this->getCacheControl($headers);
275
276
        $subscriber->onKernelResponse($event);
277
        $newHeaders = $event->getResponse()->headers->all();
278
279
        $this->assertTrue(isset($newHeaders['x-reverse-proxy-ttl']), implode(',', array_keys($newHeaders)));
280
        $this->assertEquals(600, $newHeaders['x-reverse-proxy-ttl'][0]);
281
    }
282
283
    public function testDebugHeader()
284
    {
285
        $subscriber = \Mockery::mock('FOS\HttpCacheBundle\EventListener\CacheControlSubscriber[matchRule]', array('X-Cache-Debug'))
286
            ->shouldAllowMockingProtectedMethods()
287
            ->shouldReceive('matchRule')->once()->andReturn(false)
288
            ->getMock()
289
        ;
290
        $event = $this->buildEvent();
291
292
        $subscriber->onKernelResponse($event);
293
        $newHeaders = $event->getResponse()->headers->all();
294
295
        $this->assertTrue(isset($newHeaders['x-cache-debug']), implode(',', array_keys($newHeaders)));
296
        $this->assertTrue(isset($newHeaders['x-cache-debug'][0]));
297
    }
298
299
    public function testMatchRule()
300
    {
301
        $event = $this->buildEvent();
302
        $request = $event->getRequest();
303
        $response = $event->getResponse();
304
        $event2 = $this->buildEvent();
305
        $request2 = $event2->getRequest();
306
        $response2 = $event2->getResponse();
307
308
        $headers = array(
309
            'overwrite' => false,
310
            'cache_control' => array(
311
            'max_age' => '900',
312
            's_maxage' => '300',
313
            'public' => true,
314
            'private' => false,
315
        ), );
316
317
        $mockMatcher = \Mockery::mock('FOS\HttpCacheBundle\Http\RuleMatcherInterface')
0 ignored issues
show
Bug introduced by
The method shouldReceive() does not seem to exist on object<Mockery\Expectation>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
318
            ->shouldReceive('matches')->once()->with($request, $response)->andReturn(true)
319
            ->shouldReceive('matches')->once()->with($request2, $response2)->andReturn(false)
320
            ->getMock()
321
        ;
322
323
        $subscriber = new CacheControlSubscriber();
324
        $subscriber->addRule(
325
            $mockMatcher,
326
            $headers
327
        );
328
329
        $subscriber->onKernelResponse($event);
330
        $newHeaders = $response->headers->all();
331
        $this->assertEquals('max-age=900, public, s-maxage=300', $newHeaders['cache-control'][0]);
332
333
        $subscriber->onKernelResponse($event2);
334
        $newHeaders = $response2->headers->all();
335
        $this->assertEquals('no-cache', $newHeaders['cache-control'][0]);
336
    }
337
338
    /**
339
     * Unsafe methods should abort before even attempting to match rules.
340
     */
341 View Code Duplication
    public function testUnsafeMethod()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
342
    {
343
        $subscriber = $this->getMockBuilder('FOS\HttpCacheBundle\EventListener\CacheControlSubscriber')
344
            ->setMethods(array('matchRule'))
345
            ->getMock()
346
        ;
347
        $subscriber->expects($this->never())
348
            ->method('matchRule')
349
        ;
350
        $event = $this->buildEvent('POST');
351
352
        $subscriber->onKernelResponse($event);
353
    }
354
355
    /**
356
     * Safe methods should get into the matchRule
357
     * @dataProvider getSafeMethods
358
     * @param $method
359
     */
360 View Code Duplication
    public function testSafeMethodsTriggersMatchRule($method)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
361
    {
362
        $subscriber = $this->getMockBuilder('FOS\HttpCacheBundle\EventListener\CacheControlSubscriber')
363
            ->setMethods(array('matchRule'))
364
            ->getMock()
365
        ;
366
        $subscriber->expects($this->once())
367
            ->method('matchRule')
368
        ;
369
        $event = $this->buildEvent($method);
370
371
        $subscriber->onKernelResponse($event);
372
    }
373
374
    /**
375
     * Safe Methods data
376
     * @return array
377
     */
378
    public function getSafeMethods()
379
    {
380
        return array(
381
            'testSafeMethod for GET' => array('GET'),
382
            'testSafeMethod for HEAD' => array('HEAD'),
383
            'testSafeMethod for OPTIONS' => array('OPTIONS'),
384
        );
385
    }
386
387
    /**
388
     * Build the filter response event with a mock kernel and default request
389
     * and response objects.
390
     *
391
     * @param string $method
392
     *
393
     * @return FilterResponseEvent
394
     */
395
    protected function buildEvent($method = 'GET')
396
    {
397
        $kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
398
        $response = new Response();
399
        $request = new Request();
400
        $request->setMethod($method);
401
402
        return new FilterResponseEvent($kernel, $request, $method, $response);
403
    }
404
405
    /**
406
     * We mock the matchRule method for tests about applying the rules.
407
     *
408
     * @param array $headers The headers to return in matchRule
409
     *
410
     * @return \PHPUnit_Framework_MockObject_MockObject|CacheControlSubscriber
411
     */
412 View Code Duplication
    protected function getCacheControl(array $headers)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
413
    {
414
        $subscriber = $this->getMockBuilder('FOS\HttpCacheBundle\EventListener\CacheControlSubscriber')
415
            ->setMethods(array('matchRule'))
416
            ->getMock()
417
        ;
418
419
        $subscriber->expects($this->once())->method('matchRule')->will($this->returnValue($headers));
420
421
        return $subscriber;
422
    }
423
}
424