Completed
Push — master ( 6021e6...020901 )
by David
18s
created

FOSHttpCacheExtensionTest::testConfigLoadSymfony()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 16

Duplication

Lines 23
Ratio 100 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
c 1
b 1
f 1
dl 23
loc 23
rs 9.0856
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\DependencyInjection;
13
14
use FOS\HttpCacheBundle\DependencyInjection\FOSHttpCacheExtension;
15
use Symfony\Component\DependencyInjection\ContainerBuilder;
16
use Symfony\Component\DependencyInjection\Definition;
17
use Symfony\Component\DependencyInjection\DefinitionDecorator;
18
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
19
20
class FOSHttpCacheExtensionTest extends \PHPUnit_Framework_TestCase
21
{
22
    /**
23
     * @var FOSHttpCacheExtension
24
     */
25
    protected $extension;
26
27
    protected function setUp()
28
    {
29
        $this->extension = new FOSHttpCacheExtension();
30
    }
31
32
    public function testConfigLoadVarnish()
33
    {
34
        $container = $this->createContainer();
35
        $this->extension->load(array($this->getBaseConfig()), $container);
36
37
        $this->assertTrue($container->hasDefinition('fos_http_cache.proxy_client.varnish'));
38
        $this->assertFalse($container->hasDefinition('fos_http_cache.proxy_client.nginx'));
39
        $this->assertTrue($container->hasAlias('fos_http_cache.default_proxy_client'));
40
        $this->assertTrue($container->hasDefinition('fos_http_cache.event_listener.invalidation'));
41
        $this->assertTrue($container->hasDefinition('fos_http_cache.handler.tag_handler'));
42
43
        $this->assertFalse($container->hasParameter('fos_http_cache.proxy_client.varnish.guzzle_client'));
44
    }
45
46
    public function testConfigLoadVarnishCustomGuzzle()
47
    {
48
        $container = $this->createContainer();
49
50
        $config = $this->getBaseConfig();
51
        $config['proxy_client']['varnish']['guzzle_client'] = 'my_guzzle';
52
        $this->extension->load(array($config), $container);
53
54
        $this->assertTrue($container->hasDefinition('fos_http_cache.proxy_client.varnish'));
55
        $def = $container->getDefinition('fos_http_cache.proxy_client.varnish');
56
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $def->getArgument(2));
57
        $this->assertEquals('fos_http_cache.proxy_client.varnish.guzzle_client', $def->getArgument(2)->__toString());
58
59
        $this->assertTrue($container->hasAlias('fos_http_cache.proxy_client.varnish.guzzle_client'));
60
        $this->assertEquals('my_guzzle', $container->getAlias('fos_http_cache.proxy_client.varnish.guzzle_client'));
61
    }
62
63
    /**
64
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
65
     */
66
    public function testConfigLoadVarnishInvalidUrl()
67
    {
68
        $container = $this->createContainer();
69
        $config = $this->getBaseConfig();
70
        $config['proxy_client']['varnish']['base_url'] = 'ftp:not a valid url';
71
72
        $this->extension->load(array($config), $container);
73
    }
74
75 View Code Duplication
    public function testConfigLoadNginx()
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...
76
    {
77
        $container = $this->createContainer();
78
        $this->extension->load(array(
79
            array(
80
                'proxy_client' => array(
81
                    'nginx' => array(
82
                        'base_url' => 'my_hostname',
83
                        'servers' => array(
84
                            '127.0.0.1',
85
                        ),
86
                    ),
87
                ),
88
            ),
89
        ), $container);
90
91
        $this->assertFalse($container->hasDefinition('fos_http_cache.proxy_client.varnish'));
92
        $this->assertTrue($container->hasDefinition('fos_http_cache.proxy_client.nginx'));
93
        $this->assertTrue($container->hasAlias('fos_http_cache.default_proxy_client'));
94
        $this->assertTrue($container->hasDefinition('fos_http_cache.event_listener.invalidation'));
95
        $this->assertFalse($container->hasDefinition('fos_http_cache.handler.tag_handler'));
96
    }
