Skip to content

Commit 340bc1c

Browse files
committed
Merge pull request #39 from ddeboer/app-tests
Add integration tests against a Symfony app
2 parents 8e1ba5f + 5a32031 commit 340bc1c

File tree

16 files changed

+298
-42
lines changed

16 files changed

+298
-42
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace FOS\HttpCacheBundle\DependencyInjection\Compiler;
4+
5+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
6+
use Symfony\Component\DependencyInjection\ContainerBuilder;
7+
8+
/**
9+
* Attach Symfony2 logger to cache manager
10+
*/
11+
class LoggerPass implements CompilerPassInterface
12+
{
13+
/**
14+
* {@inheritdoc}
15+
*/
16+
public function process(ContainerBuilder $container)
17+
{
18+
if (!$container->has('logger')) {
19+
return;
20+
}
21+
22+
$subscriber = $container->getDefinition('fos_http_cache.proxy.log_subscriber')
23+
->setAbstract(false);
24+
25+
$container->getDefinition('fos_http_cache.cache_manager')
26+
->addMethodCall('addSubscriber', array($subscriber));
27+
}
28+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace FOS\HttpCacheBundle\DependencyInjection\Compiler;
4+
5+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
6+
use Symfony\Component\DependencyInjection\ContainerBuilder;
7+
8+
/**
9+
* Check for required ControllerListener if TagListener is enabled
10+
*/
11+
class TagListenerPass implements CompilerPassInterface
12+
{
13+
/**
14+
* {@inheritdoc}
15+
*/
16+
public function process(ContainerBuilder $container)
17+
{
18+
if ($container->has('fos_http_cache.tag_listener')
19+
&& !$container->has('sensio_framework_extra.controller.listener')
20+
) {
21+
throw new \RuntimeException(
22+
'The TagListener requires SensioFrameworkExtraBundle’s ControllerListener. '
23+
. 'Please install sensio/framework-extra-bundle and add it to your AppKernel.'
24+
);
25+
}
26+
}
27+
}

DependencyInjection/Configuration.php

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public function getConfigTreeBuilder()
3030

3131
$this->addRulesSection($rootNode);
3232
$this->addVarnishSection($rootNode);
33+
$this->addTagListenerSection($rootNode);
3334
$this->addFlashMessageListenerSection($rootNode);
3435
$this->addInvalidatorsSection($rootNode);
3536

@@ -116,20 +117,24 @@ private function addVarnishSection(ArrayNodeDefinition $rootNode)
116117
->end();
117118
}
118119

120+
private function addTagListenerSection(ArrayNodeDefinition $rootNode)
121+
{
122+
$rootNode
123+
->children()
124+
->arrayNode('tag_listener')
125+
->canBeDisabled()
126+
->end()
127+
->end();
128+
}
129+
119130
private function addFlashMessageListenerSection(ArrayNodeDefinition $rootNode)
120131
{
121132
$rootNode
122133
->children()
123134
->arrayNode('flash_message_listener')
124135
->canBeUnset()
125-
->treatFalseLike(array('enabled' => false))
126-
->treatTrueLike(array('enabled' => true))
127-
->treatNullLike(array('enabled' => true))
136+
->canBeEnabled()
128137
->children()
129-
->scalarNode('enabled')
130-
->defaultTrue()
131-
->info('Whether to enable the listener. Automatically set if the flash_message_listener is configured.')
132-
->end()
133138
->scalarNode('name')
134139
->defaultValue('flashes')
135140
->info('Name of the cookie to set for flashes.')

DependencyInjection/FOSHttpCacheExtension.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public function load(array $configs, ContainerBuilder $container)
2323
$config = $this->processConfiguration($configuration, $configs);
2424

2525
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
26-
$loader->load('services.xml');
26+
$loader->load('cache_manager.xml');
2727

2828
$container->setParameter($this->getAlias().'.debug', $config['debug']);
2929
$container->setParameter($this->getAlias().'.invalidators', $config['invalidators']);
@@ -56,9 +56,6 @@ public function load(array $configs, ContainerBuilder $container)
5656
}
5757

