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