97
98 View Code Duplication
    public function testConfigLoadSymfony()
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...
99
    {
100
        $container = $this->createContainer();
101
        $this->extension->load(array(
102
            array(
103
                'proxy_client' => array(
104
                    'symfony' => array(
105
                        'base_url' => 'my_hostname',
106
                        'servers' => array(
107
                            '127.0.0.1',
108
                        ),
109
                    ),
110
                ),
111
            ),
112
        ), $container);
113
114
        $this->assertFalse($container->hasDefinition('fos_http_cache.proxy_client.varnish'));
115
        $this->assertFalse($container->hasDefinition('fos_http_cache.proxy_client.nginx'));
116
        $this->assertTrue($container->hasDefinition('fos_http_cache.proxy_client.symfony'));
117
        $this->assertTrue($container->hasAlias('fos_http_cache.default_proxy_client'));
118
        $this->assertTrue($container->hasDefinition('fos_http_cache.event_listener.invalidation'));
119
        $this->assertFalse($container->hasDefinition('fos_http_cache.handler.tag_handler'));
120
    }
121
122
    public function testConfigCustomClient()
123
    {
124
        $container = $this->createContainer();
125
        $this->extension->load(array(
126
            array(
127
                'cache_manager' => array(
128
                    'custom_proxy_client' => 'app.cache.client',
129
                ),
130
            ),
131
        ), $container);
132
133
        $this->assertFalse($container->hasDefinition('fos_http_cache.proxy_client.varnish'));
134
        $this->assertFalse($container->hasDefinition('fos_http_cache.proxy_client.nginx'));
135
        $this->assertFalse($container->hasDefinition('fos_http_cache.proxy_client.symfony'));
136
        $this->assertTrue($container->hasAlias('fos_http_cache.default_proxy_client'));
137
        $this->assertTrue($container->hasDefinition('fos_http_cache.event_listener.invalidation'));
138
        $this->assertFalse($container->hasDefinition('fos_http_cache.handler.tag_handler'));
139
    }
140
141
    public function testEmptyConfig()
142
    {
143
        $config = array();
144
145
        $container = $this->createContainer();
146
        $this->extension->load(array($config), $container);
147
148
        $this->assertFalse($container->has('fos_http_cache.user_context.logout_handler'));
149
    }
150
151
    /**
152
     * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
153
     * @expectedExceptionMessage You can not enable cache tagging with nginx
154
     */
155
    public function testConfigTagNotSupported()
156
    {
157
        $config = array(
158
                'proxy_client' => array(
159
                    'nginx' => array(
160
                        'base_url' => 'my_hostname',
161
                        'servers' => array(
162
                            '127.0.0.1',
163
                        ),
164
                    ),
165
                ),
166
                'tags' => array(
167
                    'enabled' => true,
168
                ),
169
            );
170
171
        $container = $this->createContainer();
172
        $this->extension->load(array($config), $container);
173
    }
174
175
    public function testConfigLoadTagRules()
176
    {
177
        $config = $this->getBaseConfig() + array(
178
            'tags' => array(
179
                'rules' => array(
180
                    array(
181
                        'match' => array(
182
                            'path' => '^/$',
183
                            'host' => 'fos.lo',
184
                            'methods' => array('GET', 'HEAD'),
185
                            'ips' => array('1.1.1.1', '2.2.2.2'),
186
                            'attributes' => array(
187
                                '_controller' => '^AcmeBundle:Default:index$',
188
                            ),
189
                        ),
190
                        'tags' => array('tag-a', 'tag-b'),
191
                    ),
192
                ),
193
            ),
194
        );
195
196
        $container = $this->createContainer();
197
        $this->extension->load(array($config), $container);
198
199
        $this->assertMatcherCreated($container, array('_controller' => '^AcmeBundle:Default:index$'));
200
        $this->assertListenerHasRule($container, 'fos_http_cache.event_listener.tag');
201
    }
202
203
    public function testConfigLoadInvalidatorRules()
204
    {
205
        $config = $this->getBaseConfig() + array(
206
            'invalidation' => array(
207
                'rules' => array(
208
                    array(
209
                        'match' => array(
210
                            'attributes' => array(
211
                                '_route' => 'my_route',
212
                            ),
213
                        ),
214
                        'routes' => array(
215
                            'invalidate_route1' => array(
216
                            ),
217
                        ),
218
                    ),
219
                ),
220
            ),
221
        );
222
223
        $container = $this->createContainer();
224
        $this->extension->load(array($config), $container);
225
226
        $this->assertMatcherCreated($container, array('_route' => 'my_route'));
227
        $this->assertListenerHasRule($container, 'fos_http_cache.event_listener.invalidation');
228
229
        // Test for runtime errors
230
        $container->compile();
231
    }
