function ImageFieldDisplayTest::_testImageFieldFormatters

Same name and namespace in other branches
  1. 9 core/modules/image/tests/src/Functional/ImageFieldDisplayTest.php \Drupal\Tests\image\Functional\ImageFieldDisplayTest::_testImageFieldFormatters()
  2. 8.9.x core/modules/image/tests/src/Functional/ImageFieldDisplayTest.php \Drupal\Tests\image\Functional\ImageFieldDisplayTest::_testImageFieldFormatters()
  3. 11.x core/modules/image/tests/src/Functional/ImageFieldDisplayTest.php \Drupal\Tests\image\Functional\ImageFieldDisplayTest::_testImageFieldFormatters()

Tests image formatters on node display.

2 calls to ImageFieldDisplayTest::_testImageFieldFormatters()
ImageFieldDisplayTest::testImageFieldFormattersPrivate in core/modules/image/tests/src/Functional/ImageFieldDisplayTest.php
Tests image formatters on node display for private files.
ImageFieldDisplayTest::testImageFieldFormattersPublic in core/modules/image/tests/src/Functional/ImageFieldDisplayTest.php
Tests image formatters on node display for public files.

File

core/modules/image/tests/src/Functional/ImageFieldDisplayTest.php, line 59

Class

ImageFieldDisplayTest
Tests the display of image fields.

Namespace

Drupal\Tests\image\Functional

Code

