function ResponsiveImageFieldDisplayTest::doTestResponsiveImageFieldFormatters

Same name in other branches
  1. 8.9.x core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php \Drupal\Tests\responsive_image\Functional\ResponsiveImageFieldDisplayTest::doTestResponsiveImageFieldFormatters()
  2. 10 core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php \Drupal\Tests\responsive_image\Functional\ResponsiveImageFieldDisplayTest::doTestResponsiveImageFieldFormatters()
  3. 11.x core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php \Drupal\Tests\responsive_image\Functional\ResponsiveImageFieldDisplayTest::doTestResponsiveImageFieldFormatters()

Tests responsive image formatters on node display.

If the empty styles param is set, then the function only tests for the fallback image style (large).

Parameters

string $scheme: File scheme to use.

bool $empty_styles: If true, use an empty string for image style names. Defaults to false.

3 calls to ResponsiveImageFieldDisplayTest::doTestResponsiveImageFieldFormatters()
ResponsiveImageFieldDisplayTest::testResponsiveImageFieldFormattersEmptyStyle in core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php
Tests responsive image formatters when image style is empty.
ResponsiveImageFieldDisplayTest::testResponsiveImageFieldFormattersPrivate in core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php
Tests responsive image formatters on node display for private files.
ResponsiveImageFieldDisplayTest::testResponsiveImageFieldFormattersPublic in core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php
Tests responsive image formatters on node display for public files.

File

core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php, line 187

Class

ResponsiveImageFieldDisplayTest
Tests responsive image display formatter.

Namespace

Drupal\Tests\responsive_image\Functional

Code

protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = FALSE) {
    
    /** @var \Drupal\Core\Render\RendererInterface $renderer */
    $renderer = $this->container
        ->get('renderer');
    $node_storage = $this->container
        ->get('entity_type.manager')
        ->getStorage('node');
    $field_name = mb_strtolower($this->randomMachineName());
    $this->createImageField($field_name, 'article', [
        'uri_scheme' => $scheme,
    ]);
    // Create a new node with an image attached. Make sure we use a large image
    // so the scale effects of the image styles always have an effect.
    $test_image = current($this->getTestFiles('image', 39325));
    // Create alt text for the image.
    $alt = $this->randomMachineName();
    $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.
    $image_uri = File::load($node->{$field_name}->target_id)
        ->getFileUri();
    $image = [
        '#theme' => 'image',
        '#uri' => $image_uri,
        '#width' => 360,
        '#height' => 240,
        '#alt' => $alt,
        '#attributes' => [
            'loading' => 'lazy',
        ],
    ];
    $default_output = str_replace("\n", '', $renderer->renderRoot($image));
    $this->assertSession()
        ->responseContains($default_output);
    // Test field not being configured. This should not cause a fatal error.
    $display_options = [
        'type' => 'responsive_image_test',
        'settings' => ResponsiveImageFormatter::defaultSettings(),
    ];
    $display = $this->container
        ->get('entity_type.manager')
        ->getStorage('entity_view_display')
        ->load('node.article.default');
    if (!$display) {
        $values = [
            'targetEntityType' => 'node',
            'bundle' => 'article',
            'mode' => 'default',
            'status' => TRUE,
        ];
        $display = $this->container
            ->get('entity_type.manager')
            ->getStorage('entity_view_display')
            ->create($values);
    }
    $display->setComponent($field_name, $display_options)
        ->save();
    $this->drupalGet('node/' . $nid);
    // Test theme function for responsive image, but using the test formatter.
    $display_options = [
        'type' => 'responsive_image_test',
        'settings' => [
            'image_link' => 'file',
            'responsive_image_style' => 'style_one',
        ],
    ];
    
    /** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $display_repository */
    $display_repository = \Drupal::service('entity_display.repository');
    $display = $display_repository->getViewDisplay('node', 'article');
    $display->setComponent($field_name, $display_options)
        ->save();
    $this->drupalGet('node/' . $nid);
    // Use the responsive image formatter linked to file formatter.
    $display_options = [
        'type' => 'responsive_image',
        'settings' => [
            'image_link' => 'file',
            'responsive_image_style' => 'style_one',
        ],
    ];
    $display = $display_repository->getViewDisplay('node', 'article');
    $display->setComponent($field_name, $display_options)
        ->save();
    $this->drupalGet('node/' . $nid);
    // No image style cache tag should be found.
    $this->assertSession()
        ->responseHeaderNotContains('X-Drupal-Cache-Tags', 'image_style:');
    $this->assertSession()
        ->responseMatches('/<a(.*?)href="' . preg_quote($this->fileUrlGenerator
        ->generateString($image_uri), '/') . '"(.*?)>\\s*<picture/');
    // Verify that the image can be downloaded.
    $this->assertEquals(file_get_contents($test_image->uri), $this->drupalGet($this->fileUrlGenerator
        ->generateAbsoluteString($image_uri)), '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($this->fileUrlGenerator
            ->generateAbsoluteString($image_uri));
        $this->assertSession()
            ->statusCodeEquals(403);
        // Log in again.
        $this->drupalLogin($this->adminUser);
    }
    // Use the responsive image formatter with a responsive image style.
    $display_options['settings']['responsive_image_style'] = 'style_one';
    $display_options['settings']['image_link'] = '';
    $display->setComponent($field_name, $display_options)
        ->save();
    // Create a derivative so at least one MIME type will be known.
    $large_style = ImageStyle::load('large');
    $large_style->createDerivative($image_uri, $large_style->buildUri($image_uri));
    // Output should contain all image styles and all breakpoints.
    $this->drupalGet('node/' . $nid);
    if (!$empty_styles) {
        $this->assertSession()
            ->responseContains('/styles/medium/');
        // Assert the empty image is present.
        $this->assertSession()
            ->responseContains('data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==');
        $thumbnail_style = ImageStyle::load('thumbnail');
        // Assert the output of the 'srcset' attribute (small multipliers first).
        $this->assertSession()
            ->responseContains('data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== 1x, ' . $this->fileUrlGenerator
            ->transformRelative($thumbnail_style->buildUrl($image_uri)) . ' 1.5x');
        $this->assertSession()
            ->responseContains('/styles/medium/');
        // Assert the output of the original image.
        $this->assertSession()
            ->responseContains($this->fileUrlGenerator
            ->generateString($image_uri) . ' 3x');
        // Assert the output of the breakpoints.
        $this->assertSession()
            ->responseContains('media="(min-width: 0px)"');
        $this->assertSession()
            ->responseContains('media="(min-width: 560px)"');
        // Assert the output of the 'sizes' attribute.
        $this->assertSession()
            ->responseContains('sizes="(min-width: 700px) 700px, 100vw"');
        $this->assertSession()
            ->responseMatches('/media="\\(min-width: 560px\\)".+?sizes="\\(min-width: 700px\\) 700px, 100vw"/');
        // Assert the output of the 'srcset' attribute (small images first).
        $medium_style = ImageStyle::load('medium');
        $this->assertSession()
            ->responseContains($this->fileUrlGenerator
            ->transformRelative($medium_style->buildUrl($image_uri)) . ' 220w, ' . $this->fileUrlGenerator
            ->transformRelative($large_style->buildUrl($image_uri)) . ' 360w');
        $this->assertSession()
            ->responseContains('media="(min-width: 851px)"');
    }
    $this->assertSession()
        ->responseContains('/styles/large/');
    $this->assertSession()
        ->responseHeaderContains('X-Drupal-Cache-Tags', 'config:responsive_image.styles.style_one');
    if (!$empty_styles) {
        $this->assertSession()
            ->responseHeaderContains('X-Drupal-Cache-Tags', 'config:image.style.medium');
        $this->assertSession()
            ->responseHeaderContains('X-Drupal-Cache-Tags', 'config:image.style.thumbnail');
        $this->assertSession()
            ->responseContains('type="image/png"');
    }
    $this->assertSession()
        ->responseHeaderContains('X-Drupal-Cache-Tags', 'config:image.style.large');
    // Test the fallback image style.
    $image = \Drupal::service('image.factory')->get($image_uri);
    $fallback_image = [
        '#theme' => 'image',
        '#alt' => $alt,
        '#uri' => $this->fileUrlGenerator
            ->transformRelative($large_style->buildUrl($image->getSource())),
    ];
    // The image.html.twig template has a newline after the <img> tag but
    // responsive-image.html.twig doesn't have one after the fallback image, so
    // we remove it here.
    $default_output = trim($renderer->renderRoot($fallback_image));
    $this->assertSession()
        ->responseContains($default_output);
    if ($scheme == 'private') {
        // Log out and ensure the file cannot be accessed.
        $this->drupalLogout();
        $this->drupalGet($large_style->buildUrl($image_uri));
        $this->assertSession()
            ->statusCodeEquals(403);
        $this->assertSession()
            ->responseHeaderNotMatches('X-Drupal-Cache-Tags', '/ image_style\\:/');
    }
}

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