diff --git a/src/Symfony/Bundle/FrameworkBundle/HttpFoundation/SessionListener.php b/src/Symfony/Bundle/FrameworkBundle/HttpFoundation/SessionListener.php new file mode 100644 index 0000000000..b0086fd06d --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/HttpFoundation/SessionListener.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\HttpFoundation; + +use Symfony\Component\EventDispatcher\EventInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +/** + * SessionListener. + * + * Saves session in test environment. + * + * @author Bulat Shakirzyanov + */ +class SessionListener +{ + /** + * @var Request + */ + private $request; + + /** + * @var Boolean + */ + private $master = false; + + /** + * Assigns request and its type on 'core.request' event + * + * @param EventInterface $event + */ + public function handle(EventInterface $event) + { + $this->request = $event->get('request'); + $this->master = HttpKernelInterface::MASTER_REQUEST === $event->get('request_type'); + } + + /** + * Checks if session was initialized and saves if current request is master + * Runs on 'core.response' in test environment + * + * @param EventInterface $event + * @param Response $response + * + * @return Response + */ + public function filter(EventInterface $event, Response $response) + { + if (isset($this->request) && $this->master && null !== $this->request->getSession()) { + $this->request->getSession()->save(); + } + + return $response; + } + + /** + * Returns true is current request is master request + * + * @return Boolean + */ + public function isMaster() + { + return $this->master; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml index 3f6f3994a2..33a48880b2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml @@ -9,6 +9,7 @@ Symfony\Component\BrowserKit\History Symfony\Component\BrowserKit\CookieJar + Symfony\Bundle\FrameworkBundle\HttpFoundation\SessionListener @@ -22,5 +23,10 @@ + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/HttpFoundation/SessionListenerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/HttpFoundation/SessionListenerTest.php new file mode 100644 index 0000000000..c31b1851d3 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/HttpFoundation/SessionListenerTest.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\HttpFoundation; + +use Symfony\Bundle\FrameworkBundle\HttpFoundation\SessionListener; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +/** + * SessionListenerTest. + * + * Tests SessionListener. + * + * @author Bulat Shakirzyanov + */ +class SessionListenerTest extends \PHPUnit_Framework_TestCase +{ + private $listener; + private $session; + + public function setUp() + { + $this->listener = new SessionListener(); + $this->session = $this->getSession(); + } + + public function testShouldSaveMasterRequestSession() + { + $this->handle(new Request()); + + $this->assertRequestIsMaster(); + + $this->sessionMustBeSaved(); + + $this->filterResponse(); + } + + public function testShouldNotSaveSubRequestSession() + { + $this->handle(new Request(), HttpKernelInterface::SUB_REQUEST); + + $this->assertRequestIsNotMaster(); + + $this->sessionMustNotBeSaved(); + + $this->filterResponse(); + } + + private function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST) + { + $request->setSession($this->session); + + $this->listener->handle(new Event($this, 'core.request', array( + 'request' => $request, + 'request_type' => $type + ))); + } + + private function filterResponse() + { + $response = new Response(); + + $this->assertSame($response, $this->listener->filter(new Event( + $this, 'core.response' + ), $response)); + } + + private function assertRequestIsMaster() + { + $this->assertTrue($this->listener->isMaster()); + } + + private function assertRequestIsNotMaster() + { + $this->assertFalse($this->listener->isMaster()); + } + + private function sessionMustNotBeSaved() + { + $this->session->expects($this->never()) + ->method('save'); + } + + private function sessionMustBeSaved() + { + $this->session->expects($this->once()) + ->method('save'); + } + + private function getSession() + { + return $this->getMockBuilder('Symfony\Component\HttpFoundation\Session') + ->disableOriginalConstructor() + ->getMock(); + } +}