diff --git a/core/modules/file/tests/src/Functional/FileFieldCreationTrait.php b/core/modules/file/tests/src/Functional/FileFieldCreationTrait.php new file mode 100644 index 0000000000..89c713e077 --- /dev/null +++ b/core/modules/file/tests/src/Functional/FileFieldCreationTrait.php @@ -0,0 +1,86 @@ + $entity_type, + 'field_name' => $name, + 'type' => 'file', + 'settings' => $storage_settings, + 'cardinality' => !empty($storage_settings['cardinality']) ? $storage_settings['cardinality'] : 1, + ]); + $field_storage->save(); + + $this->attachFileField($name, $entity_type, $bundle, $field_settings, $widget_settings); + return $field_storage; + } + + /** + * Attaches a file field to an entity. + * + * @param string $name + * The name of the new field (all lowercase), exclude the "field_" prefix. + * @param string $entity_type + * The entity type this field will be added to. + * @param string $bundle + * The bundle this field will be added to. + * @param array $field_settings + * A list of field settings that will be added to the defaults. + * @param array $widget_settings + * A list of widget settings that will be added to the widget defaults. + */ + public function attachFileField($name, $entity_type, $bundle, $field_settings = [], $widget_settings = []) { + $field = [ + 'field_name' => $name, + 'label' => $name, + 'entity_type' => $entity_type, + 'bundle' => $bundle, + 'required' => !empty($field_settings['required']), + 'settings' => $field_settings, + ]; + FieldConfig::create($field)->save(); + + entity_get_form_display($entity_type, $bundle, 'default') + ->setComponent($name, [ + 'type' => 'file_generic', + 'settings' => $widget_settings, + ]) + ->save(); + // Assign display settings. + entity_get_display($entity_type, $bundle, 'default') + ->setComponent($name, [ + 'label' => 'hidden', + 'type' => 'file_default', + ]) + ->save(); + } + +} diff --git a/core/modules/file/tests/src/Functional/FileFieldTestBase.php b/core/modules/file/tests/src/Functional/FileFieldTestBase.php index d6096874d6..16733144e3 100644 --- a/core/modules/file/tests/src/Functional/FileFieldTestBase.php +++ b/core/modules/file/tests/src/Functional/FileFieldTestBase.php @@ -13,6 +13,8 @@ */ abstract class FileFieldTestBase extends BrowserTestBase { + use FileFieldCreationTrait; + /** * Modules to enable. * @@ -57,76 +59,6 @@ public function getLastFileId() { return (int) db_query('SELECT MAX(fid) FROM {file_managed}')->fetchField(); } - /** - * Creates a new file field. - * - * @param string $name - * The name of the new field (all lowercase), exclude the "field_" prefix. - * @param string $entity_type - * The entity type. - * @param string $bundle - * The bundle that this field will be added to. - * @param array $storage_settings - * A list of field storage settings that will be added to the defaults. - * @param array $field_settings - * A list of instance settings that will be added to the instance defaults. - * @param array $widget_settings - * A list of widget settings that will be added to the widget defaults. - */ - public function createFileField($name, $entity_type, $bundle, $storage_settings = [], $field_settings = [], $widget_settings = []) { - $field_storage = FieldStorageConfig::create([ - 'entity_type' => $entity_type, - 'field_name' => $name, - 'type' => 'file', - 'settings' => $storage_settings, - 'cardinality' => !empty($storage_settings['cardinality']) ? $storage_settings['cardinality'] : 1, - ]); - $field_storage->save(); - - $this->attachFileField($name, $entity_type, $bundle, $field_settings, $widget_settings); - return $field_storage; - } - - /** - * Attaches a file field to an entity. - * - * @param string $name - * The name of the new field (all lowercase), exclude the "field_" prefix. - * @param string $entity_type - * The entity type this field will be added to. - * @param string $bundle - * The bundle this field will be added to. - * @param array $field_settings - * A list of field settings that will be added to the defaults. - * @param array $widget_settings - * A list of widget settings that will be added to the widget defaults. - */ - public function attachFileField($name, $entity_type, $bundle, $field_settings = [], $widget_settings = []) { - $field = [ - 'field_name' => $name, - 'label' => $name, - 'entity_type' => $entity_type, - 'bundle' => $bundle, - 'required' => !empty($field_settings['required']), - 'settings' => $field_settings, - ]; - FieldConfig::create($field)->save(); - - entity_get_form_display($entity_type, $bundle, 'default') - ->setComponent($name, [ - 'type' => 'file_generic', - 'settings' => $widget_settings, - ]) - ->save(); - // Assign display settings. - entity_get_display($entity_type, $bundle, 'default') - ->setComponent($name, [ - 'label' => 'hidden', - 'type' => 'file_default', - ]) - ->save(); - } - /** * Updates an existing file field with new settings. */ diff --git a/core/modules/file/tests/src/FunctionalJavascript/MaximumFileSizeExceededUploadTest.php b/core/modules/file/tests/src/FunctionalJavascript/MaximumFileSizeExceededUploadTest.php new file mode 100644 index 0000000000..7ccd2b2187 --- /dev/null +++ b/core/modules/file/tests/src/FunctionalJavascript/MaximumFileSizeExceededUploadTest.php @@ -0,0 +1,119 @@ +fileSystem = $this->container->get('file_system'); + + // Create the Article node type. + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); + + // Attach a file field to the node type. + $field_settings = ['file_extensions' => 'txt']; + $this->createFileField('field_file', 'node', 'article', [], $field_settings); + + // Log in as a content author who can create Articles. + $this->user = $this->drupalCreateUser([ + 'access content', + 'create article content', + ]); + $this->drupalLogin($this->user); + + // Disable the displaying of errors, so that the AJAX responses are not + // contaminated with error messages about exceeding the maximum POST size. + // @todo Remove this when issue #2905597 is fixed. + // @see https://www.drupal.org/node/2905597 + $this->originalDisplayErrorsValue = ini_set('display_errors', '0'); + } + + /** + * {@inheritdoc} + */ + protected function tearDown() { + // Restore the displaying of errors to the original value. + // @todo Remove this when issue #2905597 is fixed. + // @see https://www.drupal.org/node/2905597 + ini_set('display_errors', $this->originalDisplayErrorsValue); + + parent::tearDown(); + } + + /** + * Tests that uploading files exceeding maximum size are handled correctly. + */ + public function testUploadFileExceedingMaximumFileSize() { + $session = $this->getSession(); + + // Create a test file that exceeds the maximum POST size with 1 kilobyte. + $post_max_size = Bytes::toInt(ini_get('post_max_size')); + $invalid_file = $this->generateFile('exceeding_post_max_size', ceil(($post_max_size + 1024) / 1024), 1024); + + // Go to the node creation form and try to upload the test file. + $this->drupalGet('node/add/article'); + $page = $session->getPage(); + $page->attachFileToField("files[field_file_0]", $this->fileSystem->realpath($invalid_file)); + + // An error message should appear informing the user that the file exceeded + // the maximum file size. + $this->assertSession()->waitForElement('css', '.messages--error'); + // The error message includes the actual file size limit which depends on + // the current environment, so we check for a part of the message. + $this->assertSession()->pageTextContains('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size'); + + // Now upload a valid file and check that the error message disappears. + $valid_file = $this->generateFile('not_exceeding_post_max_size', 8, 8); + $page->attachFileToField("files[field_file_0]", $this->fileSystem->realpath($valid_file)); + $this->assertSession()->waitForElement('named', ['id_or_name', 'field_file_0_remove_button']); + $this->assertSession()->elementNotExists('css', '.messages--error'); + } + +} diff --git a/core/tests/Drupal/Tests/TestFileCreationTrait.php b/core/tests/Drupal/Tests/TestFileCreationTrait.php index 5bb5394be9..a2f119b65c 100644 --- a/core/tests/Drupal/Tests/TestFileCreationTrait.php +++ b/core/tests/Drupal/Tests/TestFileCreationTrait.php @@ -164,7 +164,8 @@ public static function generateFile($filename, $width, $lines, $type = 'binary-t } // Create filename. - file_put_contents('public://' . $filename . '.txt', $text); + $filename = 'public://' . $filename . '.txt'; + file_put_contents($filename, $text); return $filename; }