Version 1
[yaffs-website] / web / core / modules / user / tests / src / Kernel / TempStoreDatabaseTest.php
1 <?php
2
3 namespace Drupal\Tests\user\Kernel;
4
5 use Drupal\Core\KeyValueStore\KeyValueExpirableFactory;
6 use Drupal\KernelTests\KernelTestBase;
7 use Drupal\user\SharedTempStoreFactory;
8 use Drupal\Core\Lock\DatabaseLockBackend;
9 use Drupal\Core\Database\Database;
10
11 /**
12  * Tests the temporary object storage system.
13  *
14  * @group user
15  * @see \Drupal\Core\TempStore\TempStore.
16  */
17 class TempStoreDatabaseTest extends KernelTestBase {
18
19   /**
20    * Modules to enable.
21    *
22    * @var array
23    */
24   public static $modules = ['system', 'user'];
25
26   /**
27    * A key/value store factory.
28    *
29    * @var \Drupal\user\SharedTempStoreFactory
30    */
31   protected $storeFactory;
32
33   /**
34    * The name of the key/value collection to set and retrieve.
35    *
36    * @var string
37    */
38   protected $collection;
39
40   /**
41    * An array of (fake) user IDs.
42    *
43    * @var array
44    */
45   protected $users = [];
46
47   /**
48    * An array of random stdClass objects.
49    *
50    * @var array
51    */
52   protected $objects = [];
53
54   protected function setUp() {
55     parent::setUp();
56
57     // Install system tables to test the key/value storage without installing a
58     // full Drupal environment.
59     $this->installSchema('system', ['key_value_expire']);
60
61     // Create several objects for testing.
62     for ($i = 0; $i <= 3; $i++) {
63       $this->objects[$i] = $this->randomObject();
64     }
65
66   }
67
68   /**
69    * Tests the UserTempStore API.
70    */
71   public function testUserTempStore() {
72     // Create a key/value collection.
73     $factory = new SharedTempStoreFactory(new KeyValueExpirableFactory(\Drupal::getContainer()), new DatabaseLockBackend(Database::getConnection()), $this->container->get('request_stack'));
74     $collection = $this->randomMachineName();
75
76     // Create two mock users.
77     for ($i = 0; $i <= 1; $i++) {
78       $users[$i] = mt_rand(500, 5000000);
79
80       // Storing the SharedTempStore objects in a class member variable causes a
81       // fatal exception, because in that situation garbage collection is not
82       // triggered until the test class itself is destructed, after tearDown()
83       // has deleted the database tables. Store the objects locally instead.
84       $stores[$i] = $factory->get($collection, $users[$i]);
85     }
86
87     $key = $this->randomMachineName();
88     // Test that setIfNotExists() succeeds only the first time.
89     for ($i = 0; $i <= 1; $i++) {
90       // setIfNotExists() should be TRUE the first time (when $i is 0) and
91       // FALSE the second time (when $i is 1).
92       $this->assertEqual(!$i, $stores[0]->setIfNotExists($key, $this->objects[$i]));
93       $metadata = $stores[0]->getMetadata($key);
94       $this->assertEqual($users[0], $metadata->owner);
95       $this->assertIdenticalObject($this->objects[0], $stores[0]->get($key));
96       // Another user should get the same result.
97       $metadata = $stores[1]->getMetadata($key);
98       $this->assertEqual($users[0], $metadata->owner);
99       $this->assertIdenticalObject($this->objects[0], $stores[1]->get($key));
100     }
101
102     // Remove the item and try to set it again.
103     $stores[0]->delete($key);
104     $stores[0]->setIfNotExists($key, $this->objects[1]);
105     // This time it should succeed.
106     $this->assertIdenticalObject($this->objects[1], $stores[0]->get($key));
107
108     // This user can update the object.
109     $stores[0]->set($key, $this->objects[2]);
110     $this->assertIdenticalObject($this->objects[2], $stores[0]->get($key));
111     // The object is the same when another user loads it.
112     $this->assertIdenticalObject($this->objects[2], $stores[1]->get($key));
113
114     // This user should be allowed to get, update, delete.
115     $this->assertTrue($stores[0]->getIfOwner($key) instanceof \stdClass);
116     $this->assertTrue($stores[0]->setIfOwner($key, $this->objects[1]));
117     $this->assertTrue($stores[0]->deleteIfOwner($key));
118
119     // Another user can update the object and become the owner.
120     $stores[1]->set($key, $this->objects[3]);
121     $this->assertIdenticalObject($this->objects[3], $stores[0]->get($key));
122     $this->assertIdenticalObject($this->objects[3], $stores[1]->get($key));
123     $metadata = $stores[1]->getMetadata($key);
124     $this->assertEqual($users[1], $metadata->owner);
125
126     // The first user should be informed that the second now owns the data.
127     $metadata = $stores[0]->getMetadata($key);
128     $this->assertEqual($users[1], $metadata->owner);
129
130     // The first user should no longer be allowed to get, update, delete.
131     $this->assertNull($stores[0]->getIfOwner($key));
132     $this->assertFalse($stores[0]->setIfOwner($key, $this->objects[1]));
133     $this->assertFalse($stores[0]->deleteIfOwner($key));
134
135     // Now manually expire the item (this is not exposed by the API) and then
136     // assert it is no longer accessible.
137     db_update('key_value_expire')
138       ->fields(['expire' => REQUEST_TIME - 1])
139       ->condition('collection', "user.shared_tempstore.$collection")
140       ->condition('name', $key)
141       ->execute();
142     $this->assertFalse($stores[0]->get($key));
143     $this->assertFalse($stores[1]->get($key));
144   }
145
146 }