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