diff --git a/core/modules/image/src/Tests/Update/ImageUpdateTextFormatsTest.php b/core/modules/image/src/Tests/Update/ImageUpdateTextFormatsTest.php new file mode 100644 index 0000000000..fd0441c2cb --- /dev/null +++ b/core/modules/image/src/Tests/Update/ImageUpdateTextFormatsTest.php @@ -0,0 +1,47 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + ]; + } + + /** + * Tests image_post_update_enable_filter_image_style(). + * + * @see image_post_update_enable_filter_image_style() + */ + public function testPostUpdateFilterImageStyle() { + // Check that the 'basic_html' and 'full_html' formats do not have the image + // style filter before starting the update. + $config_factory = \Drupal::configFactory(); + $basic_html_data = $config_factory->get('filter.format.basic_html'); + $this->assertNull($basic_html_data->get('filters.filter_image_style')); + $full_html_data = $config_factory->get('filter.format.full_html'); + $this->assertNull($full_html_data->get('filters.filter_image_style')); + + // Run updates. + $this->runUpdates(); + + // Check that the filter_format entities have been updated. + $basic_html_data = $config_factory->get('filter.format.basic_html'); + $this->assertNotNull($basic_html_data->get('filters.filter_image_style')); + $full_html_data = $config_factory->get('filter.format.full_html'); + $this->assertNotNull($full_html_data->get('filters.filter_image_style')); + } + +} diff --git a/core/modules/image/tests/src/Functional/FilterImageStyleTest.php b/core/modules/image/tests/src/Functional/FilterImageStyleTest.php new file mode 100644 index 0000000000..2c7aee6575 --- /dev/null +++ b/core/modules/image/tests/src/Functional/FilterImageStyleTest.php @@ -0,0 +1,120 @@ +format = FilterFormat::create([ + 'format' => $this->randomMachineName(), + 'name' => $this->randomString(), + 'filters' => [ + 'filter_html' => [ + 'status' => TRUE, + 'settings' => [ + 'allowed_html' => '', + ], + ], + 'filter_image_style' => ['status' => TRUE], + 'editor_file_reference' => ['status' => TRUE], + ], + ]); + $this->format->save(); + + $user = $this->drupalCreateUser(['access content', 'administer nodes']); + $this->drupalLogin($user); + + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + } + + /** + * Helper function to create a test node with configurable image html. + */ + protected function nodeHelper($image_html) { + $node = $this->drupalCreateNode([ + 'type' => 'page', + 'title' => $this->randomString(), + 'body' => [ + [ + 'format' => $this->format->id(), + 'value' => $image_html, + ], + ], + ]); + $node->save(); + + $this->drupalGet($node->toUrl()); + $this->assertSession()->statusCodeEquals(200); + } + + /** + * Tests that images not uploaded through media module are unmolested. + */ + public function testImageNoStyle() { + $file_url = Url::fromUri('base:core/themes/bartik/screenshot.png')->toString(); + + $image_html = ''; + $this->nodeHelper($image_html); + + /** @var \Behat\Mink\Element\NodeElement $img_element */ + $image_element = $this->getSession()->getPage()->find('css', "img"); + $this->assertNotEmpty($image_element); + + $this->assertFalse($image_element->hasAttribute('class')); + $this->assertEquals($file_url, $image_element->getAttribute('src')); + $this->assertEquals('220', $image_element->getAttribute('width')); + $this->assertFalse($image_element->hasAttribute('height')); + } + + /** + * Tests image style modification of images. + */ + public function testImageStyle() { + $this->assertArrayHasKey('medium', $this->container->get('entity_type.manager')->getStorage('image_style')->loadMultiple()); + + $file = File::create(['uri' => 'core/themes/bartik/screenshot.png']); + $file->save(); + + $image_html = ''; + $this->nodeHelper($image_html); + + /** @var \Behat\Mink\Element\NodeElement $img_element */ + $image_element = $this->getSession()->getPage()->find('css', 'img.image-style-medium'); + $this->assertFalse(empty($image_element)); + + $this->assertTrue(strpos($image_element->getAttribute('src'), 'medium')); + $this->assertEquals('220', $image_element->getAttribute('width')); + $this->assertEquals('164', $image_element->getAttribute('height')); + } + +} diff --git a/core/modules/image/tests/src/FunctionalJavascript/AddImageTest.php b/core/modules/image/tests/src/FunctionalJavascript/AddImageTest.php new file mode 100644 index 0000000000..f8562e5059 --- /dev/null +++ b/core/modules/image/tests/src/FunctionalJavascript/AddImageTest.php @@ -0,0 +1,105 @@ + 'filtered_html', + 'name' => $this->randomString(), + 'filters' => [ + 'filter_image_style' => ['status' => TRUE], + ], + ])->save(); + + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + + Editor::create([ + 'format' => 'filtered_html', + 'editor' => 'ckeditor', + ])->save(); + + $user = $this->drupalCreateUser([ + 'access content', + 'administer nodes', + 'create page content', + 'use text format filtered_html', + ]); + $this->drupalLogin($user); + } + + /** + * Tests if an image can be placed inline with the data-image-style attribute. + */ + public function testDataImageStyleElement() { + $image_url = Url::fromUri('base:core/themes/bartik/screenshot.png')->toString(); + + $this->drupalGet('node/add/page'); + $this->assertSession()->statusCodeEquals(200); + + $page = $this->getSession()->getPage(); + // Wait for the ckeditor toolbar elements to appear (loading is done). + $image_button_selector = 'a.cke_button__drupalimage'; + $this->assertJsCondition("jQuery('$image_button_selector').length > 0"); + + $image_button = $page->find('css', $image_button_selector); + $this->assertNotEmpty($image_button); + $image_button->click(); + // Wait for the modal form elements to appear (loading is done). + $this->assertJsCondition("jQuery('input[data-drupal-selector=\"edit-attributes-alt\"]').length > 0"); + + $url_input = $page->findField('attributes[src]'); + $this->assertNotEmpty($url_input); + $url_input->setValue($image_url); + + $alt_input = $page->findField('attributes[alt]'); + $this->assertNotEmpty($alt_input); + $alt_input->setValue('asd'); + + $image_style_input_name = 'attributes[data-image-style]'; + $this->assertNotEmpty($page->findField($image_style_input_name)); + $page->selectFieldOption($image_style_input_name, 'thumbnail'); + + // To prevent 403s on save, we re-set our request (cookie) state. + $this->prepareRequest(); + + // Using NodeElement::click() on the button or NodeElement::submit() on the + // form generated phantomjs-internal exceptions. This was the only recourse. + // @see https://www.drupal.org/node/2831506 + $script = "jQuery('input[id^=\"edit-actions-save-modal\"]').click()"; + $this->getSession()->executeScript($script); + $this->assertSession()->assertWaitOnAjaxRequest(); + + $source_button = $page->find('css', 'a.cke_button__source'); + $this->assertNotEmpty($source_button); + $source_button->click(); + $this->assertSession()->assertWaitOnAjaxRequest(); + + $this->assertContains('data-image-style="thumbnail"', $page->find('css', 'textarea.cke_source')->getValue()); + } + +} diff --git a/core/modules/image/tests/src/Kernel/EditorImageStyleDialogTest.php b/core/modules/image/tests/src/Kernel/EditorImageStyleDialogTest.php new file mode 100644 index 0000000000..9d4418da56 --- /dev/null +++ b/core/modules/image/tests/src/Kernel/EditorImageStyleDialogTest.php @@ -0,0 +1,169 @@ +installEntitySchema('file'); + $this->installSchema('system', ['key_value_expire']); + $this->installSchema('node', ['node_access']); + $this->installSchema('file', ['file_usage']); + $this->installConfig(['node']); + + // Install the image module config so we have the medium image style. + $this->installConfig('image'); + + // Create a node type for testing. + $type = NodeType::create(['type' => 'page', 'name' => 'page']); + $type->save(); + node_add_body_field($type); + $this->installEntitySchema('user'); + $this->container->get('router.builder')->rebuild(); + } + + /** + * Fixture to consolidate tasks while making filter status configurable. + * + * @param bool $enable_image_filter + * Whether to activate filter_image_style in the text format. + * + * @return array|\Symfony\Component\HttpFoundation\Response + * The submitted form. + */ + protected function setUpForm($enable_image_filter) { + $format = FilterFormat::create([ + 'format' => $this->randomMachineName(), + 'name' => $this->randomString(), + 'weight' => 0, + 'filters' => [ + 'filter_image_style' => ['status' => $enable_image_filter], + ], + ]); + $format->save(); + + // Set up text editor. + /** @var \Drupal\editor\EditorInterface $editor */ + $editor = Editor::create([ + 'format' => $format->id(), + 'editor' => 'ckeditor', + 'image_upload' => [ + 'max_size' => 100, + 'scheme' => 'public', + 'directory' => '', + 'status' => TRUE, + ], + ]); + $editor->save(); + + /** @var \Drupal\file\FileInterface $file */ + $file = file_save_data(file_get_contents($this->root . '/core/modules/image/sample.png'), 'public://'); + + $input = [ + 'editor_object' => [ + 'src' => file_url_transform_relative($file->getFileUri()), + 'alt' => 'Balloons floating above a field.', + 'data-entity-type' => 'file', + 'data-entity-uuid' => $file->uuid(), + ], + 'dialogOptions' => [ + 'title' => 'Edit Image', + 'dialogClass' => 'editor-image-dialog', + 'autoResize' => 'true', + ], + '_drupal_ajax' => '1', + 'ajax_page_state' => [ + 'theme' => 'bartik', + 'theme_token' => 'some-token', + 'libraries' => '', + ], + ]; + if ($enable_image_filter) { + $input['editor_object']['data-image-style'] = 'medium'; + } + + $form_state = (new FormState()) + ->setRequestMethod('POST') + ->setUserInput($input) + ->addBuildInfo('args', [$editor]); + + /** @var \Drupal\Core\Form\FormBuilderInterface $form_builder */ + $form_builder = $this->container->get('form_builder'); + $form_object = new EditorImageDialog(\Drupal::entityTypeManager()->getStorage('file')); + $form_id = $form_builder->getFormId($form_object, $form_state); + $form = []; + + /** @var \Drupal\Core\Render\RendererInterface $renderer */ + $renderer = \Drupal::service('renderer'); + $renderer->executeInRenderContext(new RenderContext(), function () use (&$form, $form_builder, $form_id, $form_state) { + $form = $form_builder->retrieveForm($form_id, $form_state); + $form_builder->prepareForm($form_id, $form, $form_state); + $form_builder->processForm($form_id, $form, $form_state); + }); + + return $form; + } + + /** + * Tests that style selection is hidden when filter_image_style is disabled. + */ + public function testDialogNoStyles() { + $form = $this->setUpForm(FALSE); + + $this->assertArrayNotHasKey('image_style', $form); + } + + /** + * Tests EditorImageDialog when filter_image_style is enabled. + */ + public function testDialogStyles() { + $form = $this->setUpForm(TRUE); + + $this->assertEquals(['large', 'medium', 'thumbnail'], array_keys($form['image_style']['selection']['#options'])); + + $this->assertEquals('medium', $form['image_style']['selection']['#default_value']); + $this->assertEquals(TRUE, $form['image_style']['selection']['#required']); + } + +} diff --git a/core/modules/system/tests/src/Functional/Update/FilterHtmlUpdateTest.php b/core/modules/system/tests/src/Functional/Update/FilterHtmlUpdateTest.php index 09e40aa983..00b72dbca5 100644 --- a/core/modules/system/tests/src/Functional/Update/FilterHtmlUpdateTest.php +++ b/core/modules/system/tests/src/Functional/Update/FilterHtmlUpdateTest.php @@ -39,7 +39,7 @@ public function testAllowedHtmlUpdate() { // Make sure we have the expected values after the update. $filters_after = [ - 'basic_html' => '