Security update for Core, with self-updated composer
[yaffs-website] / web / core / tests / Drupal / KernelTests / Core / Config / Storage / ConfigStorageTestBase.php
1 <?php
2
3 namespace Drupal\KernelTests\Core\Config\Storage;
4
5 use Drupal\KernelTests\KernelTestBase;
6
7 /**
8  * Base class for testing storage operations.
9  *
10  * All configuration storages are expected to behave identically in
11  * terms of reading, writing, listing, deleting, as well as error handling.
12  *
13  * Therefore, storage tests use an uncommon test case class structure;
14  * the base class defines the test method(s) to execute, which are identical
15  * for all storages. The storage specific test case classes supply the
16  * necessary helper methods to interact with the raw/native storage
17  * directly.
18  */
19 abstract class ConfigStorageTestBase extends KernelTestBase {
20
21   /**
22    * @var \Drupal\Core\Config\StorageInterface
23    */
24   protected $storage;
25
26   /**
27    * @var \Drupal\Core\Config\StorageInterface
28    */
29   protected $invalidStorage;
30
31   /**
32    * Tests storage CRUD operations.
33    *
34    * @todo Coverage: Trigger PDOExceptions / Database exceptions.
35    */
36   public function testCRUD() {
37     $name = 'config_test.storage';
38
39     // Checking whether a non-existing name exists returns FALSE.
40     $this->assertIdentical($this->storage->exists($name), FALSE);
41
42     // Reading a non-existing name returns FALSE.
43     $data = $this->storage->read($name);
44     $this->assertIdentical($data, FALSE);
45
46     // Writing data returns TRUE and the data has been written.
47     $data = ['foo' => 'bar'];
48     $result = $this->storage->write($name, $data);
49     $this->assertIdentical($result, TRUE);
50
51     $raw_data = $this->read($name);
52     $this->assertIdentical($raw_data, $data);
53
54     // Checking whether an existing name exists returns TRUE.
55     $this->assertIdentical($this->storage->exists($name), TRUE);
56
57     // Writing the identical data again still returns TRUE.
58     $result = $this->storage->write($name, $data);
59     $this->assertIdentical($result, TRUE);
60
61     // Listing all names returns all.
62     $names = $this->storage->listAll();
63     $this->assertTrue(in_array('system.performance', $names));
64     $this->assertTrue(in_array($name, $names));
65
66     // Listing all names with prefix returns names with that prefix only.
67     $names = $this->storage->listAll('config_test.');
68     $this->assertFalse(in_array('system.performance', $names));
69     $this->assertTrue(in_array($name, $names));
70
71     // Rename the configuration storage object.
72     $new_name = 'config_test.storage_rename';
73     $this->storage->rename($name, $new_name);
74     $raw_data = $this->read($new_name);
75     $this->assertIdentical($raw_data, $data);
76     // Rename it back so further tests work.
77     $this->storage->rename($new_name, $name);
78
79     // Deleting an existing name returns TRUE.
80     $result = $this->storage->delete($name);
81     $this->assertIdentical($result, TRUE);
82
83     // Deleting a non-existing name returns FALSE.
84     $result = $this->storage->delete($name);
85     $this->assertIdentical($result, FALSE);
86
87     // Deleting all names with prefix deletes the appropriate data and returns
88     // TRUE.
89     $files = [
90       'config_test.test.biff',
91       'config_test.test.bang',
92       'config_test.test.pow',
93     ];
94     foreach ($files as $name) {
95       $this->storage->write($name, $data);
96     }
97
98     $result = $this->storage->deleteAll('config_test.');
99     $names = $this->storage->listAll('config_test.');
100     $this->assertIdentical($result, TRUE);
101     $this->assertIdentical($names, []);
102
103     // Test renaming an object that does not exist throws an exception.
104     try {
105       $this->storage->rename('config_test.storage_does_not_exist', 'config_test.storage_does_not_exist_rename');
106     }
107     catch (\Exception $e) {
108       $class = get_class($e);
109       $this->pass($class . ' thrown upon renaming a nonexistent storage bin.');
110     }
111
112     // Test renaming to an object that already exists throws an exception.
113     try {
114       $this->storage->rename('system.cron', 'system.performance');
115     }
116     catch (\Exception $e) {
117       $class = get_class($e);
118       $this->pass($class . ' thrown upon renaming a nonexistent storage bin.');
119     }
120   }
121
122   /**
123    * Tests an invalid storage.
124    */
125   public function testInvalidStorage() {
126     $name = 'config_test.storage';
127
128     // Write something to the valid storage to prove that the storages do not
129     // pollute one another.
130     $data = ['foo' => 'bar'];
131     $result = $this->storage->write($name, $data);
132     $this->assertIdentical($result, TRUE);
133
134     $raw_data = $this->read($name);
135     $this->assertIdentical($raw_data, $data);
136
137     // Reading from a non-existing storage bin returns FALSE.
138     $result = $this->invalidStorage->read($name);
139     $this->assertIdentical($result, FALSE);
140
141     // Deleting from a non-existing storage bin throws an exception.
142     try {
143       $this->invalidStorage->delete($name);
144       $this->fail('Exception not thrown upon deleting from a non-existing storage bin.');
145     }
146     catch (\Exception $e) {
147       $class = get_class($e);
148       $this->pass($class . ' thrown upon deleting from a non-existing storage bin.');
149     }
150
151     // Listing on a non-existing storage bin returns an empty array.
152     $result = $this->invalidStorage->listAll();
153     $this->assertIdentical($result, []);
154     // Writing to a non-existing storage bin creates the bin.
155     $this->invalidStorage->write($name, ['foo' => 'bar']);
156     $result = $this->invalidStorage->read($name);
157     $this->assertIdentical($result, ['foo' => 'bar']);
158   }
159
160   /**
161    * Tests storage writing and reading data preserving data type.
162    */
163   public function testDataTypes() {
164     $name = 'config_test.types';
165     $data = [
166       'array' => [],
167       'boolean' => TRUE,
168       'exp' => 1.2e+34,
169       'float' => 3.14159,
170       'hex' => 0xC,
171       'int' => 99,
172       'octal' => 0775,
173       'string' => 'string',
174       'string_int' => '1',
175     ];
176
177     $result = $this->storage->write($name, $data);
178     $this->assertIdentical($result, TRUE);
179
180     $read_data = $this->storage->read($name);
181     $this->assertIdentical($read_data, $data);
182   }
183
184   /**
185    * Tests that the storage supports collections.
186    */
187   public function testCollection() {
188     $name = 'config_test.storage';
189     $data = ['foo' => 'bar'];
190     $result = $this->storage->write($name, $data);
191     $this->assertIdentical($result, TRUE);
192     $this->assertSame($data, $this->storage->read($name));
193
194     // Create configuration in a new collection.
195     $new_storage = $this->storage->createCollection('collection.sub.new');
196     $this->assertFalse($new_storage->exists($name));
197     $this->assertEqual([], $new_storage->listAll());
198     $new_storage->write($name, $data);
199     $this->assertIdentical($result, TRUE);
200     $this->assertSame($data, $new_storage->read($name));
201     $this->assertEqual([$name], $new_storage->listAll());
202     $this->assertTrue($new_storage->exists($name));
203     $new_data = ['foo' => 'baz'];
204     $new_storage->write($name, $new_data);
205     $this->assertIdentical($result, TRUE);
206     $this->assertSame($new_data, $new_storage->read($name));
207
208     // Create configuration in another collection.
209     $another_storage = $this->storage->createCollection('collection.sub.another');
210     $this->assertFalse($another_storage->exists($name));
211     $this->assertEqual([], $another_storage->listAll());
212     $another_storage->write($name, $new_data);
213     $this->assertIdentical($result, TRUE);
214     $this->assertSame($new_data, $another_storage->read($name));
215     $this->assertEqual([$name], $another_storage->listAll());
216     $this->assertTrue($another_storage->exists($name));
217
218     // Create configuration in yet another collection.
219     $alt_storage = $this->storage->createCollection('alternate');
220     $alt_storage->write($name, $new_data);
221     $this->assertIdentical($result, TRUE);
222     $this->assertSame($new_data, $alt_storage->read($name));
223
224     // Switch back to the collection-less mode and check the data still exists
225     // add has not been touched.
226     $this->assertSame($data, $this->storage->read($name));
227
228     // Check that the getAllCollectionNames() method works.
229     $this->assertSame(['alternate', 'collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
230
231     // Check that the collections are removed when they are empty.
232     $alt_storage->delete($name);
233     $this->assertSame(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
234
235     // Create configuration in collection called 'collection'. This ensures that
236     // FileStorage's collection storage works regardless of its use of
237     // subdirectories.
238     $parent_storage = $this->storage->createCollection('collection');
239     $this->assertFalse($parent_storage->exists($name));
240     $this->assertEqual([], $parent_storage->listAll());
241     $parent_storage->write($name, $new_data);
242     $this->assertIdentical($result, TRUE);
243     $this->assertSame($new_data, $parent_storage->read($name));
244     $this->assertEqual([$name], $parent_storage->listAll());
245     $this->assertTrue($parent_storage->exists($name));
246     $this->assertSame(['collection', 'collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
247     $parent_storage->deleteAll();
248     $this->assertSame(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
249
250     // Check that the having an empty collection-less storage does not break
251     // anything. Before deleting check that the previous delete did not affect
252     // data in another collection.
253     $this->assertSame($data, $this->storage->read($name));
254     $this->storage->delete($name);
255     $this->assertSame(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames());
256   }
257
258   abstract protected function read($name);
259
260   abstract protected function insert($name, $data);
261
262   abstract protected function update($name, $data);
263
264   abstract protected function delete($name);
265
266 }