PageRenderTime 31ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/web/core/tests/Drupal/Tests/Core/TempStore/SharedTempStoreTest.php

https://gitlab.com/mohamed_hussein/prodt
PHP | 440 lines | 254 code | 65 blank | 121 comment | 0 complexity | 823a90a43f980bd28745f2daff66f73c MD5 | raw file
  1. <?php
  2. namespace Drupal\Tests\Core\TempStore;
  3. use Drupal\Core\DependencyInjection\ContainerBuilder;
  4. use Drupal\Core\Http\RequestStack;
  5. use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
  6. use Drupal\Core\Session\AccountProxyInterface;
  7. use Drupal\Core\TempStore\Lock;
  8. use Drupal\Core\TempStore\SharedTempStoreFactory;
  9. use Drupal\Tests\UnitTestCase;
  10. use Drupal\Core\TempStore\SharedTempStore;
  11. use Drupal\Core\TempStore\TempStoreException;
  12. use Symfony\Component\DependencyInjection\ContainerInterface;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  15. /**
  16. * @coversDefaultClass \Drupal\Core\TempStore\SharedTempStore
  17. * @group TempStore
  18. */
  19. class SharedTempStoreTest extends UnitTestCase {
  20. /**
  21. * The mock key value expirable backend.
  22. *
  23. * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface|\PHPUnit\Framework\MockObject\MockObject
  24. */
  25. protected $keyValue;
  26. /**
  27. * The mock lock backend.
  28. *
  29. * @var \Drupal\Core\Lock\LockBackendInterface|\PHPUnit\Framework\MockObject\MockObject
  30. */
  31. protected $lock;
  32. /**
  33. * The temp store.
  34. *
  35. * @var \Drupal\Core\TempStore\SharedTempStore
  36. */
  37. protected $tempStore;
  38. /**
  39. * The owner used in this test.
  40. *
  41. * @var int
  42. */
  43. protected $owner = 1;
  44. /**
  45. * The request stack.
  46. *
  47. * @var \Symfony\Component\HttpFoundation\RequestStack
  48. */
  49. protected $requestStack;
  50. /**
  51. * A tempstore object belonging to the owner.
  52. *
  53. * @var object
  54. */
  55. protected $ownObject;
  56. /**
  57. * A tempstore object not belonging to the owner.
  58. *
  59. * @var object
  60. */
  61. protected $otherObject;
  62. /**
  63. * {@inheritdoc}
  64. */
  65. protected function setUp(): void {
  66. parent::setUp();
  67. $this->keyValue = $this->createMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface');
  68. $this->lock = $this->createMock('Drupal\Core\Lock\LockBackendInterface');
  69. $this->requestStack = new RequestStack();
  70. $request = Request::createFromGlobals();
  71. $session = $this->createMock(SessionInterface::class);
  72. $request->setSession($session);
  73. $this->requestStack->push($request);
  74. $current_user = $this->createMock(AccountProxyInterface::class);
  75. $this->tempStore = new SharedTempStore($this->keyValue, $this->lock, $this->owner, $this->requestStack, $current_user, 604800);
  76. $this->ownObject = (object) [
  77. 'data' => 'test_data',
  78. 'owner' => $this->owner,
  79. 'updated' => (int) $request->server->get('REQUEST_TIME'),
  80. ];
  81. // Clone the object but change the owner.
  82. $this->otherObject = clone $this->ownObject;
  83. $this->otherObject->owner = 2;
  84. }
  85. /**
  86. * @covers ::get
  87. */
  88. public function testGet() {
  89. $this->keyValue->expects($this->exactly(2))
  90. ->method('get')
  91. ->withConsecutive(
  92. ['test_2'],
  93. ['test'],
  94. )
  95. ->willReturnOnConsecutiveCalls(
  96. FALSE,
  97. $this->ownObject,
  98. );
  99. $this->assertNull($this->tempStore->get('test_2'));
  100. $this->assertSame($this->ownObject->data, $this->tempStore->get('test'));
  101. }
  102. /**
  103. * Tests the getIfOwner() method.
  104. *
  105. * @covers ::getIfOwner
  106. */
  107. public function testGetIfOwner() {
  108. $this->keyValue->expects($this->exactly(3))
  109. ->method('get')
  110. ->withConsecutive(
  111. ['test_2'],
  112. ['test'],
  113. ['test'],
  114. )
  115. ->willReturnOnConsecutiveCalls(
  116. FALSE,
  117. $this->ownObject,
  118. $this->otherObject,
  119. );
  120. $this->assertNull($this->tempStore->getIfOwner('test_2'));
  121. $this->assertSame($this->ownObject->data, $this->tempStore->getIfOwner('test'));
  122. $this->assertNull($this->tempStore->getIfOwner('test'));
  123. }
  124. /**
  125. * Tests the set() method with no lock available.
  126. *
  127. * @covers ::set
  128. */
  129. public function testSetWithNoLockAvailable() {
  130. $this->lock->expects($this->exactly(2))
  131. ->method('acquire')
  132. ->with('test')
  133. ->will($this->returnValue(FALSE));
  134. $this->lock->expects($this->once())
  135. ->method('wait')
  136. ->with('test');
  137. $this->keyValue->expects($this->once())
  138. ->method('getCollectionName');
  139. $this->expectException(TempStoreException::class);
  140. $this->tempStore->set('test', 'value');
  141. }
  142. /**
  143. * Tests a successful set() call.
  144. *
  145. * @covers ::set
  146. */
  147. public function testSet() {
  148. $this->lock->expects($this->once())
  149. ->method('acquire')
  150. ->with('test')
  151. ->will($this->returnValue(TRUE));
  152. $this->lock->expects($this->never())
  153. ->method('wait');
  154. $this->lock->expects($this->once())
  155. ->method('release')
  156. ->with('test');
  157. $this->keyValue->expects($this->once())
  158. ->method('setWithExpire')
  159. ->with('test', $this->ownObject, 604800);
  160. $this->tempStore->set('test', 'test_data');
  161. }
  162. /**
  163. * Tests the setIfNotExists() methods.
  164. *
  165. * @covers ::setIfNotExists
  166. */
  167. public function testSetIfNotExists() {
  168. $this->keyValue->expects($this->once())
  169. ->method('setWithExpireIfNotExists')
  170. ->with('test', $this->ownObject, 604800)
  171. ->will($this->returnValue(TRUE));
  172. $this->assertTrue($this->tempStore->setIfNotExists('test', 'test_data'));
  173. }
  174. /**
  175. * Tests the setIfOwner() method when no key exists.
  176. *
  177. * @covers ::setIfOwner
  178. */
  179. public function testSetIfOwnerWhenNotExists() {
  180. $this->keyValue->expects($this->once())
  181. ->method('setWithExpireIfNotExists')
  182. ->will($this->returnValue(TRUE));
  183. $this->assertTrue($this->tempStore->setIfOwner('test', 'test_data'));
  184. }
  185. /**
  186. * Tests the setIfOwner() method when a key already exists but no object.
  187. *
  188. * @covers ::setIfOwner
  189. */
  190. public function testSetIfOwnerNoObject() {
  191. $this->keyValue->expects($this->once())
  192. ->method('setWithExpireIfNotExists')
  193. ->will($this->returnValue(FALSE));
  194. $this->keyValue->expects($this->once())
  195. ->method('get')
  196. ->with('test')
  197. ->will($this->returnValue(FALSE));
  198. $this->assertFalse($this->tempStore->setIfOwner('test', 'test_data'));
  199. }
  200. /**
  201. * Tests the setIfOwner() method with matching and non matching owners.
  202. *
  203. * @covers ::setIfOwner
  204. */
  205. public function testSetIfOwner() {
  206. $this->lock->expects($this->once())
  207. ->method('acquire')
  208. ->with('test')
  209. ->will($this->returnValue(TRUE));
  210. $this->keyValue->expects($this->exactly(2))
  211. ->method('setWithExpireIfNotExists')
  212. ->will($this->returnValue(FALSE));
  213. $this->keyValue->expects($this->exactly(2))
  214. ->method('get')
  215. ->with('test')
  216. ->will($this->onConsecutiveCalls($this->ownObject, $this->otherObject));
  217. $this->assertTrue($this->tempStore->setIfOwner('test', 'test_data'));
  218. $this->assertFalse($this->tempStore->setIfOwner('test', 'test_data'));
  219. }
  220. /**
  221. * Tests the getMetadata() method.
  222. *
  223. * @covers ::getMetadata
  224. */
  225. public function testGetMetadata() {
  226. $this->keyValue->expects($this->exactly(2))
  227. ->method('get')
  228. ->with('test')
  229. ->willReturnOnConsecutiveCalls($this->ownObject, FALSE);
  230. $metadata = $this->tempStore->getMetadata('test');
  231. $this->assertInstanceOf(Lock::class, $metadata);
  232. $this->assertObjectHasAttribute('updated', $metadata);
  233. // Data should get removed.
  234. $this->assertObjectNotHasAttribute('data', $metadata);
  235. $this->assertNull($this->tempStore->getMetadata('test'));
  236. }
  237. /**
  238. * Tests the delete() method.
  239. *
  240. * @covers ::delete
  241. */
  242. public function testDelete() {
  243. $this->lock->expects($this->once())
  244. ->method('acquire')
  245. ->with('test')
  246. ->will($this->returnValue(TRUE));
  247. $this->lock->expects($this->never())
  248. ->method('wait');
  249. $this->lock->expects($this->once())
  250. ->method('release')
  251. ->with('test');
  252. $this->keyValue->expects($this->once())
  253. ->method('delete')
  254. ->with('test');
  255. $this->tempStore->delete('test');
  256. }
  257. /**
  258. * Tests the delete() method with no lock available.
  259. *
  260. * @covers ::delete
  261. */
  262. public function testDeleteWithNoLockAvailable() {
  263. $this->lock->expects($this->exactly(2))
  264. ->method('acquire')
  265. ->with('test')
  266. ->will($this->returnValue(FALSE));
  267. $this->lock->expects($this->once())
  268. ->method('wait')
  269. ->with('test');
  270. $this->keyValue->expects($this->once())
  271. ->method('getCollectionName');
  272. $this->expectException(TempStoreException::class);
  273. $this->tempStore->delete('test');
  274. }
  275. /**
  276. * Tests the deleteIfOwner() method.
  277. *
  278. * @covers ::deleteIfOwner
  279. */
  280. public function testDeleteIfOwner() {
  281. $this->lock->expects($this->once())
  282. ->method('acquire')
  283. ->with('test_2')
  284. ->will($this->returnValue(TRUE));
  285. $this->keyValue->expects($this->exactly(3))
  286. ->method('get')
  287. ->withConsecutive(
  288. ['test_1'],
  289. ['test_2'],
  290. ['test_3'],
  291. )
  292. ->willReturnOnConsecutiveCalls(
  293. FALSE,
  294. $this->ownObject,
  295. $this->otherObject,
  296. );
  297. $this->keyValue->expects($this->once())
  298. ->method('delete')
  299. ->with('test_2');
  300. $this->assertTrue($this->tempStore->deleteIfOwner('test_1'));
  301. $this->assertTrue($this->tempStore->deleteIfOwner('test_2'));
  302. $this->assertFalse($this->tempStore->deleteIfOwner('test_3'));
  303. }
  304. /**
  305. * Tests the serialization of a shared temp store.
  306. */
  307. public function testSerialization() {
  308. // Add an unserializable request to the request stack. If the tempstore
  309. // didn't use DependencySerializationTrait, an exception would be thrown
  310. // when we try to serialize the tempstore.
  311. $unserializable_request = new UnserializableRequest();
  312. $this->requestStack->push($unserializable_request);
  313. $this->requestStack->_serviceId = 'request_stack';
  314. $container = $this->prophesize(ContainerInterface::class);
  315. $container->get('request_stack')->willReturn($this->requestStack);
  316. $container->has('request_stack')->willReturn(TRUE);
  317. \Drupal::setContainer($container->reveal());
  318. $store = unserialize(serialize($this->tempStore));
  319. $this->assertInstanceOf(SharedTempStore::class, $store);
  320. $reflected_request_stack = (new \ReflectionObject($store))->getProperty('requestStack');
  321. $reflected_request_stack->setAccessible(TRUE);
  322. $request_stack = $reflected_request_stack->getValue($store);
  323. $this->assertEquals($this->requestStack, $request_stack);
  324. $this->assertSame($unserializable_request, $request_stack->pop());
  325. }
  326. /**
  327. * @group legacy
  328. */
  329. public function testLegacyConstructor() {
  330. $this->expectDeprecation('Calling Drupal\Core\TempStore\SharedTempStore::__construct() without the $current_user argument is deprecated in drupal:9.2.0 and will be required in drupal:10.0.0. See https://www.drupal.org/node/3006268');
  331. $container = new ContainerBuilder();
  332. $current_user = $this->createMock(AccountProxyInterface::class);
  333. $container->set('current_user', $current_user);
  334. \Drupal::setContainer($container);
  335. $store = new SharedTempStore($this->keyValue, $this->lock, 2, $this->requestStack, 1000);
  336. $reflection_class = new \ReflectionClass(SharedTempStore::class);
  337. $current_user_property = $reflection_class->getProperty('currentUser');
  338. $current_user_property->setAccessible(TRUE);
  339. $this->assertSame($current_user, $current_user_property->getValue($store));
  340. $expire_property = $reflection_class->getProperty('expire');
  341. $expire_property->setAccessible(TRUE);
  342. $this->assertSame(1000, $expire_property->getValue($store));
  343. }
  344. /**
  345. * @group legacy
  346. * @covers \Drupal\Core\TempStore\SharedTempStoreFactory::__construct
  347. */
  348. public function testLegacyFactoryConstructor() {
  349. $this->expectDeprecation('Calling Drupal\Core\TempStore\SharedTempStoreFactory::__construct() without the $current_user argument is deprecated in drupal:9.2.0 and will be required in drupal:10.0.0. See https://www.drupal.org/node/3006268');
  350. $container = new ContainerBuilder();
  351. $current_user = $this->createMock(AccountProxyInterface::class);
  352. $container->set('current_user', $current_user);
  353. \Drupal::setContainer($container);
  354. $key_value_factory = $this->prophesize(KeyValueExpirableFactoryInterface::class);
  355. $store = new SharedTempStoreFactory($key_value_factory->reveal(), $this->lock, $this->requestStack, 1000);
  356. $reflection_class = new \ReflectionClass(SharedTempStoreFactory::class);
  357. $current_user_property = $reflection_class->getProperty('currentUser');
  358. $current_user_property->setAccessible(TRUE);
  359. $this->assertSame($current_user, $current_user_property->getValue($store));
  360. $expire_property = $reflection_class->getProperty('expire');
  361. $expire_property->setAccessible(TRUE);
  362. $this->assertSame(1000, $expire_property->getValue($store));
  363. }
  364. }
  365. /**
  366. * A class for testing.
  367. */
  368. class UnserializableRequest extends Request {
  369. /**
  370. * @return array
  371. */
  372. public function __serialize(): array {
  373. throw new \LogicException('Oops!');
  374. }
  375. }