Further Drupal 8.6.4 changes. Some core files were not committed before a commit...
[yaffs-website] / web / core / modules / file / tests / src / Functional / FileFieldTestBase.php
1 <?php
2
3 namespace Drupal\Tests\file\Functional;
4
5 use Drupal\field\Entity\FieldStorageConfig;
6 use Drupal\field\Entity\FieldConfig;
7 use Drupal\file\FileInterface;
8 use Drupal\Tests\BrowserTestBase;
9 use Drupal\file\Entity\File;
10 use Drupal\Tests\TestFileCreationTrait;
11
12 /**
13  * Provides methods specifically for testing File module's field handling.
14  */
15 abstract class FileFieldTestBase extends BrowserTestBase {
16
17   use FileFieldCreationTrait;
18   use TestFileCreationTrait {
19     getTestFiles as drupalGetTestFiles;
20   }
21
22   /**
23   * Modules to enable.
24   *
25   * @var array
26   */
27   public static $modules = ['node', 'file', 'file_module_test', 'field_ui'];
28
29   /**
30    * An user with administration permissions.
31    *
32    * @var \Drupal\user\UserInterface
33    */
34   protected $adminUser;
35
36   protected function setUp() {
37     parent::setUp();
38     $this->adminUser = $this->drupalCreateUser(['access content', 'access administration pages', 'administer site configuration', 'administer users', 'administer permissions', 'administer content types', 'administer node fields', 'administer node display', 'administer nodes', 'bypass node access']);
39     $this->drupalLogin($this->adminUser);
40     $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
41   }
42
43   /**
44    * Retrieves a sample file of the specified type.
45    *
46    * @return \Drupal\file\FileInterface
47    */
48   public function getTestFile($type_name, $size = NULL) {
49     // Get a file to upload.
50     $file = current($this->drupalGetTestFiles($type_name, $size));
51
52     // Add a filesize property to files as would be read by
53     // \Drupal\file\Entity\File::load().
54     $file->filesize = filesize($file->uri);
55
56     return File::create((array) $file);
57   }
58
59   /**
60    * Retrieves the fid of the last inserted file.
61    */
62   public function getLastFileId() {
63     return (int) db_query('SELECT MAX(fid) FROM {file_managed}')->fetchField();
64   }
65
66   /**
67    * Updates an existing file field with new settings.
68    */
69   public function updateFileField($name, $type_name, $field_settings = [], $widget_settings = []) {
70     $field = FieldConfig::loadByName('node', $type_name, $name);
71     $field->setSettings(array_merge($field->getSettings(), $field_settings));
72     $field->save();
73
74     entity_get_form_display('node', $type_name, 'default')
75       ->setComponent($name, [
76         'settings' => $widget_settings,
77       ])
78       ->save();
79   }
80
81   /**
82    * Uploads a file to a node.
83    *
84    * @param \Drupal\file\FileInterface $file
85    *   The File to be uploaded.
86    * @param string $field_name
87    *   The name of the field on which the files should be saved.
88    * @param $nid_or_type
89    *   A numeric node id to upload files to an existing node, or a string
90    *   indicating the desired bundle for a new node.
91    * @param bool $new_revision
92    *   The revision number.
93    * @param array $extras
94    *   Additional values when a new node is created.
95    *
96    * @return int
97    *   The node id.
98    */
99   public function uploadNodeFile(FileInterface $file, $field_name, $nid_or_type, $new_revision = TRUE, array $extras = []) {
100     return $this->uploadNodeFiles([$file], $field_name, $nid_or_type, $new_revision, $extras);
101   }
102
103   /**
104    * Uploads multiple files to a node.
105    *
106    * @param \Drupal\file\FileInterface[] $files
107    *   The files to be uploaded.
108    * @param string $field_name
109    *   The name of the field on which the files should be saved.
110    * @param $nid_or_type
111    *   A numeric node id to upload files to an existing node, or a string
112    *   indicating the desired bundle for a new node.
113    * @param bool $new_revision
114    *   The revision number.
115    * @param array $extras
116    *   Additional values when a new node is created.
117    *
118    * @return int
119    *   The node id.
120    */
121   public function uploadNodeFiles(array $files, $field_name, $nid_or_type, $new_revision = TRUE, array $extras = []) {
122     $edit = [
123       'title[0][value]' => $this->randomMachineName(),
124       'revision' => (string) (int) $new_revision,
125     ];
126
127     $node_storage = $this->container->get('entity.manager')->getStorage('node');
128     if (is_numeric($nid_or_type)) {
129       $nid = $nid_or_type;
130       $node_storage->resetCache([$nid]);
131       $node = $node_storage->load($nid);
132     }
133     else {
134       // Add a new node.
135       $extras['type'] = $nid_or_type;
136       $node = $this->drupalCreateNode($extras);
137       $nid = $node->id();
138       // Save at least one revision to better simulate a real site.
139       $node->setNewRevision();
140       $node->save();
141       $node_storage->resetCache([$nid]);
142       $node = $node_storage->load($nid);
143       $this->assertNotEqual($nid, $node->getRevisionId(), 'Node revision exists.');
144     }
145
146     // Attach files to the node.
147     $field_storage = FieldStorageConfig::loadByName('node', $field_name);
148     // File input name depends on number of files already uploaded.
149     $field_num = count($node->{$field_name});
150     $name = 'files[' . $field_name . "_$field_num]";
151     if ($field_storage->getCardinality() != 1) {
152       $name .= '[]';
153     }
154     foreach ($files as $file) {
155       $file_path = $this->container->get('file_system')->realpath($file->getFileUri());
156       if (count($files) == 1) {
157         $edit[$name] = $file_path;
158       }
159       else {
160         $edit[$name][] = $file_path;
161       }
162     }
163     $this->drupalPostForm("node/$nid/edit", $edit, t('Save'));
164
165     return $nid;
166   }
167
168   /**
169    * Removes a file from a node.
170    *
171    * Note that if replacing a file, it must first be removed then added again.
172    */
173   public function removeNodeFile($nid, $new_revision = TRUE) {
174     $edit = [
175       'revision' => (string) (int) $new_revision,
176     ];
177
178     $this->drupalPostForm('node/' . $nid . '/edit', [], t('Remove'));
179     $this->drupalPostForm(NULL, $edit, t('Save'));
180   }
181
182   /**
183    * Replaces a file within a node.
184    */
185   public function replaceNodeFile($file, $field_name, $nid, $new_revision = TRUE) {
186     $edit = [
187       'files[' . $field_name . '_0]' => \Drupal::service('file_system')->realpath($file->getFileUri()),
188       'revision' => (string) (int) $new_revision,
189     ];
190
191     $this->drupalPostForm('node/' . $nid . '/edit', [], t('Remove'));
192     $this->drupalPostForm(NULL, $edit, t('Save'));
193   }
194
195   /**
196    * Asserts that a file exists physically on disk.
197    *
198    * Overrides PHPUnit\Framework\Assert::assertFileExists() to also work with
199    * file entities.
200    *
201    * @param \Drupal\File\FileInterface|string $file
202    *   Either the file entity or the file URI.
203    * @param string $message
204    *   (optional) A message to display with the assertion.
205    */
206   public static function assertFileExists($file, $message = NULL) {
207     $message = isset($message) ? $message : format_string('File %file exists on the disk.', ['%file' => $file->getFileUri()]);
208     $filename = $file instanceof FileInterface ? $file->getFileUri() : $file;
209     parent::assertFileExists($filename, $message);
210   }
211
212   /**
213    * Asserts that a file exists in the database.
214    */
215   public function assertFileEntryExists($file, $message = NULL) {
216     $this->container->get('entity.manager')->getStorage('file')->resetCache();
217     $db_file = File::load($file->id());
218     $message = isset($message) ? $message : format_string('File %file exists in database at the correct path.', ['%file' => $file->getFileUri()]);
219     $this->assertEqual($db_file->getFileUri(), $file->getFileUri(), $message);
220   }
221
222   /**
223    * Asserts that a file does not exist on disk.
224    *
225    * Overrides PHPUnit\Framework\Assert::assertFileExists() to also work with
226    * file entities.
227    *
228    * @param \Drupal\File\FileInterface|string $file
229    *   Either the file entity or the file URI.
230    * @param string $message
231    *   (optional) A message to display with the assertion.
232    */
233   public static function assertFileNotExists($file, $message = NULL) {
234     $message = isset($message) ? $message : format_string('File %file exists on the disk.', ['%file' => $file->getFileUri()]);
235     $filename = $file instanceof FileInterface ? $file->getFileUri() : $file;
236     parent::assertFileNotExists($filename, $message);
237   }
238
239   /**
240    * Asserts that a file does not exist in the database.
241    */
242   public function assertFileEntryNotExists($file, $message) {
243     $this->container->get('entity.manager')->getStorage('file')->resetCache();
244     $message = isset($message) ? $message : format_string('File %file exists in database at the correct path.', ['%file' => $file->getFileUri()]);
245     $this->assertFalse(File::load($file->id()), $message);
246   }
247
248   /**
249    * Asserts that a file's status is set to permanent in the database.
250    */
251   public function assertFileIsPermanent(FileInterface $file, $message = NULL) {
252     $message = isset($message) ? $message : format_string('File %file is permanent.', ['%file' => $file->getFileUri()]);
253     $this->assertTrue($file->isPermanent(), $message);
254   }
255
256 }