NativeSessionStorageTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\HttpFoundation\Tests\Session\Storage;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
  13. use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
  14. use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
  15. use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
  16. use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
  17. use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
  18. use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
  19. /**
  20. * Test class for NativeSessionStorage.
  21. *
  22. * @author Drak <drak@zikula.org>
  23. *
  24. * These tests require separate processes.
  25. *
  26. * @runTestsInSeparateProcesses
  27. * @preserveGlobalState disabled
  28. */
  29. class NativeSessionStorageTest extends TestCase
  30. {
  31. private $savePath;
  32. protected function setUp()
  33. {
  34. $this->iniSet('session.save_handler', 'files');
  35. $this->iniSet('session.save_path', $this->savePath = sys_get_temp_dir().'/sf2test');
  36. if (!is_dir($this->savePath)) {
  37. mkdir($this->savePath);
  38. }
  39. }
  40. protected function tearDown()
  41. {
  42. session_write_close();
  43. array_map('unlink', glob($this->savePath.'/*'));
  44. if (is_dir($this->savePath)) {
  45. rmdir($this->savePath);
  46. }
  47. $this->savePath = null;
  48. }
  49. /**
  50. * @return NativeSessionStorage
  51. */
  52. protected function getStorage(array $options = array())
  53. {
  54. $storage = new NativeSessionStorage($options);
  55. $storage->registerBag(new AttributeBag());
  56. return $storage;
  57. }
  58. public function testBag()
  59. {
  60. $storage = $this->getStorage();
  61. $bag = new FlashBag();
  62. $storage->registerBag($bag);
  63. $this->assertSame($bag, $storage->getBag($bag->getName()));
  64. }
  65. /**
  66. * @expectedException \InvalidArgumentException
  67. */
  68. public function testRegisterBagException()
  69. {
  70. $storage = $this->getStorage();
  71. $storage->getBag('non_existing');
  72. }
  73. /**
  74. * @expectedException \LogicException
  75. */
  76. public function testRegisterBagForAStartedSessionThrowsException()
  77. {
  78. $storage = $this->getStorage();
  79. $storage->start();
  80. $storage->registerBag(new AttributeBag());
  81. }
  82. public function testGetId()
  83. {
  84. $storage = $this->getStorage();
  85. $this->assertSame('', $storage->getId(), 'Empty ID before starting session');
  86. $storage->start();
  87. $id = $storage->getId();
  88. $this->assertInternalType('string', $id);
  89. $this->assertNotSame('', $id);
  90. $storage->save();
  91. $this->assertSame($id, $storage->getId(), 'ID stays after saving session');
  92. }
  93. public function testRegenerate()
  94. {
  95. $storage = $this->getStorage();
  96. $storage->start();
  97. $id = $storage->getId();
  98. $storage->getBag('attributes')->set('lucky', 7);
  99. $storage->regenerate();
  100. $this->assertNotEquals($id, $storage->getId());
  101. $this->assertEquals(7, $storage->getBag('attributes')->get('lucky'));
  102. }
  103. public function testRegenerateDestroy()
  104. {
  105. $storage = $this->getStorage();
  106. $storage->start();
  107. $id = $storage->getId();
  108. $storage->getBag('attributes')->set('legs', 11);
  109. $storage->regenerate(true);
  110. $this->assertNotEquals($id, $storage->getId());
  111. $this->assertEquals(11, $storage->getBag('attributes')->get('legs'));
  112. }
  113. public function testSessionGlobalIsUpToDateAfterIdRegeneration()
  114. {
  115. $storage = $this->getStorage();
  116. $storage->start();
  117. $storage->getBag('attributes')->set('lucky', 7);
  118. $storage->regenerate();
  119. $storage->getBag('attributes')->set('lucky', 42);
  120. $this->assertEquals(42, $_SESSION['_sf2_attributes']['lucky']);
  121. }
  122. public function testRegenerationFailureDoesNotFlagStorageAsStarted()
  123. {
  124. $storage = $this->getStorage();
  125. $this->assertFalse($storage->regenerate());
  126. $this->assertFalse($storage->isStarted());
  127. }
  128. public function testDefaultSessionCacheLimiter()
  129. {
  130. $this->iniSet('session.cache_limiter', 'nocache');
  131. $storage = new NativeSessionStorage();
  132. $this->assertEquals('', ini_get('session.cache_limiter'));
  133. }
  134. public function testExplicitSessionCacheLimiter()
  135. {
  136. $this->iniSet('session.cache_limiter', 'nocache');
  137. $storage = new NativeSessionStorage(array('cache_limiter' => 'public'));
  138. $this->assertEquals('public', ini_get('session.cache_limiter'));
  139. }
  140. public function testCookieOptions()
  141. {
  142. $options = array(
  143. 'cookie_lifetime' => 123456,
  144. 'cookie_path' => '/my/cookie/path',
  145. 'cookie_domain' => 'symfony.example.com',
  146. 'cookie_secure' => true,
  147. 'cookie_httponly' => false,
  148. );
  149. $this->getStorage($options);
  150. $temp = session_get_cookie_params();
  151. $gco = array();
  152. foreach ($temp as $key => $value) {
  153. $gco['cookie_'.$key] = $value;
  154. }
  155. $this->assertEquals($options, $gco);
  156. }
  157. public function testSessionOptions()
  158. {
  159. if (\defined('HHVM_VERSION')) {
  160. $this->markTestSkipped('HHVM is not handled in this test case.');
  161. }
  162. $options = array(
  163. 'url_rewriter.tags' => 'a=href',
  164. 'cache_expire' => '200',
  165. );
  166. $this->getStorage($options);
  167. $this->assertSame('a=href', ini_get('url_rewriter.tags'));
  168. $this->assertSame('200', ini_get('session.cache_expire'));
  169. }
  170. /**
  171. * @expectedException \InvalidArgumentException
  172. */
  173. public function testSetSaveHandlerException()
  174. {
  175. $storage = $this->getStorage();
  176. $storage->setSaveHandler(new \stdClass());
  177. }
  178. public function testSetSaveHandler53()
  179. {
  180. if (\PHP_VERSION_ID >= 50400) {
  181. $this->markTestSkipped('Test skipped, for PHP 5.3 only.');
  182. }
  183. $this->iniSet('session.save_handler', 'files');
  184. $storage = $this->getStorage();
  185. $storage->setSaveHandler();
  186. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
  187. $storage->setSaveHandler(null);
  188. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
  189. $storage->setSaveHandler(new NativeSessionHandler());
  190. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
  191. $storage->setSaveHandler(new SessionHandlerProxy(new NullSessionHandler()));
  192. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
  193. $storage->setSaveHandler(new NullSessionHandler());
  194. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
  195. $storage->setSaveHandler(new NativeProxy());
  196. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
  197. }
  198. /**
  199. * @requires PHP 5.4
  200. */
  201. public function testSetSaveHandler54()
  202. {
  203. $this->iniSet('session.save_handler', 'files');
  204. $storage = $this->getStorage();
  205. $storage->setSaveHandler();
  206. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
  207. $storage->setSaveHandler(null);
  208. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
  209. $storage->setSaveHandler(new SessionHandlerProxy(new NativeSessionHandler()));
  210. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
  211. $storage->setSaveHandler(new NativeSessionHandler());
  212. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
  213. $storage->setSaveHandler(new SessionHandlerProxy(new NullSessionHandler()));
  214. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
  215. $storage->setSaveHandler(new NullSessionHandler());
  216. $this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
  217. }
  218. /**
  219. * @expectedException \RuntimeException
  220. */
  221. public function testStartedOutside()
  222. {
  223. $storage = $this->getStorage();
  224. $this->assertFalse($storage->getSaveHandler()->isActive());
  225. $this->assertFalse($storage->isStarted());
  226. session_start();
  227. $this->assertTrue(isset($_SESSION));
  228. if (\PHP_VERSION_ID >= 50400) {
  229. // this only works in PHP >= 5.4 where session_status is available
  230. $this->assertTrue($storage->getSaveHandler()->isActive());
  231. }
  232. // PHP session might have started, but the storage driver has not, so false is correct here
  233. $this->assertFalse($storage->isStarted());
  234. $key = $storage->getMetadataBag()->getStorageKey();
  235. $this->assertArrayNotHasKey($key, $_SESSION);
  236. $storage->start();
  237. }
  238. public function testRestart()
  239. {
  240. $storage = $this->getStorage();
  241. $storage->start();
  242. $id = $storage->getId();
  243. $storage->getBag('attributes')->set('lucky', 7);
  244. $storage->save();
  245. $storage->start();
  246. $this->assertSame($id, $storage->getId(), 'Same session ID after restarting');
  247. $this->assertSame(7, $storage->getBag('attributes')->get('lucky'), 'Data still available');
  248. }
  249. /**
  250. * @requires PHP 5.4
  251. */
  252. public function testCanCreateNativeSessionStorageWhenSessionAlreadyStarted()
  253. {
  254. session_start();
  255. $this->getStorage();
  256. // Assert no exception has been thrown by `getStorage()`
  257. $this->addToAssertionCount(1);
  258. }
  259. /**
  260. * @requires PHP 5.4
  261. */
  262. public function testSetSessionOptionsOnceSessionStartedIsIgnored()
  263. {
  264. session_start();
  265. $this->getStorage(array(
  266. 'name' => 'something-else',
  267. ));
  268. // Assert no exception has been thrown by `getStorage()`
  269. $this->addToAssertionCount(1);
  270. }
  271. /**
  272. * @requires PHP 5.4
  273. */
  274. public function testGetBagsOnceSessionStartedIsIgnored()
  275. {
  276. session_start();
  277. $bag = new AttributeBag();
  278. $bag->setName('flashes');
  279. $storage = $this->getStorage();
  280. $storage->registerBag($bag);
  281. $this->assertEquals($storage->getBag('flashes'), $bag);
  282. }
  283. }