SessionTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. <?php defined('SYSPATH') OR die('Kohana bootstrap needs to be included before tests run');
  2. /**
  3. * Tests the session class
  4. *
  5. * @group kohana
  6. * @group kohana.core
  7. * @group kohana.core.session
  8. *
  9. * @package Kohana
  10. * @category Tests
  11. * @author Kohana Team
  12. * @author Jeremy Bush <[email protected]>
  13. * @copyright (c) 2008-2012 Kohana Team
  14. * @license http://kohanaframework.org/license
  15. */
  16. class Kohana_SessionTest extends Unittest_TestCase
  17. {
  18. /**
  19. * Gets a mock of the session class
  20. *
  21. * @return Session
  22. */
  23. // @codingStandardsIgnoreStart
  24. public function getMockSession(array $config = array())
  25. // @codingStandardsIgnoreEnd
  26. {
  27. return $this->getMockForAbstractClass('Session', array($config));
  28. }
  29. /**
  30. * Provides test data for
  31. *
  32. * test_constructor_uses_name_from_config_and_casts()
  33. *
  34. * @return array
  35. */
  36. public function provider_constructor_uses_settings_from_config_and_casts()
  37. {
  38. return array(
  39. // array(expected, input)
  40. // data set 0
  41. array(
  42. array(
  43. 'name' => 'awesomeness',
  44. 'lifetime' => 1231456421,
  45. 'encrypted' => FALSE
  46. ),
  47. array(
  48. 'name' => 'awesomeness',
  49. 'lifetime' => '1231456421',
  50. 'encrypted' => FALSE,
  51. ),
  52. ),
  53. // data set 1
  54. array(
  55. array(
  56. 'name' => '123',
  57. 'encrypted' => 'default',
  58. ),
  59. array(
  60. 'name' => 123,
  61. 'encrypted' => TRUE,
  62. ),
  63. ),
  64. );
  65. }
  66. /**
  67. * The constructor should change its attributes based on config
  68. * passed as the first parameter
  69. *
  70. * @test
  71. * @dataProvider provider_constructor_uses_settings_from_config_and_casts
  72. * @covers Session::__construct
  73. */
  74. public function test_constructor_uses_settings_from_config_and_casts($expected, $config)
  75. {
  76. $session = $this->getMockForAbstractClass('Session', array($config));
  77. foreach ($expected as $var => $value)
  78. {
  79. $this->assertAttributeSame($value, '_'.$var, $session);
  80. }
  81. }
  82. /**
  83. * Check that the constructor will load a session if it's provided
  84. * witha session id
  85. *
  86. * @test
  87. * @covers Session::__construct
  88. * @covers Session::read
  89. */
  90. public function test_constructor_loads_session_with_session_id()
  91. {
  92. $this->markTestIncomplete(
  93. 'Need to work out why constructor is not being called'
  94. );
  95. $config = array();
  96. $session_id = 'lolums';
  97. // Don't auto-call constructor, we need to setup the mock first
  98. $session = $this->getMockForAbstractClass(
  99. 'Session',
  100. array(),
  101. '',
  102. FALSE
  103. );
  104. $session
  105. ->expects($this->once())
  106. ->method('read')
  107. ->with($session_id);
  108. $session->__construct($config, $session_id);
  109. }
  110. /**
  111. * Calling $session->bind() should allow you to bind a variable
  112. * to a session variable
  113. *
  114. * @test
  115. * @covers Session::bind
  116. * @ticket 3164
  117. */
  118. public function test_bind_actually_binds_variable()
  119. {
  120. $session = $this->getMockForAbstractClass('Session');
  121. $var = 'asd';
  122. $session->bind('our_var', $var);
  123. $var = 'foobar';
  124. $this->assertSame('foobar', $session->get('our_var'));
  125. }
  126. /**
  127. * When a session is initially created it should have no data
  128. *
  129. *
  130. * @test
  131. * @covers Session::__construct
  132. * @covers Session::set
  133. */
  134. public function test_initially_session_has_no_data()
  135. {
  136. $session = $this->getMockSession();
  137. $this->assertAttributeSame(array(), '_data', $session);
  138. }
  139. /**
  140. * Make sure that the default session name (the one used if the
  141. * driver does not set one) is 'session'
  142. *
  143. * @test
  144. * @covers Session::__construct
  145. */
  146. public function test_default_session_name_is_set()
  147. {
  148. $session = $this->getMockSession();
  149. $this->assertAttributeSame('session', '_name', $session);
  150. }
  151. /**
  152. * By default sessions are unencrypted
  153. *
  154. * @test
  155. * @covers Session::__construct
  156. */
  157. public function test_default_session_is_unencrypted()
  158. {
  159. $session = $this->getMockSession();
  160. $this->assertAttributeSame(FALSE, '_encrypted', $session);
  161. }
  162. /**
  163. * A new session should not be classed as destroyed
  164. *
  165. * @test
  166. * @covers Session::__construct
  167. */
  168. public function test_default_session_is_not_classed_as_destroyed()
  169. {
  170. $session = $this->getMockSession();
  171. $this->assertAttributeSame(FALSE, '_destroyed', $session);
  172. }
  173. /**
  174. * Provides test data for test_get_returns_default_if_var_dnx()
  175. *
  176. * @return array
  177. */
  178. public function provider_get_returns_default_if_var_dnx()
  179. {
  180. return array(
  181. array('something_crazy', FALSE),
  182. array('a_true', TRUE),
  183. array('an_int', 158163158),
  184. );
  185. }
  186. /**
  187. * Make sure that get() is using the default value we provide and
  188. * isn't tampering with it
  189. *
  190. * @test
  191. * @dataProvider provider_get_returns_default_if_var_dnx
  192. * @covers Session::get
  193. */
  194. public function test_get_returns_default_if_var_dnx($var, $default)
  195. {
  196. $session = $this->getMockSession();
  197. $this->assertSame($default, $session->get($var, $default));
  198. }
  199. /**
  200. * By default get() should be using null as the var DNX return value
  201. *
  202. * @test
  203. * @covers Session::get
  204. */
  205. public function test_get_uses_null_as_default_return_value()
  206. {
  207. $session = $this->getMockSession();
  208. $this->assertSame(NULL, $session->get('level_of_cool'));
  209. }
  210. /**
  211. * This test makes sure that session is using array_key_exists
  212. * as isset will return FALSE if the value is NULL
  213. *
  214. * @test
  215. * @covers Session::get
  216. */
  217. public function test_get_returns_value_if_it_equals_null()
  218. {
  219. $session = $this->getMockSession();
  220. $session->set('arkward', NULL);
  221. $this->assertSame(NULL, $session->get('arkward', 'uh oh'));
  222. }
  223. /**
  224. * as_array() should return the session data by reference.
  225. *
  226. * i.e. if we modify the returned data, the session data also changes
  227. *
  228. * @test
  229. * @covers Session::as_array
  230. */
  231. public function test_as_array_returns_data_by_ref_or_copy()
  232. {
  233. $session = $this->getMockSession();
  234. $data_ref =& $session->as_array();
  235. $data_ref['something'] = 'pie';
  236. $this->assertAttributeSame($data_ref, '_data', $session);
  237. $data_copy = $session->as_array();
  238. $data_copy['pie'] = 'awesome';
  239. $this->assertAttributeNotSame($data_copy, '_data', $session);
  240. }
  241. /**
  242. * set() should add new session data and modify existing ones
  243. *
  244. * Also makes sure that set() returns $this
  245. *
  246. * @test
  247. * @covers Session::set
  248. */
  249. public function test_set_adds_and_modifies_to_session_data()
  250. {
  251. $session = $this->getMockSession();
  252. $this->assertSame($session, $session->set('pork', 'pie'));
  253. $this->assertAttributeSame(
  254. array('pork' => 'pie'),
  255. '_data',
  256. $session
  257. );
  258. $session->set('pork', 'delicious');
  259. $this->assertAttributeSame(
  260. array('pork' => 'delicious'),
  261. '_data',
  262. $session
  263. );
  264. }
  265. /**
  266. * This tests that delete() removes specified session data
  267. *
  268. * @test
  269. * @covers Session::delete
  270. */
  271. public function test_delete_removes_select_session_data()
  272. {
  273. $session = $this->getMockSession();
  274. // Bit of a hack for mass-loading session data
  275. $data =& $session->as_array();
  276. $data += array(
  277. 'a' => 'A',
  278. 'b' => 'B',
  279. 'c' => 'C',
  280. 'easy' => '123'
  281. );
  282. // Make a copy of $data for testing purposes
  283. $copy = $data;
  284. // First we make sure we can delete one item
  285. // Also, check that delete returns $this
  286. $this->assertSame($session, $session->delete('a'));
  287. unset($copy['a']);
  288. // We could test against $data but then we'd be testing
  289. // that as_array() is returning by ref
  290. $this->assertAttributeSame($copy, '_data', $session);
  291. // Now we make sure we can delete multiple items
  292. // We're checking $this is returned just in case
  293. $this->assertSame($session, $session->delete('b', 'c'));
  294. unset($copy['b'], $copy['c']);
  295. $this->assertAttributeSame($copy, '_data', $session);
  296. }
  297. /**
  298. * Provides test data for test_read_loads_session_data()
  299. *
  300. * @return array
  301. */
  302. public function provider_read_loads_session_data()
  303. {
  304. return array(
  305. // If driver returns array then just load it up
  306. array(
  307. array(),
  308. 'wacka_wacka',
  309. array()
  310. ),
  311. array(
  312. array('the it' => 'crowd'),
  313. 'the_it_crowd',
  314. array('the it' => 'crowd'),
  315. ),
  316. // If it's a string an encrpytion is disabled (by default) base64decode and unserialize
  317. array(
  318. array('dead' => 'arrival'),
  319. 'lolums',
  320. 'YToxOntzOjQ6ImRlYWQiO3M6NzoiYXJyaXZhbCI7fQ=='
  321. ),
  322. );
  323. }
  324. /**
  325. * This is one of the "big" tests for the session lib
  326. *
  327. * The test makes sure that
  328. *
  329. * 1. Session asks the driver for the data relating to $session_id
  330. * 2. That it will load the returned data into the session
  331. *
  332. * @test
  333. * @dataProvider provider_read_loads_session_data
  334. * @covers Session::read
  335. */
  336. public function test_read_loads_session_data($expected_data, $session_id, $driver_data, array $config = array())
  337. {
  338. $session = $this->getMockSession($config);
  339. $session->expects($this->once())
  340. ->method('_read')
  341. ->with($session_id)
  342. ->will($this->returnValue($driver_data));
  343. $session->read($session_id);
  344. $this->assertAttributeSame($expected_data, '_data', $session);
  345. }
  346. /**
  347. * regenerate() should tell the driver to regenerate its id
  348. *
  349. * @test
  350. * @covers Session::regenerate
  351. */
  352. public function test_regenerate_tells_driver_to_regenerate()
  353. {
  354. $session = $this->getMockSession();
  355. $new_session_id = 'asdnoawdnoainf';
  356. $session->expects($this->once())
  357. ->method('_regenerate')
  358. ->with()
  359. ->will($this->returnValue($new_session_id));
  360. $this->assertSame($new_session_id, $session->regenerate());
  361. }
  362. /**
  363. * If the driver destroys the session then all session data should be
  364. * removed
  365. *
  366. * @test
  367. * @covers Session::destroy
  368. */
  369. public function test_destroy_deletes_data_if_driver_destroys_session()
  370. {
  371. $session = $this->getMockSession();
  372. $session
  373. ->set('asd', 'dsa')
  374. ->set('dog', 'god');
  375. $session
  376. ->expects($this->once())
  377. ->method('_destroy')
  378. ->with()
  379. ->will($this->returnValue(TRUE));
  380. $this->assertTrue($session->destroy());
  381. $this->assertAttributeSame(array(), '_data', $session);
  382. }
  383. /**
  384. * The session data should only be deleted if the driver reports
  385. * that the session was destroyed ok
  386. *
  387. * @test
  388. * @covers Session::destroy
  389. */
  390. public function test_destroy_only_deletes_data_if_driver_destroys_session()
  391. {
  392. $session = $this->getMockSession();
  393. $session
  394. ->set('asd', 'dsa')
  395. ->set('dog', 'god');
  396. $session
  397. ->expects($this->once())
  398. ->method('_destroy')
  399. ->with()
  400. ->will($this->returnValue(FALSE));
  401. $this->assertFalse($session->destroy());
  402. $this->assertAttributeSame(
  403. array('asd' => 'dsa', 'dog' => 'god'),
  404. '_data',
  405. $session
  406. );
  407. }
  408. /**
  409. * If a session variable exists then get_once should get it then remove it.
  410. * If the variable does not exist then it should return the default
  411. *
  412. * @test
  413. * @covers Session::get_once
  414. */
  415. public function test_get_once_gets_once_or_returns_default()
  416. {
  417. $session = $this->getMockSession();
  418. $session->set('foo', 'bar');
  419. // Test that a default is returned
  420. $this->assertSame('mud', $session->get_once('fud', 'mud'));
  421. // Now test that it actually removes the value
  422. $this->assertSame('bar', $session->get_once('foo'));
  423. $this->assertAttributeSame(array(), '_data', $session);
  424. $this->assertSame('maybe', $session->get_once('foo', 'maybe'));
  425. }
  426. }