SessionManagerTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. // @codingStandardsIgnoreStart
  7. namespace {
  8. $mockPHPFunctions = false;
  9. }
  10. namespace Magento\Framework\Session {
  11. use Magento\Framework\App\DeploymentConfig;
  12. use Magento\Framework\App\State;
  13. // @codingStandardsIgnoreEnd
  14. /**
  15. * Mock session_status if in test mode, or continue normal execution otherwise
  16. *
  17. * @return int Session status code
  18. */
  19. function session_status()
  20. {
  21. global $mockPHPFunctions;
  22. if ($mockPHPFunctions) {
  23. return PHP_SESSION_NONE;
  24. }
  25. return call_user_func_array('\session_status', func_get_args());
  26. }
  27. function headers_sent()
  28. {
  29. global $mockPHPFunctions;
  30. if ($mockPHPFunctions) {
  31. return false;
  32. }
  33. return call_user_func_array('\headers_sent', func_get_args());
  34. }
  35. /**
  36. * Mock ini_set global function
  37. *
  38. * @param string $varName
  39. * @param string $newValue
  40. * @return bool|string
  41. */
  42. function ini_set($varName, $newValue)
  43. {
  44. global $mockPHPFunctions;
  45. if ($mockPHPFunctions) {
  46. SessionManagerTest::$isIniSetInvoked[$varName] = $newValue;
  47. return true;
  48. }
  49. return call_user_func_array('\ini_set', func_get_args());
  50. }
  51. /**
  52. * Mock session_set_save_handler global function
  53. *
  54. * @return bool
  55. */
  56. function session_set_save_handler()
  57. {
  58. global $mockPHPFunctions;
  59. if ($mockPHPFunctions) {
  60. SessionManagerTest::$isSessionSetSaveHandlerInvoked = true;
  61. return true;
  62. }
  63. return call_user_func_array('\session_set_save_handler', func_get_args());
  64. }
  65. /**
  66. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  67. */
  68. class SessionManagerTest extends \PHPUnit\Framework\TestCase
  69. {
  70. /**
  71. * @var string[]
  72. */
  73. public static $isIniSetInvoked = [];
  74. /**
  75. * @var bool
  76. */
  77. public static $isSessionSetSaveHandlerInvoked;
  78. /**
  79. * @var \Magento\Framework\Session\SessionManagerInterface
  80. */
  81. private $model;
  82. /**
  83. * @var \Magento\Framework\Session\SidResolverInterface
  84. */
  85. private $sidResolver;
  86. /**
  87. * @var string
  88. */
  89. private $sessionName;
  90. /**
  91. * @var \Magento\TestFramework\ObjectManager
  92. */
  93. private $objectManager;
  94. /**
  95. * @var \Magento\Framework\App\RequestInterface
  96. */
  97. private $request;
  98. /**
  99. * @var State|\PHPUnit_Framework_MockObject_MockObject
  100. */
  101. private $appState;
  102. protected function setUp()
  103. {
  104. $this->sessionName = 'frontEndSession';
  105. ini_set('session.use_only_cookies', '0');
  106. ini_set('session.name', $this->sessionName);
  107. $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
  108. /** @var \Magento\Framework\Session\SidResolverInterface $sidResolver */
  109. $this->appState = $this->getMockBuilder(State::class)
  110. ->setMethods(['getAreaCode'])
  111. ->disableOriginalConstructor()
  112. ->getMock();
  113. /** @var \Magento\Framework\Session\SidResolver $sidResolver */
  114. $this->sidResolver = $this->objectManager->create(
  115. \Magento\Framework\Session\SidResolver::class,
  116. [
  117. 'appState' => $this->appState,
  118. ]
  119. );
  120. $this->request = $this->objectManager->get(\Magento\Framework\App\RequestInterface::class);
  121. }
  122. protected function tearDown()
  123. {
  124. global $mockPHPFunctions;
  125. $mockPHPFunctions = false;
  126. self::$isIniSetInvoked = [];
  127. self::$isSessionSetSaveHandlerInvoked = false;
  128. if ($this->model !== null) {
  129. $this->model->destroy();
  130. $this->model = null;
  131. }
  132. }
  133. public function testSessionNameFromIni()
  134. {
  135. $this->initializeModel();
  136. $this->model->start();
  137. $this->assertSame($this->sessionName, $this->model->getName());
  138. $this->model->destroy();
  139. }
  140. public function testSessionUseOnlyCookies()
  141. {
  142. $this->initializeModel();
  143. $expectedValue = '1';
  144. $sessionUseOnlyCookies = ini_get('session.use_only_cookies');
  145. $this->assertSame($expectedValue, $sessionUseOnlyCookies);
  146. }
  147. public function testGetData()
  148. {
  149. $this->initializeModel();
  150. $this->model->setData(['test_key' => 'test_value']);
  151. $this->assertEquals('test_value', $this->model->getData('test_key', true));
  152. $this->assertNull($this->model->getData('test_key'));
  153. }
  154. public function testGetSessionId()
  155. {
  156. $this->initializeModel();
  157. $this->assertEquals(session_id(), $this->model->getSessionId());
  158. }
  159. public function testGetName()
  160. {
  161. $this->initializeModel();
  162. $this->assertEquals(session_name(), $this->model->getName());
  163. }
  164. public function testSetName()
  165. {
  166. $this->initializeModel();
  167. $this->model->destroy();
  168. $this->model->setName('test');
  169. $this->model->start();
  170. $this->assertEquals('test', $this->model->getName());
  171. }
  172. public function testDestroy()
  173. {
  174. $this->initializeModel();
  175. $data = ['key' => 'value'];
  176. $this->model->setData($data);
  177. $this->assertEquals($data, $this->model->getData());
  178. $this->model->destroy();
  179. $this->assertEquals([], $this->model->getData());
  180. }
  181. public function testSetSessionId()
  182. {
  183. $this->initializeModel();
  184. $sessionId = $this->model->getSessionId();
  185. $this->appState->expects($this->atLeastOnce())
  186. ->method('getAreaCode')
  187. ->willReturn(\Magento\Framework\App\Area::AREA_FRONTEND);
  188. $this->model->setSessionId($this->sidResolver->getSid($this->model));
  189. $this->assertEquals($sessionId, $this->model->getSessionId());
  190. $this->model->setSessionId('test');
  191. $this->assertEquals('test', $this->model->getSessionId());
  192. }
  193. /**
  194. * @magentoConfigFixture current_store web/session/use_frontend_sid 1
  195. */
  196. public function testSetSessionIdFromParam()
  197. {
  198. $this->initializeModel();
  199. $this->appState->expects($this->atLeastOnce())
  200. ->method('getAreaCode')
  201. ->willReturn(\Magento\Framework\App\Area::AREA_FRONTEND);
  202. $this->assertNotEquals('test_id', $this->model->getSessionId());
  203. $this->request->getQuery()->set($this->sidResolver->getSessionIdQueryParam($this->model), 'test-id');
  204. $this->model->setSessionId($this->sidResolver->getSid($this->model));
  205. $this->assertEquals('test-id', $this->model->getSessionId());
  206. /* Use not valid identifier */
  207. $this->request->getQuery()->set($this->sidResolver->getSessionIdQueryParam($this->model), 'test_id');
  208. $this->model->setSessionId($this->sidResolver->getSid($this->model));
  209. $this->assertEquals('test-id', $this->model->getSessionId());
  210. }
  211. public function testGetSessionIdForHost()
  212. {
  213. $this->initializeModel();
  214. $_SERVER['HTTP_HOST'] = 'localhost';
  215. $this->model->start();
  216. $this->assertEmpty($this->model->getSessionIdForHost('localhost'));
  217. $this->assertNotEmpty($this->model->getSessionIdForHost('test'));
  218. $this->model->destroy();
  219. }
  220. public function testIsValidForHost()
  221. {
  222. $this->initializeModel();
  223. $_SERVER['HTTP_HOST'] = 'localhost';
  224. $this->model->start();
  225. $reflection = new \ReflectionMethod($this->model, '_addHost');
  226. $reflection->setAccessible(true);
  227. $reflection->invoke($this->model);
  228. $this->assertFalse($this->model->isValidForHost('test.com'));
  229. $this->assertTrue($this->model->isValidForHost('localhost'));
  230. $this->model->destroy();
  231. }
  232. /**
  233. * @expectedException \Magento\Framework\Exception\SessionException
  234. * @expectedExceptionMessage Area code not set: Area code must be set before starting a session.
  235. */
  236. public function testStartAreaNotSet()
  237. {
  238. $scope = $this->objectManager->get(\Magento\Framework\Config\ScopeInterface::class);
  239. $appState = new \Magento\Framework\App\State($scope);
  240. /**
  241. * Must be created by "new" in order to get a real Magento\Framework\App\State object that
  242. * is not overridden in the TestFramework
  243. *
  244. * @var \Magento\Framework\Session\SessionManager _model
  245. */
  246. $this->model = new \Magento\Framework\Session\SessionManager(
  247. $this->objectManager->get(\Magento\Framework\App\Request\Http::class),
  248. $this->sidResolver,
  249. $this->objectManager->get(\Magento\Framework\Session\Config\ConfigInterface::class),
  250. $this->objectManager->get(\Magento\Framework\Session\SaveHandlerInterface::class),
  251. $this->objectManager->get(\Magento\Framework\Session\ValidatorInterface::class),
  252. $this->objectManager->get(\Magento\Framework\Session\StorageInterface::class),
  253. $this->objectManager->get(\Magento\Framework\Stdlib\CookieManagerInterface::class),
  254. $this->objectManager->get(\Magento\Framework\Stdlib\Cookie\CookieMetadataFactory::class),
  255. $appState
  256. );
  257. global $mockPHPFunctions;
  258. $mockPHPFunctions = true;
  259. $this->model->start();
  260. }
  261. public function testConstructor()
  262. {
  263. global $mockPHPFunctions;
  264. $mockPHPFunctions = true;
  265. $deploymentConfigMock = $this->createMock(DeploymentConfig::class);
  266. $deploymentConfigMock->method('get')
  267. ->willReturnCallback(function ($configPath) {
  268. switch ($configPath) {
  269. case Config::PARAM_SESSION_SAVE_METHOD:
  270. return 'db';
  271. case Config::PARAM_SESSION_CACHE_LIMITER:
  272. return 'private_no_expire';
  273. case Config::PARAM_SESSION_SAVE_PATH:
  274. return 'explicit_save_path';
  275. default:
  276. return null;
  277. }
  278. });
  279. $sessionConfig = $this->objectManager->create(Config::class, ['deploymentConfig' => $deploymentConfigMock]);
  280. $saveHandler = $this->objectManager->create(SaveHandler::class, ['sessionConfig' => $sessionConfig]);
  281. $this->model = $this->objectManager->create(
  282. \Magento\Framework\Session\SessionManager::class,
  283. [
  284. 'sidResolver' => $this->sidResolver,
  285. 'saveHandler' => $saveHandler,
  286. 'sessionConfig' => $sessionConfig,
  287. ]
  288. );
  289. $this->assertEquals('db', $sessionConfig->getOption('session.save_handler'));
  290. $this->assertEquals('private_no_expire', $sessionConfig->getOption('session.cache_limiter'));
  291. $this->assertEquals('explicit_save_path', $sessionConfig->getOption('session.save_path'));
  292. $this->assertArrayHasKey('session.use_only_cookies', self::$isIniSetInvoked);
  293. $this->assertEquals('1', self::$isIniSetInvoked['session.use_only_cookies']);
  294. foreach ($sessionConfig->getOptions() as $option => $value) {
  295. if ($option=='session.save_handler') {
  296. $this->assertArrayNotHasKey('session.save_handler', self::$isIniSetInvoked);
  297. } else {
  298. $this->assertArrayHasKey($option, self::$isIniSetInvoked);
  299. $this->assertEquals($value, self::$isIniSetInvoked[$option]);
  300. }
  301. }
  302. $this->assertTrue(self::$isSessionSetSaveHandlerInvoked);
  303. }
  304. private function initializeModel(): void
  305. {
  306. $this->model = $this->objectManager->create(
  307. \Magento\Framework\Session\SessionManager::class,
  308. [
  309. 'sidResolver' => $this->sidResolver
  310. ]
  311. );
  312. }
  313. }
  314. }