Pull merge.
[yaffs-website] / vendor / symfony / http-kernel / Tests / EventListener / TestSessionListenerTest.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.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 Symfony\Component\HttpKernel\Tests\EventListener;
13
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
16 use Symfony\Component\HttpFoundation\Request;
17 use Symfony\Component\HttpFoundation\Response;
18 use Symfony\Component\HttpFoundation\Session\SessionInterface;
19 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
20 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
21 use Symfony\Component\HttpKernel\EventListener\SessionListener;
22 use Symfony\Component\HttpKernel\EventListener\TestSessionListener;
23 use Symfony\Component\HttpKernel\HttpKernelInterface;
24
25 /**
26  * SessionListenerTest.
27  *
28  * Tests SessionListener.
29  *
30  * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
31  */
32 class TestSessionListenerTest extends TestCase
33 {
34     /**
35      * @var TestSessionListener
36      */
37     private $listener;
38
39     /**
40      * @var SessionInterface
41      */
42     private $session;
43
44     protected function setUp()
45     {
46         $this->listener = $this->getMockForAbstractClass('Symfony\Component\HttpKernel\EventListener\AbstractTestSessionListener');
47         $this->session = $this->getSession();
48         $this->listener->expects($this->any())
49              ->method('getSession')
50              ->will($this->returnValue($this->session));
51     }
52
53     public function testShouldSaveMasterRequestSession()
54     {
55         $this->sessionHasBeenStarted();
56         $this->sessionMustBeSaved();
57
58         $this->filterResponse(new Request());
59     }
60
61     public function testShouldNotSaveSubRequestSession()
62     {
63         $this->sessionMustNotBeSaved();
64
65         $this->filterResponse(new Request(), HttpKernelInterface::SUB_REQUEST);
66     }
67
68     public function testDoesNotDeleteCookieIfUsingSessionLifetime()
69     {
70         $this->sessionHasBeenStarted();
71
72         @ini_set('session.cookie_lifetime', 0);
73
74         $response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST);
75         $cookies = $response->headers->getCookies();
76
77         $this->assertEquals(0, reset($cookies)->getExpiresTime());
78     }
79
80     /**
81      * @requires function \Symfony\Component\HttpFoundation\Session\Session::isEmpty
82      */
83     public function testEmptySessionDoesNotSendCookie()
84     {
85         $this->sessionHasBeenStarted();
86         $this->sessionIsEmpty();
87
88         $response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST);
89
90         $this->assertSame(array(), $response->headers->getCookies());
91     }
92
93     public function testEmptySessionWithNewSessionIdDoesSendCookie()
94     {
95         $this->sessionHasBeenStarted();
96         $this->sessionIsEmpty();
97         $this->fixSessionId('456');
98
99         $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
100         $request = Request::create('/', 'GET', array(), array('MOCKSESSID' => '123'));
101         $event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
102         $this->listener->onKernelRequest($event);
103
104         $response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST);
105
106         $this->assertNotEmpty($response->headers->getCookies());
107     }
108
109     /**
110      * @dataProvider anotherCookieProvider
111      */
112     public function testSessionWithNewSessionIdAndNewCookieDoesNotSendAnotherCookie($existing, array $expected)
113     {
114         $this->sessionHasBeenStarted();
115         $this->sessionIsEmpty();
116         $this->fixSessionId('456');
117
118         $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
119         $request = Request::create('/', 'GET', array(), array('MOCKSESSID' => '123'));
120         $event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
121         $this->listener->onKernelRequest($event);
122
123         $response = new Response('', 200, array('Set-Cookie' => $existing));
124
125         $response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST, $response);
126
127         $this->assertSame($expected, $response->headers->get('Set-Cookie', null, false));
128     }
129
130     public function anotherCookieProvider()
131     {
132         return array(
133             'same' => array('MOCKSESSID=789; path=/', array('MOCKSESSID=789; path=/')),
134             'different domain' => array('MOCKSESSID=789; path=/; domain=example.com', array('MOCKSESSID=789; path=/; domain=example.com', 'MOCKSESSID=456; path=/')),
135             'different path' => array('MOCKSESSID=789; path=/foo', array('MOCKSESSID=789; path=/foo', 'MOCKSESSID=456; path=/')),
136         );
137     }
138
139     public function testUnstartedSessionIsNotSave()
140     {
141         $this->sessionHasNotBeenStarted();
142         $this->sessionMustNotBeSaved();
143
144         $this->filterResponse(new Request());
145     }
146
147     public function testDoesNotImplementServiceSubscriberInterface()
148     {
149         $this->assertTrue(interface_exists(ServiceSubscriberInterface::class));
150         $this->assertTrue(class_exists(SessionListener::class));
151         $this->assertTrue(class_exists(TestSessionListener::class));
152         $this->assertFalse(is_subclass_of(SessionListener::class, ServiceSubscriberInterface::class), 'Implementing ServiceSubscriberInterface would create a dep on the DI component, which eg Silex cannot afford');
153         $this->assertFalse(is_subclass_of(TestSessionListener::class, ServiceSubscriberInterface::class, 'Implementing ServiceSubscriberInterface would create a dep on the DI component, which eg Silex cannot afford'));
154     }
155
156     private function filterResponse(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, Response $response = null)
157     {
158         $request->setSession($this->session);
159         $response = $response ?: new Response();
160         $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
161         $event = new FilterResponseEvent($kernel, $request, $type, $response);
162
163         $this->listener->onKernelResponse($event);
164
165         $this->assertSame($response, $event->getResponse());
166
167         return $response;
168     }
169
170     private function sessionMustNotBeSaved()
171     {
172         $this->session->expects($this->never())
173             ->method('save');
174     }
175
176     private function sessionMustBeSaved()
177     {
178         $this->session->expects($this->once())
179             ->method('save');
180     }
181
182     private function sessionHasBeenStarted()
183     {
184         $this->session->expects($this->once())
185             ->method('isStarted')
186             ->will($this->returnValue(true));
187     }
188
189     private function sessionHasNotBeenStarted()
190     {
191         $this->session->expects($this->once())
192             ->method('isStarted')
193             ->will($this->returnValue(false));
194     }
195
196     private function sessionIsEmpty()
197     {
198         $this->session->expects($this->once())
199             ->method('isEmpty')
200             ->will($this->returnValue(true));
201     }
202
203     private function fixSessionId($sessionId)
204     {
205         $this->session->expects($this->any())
206             ->method('getId')
207             ->will($this->returnValue($sessionId));
208     }
209
210     private function getSession()
211     {
212         $mock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session')
213             ->disableOriginalConstructor()
214             ->getMock();
215
216         // set return value for getName()
217         $mock->expects($this->any())->method('getName')->will($this->returnValue('MOCKSESSID'));
218
219         return $mock;
220     }
221 }