232
233
    public function testConfigLoadCacheControl()
234
    {
235
        $config = array(
236
            'cache_control' => array(
237
                'rules' => array(
238
                    array(
239
                        'match' => array(
240
                            'path' => '^/$',
241
                            'host' => 'fos.lo',
242
                            'methods' => array('GET', 'HEAD'),
243
                            'ips' => array('1.1.1.1', '2.2.2.2'),
244
                            'attributes' => array(
245
                                '_controller' => '^AcmeBundle:Default:index$',
246
                            ),
247
                        ),
248
                        'headers' => array(
249
                            'cache_control' => array('public' => true),
250
                            'reverse_proxy_ttl' => 42,
251
                            'vary' => array('Cookie', 'Accept-Language'),
252
                        ),
253
                    ),
254
                ),
255
            ),
256
        );
257
258
        $container = $this->createContainer();
259
        $this->extension->load(array($config), $container);
260
261
        $this->assertMatcherCreated($container, array('_controller' => '^AcmeBundle:Default:index$'));
262
        $this->assertListenerHasRule($container, 'fos_http_cache.event_listener.cache_control');
263
    }
264
265
    /**
266
     * Check if comma separated strings are parsed as expected.
267
     */
268
    public function testConfigLoadCacheControlSplit()
269
    {
270
        $config = array(
271
            'cache_control' => array(
272
                'rules' => array(
273
                    array(
274
                        'match' => array(
275
                            'methods' => 'GET,HEAD',
276
                            'ips' => '1.1.1.1,2.2.2.2',
277
                            'attributes' => array(
278
                                '_controller' => '^AcmeBundle:Default:index$',
279
                            ),
280
                        ),
281
                        'headers' => array(
282
                            'vary' => 'Cookie, Accept-Language',
283
                        ),
284
                    ),
285
                ),
286
            ),
287
        );
288
289
        $container = $this->createContainer();
290
        $this->extension->load(array($config), $container);
291
292
        $matcherDefinition = $this->assertMatcherCreated($container, array('_controller' => '^AcmeBundle:Default:index$'));
293
        $this->assertEquals(array('GET', 'HEAD'), $matcherDefinition->getArgument(2));
294
    }
295
296
    public function testConfigUserContext()
297
    {
298
        $config = $this->getBaseConfig() + array(
299
            'user_context' => array(
300
                'match' => array(
301
                    'matcher_service' => 'my_request_matcher_id',
302
                    'method' => 'AUTHENTICATE',
303
                    'accept' => 'application/vnd.test',
304
                ),
305
                'user_identifier_headers' => array('X-Foo'),
306
                'user_hash_header' => 'X-Bar',
307
                'hash_cache_ttl' => 30,
308
                'always_vary_on_context_hash' => true,
309
                'role_provider' => true,
310
            ),
311
        );
312
313
        $container = $this->createContainer();
314
        $this->extension->load(array($config), $container);
315
316
        $this->assertTrue($container->has('fos_http_cache.event_listener.user_context'));
317
        $this->assertTrue($container->has('fos_http_cache.user_context.hash_generator'));
318
        $this->assertTrue($container->has('fos_http_cache.user_context.request_matcher'));
319
        $this->assertTrue($container->has('fos_http_cache.user_context.role_provider'));
320
        $this->assertTrue($container->has('fos_http_cache.user_context.logout_handler'));
321
322
        $this->assertEquals(array('fos_http_cache.user_context.role_provider' => array(array())), $container->findTaggedServiceIds('fos_http_cache.user_context_provider'));
323
    }
324
325
    public function testConfigWithoutUserContext()
