PageRenderTime 46ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/TestCase/Network/SessionTest.php

http://github.com/cakephp/cakephp
PHP | 540 lines | 300 code | 69 blank | 171 comment | 0 complexity | d3e322d3e35ec500deedaafd5a50cf08 MD5 | raw file
Possible License(s): JSON
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 1.2.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Network;
  16. use Cake\Core\Configure;
  17. use Cake\Network\Session;
  18. use Cake\Network\Session\CacheSession;
  19. use Cake\Network\Session\DatabaseSession;
  20. use Cake\TestSuite\TestCase;
  21. /**
  22. * TestCacheSession
  23. */
  24. class TestCacheSession extends CacheSession
  25. {
  26. protected function _writeSession()
  27. {
  28. return true;
  29. }
  30. }
  31. /**
  32. * TestDatabaseSession
  33. */
  34. class TestDatabaseSession extends DatabaseSession
  35. {
  36. protected function _writeSession()
  37. {
  38. return true;
  39. }
  40. }
  41. /**
  42. * SessionTest class
  43. */
  44. class SessionTest extends TestCase
  45. {
  46. protected static $_gcDivisor;
  47. /**
  48. * Fixtures used in the SessionTest
  49. *
  50. * @var array
  51. */
  52. public $fixtures = ['core.cake_sessions', 'core.sessions'];
  53. /**
  54. * setup before class.
  55. *
  56. * @return void
  57. */
  58. public static function setupBeforeClass()
  59. {
  60. // Make sure garbage collector will be called
  61. static::$_gcDivisor = ini_get('session.gc_divisor');
  62. ini_set('session.gc_divisor', '1');
  63. }
  64. /**
  65. * teardown after class
  66. *
  67. * @return void
  68. */
  69. public static function teardownAfterClass()
  70. {
  71. // Revert to the default setting
  72. ini_set('session.gc_divisor', static::$_gcDivisor);
  73. }
  74. /**
  75. * setUp method
  76. *
  77. * @return void
  78. */
  79. public function setUp()
  80. {
  81. parent::setUp();
  82. }
  83. /**
  84. * tearDown method
  85. *
  86. * @return void
  87. */
  88. public function tearDown()
  89. {
  90. unset($_SESSION);
  91. parent::tearDown();
  92. }
  93. /**
  94. * test setting ini properties with Session configuration.
  95. *
  96. * @return void
  97. */
  98. public function testSessionConfigIniSetting()
  99. {
  100. $_SESSION = null;
  101. $config = [
  102. 'cookie' => 'test',
  103. 'checkAgent' => false,
  104. 'timeout' => 86400,
  105. 'ini' => [
  106. 'session.referer_check' => 'example.com',
  107. 'session.use_trans_sid' => false
  108. ]
  109. ];
  110. $session = Session::create($config);
  111. $this->assertEquals('', ini_get('session.use_trans_sid'), 'Ini value is incorrect');
  112. $this->assertEquals('example.com', ini_get('session.referer_check'), 'Ini value is incorrect');
  113. $this->assertEquals('test', ini_get('session.name'), 'Ini value is incorrect');
  114. }
  115. /**
  116. * test session cookie path setting
  117. *
  118. * @return void
  119. */
  120. public function testCookiePath()
  121. {
  122. ini_set('session.cookie_path', '/foo');
  123. $session = new Session();
  124. $this->assertEquals('/', ini_get('session.cookie_path'));
  125. $session = new Session(['cookiePath' => '/base']);
  126. $this->assertEquals('/base', ini_get('session.cookie_path'));
  127. }
  128. /**
  129. * testCheck method
  130. *
  131. * @return void
  132. */
  133. public function testCheck()
  134. {
  135. $session = new Session();
  136. $session->write('SessionTestCase', 'value');
  137. $this->assertTrue($session->check('SessionTestCase'));
  138. $this->assertFalse($session->check('NotExistingSessionTestCase'));
  139. $this->assertFalse($session->check('Crazy.foo'));
  140. $session->write('Crazy.foo', ['bar' => 'baz']);
  141. $this->assertTrue($session->check('Crazy.foo'));
  142. $this->assertTrue($session->check('Crazy.foo.bar'));
  143. }
  144. /**
  145. * testSimpleRead method
  146. *
  147. * @return void
  148. */
  149. public function testSimpleRead()
  150. {
  151. $session = new Session();
  152. $session->write('testing', '1,2,3');
  153. $result = $session->read('testing');
  154. $this->assertEquals('1,2,3', $result);
  155. $session->write('testing', ['1' => 'one', '2' => 'two', '3' => 'three']);
  156. $result = $session->read('testing.1');
  157. $this->assertEquals('one', $result);
  158. $result = $session->read('testing');
  159. $this->assertEquals(['1' => 'one', '2' => 'two', '3' => 'three'], $result);
  160. $result = $session->read();
  161. $this->assertTrue(isset($result['testing']));
  162. $session->write('This.is.a.deep.array.my.friend', 'value');
  163. $result = $session->read('This.is.a.deep.array');
  164. $this->assertEquals(['my' => ['friend' => 'value']], $result);
  165. }
  166. /**
  167. * testReadEmpty
  168. *
  169. * @return void
  170. */
  171. public function testReadEmpty()
  172. {
  173. $session = new Session();
  174. $this->assertNull($session->read(''));
  175. }
  176. /**
  177. * test writing a hash of values/
  178. *
  179. * @return void
  180. */
  181. public function testWriteArray()
  182. {
  183. $session = new Session();
  184. $session->write([
  185. 'one' => 1,
  186. 'two' => 2,
  187. 'three' => ['something'],
  188. 'null' => null
  189. ]);
  190. $this->assertEquals(1, $session->read('one'));
  191. $this->assertEquals(['something'], $session->read('three'));
  192. $this->assertEquals(null, $session->read('null'));
  193. }
  194. /**
  195. * Test overwriting a string value as if it were an array.
  196. *
  197. * @return void
  198. */
  199. public function testWriteOverwriteStringValue()
  200. {
  201. $session = new Session();
  202. $session->write('Some.string', 'value');
  203. $this->assertEquals('value', $session->read('Some.string'));
  204. $session->write('Some.string.array', ['values']);
  205. $this->assertEquals(['values'], $session->read('Some.string.array'));
  206. }
  207. /**
  208. * Test consuming session data.
  209. *
  210. * @return void
  211. */
  212. public function testConsume()
  213. {
  214. $session = new Session();
  215. $session->write('Some.string', 'value');
  216. $session->write('Some.array', ['key1' => 'value1', 'key2' => 'value2']);
  217. $this->assertEquals('value', $session->read('Some.string'));
  218. $value = $session->consume('Some.string');
  219. $this->assertEquals('value', $value);
  220. $this->assertFalse($session->check('Some.string'));
  221. $value = $session->consume('');
  222. $this->assertNull($value);
  223. $value = $session->consume(null);
  224. $this->assertNull($value);
  225. $value = $session->consume('Some.array');
  226. $expected = ['key1' => 'value1', 'key2' => 'value2'];
  227. $this->assertEquals($expected, $value);
  228. $this->assertFalse($session->check('Some.array'));
  229. }
  230. /**
  231. * testId method
  232. *
  233. * @return void
  234. */
  235. public function testId()
  236. {
  237. $session = new Session();
  238. $result = $session->id();
  239. $expected = session_id();
  240. $this->assertEquals($expected, $result);
  241. $session->id('MySessionId');
  242. $this->assertEquals('MySessionId', $session->id());
  243. $this->assertEquals('MySessionId', session_id());
  244. $session->id('');
  245. $this->assertEquals('', session_id());
  246. }
  247. /**
  248. * testStarted method
  249. *
  250. * @return void
  251. */
  252. public function testStarted()
  253. {
  254. $session = new Session();
  255. $this->assertFalse($session->started());
  256. $this->assertTrue($session->start());
  257. $this->assertTrue($session->started());
  258. }
  259. /**
  260. * testClear method
  261. *
  262. * @return void
  263. */
  264. public function testClear()
  265. {
  266. $session = new Session();
  267. $session->write('Delete.me', 'Clearing out');
  268. $session->clear();
  269. $this->assertFalse($session->check('Delete.me'));
  270. $this->assertFalse($session->check('Delete'));
  271. }
  272. /**
  273. * testDelete method
  274. *
  275. * @return void
  276. */
  277. public function testDelete()
  278. {
  279. $session = new Session();
  280. $session->write('Delete.me', 'Clearing out');
  281. $session->delete('Delete.me');
  282. $this->assertFalse($session->check('Delete.me'));
  283. $this->assertTrue($session->check('Delete'));
  284. $session->write('Clearing.sale', 'everything must go');
  285. $session->delete('');
  286. $this->assertTrue($session->check('Clearing.sale'));
  287. $session->delete(null);
  288. $this->assertTrue($session->check('Clearing.sale'));
  289. $session->delete('Clearing');
  290. $this->assertFalse($session->check('Clearing.sale'));
  291. $this->assertFalse($session->check('Clearing'));
  292. }
  293. /**
  294. * testDestroy method
  295. *
  296. * @return void
  297. */
  298. public function testDestroy()
  299. {
  300. $session = new Session();
  301. $session->start();
  302. $session->write('bulletProof', 'invincible');
  303. $session->id('foo');
  304. $session->destroy();
  305. $this->assertFalse($session->check('bulletProof'));
  306. }
  307. /**
  308. * testCheckingSavedEmpty method
  309. *
  310. * @return void
  311. */
  312. public function testCheckingSavedEmpty()
  313. {
  314. $session = new Session();
  315. $session->write('SessionTestCase', 0);
  316. $this->assertTrue($session->check('SessionTestCase'));
  317. $session->write('SessionTestCase', '0');
  318. $this->assertTrue($session->check('SessionTestCase'));
  319. $session->write('SessionTestCase', false);
  320. $this->assertTrue($session->check('SessionTestCase'));
  321. $session->write('SessionTestCase', null);
  322. $this->assertFalse($session->check('SessionTestCase'));
  323. }
  324. /**
  325. * testCheckKeyWithSpaces method
  326. *
  327. * @return void
  328. */
  329. public function testCheckKeyWithSpaces()
  330. {
  331. $session = new Session();
  332. $session->write('Session Test', "test");
  333. $this->assertTrue($session->check('Session Test'));
  334. $session->delete('Session Test');
  335. $session->write('Session Test.Test Case', "test");
  336. $this->assertTrue($session->check('Session Test.Test Case'));
  337. }
  338. /**
  339. * testCheckEmpty
  340. *
  341. * @return void
  342. */
  343. public function testCheckEmpty()
  344. {
  345. $session = new Session();
  346. $this->assertFalse($session->check());
  347. }
  348. /**
  349. * test key exploitation
  350. *
  351. * @return void
  352. */
  353. public function testKeyExploit()
  354. {
  355. $session = new Session();
  356. $key = "a'] = 1; phpinfo(); \$_SESSION['a";
  357. $session->write($key, 'haxored');
  358. $result = $session->read($key);
  359. $this->assertNull($result);
  360. }
  361. /**
  362. * testReadingSavedEmpty method
  363. *
  364. * @return void
  365. */
  366. public function testReadingSavedEmpty()
  367. {
  368. $session = new Session();
  369. $session->write('SessionTestCase', 0);
  370. $this->assertEquals(0, $session->read('SessionTestCase'));
  371. $session->write('SessionTestCase', '0');
  372. $this->assertEquals('0', $session->read('SessionTestCase'));
  373. $this->assertFalse($session->read('SessionTestCase') === 0);
  374. $session->write('SessionTestCase', false);
  375. $this->assertFalse($session->read('SessionTestCase'));
  376. $session->write('SessionTestCase', null);
  377. $this->assertEquals(null, $session->read('SessionTestCase'));
  378. }
  379. /**
  380. * test using a handler from app/Model/Datasource/Session.
  381. *
  382. * @return void
  383. */
  384. public function testUsingAppLibsHandler()
  385. {
  386. Configure::write('App.namespace', 'TestApp');
  387. $config = [
  388. 'defaults' => 'cake',
  389. 'handler' => [
  390. 'engine' => 'TestAppLibSession',
  391. 'these' => 'are',
  392. 'a few' => 'options'
  393. ]
  394. ];
  395. $session = Session::create($config);
  396. $this->assertInstanceOf('TestApp\Network\Session\TestAppLibSession', $session->engine());
  397. $this->assertEquals('user', ini_get('session.save_handler'));
  398. $this->assertEquals(['these' => 'are', 'a few' => 'options'], $session->engine()->options);
  399. }
  400. /**
  401. * test using a handler from a plugin.
  402. *
  403. * @return void
  404. */
  405. public function testUsingPluginHandler()
  406. {
  407. Configure::write('App.namespace', 'TestApp');
  408. \Cake\Core\Plugin::load('TestPlugin');
  409. $config = [
  410. 'defaults' => 'cake',
  411. 'handler' => [
  412. 'engine' => 'TestPlugin.TestPluginSession'
  413. ]
  414. ];
  415. $session = Session::create($config);
  416. $this->assertInstanceOf('TestPlugin\Network\Session\TestPluginSession', $session->engine());
  417. $this->assertEquals('user', ini_get('session.save_handler'));
  418. }
  419. /**
  420. * Tests that it is possible to pass an already made instance as the session engine
  421. *
  422. * @return void
  423. */
  424. public function testEngineWithPreMadeInstance()
  425. {
  426. Configure::write('App.namespace', 'TestApp');
  427. $engine = new \TestApp\Network\Session\TestAppLibSession;
  428. $session = new Session(['handler' => ['engine' => $engine]]);
  429. $this->assertSame($engine, $session->engine());
  430. $session = new Session();
  431. $session->engine($engine);
  432. $this->assertSame($engine, $session->engine());
  433. }
  434. /**
  435. * Tests instantiating a missing engine
  436. *
  437. * @expectedException \InvalidArgumentException
  438. * @expectedExceptionMessage The class "Derp" does not exist and cannot be used as a session engine
  439. * @return void
  440. */
  441. public function testBadEngine()
  442. {
  443. $session = new Session();
  444. $session->engine('Derp');
  445. }
  446. /**
  447. * Test that cookieTimeout matches timeout when unspecified.
  448. *
  449. * @return void
  450. */
  451. public function testCookieTimeoutFallback()
  452. {
  453. $config = [
  454. 'defaults' => 'cake',
  455. 'timeout' => 400,
  456. ];
  457. new Session($config);
  458. $this->assertEquals(0, ini_get('session.cookie_lifetime'));
  459. $this->assertEquals(400 * 60, ini_get('session.gc_maxlifetime'));
  460. }
  461. /**
  462. * Tests that the cookie name can be changed with configuration
  463. *
  464. * @return void
  465. */
  466. public function testSessionName()
  467. {
  468. new Session(['cookie' => 'made_up_name']);
  469. $this->assertEquals('made_up_name', session_name());
  470. }
  471. }