session.test.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. <?php
  2. use Laravel\Session;
  3. use Laravel\Session\Payload;
  4. class DummyPayload {
  5. public function test() { return 'Foo'; }
  6. }
  7. class SessionTest extends PHPUnit_Framework_TestCase {
  8. /**
  9. * Setup the testing environment.
  10. */
  11. public function setUp()
  12. {
  13. Config::set('application.key', 'foo');
  14. Session::$instance = null;
  15. }
  16. /**
  17. * Tear down the testing environment.
  18. */
  19. public function tearDown()
  20. {
  21. Config::set('application.key', '');
  22. Session::$instance = null;
  23. }
  24. /**
  25. * Test the __callStatic method.
  26. *
  27. * @group laravel
  28. */
  29. public function testPayloadCanBeCalledStaticly()
  30. {
  31. Session::$instance = new DummyPayload;
  32. $this->assertEquals('Foo', Session::test());
  33. }
  34. /**
  35. * Test the Session::started method.
  36. *
  37. * @group laravel
  38. */
  39. public function testStartedMethodIndicatesIfSessionIsStarted()
  40. {
  41. $this->assertFalse(Session::started());
  42. Session::$instance = 'foo';
  43. $this->assertTrue(Session::started());
  44. }
  45. /**
  46. * Test the Payload::load method.
  47. *
  48. * @group laravel
  49. */
  50. public function testLoadMethodCreatesNewSessionWithNullIDGiven()
  51. {
  52. $payload = $this->getPayload();
  53. $payload->load(null);
  54. $this->verifyNewSession($payload);
  55. }
  56. /**
  57. * Test the Payload::load method.
  58. *
  59. * @group laravel
  60. */
  61. public function testLoadMethodCreatesNewSessionWhenSessionIsExpired()
  62. {
  63. $payload = $this->getPayload();
  64. $session = $this->getSession();
  65. $session['last_activity'] = time() - 10000;
  66. $payload->driver->expects($this->any())
  67. ->method('load')
  68. ->will($this->returnValue($session));
  69. $payload->load('foo');
  70. $this->verifyNewSession($payload);
  71. $this->assertTrue($payload->session['id'] !== $session['id']);
  72. }
  73. /**
  74. * Assert that a session is new.
  75. *
  76. * @param Payload $payload
  77. * @return void
  78. */
  79. protected function verifyNewSession($payload)
  80. {
  81. $this->assertFalse($payload->exists);
  82. $this->assertTrue(isset($payload->session['id']));
  83. $this->assertEquals(array(), $payload->session['data'][':new:']);
  84. $this->assertEquals(array(), $payload->session['data'][':old:']);
  85. $this->assertTrue(isset($payload->session['data'][Session::csrf_token]));
  86. }
  87. /**
  88. * Test the Payload::load method.
  89. *
  90. * @group laravel
  91. */
  92. public function testLoadMethodSetsValidSession()
  93. {
  94. $payload = $this->getPayload();
  95. $session = $this->getSession();
  96. $payload->driver->expects($this->any())
  97. ->method('load')
  98. ->will($this->returnValue($session));
  99. $payload->load('foo');
  100. $this->assertEquals($session, $payload->session);
  101. }
  102. /**
  103. * Test the Payload::load method.
  104. *
  105. * @group laravel
  106. */
  107. public function testLoadMethodSetsCSRFTokenIfDoesntExist()
  108. {
  109. $payload = $this->getPayload();
  110. $session = $this->getSession();
  111. unset($session['data']['csrf_token']);
  112. $payload->driver->expects($this->any())
  113. ->method('load')
  114. ->will($this->returnValue($session));
  115. $payload->load('foo');
  116. $this->assertEquals('foo', $payload->session['id']);
  117. $this->assertTrue(isset($payload->session['data']['csrf_token']));
  118. }
  119. /**
  120. * Test the various data retrieval methods.
  121. *
  122. * @group laravel
  123. */
  124. public function testSessionDataCanBeRetrievedProperly()
  125. {
  126. $payload = $this->getPayload();
  127. $payload->session = $this->getSession();
  128. $this->assertTrue($payload->has('name'));
  129. $this->assertEquals('Taylor', $payload->get('name'));
  130. $this->assertFalse($payload->has('foo'));
  131. $this->assertEquals('Default', $payload->get('foo', 'Default'));
  132. $this->assertTrue($payload->has('votes'));
  133. $this->assertEquals(10, $payload->get('votes'));
  134. $this->assertTrue($payload->has('state'));
  135. $this->assertEquals('AR', $payload->get('state'));
  136. }
  137. /**
  138. * Test the various data manipulation methods.
  139. *
  140. * @group laravel
  141. */
  142. public function testDataCanBeSetProperly()
  143. {
  144. $payload = $this->getPayload();
  145. $payload->session = $this->getSession();
  146. // Test the "put" and "flash" methods.
  147. $payload->put('name', 'Weldon');
  148. $this->assertEquals('Weldon', $payload->session['data']['name']);
  149. $payload->flash('language', 'php');
  150. $this->assertEquals('php', $payload->session['data'][':new:']['language']);
  151. // Test the "reflash" method.
  152. $payload->session['data'][':new:'] = array('name' => 'Taylor');
  153. $payload->session['data'][':old:'] = array('age' => 25);
  154. $payload->reflash();
  155. $this->assertEquals(array('name' => 'Taylor', 'age' => 25), $payload->session['data'][':new:']);
  156. // Test the "keep" method.
  157. $payload->session['data'][':new:'] = array();
  158. $payload->keep(array('age'));
  159. $this->assertEquals(25, $payload->session['data'][':new:']['age']);
  160. }
  161. /**
  162. * Test the Payload::forget method.
  163. *
  164. * @group laravel
  165. */
  166. public function testSessionDataCanBeForgotten()
  167. {
  168. $payload = $this->getPayload();
  169. $payload->session = $this->getSession();
  170. $this->assertTrue(isset($payload->session['data']['name']));
  171. $payload->forget('name');
  172. $this->assertFalse(isset($payload->session['data']['name']));
  173. }
  174. /**
  175. * Test the Payload::flush method.
  176. *
  177. * @group laravel
  178. */
  179. public function testFlushMaintainsTokenButDeletesEverythingElse()
  180. {
  181. $payload = $this->getPayload();
  182. $payload->session = $this->getSession();
  183. $this->assertTrue(isset($payload->session['data']['name']));
  184. $payload->flush();
  185. $this->assertFalse(isset($payload->session['data']['name']));
  186. $this->assertEquals('bar', $payload->session['data']['csrf_token']);
  187. $this->assertEquals(array(), $payload->session['data'][':new:']);
  188. $this->assertEquals(array(), $payload->session['data'][':old:']);
  189. }
  190. /**
  191. * Test the Payload::regenerate method.
  192. *
  193. * @group laravel
  194. */
  195. public function testRegenerateMethodSetsNewIDAndTurnsOffExistenceIndicator()
  196. {
  197. $payload = $this->getPayload();
  198. $payload->sesion = $this->getSession();
  199. $payload->exists = true;
  200. $payload->regenerate();
  201. $this->assertFalse($payload->exists);
  202. $this->assertTrue(strlen($payload->session['id']) == 40);
  203. }
  204. /**
  205. * Test the Payload::token method.
  206. *
  207. * @group laravel
  208. */
  209. public function testTokenMethodReturnsCSRFToken()
  210. {
  211. $payload = $this->getPayload();
  212. $payload->session = $this->getSession();
  213. $this->assertEquals('bar', $payload->token());
  214. }
  215. /**
  216. * Test the Payload::save method.
  217. *
  218. * @group laravel
  219. */
  220. public function testSaveMethodCorrectlyCallsDriver()
  221. {
  222. $payload = $this->getPayload();
  223. $session = $this->getSession();
  224. $payload->session = $session;
  225. $payload->exists = true;
  226. $config = Laravel\Config::get('session');
  227. $expect = $session;
  228. $expect['data'][':old:'] = $session['data'][':new:'];
  229. $expect['data'][':new:'] = array();
  230. $payload->driver->expects($this->once())
  231. ->method('save')
  232. ->with($this->equalTo($expect), $this->equalTo($config), $this->equalTo(true));
  233. $payload->save();
  234. $this->assertEquals($session['data'][':new:'], $payload->session['data'][':old:']);
  235. }
  236. /**
  237. * Test the Payload::save method.
  238. *
  239. * @group laravel
  240. */
  241. public function testSaveMethodSweepsIfSweeperAndOddsHitWithTimeGreaterThanThreshold()
  242. {
  243. Config::set('session.sweepage', array(100, 100));
  244. $payload = $this->getPayload();
  245. $payload->driver = $this->getMock('Laravel\\Session\\Drivers\\File', array('save', 'sweep'), array(null));
  246. $payload->session = $this->getSession();
  247. $expiration = time() - (Config::get('session.lifetime') * 60);
  248. // Here we set the time to the expected expiration minus 5 seconds, just to
  249. // allow plenty of room for PHP execution. In the next test, we'll do the
  250. // same thing except add 5 seconds to check that the time is between a
  251. // given window.
  252. $payload->driver->expects($this->once())
  253. ->method('sweep')
  254. ->with($this->greaterThan($expiration - 5));
  255. $payload->save();
  256. Config::set('session.sweepage', array(2, 100));
  257. }
  258. /**
  259. * Test the Payload::save method.
  260. *
  261. * @group laravel
  262. */
  263. public function testSaveMethodSweepsIfSweeperAndOddsHitWithTimeLessThanThreshold()
  264. {
  265. Config::set('session.sweepage', array(100, 100));
  266. $payload = $this->getPayload();
  267. $payload->driver = $this->getMock('Laravel\\Session\\Drivers\\File', array('save', 'sweep'), array(null));
  268. $payload->session = $this->getSession();
  269. $expiration = time() - (Config::get('session.lifetime') * 60);
  270. $payload->driver->expects($this->once())
  271. ->method('sweep')
  272. ->with($this->lessThan($expiration + 5));
  273. $payload->save();
  274. Config::set('session.sweepage', array(2, 100));
  275. }
  276. /**
  277. * Test that the session sweeper is never called if not a sweeper.
  278. *
  279. * @group laravel
  280. */
  281. public function testSweeperShouldntBeCalledIfDriverIsntSweeper()
  282. {
  283. Config::set('session.sweepage', array(100, 100));
  284. $payload = $this->getPayload();
  285. $payload->driver = $this->getMock('Laravel\\Session\\Drivers\\APC', array('save', 'sweep'), array(), '', false);
  286. $payload->session = $this->getSession();
  287. $payload->driver->expects($this->never())->method('sweep');
  288. $payload->save();
  289. Config::set('session.sweepage', array(2, 100));
  290. }
  291. /**
  292. * Test the Payload::save method.
  293. *
  294. * @group laravel
  295. */
  296. public function testSaveMethodSetsCookieWithCorrectValues()
  297. {
  298. $payload = $this->getPayload();
  299. $payload->session = $this->getSession();
  300. $payload->save();
  301. $this->assertTrue(isset(Cookie::$jar[Config::get('session.cookie')]));
  302. $cookie = Cookie::$jar[Config::get('session.cookie')];
  303. $this->assertEquals('foo', $cookie['value']);
  304. $this->assertEquals(Config::get('session.lifetime'), $cookie['minutes']);
  305. $this->assertEquals(Config::get('session.domain'), $cookie['domain']);
  306. $this->assertEquals(Config::get('session.path'), $cookie['path']);
  307. $this->assertEquals(Config::get('session.secure'), $cookie['secure']);
  308. }
  309. /**
  310. * Test the Session::activity method.
  311. *
  312. * @group laravel
  313. */
  314. public function testActivityMethodReturnsLastActivity()
  315. {
  316. $payload = $this->getPayload();
  317. $payload->session['last_activity'] = 10;
  318. $this->assertEquals(10, $payload->activity());
  319. }
  320. /**
  321. * Get a session payload instance.
  322. *
  323. * @return Payload
  324. */
  325. protected function getPayload()
  326. {
  327. return new Payload($this->getMockDriver());
  328. }
  329. /**
  330. * Get a mock driver instance.
  331. *
  332. * @return Driver
  333. */
  334. protected function getMockDriver()
  335. {
  336. $mock = $this->getMock('Laravel\\Session\\Drivers\\Driver', array('id', 'load', 'save', 'delete'));
  337. $mock->expects($this->any())->method('id')->will($this->returnValue(Str::random(40)));
  338. return $mock;
  339. }
  340. /**
  341. * Get a dummy session.
  342. *
  343. * @return array
  344. */
  345. protected function getSession()
  346. {
  347. return array(
  348. 'id' => 'foo',
  349. 'last_activity' => time(),
  350. 'data' => array(
  351. 'name' => 'Taylor',
  352. 'age' => 25,
  353. 'csrf_token' => 'bar',
  354. ':new:' => array(
  355. 'votes' => 10,
  356. ),
  357. ':old:' => array(
  358. 'state' => 'AR',
  359. ),
  360. ));
  361. }
  362. }