326
    {
327
        $config = array(
328
            array('user_context' => array(
329
                'enabled' => false,
330
                'match' => array(
331
                    'matcher_service' => 'my_request_matcher_id',
332
                    'method' => 'AUTHENTICATE',
333
                    'accept' => 'application/vnd.test',
334
                ),
335
                'user_identifier_headers' => array('X-Foo'),
336
                'user_hash_header' => 'X-Bar',
337
                'hash_cache_ttl' => 30,
338
                'always_vary_on_context_hash' => true,
339
                'role_provider' => true,
340
            )),
341
        );
342
343
        $container = $this->createContainer();
344
        $this->extension->load($config, $container);
345
346
        $this->assertFalse($container->has('fos_http_cache.event_listener.user_context'));
347
        $this->assertFalse($container->has('fos_http_cache.user_context.hash_generator'));
348
        $this->assertFalse($container->has('fos_http_cache.user_context.request_matcher'));
349
        $this->assertFalse($container->has('fos_http_cache.user_context.role_provider'));
350
        $this->assertFalse($container->has('fos_http_cache.user_context.logout_handler'));
351
    }
352
353
    public function testConfigLoadFlashMessageSubscriber()
354
    {
355
        $config = array(
356
            array('flash_message' => true,
357
            ),
358
        );
359
360
        $container = $this->createContainer();
361
        $this->extension->load($config, $container);
362
    }
363
364
    protected function createContainer()
365
    {
366
        $container = new ContainerBuilder(
367
            new ParameterBag(array('kernel.debug' => false))
368
        );
369
370
        // The cache_manager service depends on the router service
371
        $container->setDefinition(
372
            'router',
373
            new Definition('\Symfony\Component\Routing\Router')
374
        );
375
376
        return $container;
377
    }
378
379 View Code Duplication
    protected function getBaseConfig()
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...
380
    {
381
        return array(
382
            'proxy_client' => array(
383
                'varnish' => array(
384
                    'base_url' => 'my_hostname',
385
                    'servers' => array(
386
                        '127.0.0.1',
387
                    ),
388
                ),
389
            ),
390
        );
391
    }
392
393
    /**
394
     * @param ContainerBuilder $container
395
     * @param array            $attributes
396
     *
397
     * @return DefinitionDecorator
0 ignored issues
show
Documentation introduced by
Should the return type not be DefinitionDecorator|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
398
     */
399
    private function assertMatcherCreated(ContainerBuilder $container, array $attributes)
400
    {
401
        // Extract the corresponding definition
402
        $matcherDefinition = null;
403
        $matcherId = null;
404
        foreach ($container->getDefinitions() as $id => $definition) {
405
            if ($definition instanceof DefinitionDecorator &&
406
                $definition->getParent() === 'fos_http_cache.request_matcher'
407
            ) {
408
                if ($matcherDefinition) {
409
                    $this->fail('More then one request matcher was created');
410
                }
411
                $matcherId = $id;
412
                $matcherDefinition = $definition;
413
            }
414
        }
415
416
        // definition should exist
417
        $this->assertNotNull($matcherDefinition);
418
419
        // 5th argument should contain the request attribute criteria
420
        $this->assertEquals($attributes, $matcherDefinition->getArgument(4));
421
422
        $ruleDefinition = null;
423
        foreach ($container->getDefinitions() as $definition) {
424
            if ($definition instanceof DefinitionDecorator &&
425
                $definition->getParent() === 'fos_http_cache.rule_matcher'
426
            ) {
427
                if ($ruleDefinition) {
428
                    $this->fail('More then one rule matcher was created');
429
                }
430
                $ruleDefinition = $definition;
431
            }
432
        }
433
434
        // definition should exist
435
        $this->assertNotNull($ruleDefinition);
436
437
        // first argument should be the reference to the matcher
438
        $reference = $ruleDefinition->getArgument(0);
439
        $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $reference);
440
        $this->assertEquals($matcherId, (string) $reference);
441
442
        return $matcherDefinition;
443
    }
444
445
    /**
446
     * Assert that the service $id exists and has a method call mapped onto it.
447
     *
448
     * @param ContainerBuilder $container
449
     * @param string           $id        The service id to investigate
450
     */
451
    private function assertListenerHasRule(ContainerBuilder $container, $id)
452
    {
453
        $this->assertTrue($container->hasDefinition($id));
454
        $listener = $container->getDefinition($id);
455
        $this->assertTrue($listener->hasMethodCall('addRule'));
456
        $this->assertCount(1, $listener->getMethodCalls());
457
    }
458
}
459