public function _testImageFieldFormatters($scheme) {
  /** @var \Drupal\Core\Render\RendererInterface $renderer */
  $renderer = $this->container
    ->get('renderer');
  $node_storage = $this->container
    ->get('entity_type.manager')
    ->getStorage('node');
  $field_name = $this->randomMachineName();
  $field_settings = [
    'alt_field_required' => 0,
  ];
  $instance = $this->createImageField($field_name, 'node', 'article', [
    'uri_scheme' => $scheme,
  ], $field_settings);
  // Go to manage display page.
  $this->drupalGet("admin/structure/types/manage/article/display");
  // Test for existence of link to image styles configuration.
  $this->submitForm([], "{$field_name}_settings_edit");
  $this->assertSession()
    ->linkByHrefExists(Url::fromRoute('entity.image_style.collection')->toString(), 0, 'Link to image styles configuration is found');
  // Remove 'administer image styles' permission from testing admin user.
  $admin_user_roles = $this->adminUser
    ->getRoles(TRUE);
  user_role_change_permissions(reset($admin_user_roles), [
    'administer image styles' => FALSE,
  ]);
  // Go to manage display page again.
  $this->drupalGet("admin/structure/types/manage/article/display");
  // Test for absence of link to image styles configuration.
  $this->submitForm([], "{$field_name}_settings_edit");
  $this->assertSession()
    ->linkByHrefNotExists(Url::fromRoute('entity.image_style.collection')->toString(), 'Link to image styles configuration is absent when permissions are insufficient');
  // Restore 'administer image styles' permission to testing admin user
  user_role_change_permissions(reset($admin_user_roles), [
    'administer image styles' => TRUE,
  ]);
  // Create a new node with an image attached.
  $test_image = current($this->drupalGetTestFiles('image'));
  // Ensure that preview works.
  $this->previewNodeImage($test_image, $field_name, 'article');
  // After previewing, make the alt field required. It cannot be required
  // during preview because the form validation will fail.
  $instance->setSetting('alt_field_required', 1);
  $instance->save();
  // Create alt text for the image.
  $alt = $this->randomMachineName();
  // Save node.
  $nid = $this->uploadNodeImage($test_image, $field_name, 'article', $alt);
  $node_storage->resetCache([
    $nid,
  ]);
  $node = $node_storage->load($nid);
  // Test that the default formatter is being used.
  /** @var \Drupal\file\FileInterface $file */
  $file = $node->{$field_name}->entity;
  $image_uri = $file->getFileUri();
  $image = [
    '#theme' => 'image',
    '#uri' => $image_uri,
    '#width' => 40,
    '#height' => 20,
    '#alt' => $alt,
    '#attributes' => [
      'loading' => 'lazy',
    ],
  ];
  $default_output = str_replace("\n", '', (string) $renderer->renderRoot($image));
  $this->assertSession()
    ->responseContains($default_output);
  // Test the image linked to file formatter.
  $display_options = [
    'type' => 'image',
    'settings' => [
      'image_link' => 'file',
    ],
  ];
  $display = \Drupal::service('entity_display.repository')->getViewDisplay('node', $node->getType());
  $display->setComponent($field_name, $display_options)
    ->save();
  $image = [
    '#theme' => 'image',
    '#uri' => $image_uri,
    '#width' => 40,
    '#height' => 20,
    '#alt' => $alt,
    '#attributes' => [
      'loading' => 'lazy',
    ],
  ];
  $default_output = '<a href="' . $file->createFileUrl() . '">' . (string) $renderer->renderRoot($image) . '</a>';
  $this->drupalGet('node/' . $nid);
  $this->assertSession()
    ->responseHeaderContains('X-Drupal-Cache-Tags', $file->getCacheTags()[0]);
  // @todo Remove in https://www.drupal.org/node/2646744.
  $this->assertCacheContext('url.site');
  // Verify that no image style cache tags are found.
  $this->assertSession()
    ->responseHeaderNotContains('X-Drupal-Cache-Tags', 'image_style:');
  $this->assertSession()
    ->responseContains($default_output);
  // Verify that the image can be downloaded.
  $this->assertEquals(file_get_contents($test_image->uri), $this->drupalGet($file->createFileUrl(FALSE)), 'File was downloaded successfully.');
  if ($scheme == 'private') {
    // Only verify HTTP headers when using private scheme and the headers are
    // sent by Drupal.
    $this->assertSession()
      ->responseHeaderEquals('Content-Type', 'image/png');
    $this->assertSession()
      ->responseHeaderContains('Cache-Control', 'private');
    // Log out and ensure the file cannot be accessed.
    $this->drupalLogout();
    $this->drupalGet($file->createFileUrl(FALSE));
    $this->assertSession()
      ->statusCodeEquals(403);
    // Log in again.
    $this->drupalLogin($this->adminUser);
  }
  // Test the image linked to content formatter.
  $display_options['settings']['image_link'] = 'content';
  $display->setComponent($field_name, $display_options)
    ->save();
  $image = [
    '#theme' => 'image',
    '#uri' => $image_uri,
    '#width' => 40,
    '#height' => 20,
  ];
  $this->drupalGet('node/' . $nid);
  $this->assertSession()
    ->responseHeaderContains('X-Drupal-Cache-Tags', $file->getCacheTags()[0]);
  // Verify that no image style cache tags are found.
  $this->assertSession()
    ->responseHeaderNotContains('X-Drupal-Cache-Tags', 'image_style:');
  $this->assertSession()
    ->elementsCount('xpath', '//a[@href="' . $node->toUrl()
    ->toString() . '"]/img[@src="' . $file->createFileUrl() . '" and @alt="' . $alt . '" and @width="' . $image['#width'] . '" and @height="' . $image['#height'] . '"]', 1);
  // Test the image style 'thumbnail' formatter.
  $display_options['settings']['image_link'] = '';
  $display_options['settings']['image_style'] = 'thumbnail';
  $display->setComponent($field_name, $display_options)
    ->save();
  // Ensure the derivative image is generated so we do not have to deal with
  // image style callback paths.
  $this->drupalGet(ImageStyle::load('thumbnail')->buildUrl($image_uri));
  $image_style = [
    '#theme' => 'image_style',
    '#uri' => $image_uri,
    '#width' => 40,
    '#height' => 20,
    '#style_name' => 'thumbnail',
    '#alt' => $alt,
    '#attributes' => [
      'loading' => 'lazy',
    ],
  ];
  $default_output = (string) $renderer->renderRoot($image_style);
  $this->drupalGet('node/' . $nid);
  $image_style = ImageStyle::load('thumbnail');
  $this->assertSession()
    ->responseHeaderContains('X-Drupal-Cache-Tags', $image_style->getCacheTags()[0]);
  $this->assertSession()
    ->responseContains($default_output);
  if ($scheme == 'private') {
    // Log out and ensure the file cannot be accessed.
    $this->drupalLogout();
    $this->drupalGet(ImageStyle::load('thumbnail')->buildUrl($image_uri));
    $this->assertSession()
      ->statusCodeEquals(403);
    // Log in again.
    $this->drupalLogin($this->adminUser);
  }
  // Test the image URL formatter without an image style.
  $display_options = [
    'type' => 'image_url',
    'settings' => [
      'image_style' => '',
    ],
  ];
  $expected_url = $file->createFileUrl();
  $this->assertEquals($expected_url, $node->{$field_name}
    ->view($display_options)[0]['#markup']);
  // Test the image URL formatter with an image style.
  $display_options['settings']['image_style'] = 'thumbnail';
  $expected_url = \Drupal::service('file_url_generator')->transformRelative(ImageStyle::load('thumbnail')->buildUrl($image_uri));
  $this->assertEquals($expected_url, $node->{$field_name}
    ->view($display_options)[0]['#markup']);
  // Test the settings summary.
  $display_options = [
    'type' => 'image_url',
    'settings' => [
      'image_style' => 'thumbnail',
    ],
  ];
  $display = \Drupal::service('entity_display.repository')->getViewDisplay('node', $node->getType(), 'default');
  $display->setComponent($field_name, $display_options)
    ->save();
  $this->drupalGet("admin/structure/types/manage/" . $node->getType() . "/display");
  $this->assertSession()
    ->responseContains('Image style: Thumbnail (100×100)');
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.