From 86138312e24fe983cc2880296f1c27f037e705ef Mon Sep 17 00:00:00 2001 From: Yanick Witschi Date: Wed, 22 Mar 2017 21:45:47 +0100 Subject: [PATCH 01/14] WIP --- composer.json | 3 + src/ContaoManager/Plugin.php | 3 +- .../HeaderReplay/BackendSessionListener.php | 77 +++++++++++++++++++ .../HeaderReplay/PageLayoutListener.php | 64 +++++++++++++++ src/Resources/config/listener.yml | 14 ++++ .../contao/classes/FrontendTemplate.php | 10 ++- 6 files changed, 167 insertions(+), 4 deletions(-) create mode 100644 src/EventListener/HeaderReplay/BackendSessionListener.php create mode 100644 src/EventListener/HeaderReplay/PageLayoutListener.php diff --git a/composer.json b/composer.json index 27eece48d0..6a7eaf0b48 100644 --- a/composer.json +++ b/composer.json @@ -42,6 +42,9 @@ "simplepie/simplepie": "^1.3", "tecnickcom/tcpdf": "^6.0", "true/punycode": "^2.0", + "terminal42/header-replay-bundle": "^1.0", + "friendsofsymfony/http-cache": "^2.0", + "php-http/guzzle6-adapter": "^1.1", "twig/twig": "^1.26", "webmozart/path-util": "^2.0", "contao/image": "^0.3.1", diff --git a/src/ContaoManager/Plugin.php b/src/ContaoManager/Plugin.php index 155e2dae23..0697f114e7 100644 --- a/src/ContaoManager/Plugin.php +++ b/src/ContaoManager/Plugin.php @@ -29,6 +29,7 @@ use Symfony\Bundle\TwigBundle\TwigBundle; use Symfony\Component\Config\Loader\LoaderResolverInterface; use Symfony\Component\HttpKernel\KernelInterface; +use Terminal42\HeaderReplay\HeaderReplayBundle; /** * Plugin for the Contao Manager. @@ -43,7 +44,7 @@ class Plugin implements BundlePluginInterface, RoutingPluginInterface public function getBundles(ParserInterface $parser) { return [ - BundleConfig::create(KnpMenuBundle::class), + BundleConfig::create(HeaderReplayBundle::class), BundleConfig::create(KnpTimeBundle::class), BundleConfig::create(ContaoCoreBundle::class) ->setReplace(['core']) diff --git a/src/EventListener/HeaderReplay/BackendSessionListener.php b/src/EventListener/HeaderReplay/BackendSessionListener.php new file mode 100644 index 0000000000..f57c49b37e --- /dev/null +++ b/src/EventListener/HeaderReplay/BackendSessionListener.php @@ -0,0 +1,77 @@ + + */ +class BackendSessionListener +{ + /** + * @var bool + */ + private $disableIpCheck; + + /** + * BackendSessionListener constructor. + * + * @param bool $disableIpCheck + */ + public function __construct($disableIpCheck) + { + $this->disableIpCheck = $disableIpCheck; + } + + /** + * @param HeaderReplayEvent $event + */ + public function onReplay(HeaderReplayEvent $event) + { + $request = $event->getRequest(); + + if (null === $request->getSession() || !$this->hasAuthenticatedBackendUser($request)) { + return; + } + + $headers = $event->getHeaders(); + $headers->set(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME, 'true'); + } + + /** + * Checks if there is an authenticated back end user. + * + * @param Request $request + * + * @return bool + */ + private function hasAuthenticatedBackendUser(Request $request) + { + if (!$request->cookies->has('BE_USER_AUTH')) { + return false; + } + + $sessionHash = sha1( + sprintf( + '%s%sBE_USER_AUTH', + $request->getSession()->getId(), + $this->disableIpCheck ? '' : $request->getClientIp() + ) + ); + + return $request->cookies->get('BE_USER_AUTH') === $sessionHash; + } +} diff --git a/src/EventListener/HeaderReplay/PageLayoutListener.php b/src/EventListener/HeaderReplay/PageLayoutListener.php new file mode 100644 index 0000000000..62a93aef53 --- /dev/null +++ b/src/EventListener/HeaderReplay/PageLayoutListener.php @@ -0,0 +1,64 @@ + + */ +class PageLayoutListener +{ + /** + * @var ContaoFrameworkInterface + */ + private $framework; + + /** + * PageLayoutListener constructor. + * + * @param ContaoFrameworkInterface $framework + */ + public function __construct(ContaoFrameworkInterface $framework) + { + $this->framework = $framework; + } + + /** + * @param HeaderReplayEvent $event + */ + public function onReplay(HeaderReplayEvent $event) + { + $request = $event->getRequest(); + + $this->framework->initialize(); + + $mobile = $this->framework->getAdapter(Environment::class)->get('agent')->mobile; + + if ($request->cookies->has('TL_VIEW')) { + switch ($request->cookies->get('TL_VIEW')) { + case 'mobile': + $mobile = true; + break; + case 'desktop': + $mobile = false; + } + } + + $headers = $event->getHeaders(); + $headers->set('Contao-Page-Layout', $mobile ? 'mobile' : 'desktop'); + } +} diff --git a/src/Resources/config/listener.yml b/src/Resources/config/listener.yml index 15db998862..6ca9df9825 100644 --- a/src/Resources/config/listener.yml +++ b/src/Resources/config/listener.yml @@ -69,6 +69,20 @@ services: tags: - { name: kernel.event_listener, event: kernel.exception, method: onKernelException, priority: 96 } + contao.listener.header_replay.backend_session: + class: Contao\CoreBundle\EventListener\HeaderReplay\BackendSessionListener + arguments: + - "%contao.security.disable_ip_check%" + tags: + - { name: kernel.event_listener, event: t42.header_replay, method: onReplay } + + contao.listener.header_replay.page_layout: + class: Contao\CoreBundle\EventListener\HeaderReplay\PageLayoutListener + arguments: + - "@contao.framework" + tags: + - { name: kernel.event_listener, event: t42.header_replay, method: onReplay } + contao.listener.insecure_installation: class: Contao\CoreBundle\EventListener\InsecureInstallationListener tags: diff --git a/src/Resources/contao/classes/FrontendTemplate.php b/src/Resources/contao/classes/FrontendTemplate.php index af8be85f8a..be2128aa0b 100644 --- a/src/Resources/contao/classes/FrontendTemplate.php +++ b/src/Resources/contao/classes/FrontendTemplate.php @@ -371,9 +371,13 @@ private function setCacheHeaders(Response $response) return $response->setPrivate(); } - // Do not cache the response if a user is logged in or the page is protected or uses a mobile layout - // TODO: Add support for proxies so they can vary on member context and page layout - if (FE_USER_LOGGED_IN === true || BE_USER_LOGGED_IN === true || $objPage->isMobile || $objPage->protected || $this->hasAuthenticatedBackendUser()) + // Vary on page layout + $response->setVary(['Contao-Page-Layout'], false); + $response->headers->set('Contao-Page-Layout', $objPage->isMobile ? 'mobile' : 'desktop'); + + // Do not cache the response if a user is logged in or the page is protected + // TODO: Add support for proxies so they can vary on member context + if (FE_USER_LOGGED_IN === true || BE_USER_LOGGED_IN === true || $objPage->protected || $this->hasAuthenticatedBackendUser()) { return $response->setPrivate(); } From 393e046121ea88ba23ddb7490513b8cafcd814cb Mon Sep 17 00:00:00 2001 From: Yanick Witschi Date: Mon, 12 Jun 2017 15:56:45 +0200 Subject: [PATCH 02/14] Added unit tests for the backend session listener --- .../BackendSessionListenerTest.php | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 tests/EventListener/HeaderReplay/BackendSessionListenerTest.php diff --git a/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php b/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php new file mode 100644 index 0000000000..534ee0ef0a --- /dev/null +++ b/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php @@ -0,0 +1,103 @@ + + */ +class BackendSessionListenerTest extends TestCase +{ + /** + * Tests the object instantiation. + */ + public function testInstantiation() + { + $listener = new BackendSessionListener(false); + + $this->assertInstanceOf('Contao\CoreBundle\EventListener\HeaderReplay\BackendSessionListener', $listener); + } + + public function testOnReplayWithNoSession() + { + $listener = new BackendSessionListener(false); + + $request = new Request(); + $headers = new ResponseHeaderBag(); + $event = new HeaderReplayEvent($request, $headers); + + $listener->onReplay($event); + + $this->assertArrayNotHasKey(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME, $event->getHeaders()->all()); + } + + public function testOnReplayWithNoAuthCookie() + { + $listener = new BackendSessionListener(false); + + $session = new Session(); + $request = new Request(); + $request->setSession($session); + $headers = new ResponseHeaderBag(); + $event = new HeaderReplayEvent($request, $headers); + + $listener->onReplay($event); + + $this->assertNotNull($request->getSession()); + $this->assertArrayNotHasKey(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME, $event->getHeaders()->all()); + } + + public function testOnReplayWithNoValidCookie() + { + $listener = new BackendSessionListener(false); + + $session = new Session(); + $request = new Request(); + $request->cookies->set('BE_USER_AUTH', 'foobar'); + $request->setSession($session); + $headers = new ResponseHeaderBag(); + $event = new HeaderReplayEvent($request, $headers); + + $listener->onReplay($event); + + $this->assertNotNull($request->getSession()); + $this->assertTrue($request->cookies->has('BE_USER_AUTH')); + $this->assertArrayNotHasKey(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME, $event->getHeaders()->all()); + } + + public function testOnReplay() + { + $listener = new BackendSessionListener(false); + + $session = new Session(); + $session->setId('foobar-id'); + $request = new Request(); + $request->cookies->set('BE_USER_AUTH', 'f6d5c422c903288859fb5ccf03c8af8b0fb4b70a'); + $request->setSession($session); + $headers = new ResponseHeaderBag(); + $event = new HeaderReplayEvent($request, $headers); + + $listener->onReplay($event); + + $this->assertNotNull($request->getSession()); + $this->assertTrue($request->cookies->has('BE_USER_AUTH')); + $this->assertArrayNotHasKey(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME, $event->getHeaders()->all()); + } +} From 1fe7aaf3f3b2c01e186c2243664c2b4413c86fa4 Mon Sep 17 00:00:00 2001 From: Yanick Witschi Date: Mon, 12 Jun 2017 16:26:00 +0200 Subject: [PATCH 03/14] Added unit tests for page layout listener --- .../HeaderReplay/PageLayoutListenerTest.php | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 tests/EventListener/HeaderReplay/PageLayoutListenerTest.php diff --git a/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php b/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php new file mode 100644 index 0000000000..7f397ce4ce --- /dev/null +++ b/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php @@ -0,0 +1,96 @@ + + */ +class PageLayoutListenerTest extends TestCase +{ + /** + * Tests the object instantiation. + */ + public function testInstantiation() + { + $listener = new PageLayoutListener($this->mockContaoFramework()); + + $this->assertInstanceOf('Contao\CoreBundle\EventListener\HeaderReplay\PageLayoutListener', $listener); + } + + /** + * @param bool $agentIsMobile + * @param string|null $tlViewCookie + * @param string $expectedHeaderValue + * + * @dataProvider onReplayProvider + */ + public function testOnReplay($agentIsMobile, $tlViewCookie, $expectedHeaderValue) + { + $envAdapter = $this + ->getMockBuilder(Adapter::class) + ->disableOriginalConstructor() + ->setMethods(['get']) + ->getMock() + ; + + $envAdapter + ->method('get') + ->willReturnCallback(function ($key) use ($agentIsMobile) { + switch ($key) { + case 'agent': + return (object) ['mobile' => $agentIsMobile]; + default: + return null; + } + }) + ; + + $framework = $this->mockContaoFramework(null, null, [ + Environment::class => $envAdapter + ]); + + $listener = new PageLayoutListener($framework); + $request = new Request(); + + if (null !== $tlViewCookie) { + $request->cookies->set('TL_VIEW', $tlViewCookie); + } + + $headers = new ResponseHeaderBag(); + $event = new HeaderReplayEvent($request, $headers); + + $listener->onReplay($event); + + $this->assertSame($expectedHeaderValue, $event->getHeaders()->get('Contao-Page-Layout')); + } + + public function onReplayProvider() + { + return [ + 'No cookie -> desktop' => [false, null, 'desktop'], + 'No cookie -> mobile' => [true, null, 'mobile'], + 'Cookie mobile -> mobile when agent match' => [true, 'mobile', 'mobile'], + 'Cookie mobile -> mobile when agent does not match' => [false, 'mobile', 'mobile'], + 'Cookie desktop -> desktop when agent match' => [true, 'desktop', 'desktop'], + 'Cookie desktop -> desktop when agent does not match' => [false, 'desktop', 'desktop'], + ]; + } +} From 6f29f611bba47927d3a5639e7f653bc1cbeed40d Mon Sep 17 00:00:00 2001 From: Yanick Witschi Date: Mon, 12 Jun 2017 16:34:37 +0200 Subject: [PATCH 04/14] Not needed here --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 6a7eaf0b48..172772a4ae 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,6 @@ "tecnickcom/tcpdf": "^6.0", "true/punycode": "^2.0", "terminal42/header-replay-bundle": "^1.0", - "friendsofsymfony/http-cache": "^2.0", "php-http/guzzle6-adapter": "^1.1", "twig/twig": "^1.26", "webmozart/path-util": "^2.0", From 9fdb93eeff406adec46fe2f3aad69fec83e93cb4 Mon Sep 17 00:00:00 2001 From: Yanick Witschi Date: Mon, 12 Jun 2017 16:58:45 +0200 Subject: [PATCH 05/14] Fixed rebase bug --- src/ContaoManager/Plugin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ContaoManager/Plugin.php b/src/ContaoManager/Plugin.php index 0697f114e7..1d03d07723 100644 --- a/src/ContaoManager/Plugin.php +++ b/src/ContaoManager/Plugin.php @@ -45,6 +45,7 @@ public function getBundles(ParserInterface $parser) { return [ BundleConfig::create(HeaderReplayBundle::class), + BundleConfig::create(KnpMenuBundle::class), BundleConfig::create(KnpTimeBundle::class), BundleConfig::create(ContaoCoreBundle::class) ->setReplace(['core']) From ba768e4e60e3760919f8219415e830b8128b9081 Mon Sep 17 00:00:00 2001 From: Yanick Witschi Date: Mon, 12 Jun 2017 17:21:14 +0200 Subject: [PATCH 06/14] Fixed event configuration --- src/Resources/config/listener.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Resources/config/listener.yml b/src/Resources/config/listener.yml index 6ca9df9825..2050c533d2 100644 --- a/src/Resources/config/listener.yml +++ b/src/Resources/config/listener.yml @@ -74,14 +74,14 @@ services: arguments: - "%contao.security.disable_ip_check%" tags: - - { name: kernel.event_listener, event: t42.header_replay, method: onReplay } + - { name: kernel.event_listener, event: terminal42.header_replay, method: onReplay } contao.listener.header_replay.page_layout: class: Contao\CoreBundle\EventListener\HeaderReplay\PageLayoutListener arguments: - "@contao.framework" tags: - - { name: kernel.event_listener, event: t42.header_replay, method: onReplay } + - { name: kernel.event_listener, event: terminal42.header_replay, method: onReplay } contao.listener.insecure_installation: class: Contao\CoreBundle\EventListener\InsecureInstallationListener From b302245c0415ce887912b598469dd9c2c6427c5e Mon Sep 17 00:00:00 2001 From: Yanick Witschi Date: Mon, 12 Jun 2017 17:42:06 +0200 Subject: [PATCH 07/14] Fixed tests --- .../HeaderReplay/BackendSessionListenerTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php b/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php index 534ee0ef0a..01720e6210 100644 --- a/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php +++ b/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php @@ -45,7 +45,7 @@ public function testOnReplayWithNoSession() $listener->onReplay($event); - $this->assertArrayNotHasKey(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME, $event->getHeaders()->all()); + $this->assertArrayNotHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); } public function testOnReplayWithNoAuthCookie() @@ -61,7 +61,7 @@ public function testOnReplayWithNoAuthCookie() $listener->onReplay($event); $this->assertNotNull($request->getSession()); - $this->assertArrayNotHasKey(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME, $event->getHeaders()->all()); + $this->assertArrayNotHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); } public function testOnReplayWithNoValidCookie() @@ -79,7 +79,7 @@ public function testOnReplayWithNoValidCookie() $this->assertNotNull($request->getSession()); $this->assertTrue($request->cookies->has('BE_USER_AUTH')); - $this->assertArrayNotHasKey(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME, $event->getHeaders()->all()); + $this->assertArrayNotHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); } public function testOnReplay() @@ -98,6 +98,6 @@ public function testOnReplay() $this->assertNotNull($request->getSession()); $this->assertTrue($request->cookies->has('BE_USER_AUTH')); - $this->assertArrayNotHasKey(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME, $event->getHeaders()->all()); + $this->assertArrayHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); } } From ac60724d1a5317a4747b883bc65cb7af599cf079 Mon Sep 17 00:00:00 2001 From: Yanick Witschi Date: Mon, 12 Jun 2017 17:46:41 +0200 Subject: [PATCH 08/14] Added scope matcher to only check on front end or back end requests respectively --- .../HeaderReplay/BackendSessionListener.php | 17 +++++++++-- .../HeaderReplay/PageLayoutListener.php | 14 ++++++++- src/Resources/config/listener.yml | 2 ++ .../BackendSessionListenerTest.php | 29 +++++++++++++++---- .../HeaderReplay/PageLayoutListenerTest.php | 19 ++++++++++-- 5 files changed, 70 insertions(+), 11 deletions(-) diff --git a/src/EventListener/HeaderReplay/BackendSessionListener.php b/src/EventListener/HeaderReplay/BackendSessionListener.php index f57c49b37e..9e43d4e49e 100644 --- a/src/EventListener/HeaderReplay/BackendSessionListener.php +++ b/src/EventListener/HeaderReplay/BackendSessionListener.php @@ -10,6 +10,7 @@ namespace Contao\CoreBundle\EventListener\HeaderReplay; +use Contao\CoreBundle\Routing\ScopeMatcher; use Symfony\Component\HttpFoundation\Request; use Terminal42\HeaderReplay\Event\HeaderReplayEvent; use Terminal42\HeaderReplay\EventListener\HeaderReplayListener; @@ -21,6 +22,11 @@ */ class BackendSessionListener { + /** + * @var ScopeMatcher + */ + private $scopeMatcher; + /** * @var bool */ @@ -29,10 +35,12 @@ class BackendSessionListener /** * BackendSessionListener constructor. * - * @param bool $disableIpCheck + * @param ScopeMatcher $scopeMatcher + * @param bool $disableIpCheck */ - public function __construct($disableIpCheck) + public function __construct(ScopeMatcher $scopeMatcher, $disableIpCheck) { + $this->scopeMatcher = $scopeMatcher; $this->disableIpCheck = $disableIpCheck; } @@ -43,7 +51,10 @@ public function onReplay(HeaderReplayEvent $event) { $request = $event->getRequest(); - if (null === $request->getSession() || !$this->hasAuthenticatedBackendUser($request)) { + if (!$this->scopeMatcher->isBackendRequest($request) + || null === $request->getSession() + || !$this->hasAuthenticatedBackendUser($request) + ) { return; } diff --git a/src/EventListener/HeaderReplay/PageLayoutListener.php b/src/EventListener/HeaderReplay/PageLayoutListener.php index 62a93aef53..a4a1ac19ce 100644 --- a/src/EventListener/HeaderReplay/PageLayoutListener.php +++ b/src/EventListener/HeaderReplay/PageLayoutListener.php @@ -11,6 +11,7 @@ namespace Contao\CoreBundle\EventListener\HeaderReplay; use Contao\CoreBundle\Framework\ContaoFrameworkInterface; +use Contao\CoreBundle\Routing\ScopeMatcher; use Contao\Environment; use Terminal42\HeaderReplay\Event\HeaderReplayEvent; @@ -22,6 +23,11 @@ */ class PageLayoutListener { + /** + * @var ScopeMatcher + */ + private $scopeMatcher; + /** * @var ContaoFrameworkInterface */ @@ -30,10 +36,12 @@ class PageLayoutListener /** * PageLayoutListener constructor. * + * @param ScopeMatcher $scopeMatcher * @param ContaoFrameworkInterface $framework */ - public function __construct(ContaoFrameworkInterface $framework) + public function __construct(ScopeMatcher $scopeMatcher, ContaoFrameworkInterface $framework) { + $this->scopeMatcher = $scopeMatcher; $this->framework = $framework; } @@ -44,6 +52,10 @@ public function onReplay(HeaderReplayEvent $event) { $request = $event->getRequest(); + if (!$this->scopeMatcher->isFrontendRequest($request)) { + return; + } + $this->framework->initialize(); $mobile = $this->framework->getAdapter(Environment::class)->get('agent')->mobile; diff --git a/src/Resources/config/listener.yml b/src/Resources/config/listener.yml index 2050c533d2..fba7b1c524 100644 --- a/src/Resources/config/listener.yml +++ b/src/Resources/config/listener.yml @@ -72,6 +72,7 @@ services: contao.listener.header_replay.backend_session: class: Contao\CoreBundle\EventListener\HeaderReplay\BackendSessionListener arguments: + - "@contao.routing.scope_matcher" - "%contao.security.disable_ip_check%" tags: - { name: kernel.event_listener, event: terminal42.header_replay, method: onReplay } @@ -79,6 +80,7 @@ services: contao.listener.header_replay.page_layout: class: Contao\CoreBundle\EventListener\HeaderReplay\PageLayoutListener arguments: + - "@contao.routing.scope_matcher" - "@contao.framework" tags: - { name: kernel.event_listener, event: terminal42.header_replay, method: onReplay } diff --git a/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php b/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php index 01720e6210..c178ef61ae 100644 --- a/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php +++ b/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php @@ -11,8 +11,10 @@ namespace Contao\CoreBundle\Tests\EventListener\HeaderReplay; use Contao\CoreBundle\EventListener\HeaderReplay\BackendSessionListener; +use Contao\CoreBundle\Routing\ScopeMatcher; use Contao\CoreBundle\Tests\TestCase; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestMatcher; use Symfony\Component\HttpFoundation\ResponseHeaderBag; use Symfony\Component\HttpFoundation\Session\Session; use Terminal42\HeaderReplay\Event\HeaderReplayEvent; @@ -30,16 +32,30 @@ class BackendSessionListenerTest extends TestCase */ public function testInstantiation() { - $listener = new BackendSessionListener(false); + $listener = new BackendSessionListener($this->mockScopeMatcher(), false); $this->assertInstanceOf('Contao\CoreBundle\EventListener\HeaderReplay\BackendSessionListener', $listener); } + public function testOnReplayWithNoBackendScope() + { + $listener = new BackendSessionListener($this->mockScopeMatcher(), false); + + $request = new Request(); + $headers = new ResponseHeaderBag(); + $event = new HeaderReplayEvent($request, $headers); + + $listener->onReplay($event); + + $this->assertArrayNotHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); + } + public function testOnReplayWithNoSession() { - $listener = new BackendSessionListener(false); + $listener = new BackendSessionListener($this->mockScopeMatcher(), false); $request = new Request(); + $request->attributes->set('_scope', 'backend'); $headers = new ResponseHeaderBag(); $event = new HeaderReplayEvent($request, $headers); @@ -50,10 +66,11 @@ public function testOnReplayWithNoSession() public function testOnReplayWithNoAuthCookie() { - $listener = new BackendSessionListener(false); + $listener = new BackendSessionListener($this->mockScopeMatcher(), false); $session = new Session(); $request = new Request(); + $request->attributes->set('_scope', 'backend'); $request->setSession($session); $headers = new ResponseHeaderBag(); $event = new HeaderReplayEvent($request, $headers); @@ -66,10 +83,11 @@ public function testOnReplayWithNoAuthCookie() public function testOnReplayWithNoValidCookie() { - $listener = new BackendSessionListener(false); + $listener = new BackendSessionListener($this->mockScopeMatcher(), false); $session = new Session(); $request = new Request(); + $request->attributes->set('_scope', 'backend'); $request->cookies->set('BE_USER_AUTH', 'foobar'); $request->setSession($session); $headers = new ResponseHeaderBag(); @@ -84,11 +102,12 @@ public function testOnReplayWithNoValidCookie() public function testOnReplay() { - $listener = new BackendSessionListener(false); + $listener = new BackendSessionListener($this->mockScopeMatcher(), false); $session = new Session(); $session->setId('foobar-id'); $request = new Request(); + $request->attributes->set('_scope', 'backend'); $request->cookies->set('BE_USER_AUTH', 'f6d5c422c903288859fb5ccf03c8af8b0fb4b70a'); $request->setSession($session); $headers = new ResponseHeaderBag(); diff --git a/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php b/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php index 7f397ce4ce..f851299ec4 100644 --- a/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php +++ b/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php @@ -30,11 +30,25 @@ class PageLayoutListenerTest extends TestCase */ public function testInstantiation() { - $listener = new PageLayoutListener($this->mockContaoFramework()); + $listener = new PageLayoutListener($this->mockScopeMatcher(), $this->mockContaoFramework()); $this->assertInstanceOf('Contao\CoreBundle\EventListener\HeaderReplay\PageLayoutListener', $listener); } + public function testOnReplayWithNoFrontendScope() + { + $listener = new PageLayoutListener($this->mockScopeMatcher(), $this->mockContaoFramework()); + + $request = new Request(); + + $headers = new ResponseHeaderBag(); + $event = new HeaderReplayEvent($request, $headers); + + $listener->onReplay($event); + + $this->assertArrayNotHasKey('contao-page-layout', $event->getHeaders()->all()); + } + /** * @param bool $agentIsMobile * @param string|null $tlViewCookie @@ -67,8 +81,9 @@ public function testOnReplay($agentIsMobile, $tlViewCookie, $expectedHeaderValue Environment::class => $envAdapter ]); - $listener = new PageLayoutListener($framework); + $listener = new PageLayoutListener($this->mockScopeMatcher(), $framework); $request = new Request(); + $request->attributes->set('_scope', 'frontend'); if (null !== $tlViewCookie) { $request->cookies->set('TL_VIEW', $tlViewCookie); From 184b445ea9a47c8159ee49e9d45a68d53275fac5 Mon Sep 17 00:00:00 2001 From: Yanick Witschi Date: Mon, 12 Jun 2017 18:31:39 +0200 Subject: [PATCH 09/14] Fixed unit tests --- tests/ContaoManager/PluginTest.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/ContaoManager/PluginTest.php b/tests/ContaoManager/PluginTest.php index f8857c4149..2c8699356b 100644 --- a/tests/ContaoManager/PluginTest.php +++ b/tests/ContaoManager/PluginTest.php @@ -30,6 +30,7 @@ use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\Loader\LoaderResolverInterface; use Symfony\Component\HttpKernel\KernelInterface; +use Terminal42\HeaderReplay\HeaderReplayBundle; /** * Tests the Plugin class. @@ -58,18 +59,22 @@ public function testGetBundles() /** @var BundleConfig[] $bundles */ $bundles = $plugin->getBundles(new DelegatingParser()); - $this->assertCount(3, $bundles); + $this->assertCount(4, $bundles); - $this->assertSame(KnpMenuBundle::class, $bundles[0]->getName()); + $this->assertSame(HeaderReplayBundle::class, $bundles[0]->getName()); $this->assertSame([], $bundles[0]->getReplace()); $this->assertSame([], $bundles[0]->getLoadAfter()); - $this->assertSame(KnpTimeBundle::class, $bundles[1]->getName()); + $this->assertSame(KnpMenuBundle::class, $bundles[1]->getName()); $this->assertSame([], $bundles[1]->getReplace()); $this->assertSame([], $bundles[1]->getLoadAfter()); - $this->assertSame(ContaoCoreBundle::class, $bundles[2]->getName()); - $this->assertSame(['core'], $bundles[2]->getReplace()); + $this->assertSame(KnpTimeBundle::class, $bundles[2]->getName()); + $this->assertSame([], $bundles[2]->getReplace()); + $this->assertSame([], $bundles[2]->getLoadAfter()); + + $this->assertSame(ContaoCoreBundle::class, $bundles[3]->getName()); + $this->assertSame(['core'], $bundles[3]->getReplace()); $this->assertSame( [ @@ -86,7 +91,7 @@ public function testGetBundles() SensioFrameworkExtraBundle::class, ContaoManagerBundle::class, ], - $bundles[2]->getLoadAfter() + $bundles[3]->getLoadAfter() ); } From 46db3f60b00f88ec0a24b5c5ffdbabacf3033fa5 Mon Sep 17 00:00:00 2001 From: Yanick Witschi Date: Tue, 13 Jun 2017 11:24:03 +0200 Subject: [PATCH 10/14] Do not initialize framework if not needed --- .../HeaderReplay/PageLayoutListener.php | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/EventListener/HeaderReplay/PageLayoutListener.php b/src/EventListener/HeaderReplay/PageLayoutListener.php index a4a1ac19ce..9df5ce0a54 100644 --- a/src/EventListener/HeaderReplay/PageLayoutListener.php +++ b/src/EventListener/HeaderReplay/PageLayoutListener.php @@ -56,18 +56,11 @@ public function onReplay(HeaderReplayEvent $event) return; } - $this->framework->initialize(); - - $mobile = $this->framework->getAdapter(Environment::class)->get('agent')->mobile; - if ($request->cookies->has('TL_VIEW')) { - switch ($request->cookies->get('TL_VIEW')) { - case 'mobile': - $mobile = true; - break; - case 'desktop': - $mobile = false; - } + $mobile = 'mobile' === $request->cookies->get('TL_VIEW'); + } else { + $this->framework->initialize(); + $mobile = $this->framework->getAdapter(Environment::class)->get('agent')->mobile; } $headers = $event->getHeaders(); From bee3ce2b6706c2fef217e6d66d71e3086604c69a Mon Sep 17 00:00:00 2001 From: Yanick Witschi Date: Tue, 13 Jun 2017 11:32:13 +0200 Subject: [PATCH 11/14] CS --- .../HeaderReplay/BackendSessionListener.php | 4 ++++ .../HeaderReplay/PageLayoutListener.php | 7 +++++++ .../contao/classes/FrontendTemplate.php | 2 +- .../HeaderReplay/BackendSessionListenerTest.php | 17 +++++++++++++++++ .../HeaderReplay/PageLayoutListenerTest.php | 11 +++++++++++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/EventListener/HeaderReplay/BackendSessionListener.php b/src/EventListener/HeaderReplay/BackendSessionListener.php index 9e43d4e49e..d147bf8f35 100644 --- a/src/EventListener/HeaderReplay/BackendSessionListener.php +++ b/src/EventListener/HeaderReplay/BackendSessionListener.php @@ -45,6 +45,10 @@ public function __construct(ScopeMatcher $scopeMatcher, $disableIpCheck) } /** + * Sets the "force no cache" header on the replay response to disable + * reverse proxy caching if a back end user is logged in (front end + * preview mode). + * * @param HeaderReplayEvent $event */ public function onReplay(HeaderReplayEvent $event) diff --git a/src/EventListener/HeaderReplay/PageLayoutListener.php b/src/EventListener/HeaderReplay/PageLayoutListener.php index 9df5ce0a54..72d90b3827 100644 --- a/src/EventListener/HeaderReplay/PageLayoutListener.php +++ b/src/EventListener/HeaderReplay/PageLayoutListener.php @@ -46,6 +46,13 @@ public function __construct(ScopeMatcher $scopeMatcher, ContaoFrameworkInterface } /** + * Adds the "Contao-Page-Layout" header to the replay response based + * on either the TL_VIEW cookie (if present) or the current browser + * user agent string so that the reverse proxy gains the ability to + * vary on it. This is needed so that the reverse proxy generates two + * entries for the same URL when you are using mobile and desktop page + * layouts. + * * @param HeaderReplayEvent $event */ public function onReplay(HeaderReplayEvent $event) diff --git a/src/Resources/contao/classes/FrontendTemplate.php b/src/Resources/contao/classes/FrontendTemplate.php index be2128aa0b..2720bbe03d 100644 --- a/src/Resources/contao/classes/FrontendTemplate.php +++ b/src/Resources/contao/classes/FrontendTemplate.php @@ -372,7 +372,7 @@ private function setCacheHeaders(Response $response) } // Vary on page layout - $response->setVary(['Contao-Page-Layout'], false); + $response->setVary(array('Contao-Page-Layout'), false); $response->headers->set('Contao-Page-Layout', $objPage->isMobile ? 'mobile' : 'desktop'); // Do not cache the response if a user is logged in or the page is protected diff --git a/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php b/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php index c178ef61ae..8ffce6cd8b 100644 --- a/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php +++ b/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php @@ -37,6 +37,9 @@ public function testInstantiation() $this->assertInstanceOf('Contao\CoreBundle\EventListener\HeaderReplay\BackendSessionListener', $listener); } + /** + * Tests no header is added when not in Contao back end scope. + */ public function testOnReplayWithNoBackendScope() { $listener = new BackendSessionListener($this->mockScopeMatcher(), false); @@ -50,6 +53,9 @@ public function testOnReplayWithNoBackendScope() $this->assertArrayNotHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); } + /** + * Tests no header is added when the request has no session. + */ public function testOnReplayWithNoSession() { $listener = new BackendSessionListener($this->mockScopeMatcher(), false); @@ -64,6 +70,10 @@ public function testOnReplayWithNoSession() $this->assertArrayNotHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); } + /** + * Tests no header is added when the request has no back end user authentication + * cookie. + */ public function testOnReplayWithNoAuthCookie() { $listener = new BackendSessionListener($this->mockScopeMatcher(), false); @@ -81,6 +91,9 @@ public function testOnReplayWithNoAuthCookie() $this->assertArrayNotHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); } + /** + * Tests no header is added if the auth cookie has an invalid value. + */ public function testOnReplayWithNoValidCookie() { $listener = new BackendSessionListener($this->mockScopeMatcher(), false); @@ -100,6 +113,10 @@ public function testOnReplayWithNoValidCookie() $this->assertArrayNotHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); } + /** + * Tests that the header is correctly added when scope and auth cookie are + * correct. + */ public function testOnReplay() { $listener = new BackendSessionListener($this->mockScopeMatcher(), false); diff --git a/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php b/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php index f851299ec4..d35943387d 100644 --- a/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php +++ b/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php @@ -35,6 +35,9 @@ public function testInstantiation() $this->assertInstanceOf('Contao\CoreBundle\EventListener\HeaderReplay\PageLayoutListener', $listener); } + /** + * Tests that no header is added when not a Contao front end scope. + */ public function testOnReplayWithNoFrontendScope() { $listener = new PageLayoutListener($this->mockScopeMatcher(), $this->mockContaoFramework()); @@ -50,6 +53,9 @@ public function testOnReplayWithNoFrontendScope() } /** + * Tests all combinations of user agent result, TL_VIEW cookie value and checks + * if the header value is set correctly. + * * @param bool $agentIsMobile * @param string|null $tlViewCookie * @param string $expectedHeaderValue @@ -97,6 +103,11 @@ public function testOnReplay($agentIsMobile, $tlViewCookie, $expectedHeaderValue $this->assertSame($expectedHeaderValue, $event->getHeaders()->get('Contao-Page-Layout')); } + /** + * Data provider for the testOnReplayWithNoFrontendScope test. + * + * @return array + */ public function onReplayProvider() { return [ From 78944353582eca0f0ec1efa7144dd7010870fd4d Mon Sep 17 00:00:00 2001 From: Leo Feyer Date: Tue, 13 Jun 2017 13:40:07 +0200 Subject: [PATCH 12/14] Fix the coding style. --- composer.json | 2 +- src/ContaoManager/Plugin.php | 2 +- .../HeaderReplay/BackendSessionListener.php | 7 +- .../HeaderReplay/PageLayoutListener.php | 21 ++--- tests/ContaoManager/PluginTest.php | 13 +-- .../BackendSessionListenerTest.php | 84 ++++++++++--------- .../HeaderReplay/PageLayoutListenerTest.php | 30 +++---- 7 files changed, 81 insertions(+), 78 deletions(-) diff --git a/composer.json b/composer.json index 172772a4ae..0367f9253a 100644 --- a/composer.json +++ b/composer.json @@ -38,12 +38,12 @@ "patchwork/utf8": "^1.2", "phpspec/php-diff": "^1.0", "phpunit/php-token-stream": "^1.4", + "php-http/guzzle6-adapter": "^1.1", "psr/log": "^1.0", "simplepie/simplepie": "^1.3", "tecnickcom/tcpdf": "^6.0", "true/punycode": "^2.0", "terminal42/header-replay-bundle": "^1.0", - "php-http/guzzle6-adapter": "^1.1", "twig/twig": "^1.26", "webmozart/path-util": "^2.0", "contao/image": "^0.3.1", diff --git a/src/ContaoManager/Plugin.php b/src/ContaoManager/Plugin.php index 1d03d07723..f6114de013 100644 --- a/src/ContaoManager/Plugin.php +++ b/src/ContaoManager/Plugin.php @@ -44,9 +44,9 @@ class Plugin implements BundlePluginInterface, RoutingPluginInterface public function getBundles(ParserInterface $parser) { return [ - BundleConfig::create(HeaderReplayBundle::class), BundleConfig::create(KnpMenuBundle::class), BundleConfig::create(KnpTimeBundle::class), + BundleConfig::create(HeaderReplayBundle::class), BundleConfig::create(ContaoCoreBundle::class) ->setReplace(['core']) ->setLoadAfter( diff --git a/src/EventListener/HeaderReplay/BackendSessionListener.php b/src/EventListener/HeaderReplay/BackendSessionListener.php index d147bf8f35..27339647a1 100644 --- a/src/EventListener/HeaderReplay/BackendSessionListener.php +++ b/src/EventListener/HeaderReplay/BackendSessionListener.php @@ -33,7 +33,7 @@ class BackendSessionListener private $disableIpCheck; /** - * BackendSessionListener constructor. + * Constructor. * * @param ScopeMatcher $scopeMatcher * @param bool $disableIpCheck @@ -45,9 +45,8 @@ public function __construct(ScopeMatcher $scopeMatcher, $disableIpCheck) } /** - * Sets the "force no cache" header on the replay response to disable - * reverse proxy caching if a back end user is logged in (front end - * preview mode). + * Sets the "force no cache" header on the replay response to disable reverse proxy + * caching if a back end user is logged in (front end preview mode). * * @param HeaderReplayEvent $event */ diff --git a/src/EventListener/HeaderReplay/PageLayoutListener.php b/src/EventListener/HeaderReplay/PageLayoutListener.php index 72d90b3827..53820ca027 100644 --- a/src/EventListener/HeaderReplay/PageLayoutListener.php +++ b/src/EventListener/HeaderReplay/PageLayoutListener.php @@ -16,8 +16,7 @@ use Terminal42\HeaderReplay\Event\HeaderReplayEvent; /** - * Extracts the page layout for proper Vary handling based - * on the terminal42/header-replay-bundle. + * Adds the Contao-Page-Layout header based on the terminal42/header-replay-bundle. * * @author Yanick Witschi */ @@ -34,7 +33,7 @@ class PageLayoutListener private $framework; /** - * PageLayoutListener constructor. + * Constructor. * * @param ScopeMatcher $scopeMatcher * @param ContaoFrameworkInterface $framework @@ -46,12 +45,10 @@ public function __construct(ScopeMatcher $scopeMatcher, ContaoFrameworkInterface } /** - * Adds the "Contao-Page-Layout" header to the replay response based - * on either the TL_VIEW cookie (if present) or the current browser - * user agent string so that the reverse proxy gains the ability to - * vary on it. This is needed so that the reverse proxy generates two - * entries for the same URL when you are using mobile and desktop page - * layouts. + * Adds the "Contao-Page-Layout" header to the replay response based on either the TL_VIEW cookie + * or the current browser user agent string, so that the reverse proxy gains the ability to vary on + * it. This is needed so that the reverse proxy generates two entries for the same URL when you are + * using mobile and desktop page layouts. * * @param HeaderReplayEvent $event */ @@ -67,7 +64,11 @@ public function onReplay(HeaderReplayEvent $event) $mobile = 'mobile' === $request->cookies->get('TL_VIEW'); } else { $this->framework->initialize(); - $mobile = $this->framework->getAdapter(Environment::class)->get('agent')->mobile; + + /** @var Environment $environment */ + $environment = $this->framework->getAdapter(Environment::class); + + $mobile = $environment->get('agent')->mobile; } $headers = $event->getHeaders(); diff --git a/tests/ContaoManager/PluginTest.php b/tests/ContaoManager/PluginTest.php index 2c8699356b..a11f821abb 100644 --- a/tests/ContaoManager/PluginTest.php +++ b/tests/ContaoManager/PluginTest.php @@ -36,6 +36,7 @@ * Tests the Plugin class. * * @author Leo Feyer + * @author Yanick Witschi */ class PluginTest extends TestCase { @@ -61,18 +62,18 @@ public function testGetBundles() $this->assertCount(4, $bundles); - $this->assertSame(HeaderReplayBundle::class, $bundles[0]->getName()); - $this->assertSame([], $bundles[0]->getReplace()); - $this->assertSame([], $bundles[0]->getLoadAfter()); - - $this->assertSame(KnpMenuBundle::class, $bundles[1]->getName()); + $this->assertSame(KnpMenuBundle::class, $bundles[0]->getName()); $this->assertSame([], $bundles[1]->getReplace()); $this->assertSame([], $bundles[1]->getLoadAfter()); - $this->assertSame(KnpTimeBundle::class, $bundles[2]->getName()); + $this->assertSame(KnpTimeBundle::class, $bundles[1]->getName()); $this->assertSame([], $bundles[2]->getReplace()); $this->assertSame([], $bundles[2]->getLoadAfter()); + $this->assertSame(HeaderReplayBundle::class, $bundles[2]->getName()); + $this->assertSame([], $bundles[0]->getReplace()); + $this->assertSame([], $bundles[0]->getLoadAfter()); + $this->assertSame(ContaoCoreBundle::class, $bundles[3]->getName()); $this->assertSame(['core'], $bundles[3]->getReplace()); diff --git a/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php b/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php index 8ffce6cd8b..2a547ebb8b 100644 --- a/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php +++ b/tests/EventListener/HeaderReplay/BackendSessionListenerTest.php @@ -11,10 +11,8 @@ namespace Contao\CoreBundle\Tests\EventListener\HeaderReplay; use Contao\CoreBundle\EventListener\HeaderReplay\BackendSessionListener; -use Contao\CoreBundle\Routing\ScopeMatcher; use Contao\CoreBundle\Tests\TestCase; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\RequestMatcher; use Symfony\Component\HttpFoundation\ResponseHeaderBag; use Symfony\Component\HttpFoundation\Session\Session; use Terminal42\HeaderReplay\Event\HeaderReplayEvent; @@ -38,102 +36,110 @@ public function testInstantiation() } /** - * Tests no header is added when not in Contao back end scope. + * Tests that no header is added outside the Contao back end scope. */ public function testOnReplayWithNoBackendScope() { - $listener = new BackendSessionListener($this->mockScopeMatcher(), false); - - $request = new Request(); - $headers = new ResponseHeaderBag(); - $event = new HeaderReplayEvent($request, $headers); + $event = new HeaderReplayEvent(new Request(), new ResponseHeaderBag()); + $listener = new BackendSessionListener($this->mockScopeMatcher(), false); $listener->onReplay($event); - $this->assertArrayNotHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); + $this->assertArrayNotHasKey( + strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), + $event->getHeaders()->all() + ); } /** - * Tests no header is added when the request has no session. + * Tests that no header is added when the request has no session. */ public function testOnReplayWithNoSession() { - $listener = new BackendSessionListener($this->mockScopeMatcher(), false); - $request = new Request(); $request->attributes->set('_scope', 'backend'); - $headers = new ResponseHeaderBag(); - $event = new HeaderReplayEvent($request, $headers); + $event = new HeaderReplayEvent($request, new ResponseHeaderBag()); + + $listener = new BackendSessionListener($this->mockScopeMatcher(), false); $listener->onReplay($event); - $this->assertArrayNotHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); + $this->assertArrayNotHasKey( + strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), + $event->getHeaders()->all() + ); } /** - * Tests no header is added when the request has no back end user authentication - * cookie. + * Tests that no header is added when the request has no back end user authentication cookie. */ public function testOnReplayWithNoAuthCookie() { - $listener = new BackendSessionListener($this->mockScopeMatcher(), false); - - $session = new Session(); $request = new Request(); $request->attributes->set('_scope', 'backend'); - $request->setSession($session); - $headers = new ResponseHeaderBag(); - $event = new HeaderReplayEvent($request, $headers); + $request->setSession(new Session()); + + $event = new HeaderReplayEvent($request, new ResponseHeaderBag()); + $listener = new BackendSessionListener($this->mockScopeMatcher(), false); $listener->onReplay($event); + $this->assertArrayNotHasKey( + strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), + $event->getHeaders()->all() + ); + $this->assertNotNull($request->getSession()); - $this->assertArrayNotHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); } /** - * Tests no header is added if the auth cookie has an invalid value. + * Tests that no header is added if the auth cookie has an invalid value. */ public function testOnReplayWithNoValidCookie() { - $listener = new BackendSessionListener($this->mockScopeMatcher(), false); - - $session = new Session(); $request = new Request(); $request->attributes->set('_scope', 'backend'); $request->cookies->set('BE_USER_AUTH', 'foobar'); - $request->setSession($session); - $headers = new ResponseHeaderBag(); - $event = new HeaderReplayEvent($request, $headers); + $request->setSession(new Session()); + + $event = new HeaderReplayEvent($request, new ResponseHeaderBag()); + $listener = new BackendSessionListener($this->mockScopeMatcher(), false); $listener->onReplay($event); + $this->assertArrayNotHasKey( + strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), + $event->getHeaders()->all() + ); + $this->assertNotNull($request->getSession()); $this->assertTrue($request->cookies->has('BE_USER_AUTH')); - $this->assertArrayNotHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); } /** - * Tests that the header is correctly added when scope and auth cookie are - * correct. + * Tests that the header is correctly added when scope and auth cookie are correct. */ public function testOnReplay() { - $listener = new BackendSessionListener($this->mockScopeMatcher(), false); - $session = new Session(); $session->setId('foobar-id'); + $request = new Request(); $request->attributes->set('_scope', 'backend'); $request->cookies->set('BE_USER_AUTH', 'f6d5c422c903288859fb5ccf03c8af8b0fb4b70a'); $request->setSession($session); - $headers = new ResponseHeaderBag(); - $event = new HeaderReplayEvent($request, $headers); + $event = new HeaderReplayEvent($request, new ResponseHeaderBag()); + + $listener = new BackendSessionListener($this->mockScopeMatcher(), false); $listener->onReplay($event); + $this->assertArrayHasKey( + strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), + $event->getHeaders()->all() + ); + $this->assertNotNull($request->getSession()); $this->assertTrue($request->cookies->has('BE_USER_AUTH')); - $this->assertArrayHasKey(strtolower(HeaderReplayListener::FORCE_NO_CACHE_HEADER_NAME), $event->getHeaders()->all()); } } diff --git a/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php b/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php index d35943387d..e13c5259c7 100644 --- a/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php +++ b/tests/EventListener/HeaderReplay/PageLayoutListenerTest.php @@ -36,25 +36,21 @@ public function testInstantiation() } /** - * Tests that no header is added when not a Contao front end scope. + * Tests that no header is added outside the Contao front end scope. */ public function testOnReplayWithNoFrontendScope() { - $listener = new PageLayoutListener($this->mockScopeMatcher(), $this->mockContaoFramework()); - - $request = new Request(); - - $headers = new ResponseHeaderBag(); - $event = new HeaderReplayEvent($request, $headers); + $event = new HeaderReplayEvent(new Request(), new ResponseHeaderBag()); + $listener = new PageLayoutListener($this->mockScopeMatcher(), $this->mockContaoFramework()); $listener->onReplay($event); $this->assertArrayNotHasKey('contao-page-layout', $event->getHeaders()->all()); } /** - * Tests all combinations of user agent result, TL_VIEW cookie value and checks - * if the header value is set correctly. + * Tests all combinations of user agent result, TL_VIEW cookie value and checks if the + * header value is set correctly. * * @param bool $agentIsMobile * @param string|null $tlViewCookie @@ -77,17 +73,13 @@ public function testOnReplay($agentIsMobile, $tlViewCookie, $expectedHeaderValue switch ($key) { case 'agent': return (object) ['mobile' => $agentIsMobile]; + default: return null; } }) ; - $framework = $this->mockContaoFramework(null, null, [ - Environment::class => $envAdapter - ]); - - $listener = new PageLayoutListener($this->mockScopeMatcher(), $framework); $request = new Request(); $request->attributes->set('_scope', 'frontend'); @@ -95,8 +87,12 @@ public function testOnReplay($agentIsMobile, $tlViewCookie, $expectedHeaderValue $request->cookies->set('TL_VIEW', $tlViewCookie); } - $headers = new ResponseHeaderBag(); - $event = new HeaderReplayEvent($request, $headers); + $event = new HeaderReplayEvent($request, new ResponseHeaderBag()); + + $listener = new PageLayoutListener( + $this->mockScopeMatcher(), + $this->mockContaoFramework(null, null, [Environment::class => $envAdapter]) + ); $listener->onReplay($event); @@ -104,7 +100,7 @@ public function testOnReplay($agentIsMobile, $tlViewCookie, $expectedHeaderValue } /** - * Data provider for the testOnReplayWithNoFrontendScope test. + * Provides the data for the testOnReplayWithNoFrontendScope test. * * @return array */ From 7b19aa8f1c1fa9e8c0ae2cf0d9135464fda461e5 Mon Sep 17 00:00:00 2001 From: Leo Feyer Date: Tue, 13 Jun 2017 14:15:31 +0200 Subject: [PATCH 13/14] Fix the tests. --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 0367f9253a..5560ae895f 100644 --- a/composer.json +++ b/composer.json @@ -80,6 +80,7 @@ "lexik/maintenance-bundle": "^2.0", "monolog/monolog": "^1.22", "phpunit/phpunit": "^5.0", + "php-http/message-factory": "^1.0.2" "satooshi/php-coveralls": "^1.0", "symfony/phpunit-bridge": "^3.2" }, From cc88bd326a488f8f576e9972eecce948a2f4c80d Mon Sep 17 00:00:00 2001 From: Leo Feyer Date: Tue, 13 Jun 2017 14:15:54 +0200 Subject: [PATCH 14/14] Fix the tests. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5560ae895f..540640fa47 100644 --- a/composer.json +++ b/composer.json @@ -80,7 +80,7 @@ "lexik/maintenance-bundle": "^2.0", "monolog/monolog": "^1.22", "phpunit/phpunit": "^5.0", - "php-http/message-factory": "^1.0.2" + "php-http/message-factory": "^1.0.2", "satooshi/php-coveralls": "^1.0", "symfony/phpunit-bridge": "^3.2" },