5858
if (isset($config['varnish'])) {
59-
if (!class_exists('\Guzzle\Http\Client')) {
60-
throw new \RuntimeException('The Varnish component requires guzzle/http to be installed');
61-
}
6259
$loader->load('varnish.xml');
6360
$container->setParameter($this->getAlias().'.varnish.ips', $config['varnish']['ips']);
6461
$container->setParameter($this->getAlias().'.varnish.host', $config['varnish']['host']);
@@ -68,6 +65,14 @@ public function load(array $configs, ContainerBuilder $container)
6865
$loader->load('authorization_request_listener.xml');
6966
}
7067

68+
if ($config['tag_listener']['enabled']) {
69+
if (!class_exists('\Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
70+
throw new \RuntimeException('The TagListener requires symfony/expression-language');
71+
}
72+
73+
$loader->load('tag_listener.xml');
74+
}
75+
7176
if (!empty($config['flash_message_listener']) && $config['flash_message_listener']['enabled']) {
7277
$loader->load('flash_message_listener.xml');
7378

FOSHttpCacheBundle.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,19 @@
22

33
namespace FOS\HttpCacheBundle;
44

5+
use FOS\HttpCacheBundle\DependencyInjection\Compiler\LoggerPass;
6+
use FOS\HttpCacheBundle\DependencyInjection\Compiler\TagListenerPass;
7+
use Symfony\Component\DependencyInjection\ContainerBuilder;
58
use Symfony\Component\HttpKernel\Bundle\Bundle;
69

710
class FOSHttpCacheBundle extends Bundle
811
{
12+
/**
13+
* {@inheritdoc}
14+
*/
15+
public function build(ContainerBuilder $container)
16+
{
17+
$container->addCompilerPass(new LoggerPass());
18+
$container->addCompilerPass(new TagListenerPass());
19+
}
920
}

Resources/config/services.xml renamed to Resources/config/cache_manager.xml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,19 @@
1616
class="FOS\HttpCacheBundle\CacheManager">
1717
<argument type="service" id="fos_http_cache.http_cache" />
1818
<argument type="service" id="router" />
19+
<call method="setEventDispatcher">
20+
<argument id="event_dispatcher" type="service" on-invalid="ignore" />
21+
</call>
1922
</service>
2023

21-
<service id="fos_http_cache.event_listener.invalidation" class="FOS\HttpCacheBundle\EventListener\InvalidationListener">
24+
<service id="fos_http_cache.proxy.log_subscriber"
25+
class="FOS\HttpCache\EventListener\LogSubscriber"
26+
abstract="true">
27+
<argument type="service" id="logger" />
28+
</service>
29+
30+
<service id="fos_http_cache.event_listener.invalidation"
31+
class="FOS\HttpCacheBundle\EventListener\InvalidationListener">
2232
<argument type="service" id="fos_http_cache.cache_manager" />
2333
<argument type="service" id="fos_http_cache.invalidator.collection" />
2434
<argument type="service" id="router" />

Resources/config/tag_listener.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
6+
7+
<services>
8+
<service id="fos_http_cache.tag_listener"
9+
class="FOS\HttpCacheBundle\EventListener\TagListener">
10+
<argument type="service" id="fos_http_cache.cache_manager" />
11+
<tag name="kernel.event_subscriber" event="kernel.response" />
12+
</service>
13+
</services>
14+
</container>

Resources/config/varnish.xml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@
66

77
<services>
88
<service id="fos_http_cache.varnish"
9-
class="FOS\HttpCacheBundle\HttpCache\Varnish">
10-
<argument>%fos_http_cache.http_cache.varnish.ips%</argument>
11-
<argument>%fos_http_cache.http_cache.varnish.host%</argument>
12-
<call method="setLogger">
13-
<argument id="logger" type="service" on-invalid="null" />
14-
</call>
9+
class="FOS\HttpCache\Invalidation\Varnish">
10+
<argument>%fos_http_cache.varnish.ips%</argument>
11+
<argument>%fos_http_cache.varnish.host%</argument>
1512
</service>
1613

1714
<service id="fos_http_cache.http_cache"

Tests/EventListener/Fixture/FooControllerTagAtMethod.php

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace FOS\HttpCacheBundle\Tests\Functional\EventListener;
4+
5+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
6+
7+
class TagListenerTest extends WebTestCase
8+
{
9+
public function testTagsAreSet()
10+
{
11+
$client = static::createClient();
12+
13+
$client->request('GET', '/test/list');
14+
$response = $client->getResponse();
15+
$this->assertEquals('all-items,item-123', $response->headers->get('X-Cache-Tags'));
16+
17+
$client->request('GET', '/test/123');
18+
$response = $client->getResponse();
19+
$this->assertEquals('item-123', $response->headers->get('X-Cache-Tags'));
20+
}
21+
22+
public function testTagsAreInvalidated()
23+
{
24+
$client = static::createClient();
25+
26+
$client->getContainer()->mock(
27+
'fos_http_cache.cache_manager',
28+
'\FOS\HttpCacheBundle\CacheManager'
29+
)
30+
->shouldReceive('invalidateTags')->once()->with(array('all-items'))
31+
->shouldReceive('invalidateTags')->once()->with(array('item-123'))
32+
->shouldReceive('flush')->once()
33+
;
34+
35+
$client->request('POST', '/test/123');
36+
}
37+
38+
public function testErrorIsNotInvalidated()
39+
{
40+
$client = static::createClient();
41+
42+
$client->getContainer()->mock(
43+
'fos_http_cache.cache_manager',
44+
'\FOS\HttpCacheBundle\CacheManager'
45+
)
46+
->shouldReceive('invalidateTags')->never()
47+
->shouldReceive('flush')->once()
48+
;
49+
50+
$client->request('POST', '/test/error');
51+
}
52+
53+
protected function tearDown()
54+
{
55+
static::createClient()->getContainer()->unmock('fos_http_cache.cache_manager');
56+
}
57+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace FOS\HttpCacheBundle\Tests\Functional\Fixtures\Controller;
4+
5+
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
6+
use Symfony\Component\HttpFoundation\Request;
7+
use Symfony\Component\HttpFoundation\Response;
8+
use FOS\HttpCacheBundle\Configuration\Tag;
9+
10+
class TestController extends Controller
11+
{
12+
/**
13+
* @Tag("all-items")
14+
* @Tag("item-123")
15+
*/
16+
public function listAction()
17+
{
18+
return new Response('All items including 123');
19+
}
20+
21+
/**
22+
* @Tag(expression="'item-'~id")
23+
*/
24+
public function itemAction(Request $request, $id)
25+
{
26+
if (!$request->isMethodSafe()) {
27+
$this->container->get('fos_http_cache.cache_manager')->invalidateTags(array('all-items'));
28+
}
29+
30+
return new Response('Item ' . $id . ' invalidated');
31+
}
32+
33+
/**
34+
* @Tag("items")
35+
*/
36+
public function errorAction()
37+
{
38+
return new Response('Forbidden', 403);
39+
}
40+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
use Symfony\Component\Config\Loader\LoaderInterface;
4+
use Symfony\Component\HttpKernel\Kernel;
5+
6+
class AppKernel extends Kernel
7+
{
8+
/**
9+
* {@inheritdoc}
10+
*/
11+
public function registerBundles()
12+
{
13+
return array(
14+
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
15+
new \Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
16+
new \Symfony\Bundle\MonologBundle\MonologBundle(),
17+
new \FOS\HttpCacheBundle\FOSHttpCacheBundle(),
18+
);
19+
}
20+
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
public function registerContainerConfiguration(LoaderInterface $loader)
25+
{
26+
$loader->load(__DIR__.'/config/config.yml');
27+
}
28+
29+
/**
30+
* {@inheritdoc}
31+
*/
32+
public function getCacheDir()
33+
{
34+
return sys_get_temp_dir().'/fos-http-cache-bundle/cache';
35+
}
36+
37+
/**
38+
* {@inheritdoc}
39+
*/
40+
public function getLogDir()
41+
{
42+
return sys_get_temp_dir().'/fos-http-cache-bundle/logs';
43+
}
44+
45+
/**
46+
* {@inheritdoc}
47+
*/
48+
protected function getContainerBaseClass()
49+
{
50+
return '\PSS\SymfonyMockerContainer\DependencyInjection\MockerContainer';
51+
}
52+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
framework:
2+
secret: fos
3+
router:
4+
resource: "%kernel.root_dir%/config/routing.yml"
5+
test: ~
6+
7+
fos_http_cache:
8+
varnish:
9+
ips: 127.0.0.1
10+
11+
monolog:
12+
handlers:
13+
main:
14+
type: stream
15+
level: debug

0 commit comments

Comments
 (0)