Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / modules / file / tests / src / Kernel / UsageTest.php
1 <?php
2
3 namespace Drupal\Tests\file\Kernel;
4
5 use Drupal\field\Entity\FieldConfig;
6 use Drupal\field\Entity\FieldStorageConfig;
7 use Drupal\language\Entity\ConfigurableLanguage;
8 use Drupal\language\Entity\ContentLanguageSettings;
9 use Drupal\node\Entity\Node;
10 use Drupal\node\Entity\NodeType;
11
12 /**
13  * Tests file usage functions.
14  *
15  * @group file
16  */
17 class UsageTest extends FileManagedUnitTestBase {
18
19   /**
20    * Tests \Drupal\file\FileUsage\DatabaseFileUsageBackend::listUsage().
21    */
22   public function testGetUsage() {
23     $file = $this->createFile();
24     db_insert('file_usage')
25       ->fields([
26         'fid' => $file->id(),
27         'module' => 'testing',
28         'type' => 'foo',
29         'id' => 1,
30         'count' => 1,
31       ])
32       ->execute();
33     db_insert('file_usage')
34       ->fields([
35         'fid' => $file->id(),
36         'module' => 'testing',
37         'type' => 'bar',
38         'id' => 2,
39         'count' => 2,
40       ])
41       ->execute();
42
43     $usage = $this->container->get('file.usage')->listUsage($file);
44
45     $this->assertEqual(count($usage['testing']), 2, 'Returned the correct number of items.');
46     $this->assertTrue(isset($usage['testing']['foo'][1]), 'Returned the correct id.');
47     $this->assertTrue(isset($usage['testing']['bar'][2]), 'Returned the correct id.');
48     $this->assertEqual($usage['testing']['foo'][1], 1, 'Returned the correct count.');
49     $this->assertEqual($usage['testing']['bar'][2], 2, 'Returned the correct count.');
50   }
51
52   /**
53    * Tests \Drupal\file\FileUsage\DatabaseFileUsageBackend::add().
54    */
55   public function testAddUsage() {
56     $file = $this->createFile();
57     $file_usage = $this->container->get('file.usage');
58     $file_usage->add($file, 'testing', 'foo', 1);
59     // Add the file twice to ensure that the count is incremented rather than
60     // creating additional records.
61     $file_usage->add($file, 'testing', 'bar', 2);
62     $file_usage->add($file, 'testing', 'bar', 2);
63
64     $usage = db_select('file_usage', 'f')
65       ->fields('f')
66       ->condition('f.fid', $file->id())
67       ->execute()
68       ->fetchAllAssoc('id');
69     $this->assertEqual(count($usage), 2, 'Created two records');
70     $this->assertEqual($usage[1]->module, 'testing', 'Correct module');
71     $this->assertEqual($usage[2]->module, 'testing', 'Correct module');
72     $this->assertEqual($usage[1]->type, 'foo', 'Correct type');
73     $this->assertEqual($usage[2]->type, 'bar', 'Correct type');
74     $this->assertEqual($usage[1]->count, 1, 'Correct count');
75     $this->assertEqual($usage[2]->count, 2, 'Correct count');
76   }
77
78   /**
79    * Tests file usage deletion when files are made temporary.
80    */
81   public function testRemoveUsageTemporary() {
82     $this->config('file.settings')
83       ->set('make_unused_managed_files_temporary', TRUE)
84       ->save();
85     $file = $this->doTestRemoveUsage();
86     $this->assertTrue($file->isTemporary());
87   }
88
89   /**
90    * Tests file usage deletion when files are made temporary.
91    */
92   public function testRemoveUsageNonTemporary() {
93     $this->config('file.settings')
94       ->set('make_unused_managed_files_temporary', FALSE)
95       ->save();
96     $file = $this->doTestRemoveUsage();
97     $this->assertFalse($file->isTemporary());
98   }
99
100   /**
101    * Tests \Drupal\file\FileUsage\DatabaseFileUsageBackend::delete().
102    */
103   public function doTestRemoveUsage() {
104     $file = $this->createFile();
105     $file->setPermanent();
106     $file_usage = $this->container->get('file.usage');
107     db_insert('file_usage')
108       ->fields([
109         'fid' => $file->id(),
110         'module' => 'testing',
111         'type' => 'bar',
112         'id' => 2,
113         'count' => 3,
114       ])
115       ->execute();
116
117     // Normal decrement.
118     $file_usage->delete($file, 'testing', 'bar', 2);
119     $count = db_select('file_usage', 'f')
120       ->fields('f', ['count'])
121       ->condition('f.fid', $file->id())
122       ->execute()
123       ->fetchField();
124     $this->assertEqual(2, $count, 'The count was decremented correctly.');
125
126     // Multiple decrement and removal.
127     $file_usage->delete($file, 'testing', 'bar', 2, 2);
128     $count = db_select('file_usage', 'f')
129       ->fields('f', ['count'])
130       ->condition('f.fid', $file->id())
131       ->execute()
132       ->fetchField();
133     $this->assertIdentical(FALSE, $count, 'The count was removed entirely when empty.');
134
135     // Non-existent decrement.
136     $file_usage->delete($file, 'testing', 'bar', 2);
137     $count = db_select('file_usage', 'f')
138       ->fields('f', ['count'])
139       ->condition('f.fid', $file->id())
140       ->execute()
141       ->fetchField();
142     $this->assertIdentical(FALSE, $count, 'Decrementing non-exist record complete.');
143     return $file;
144   }
145
146   /**
147    * Create files for all the possible combinations of age and status.
148    *
149    * We are using UPDATE statements because using the API would set the
150    * timestamp.
151    */
152   public function createTempFiles() {
153     // Temporary file that is old.
154     $temp_old = file_save_data('');
155     db_update('file_managed')
156       ->fields([
157         'status' => 0,
158         'changed' => REQUEST_TIME - $this->config('system.file')->get('temporary_maximum_age') - 1,
159       ])
160       ->condition('fid', $temp_old->id())
161       ->execute();
162     $this->assertTrue(file_exists($temp_old->getFileUri()), 'Old temp file was created correctly.');
163
164     // Temporary file that is new.
165     $temp_new = file_save_data('');
166     db_update('file_managed')
167       ->fields(['status' => 0])
168       ->condition('fid', $temp_new->id())
169       ->execute();
170     $this->assertTrue(file_exists($temp_new->getFileUri()), 'New temp file was created correctly.');
171
172     // Permanent file that is old.
173     $perm_old = file_save_data('');
174     db_update('file_managed')
175       ->fields(['changed' => REQUEST_TIME - $this->config('system.file')->get('temporary_maximum_age') - 1])
176       ->condition('fid', $temp_old->id())
177       ->execute();
178     $this->assertTrue(file_exists($perm_old->getFileUri()), 'Old permanent file was created correctly.');
179
180     // Permanent file that is new.
181     $perm_new = file_save_data('');
182     $this->assertTrue(file_exists($perm_new->getFileUri()), 'New permanent file was created correctly.');
183     return [$temp_old, $temp_new, $perm_old, $perm_new];
184   }
185
186   /**
187    * Ensure that temporary files are removed by default.
188    */
189   public function testTempFileCleanupDefault() {
190     list($temp_old, $temp_new, $perm_old, $perm_new) = $this->createTempFiles();
191
192     // Run cron and then ensure that only the old, temp file was deleted.
193     $this->container->get('cron')->run();
194     $this->assertFalse(file_exists($temp_old->getFileUri()), 'Old temp file was correctly removed.');
195     $this->assertTrue(file_exists($temp_new->getFileUri()), 'New temp file was correctly ignored.');
196     $this->assertTrue(file_exists($perm_old->getFileUri()), 'Old permanent file was correctly ignored.');
197     $this->assertTrue(file_exists($perm_new->getFileUri()), 'New permanent file was correctly ignored.');
198   }
199
200   /**
201    * Ensure that temporary files are kept as configured.
202    */
203   public function testTempFileNoCleanup() {
204     list($temp_old, $temp_new, $perm_old, $perm_new) = $this->createTempFiles();
205
206     // Set the max age to 0, meaning no temporary files will be deleted.
207     $this->config('system.file')
208       ->set('temporary_maximum_age', 0)
209       ->save();
210
211     // Run cron and then ensure that no file was deleted.
212     $this->container->get('cron')->run();
213     $this->assertTrue(file_exists($temp_old->getFileUri()), 'Old temp file was correctly ignored.');
214     $this->assertTrue(file_exists($temp_new->getFileUri()), 'New temp file was correctly ignored.');
215     $this->assertTrue(file_exists($perm_old->getFileUri()), 'Old permanent file was correctly ignored.');
216     $this->assertTrue(file_exists($perm_new->getFileUri()), 'New permanent file was correctly ignored.');
217   }
218
219   /**
220    * Ensure that temporary files are kept as configured.
221    */
222   public function testTempFileCustomCleanup() {
223     list($temp_old, $temp_new, $perm_old, $perm_new) = $this->createTempFiles();
224
225     // Set the max age to older than default.
226     $this->config('system.file')
227       ->set('temporary_maximum_age', 21600 + 2)
228       ->save();
229
230     // Run cron and then ensure that more files were deleted.
231     $this->container->get('cron')->run();
232     $this->assertTrue(file_exists($temp_old->getFileUri()), 'Old temp file was correctly ignored.');
233     $this->assertTrue(file_exists($temp_new->getFileUri()), 'New temp file was correctly ignored.');
234     $this->assertTrue(file_exists($perm_old->getFileUri()), 'Old permanent file was correctly ignored.');
235     $this->assertTrue(file_exists($perm_new->getFileUri()), 'New permanent file was correctly ignored.');
236   }
237
238   /**
239    * Tests file usage with translated entities.
240    */
241   public function testFileUsageWithEntityTranslation() {
242     /** @var \Drupal\file\FileUsage\FileUsageInterface $file_usage */
243     $file_usage = $this->container->get('file.usage');
244
245     $this->enableModules(['node', 'language']);
246     $this->installEntitySchema('node');
247     $this->installSchema('node', ['node_access']);
248
249     // Activate English and Romanian languages.
250     ConfigurableLanguage::create(['id' => 'en'])->save();
251     ConfigurableLanguage::create(['id' => 'ro'])->save();
252
253     NodeType::create(['type' => 'page'])->save();
254     ContentLanguageSettings::loadByEntityTypeBundle('node', 'page')
255       ->setLanguageAlterable(FALSE)
256       ->setDefaultLangcode('en')
257       ->save();
258     // Create a file field attached to 'page' node-type.
259     FieldStorageConfig::create([
260       'type' => 'file',
261       'entity_type' => 'node',
262       'field_name' => 'file',
263     ])->save();
264     FieldConfig::create([
265       'entity_type' => 'node',
266       'bundle' => 'page',
267       'field_name' => 'file',
268       'label' => 'File',
269     ])->save();
270
271     // Create a node, attach a file and add a Romanian translation.
272     $node = Node::create(['type' => 'page', 'title' => 'Page']);
273     $node
274       ->set('file', $file = $this->createFile())
275       ->addTranslation('ro', $node->getTranslation('en')->toArray())
276       ->save();
277
278     // Check that the file is used twice.
279     $usage = $file_usage->listUsage($file);
280     $this->assertEquals(2, $usage['file']['node'][$node->id()]);
281
282     // Remove the Romanian translation.
283     $node->removeTranslation('ro');
284     $node->save();
285
286     // Check that one usage has been removed and is used only once now.
287     $usage = $file_usage->listUsage($file);
288     $this->assertEquals(1, $usage['file']['node'][$node->id()]);
289   }
290
291 }