View source
<?php
namespace Drupal\Tests\responsive_image\Functional;
use Drupal\image\Entity\ImageStyle;
use Drupal\node\Entity\Node;
use Drupal\file\Entity\File;
use Drupal\responsive_image\Plugin\Field\FieldFormatter\ResponsiveImageFormatter;
use Drupal\responsive_image\Entity\ResponsiveImageStyle;
use Drupal\responsive_image\ResponsiveImageStyleInterface;
use Drupal\Tests\image\Functional\ImageFieldTestBase;
use Drupal\Tests\TestFileCreationTrait;
use Drupal\user\RoleInterface;
class ResponsiveImageFieldDisplayTest extends ImageFieldTestBase {
use TestFileCreationTrait;
protected $defaultTheme = 'stark';
protected $dumpHeaders = TRUE;
protected $responsiveImgStyle;
public static $modules = [
'field_ui',
'responsive_image',
'responsive_image_test_module',
];
protected function setUp() {
parent::setUp();
$this->adminUser = $this
->drupalCreateUser([
'administer responsive images',
'access content',
'access administration pages',
'administer site configuration',
'administer content types',
'administer node display',
'administer nodes',
'create article content',
'edit any article content',
'delete any article content',
'administer image styles',
]);
$this
->drupalLogin($this->adminUser);
$this->responsiveImgStyle = ResponsiveImageStyle::create([
'id' => 'style_one',
'label' => 'Style One',
'breakpoint_group' => 'responsive_image_test_module',
'fallback_image_style' => 'large',
]);
}
public function testResponsiveImageFieldFormattersPublic() {
$this
->addTestImageStyleMappings();
$this
->doTestResponsiveImageFieldFormatters('public');
}
public function testResponsiveImageFieldFormattersPrivate() {
$this
->addTestImageStyleMappings();
user_role_change_permissions(RoleInterface::ANONYMOUS_ID, [
'access content' => FALSE,
]);
$this
->doTestResponsiveImageFieldFormatters('private');
}
public function testResponsiveImageFieldFormattersEmptyStyle() {
$this
->addTestImageStyleMappings(TRUE);
$this
->doTestResponsiveImageFieldFormatters('public', TRUE);
}
protected function addTestImageStyleMappings($empty_styles = FALSE) {
if ($empty_styles) {
$this->responsiveImgStyle
->addImageStyleMapping('responsive_image_test_module.mobile', '1x', [
'image_mapping_type' => 'image_style',
'image_mapping' => '',
])
->addImageStyleMapping('responsive_image_test_module.narrow', '1x', [
'image_mapping_type' => 'sizes',
'image_mapping' => [
'sizes' => '(min-width: 700px) 700px, 100vw',
'sizes_image_styles' => [],
],
])
->addImageStyleMapping('responsive_image_test_module.wide', '1x', [
'image_mapping_type' => 'image_style',
'image_mapping' => '',
])
->save();
}
else {
$this->responsiveImgStyle
->addImageStyleMapping('responsive_image_test_module.mobile', '1x', [
'image_mapping_type' => 'image_style',
'image_mapping' => ResponsiveImageStyleInterface::EMPTY_IMAGE,
])
->addImageStyleMapping('responsive_image_test_module.mobile', '1.5x', [
'image_mapping_type' => 'image_style',
'image_mapping' => 'thumbnail',
])
->addImageStyleMapping('responsive_image_test_module.narrow', '1x', [
'image_mapping_type' => 'sizes',
'image_mapping' => [
'sizes' => '(min-width: 700px) 700px, 100vw',
'sizes_image_styles' => [
'large',
'medium',
],
],
])
->addImageStyleMapping('responsive_image_test_module.wide', '1x', [
'image_mapping_type' => 'image_style',
'image_mapping' => 'large',
])
->addImageStyleMapping('responsive_image_test_module.wide', '3x', [
'image_mapping_type' => 'image_style',
'image_mapping' => ResponsiveImageStyleInterface::ORIGINAL_IMAGE,
])
->save();
}
}
protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = FALSE) {
$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,
]);
$test_image = current($this
->getTestFiles('image', 39325));
$alt = $this
->randomMachineName();
$nid = $this
->uploadNodeImage($test_image, $field_name, 'article', $alt);
$node_storage
->resetCache([
$nid,
]);
$node = $node_storage
->load($nid);
$image_uri = File::load($node->{$field_name}->target_id)
->getFileUri();
$image = [
'#theme' => 'image',
'#uri' => $image_uri,
'#width' => 360,
'#height' => 240,
'#alt' => $alt,
];
$default_output = str_replace("\n", NULL, $renderer
->renderRoot($image));
$this
->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');
$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);
$display_options = [
'type' => 'responsive_image_test',
'settings' => [
'image_link' => 'file',
'responsive_image_style' => 'style_one',
],
];
$display_repository = \Drupal::service('entity_display.repository');
$display = $display_repository
->getViewDisplay('node', 'article');
$display
->setComponent($field_name, $display_options)
->save();
$this
->drupalGet('node/' . $nid);
$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);
$cache_tags_header = $this
->drupalGetHeader('X-Drupal-Cache-Tags');
$this
->assertTrue(!preg_match('/ image_style\\:/', $cache_tags_header), 'No image style cache tag found.');
$this
->assertPattern('/<a(.*?)href="' . preg_quote(file_url_transform_relative(file_create_url($image_uri)), '/') . '"(.*?)>\\s*<picture/');
$this
->assertEqual(file_get_contents($test_image->uri), $this
->drupalGet(file_create_url($image_uri)), 'File was downloaded successfully.');
if ($scheme == 'private') {
$this
->assertEqual($this
->drupalGetHeader('Content-Type'), 'image/png', 'Content-Type header was sent.');
$this
->assertTrue(strstr($this
->drupalGetHeader('Cache-Control'), 'private') !== FALSE, 'Cache-Control header was sent.');
$this
->drupalLogout();
$this
->drupalGet(file_create_url($image_uri));
$this
->assertSession()
->statusCodeEquals(403);
$this
->drupalLogin($this->adminUser);
}
$display_options['settings']['responsive_image_style'] = 'style_one';
$display_options['settings']['image_link'] = '';
$display
->setComponent($field_name, $display_options)
->save();
$large_style = ImageStyle::load('large');
$large_style
->createDerivative($image_uri, $large_style
->buildUri($image_uri));
$this
->drupalGet('node/' . $nid);
if (!$empty_styles) {
$this
->assertRaw('/styles/medium/');
$this
->assertRaw('data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==');
$thumbnail_style = ImageStyle::load('thumbnail');
$this
->assertRaw('data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== 1x, ' . file_url_transform_relative($thumbnail_style
->buildUrl($image_uri)) . ' 1.5x');
$this
->assertRaw('/styles/medium/');
$this
->assertRaw(file_url_transform_relative(file_create_url($image_uri)) . ' 3x');
$this
->assertRaw('media="(min-width: 0px)"');
$this
->assertRaw('media="(min-width: 560px)"');
$this
->assertRaw('sizes="(min-width: 700px) 700px, 100vw"');
$this
->assertPattern('/media="\\(min-width: 560px\\)".+?sizes="\\(min-width: 700px\\) 700px, 100vw"/');
$medium_style = ImageStyle::load('medium');
$this
->assertRaw(file_url_transform_relative($medium_style
->buildUrl($image_uri)) . ' 220w, ' . file_url_transform_relative($large_style
->buildUrl($image_uri)) . ' 360w');
$this
->assertRaw('media="(min-width: 851px)"');
}
$this
->assertRaw('/styles/large/');
$cache_tags = explode(' ', $this
->drupalGetHeader('X-Drupal-Cache-Tags'));
$this
->assertContains('config:responsive_image.styles.style_one', $cache_tags);
if (!$empty_styles) {
$this
->assertContains('config:image.style.medium', $cache_tags);
$this
->assertContains('config:image.style.thumbnail', $cache_tags);
$this
->assertRaw('type="image/png"');
}
$this
->assertContains('config:image.style.large', $cache_tags);
$image = \Drupal::service('image.factory')
->get($image_uri);
$fallback_image = [
'#theme' => 'image',
'#alt' => $alt,
'#uri' => file_url_transform_relative($large_style
->buildUrl($image
->getSource())),
];
$default_output = trim($renderer
->renderRoot($fallback_image));
$this
->assertRaw($default_output, 'Image style large formatter displaying correctly on full node view.');
if ($scheme == 'private') {
$this
->drupalLogout();
$this
->drupalGet($large_style
->buildUrl($image_uri));
$this
->assertSession()
->statusCodeEquals(403);
$cache_tags_header = $this
->drupalGetHeader('X-Drupal-Cache-Tags');
$this
->assertTrue(!preg_match('/ image_style\\:/', $cache_tags_header), 'No image style cache tag found.');
}
}
public function testResponsiveImageFieldFormattersLinkToFile() {
$this
->addTestImageStyleMappings();
$this
->assertResponsiveImageFieldFormattersLink('file');
}
public function testResponsiveImageFieldFormattersLinkToNode() {
$this
->addTestImageStyleMappings();
$this
->assertResponsiveImageFieldFormattersLink('content');
}
public function testResponsiveImageFieldFormattersEmptyMediaQuery() {
$this->responsiveImgStyle
->addImageStyleMapping('responsive_image_test_module.empty', '1x', [
'image_mapping_type' => 'image_style',
'image_mapping' => ResponsiveImageStyleInterface::EMPTY_IMAGE,
])
->addImageStyleMapping('responsive_image_test_module.mobile', '1x', [
'image_mapping_type' => 'image_style',
'image_mapping' => 'thumbnail',
])
->save();
$node_storage = $this->container
->get('entity_type.manager')
->getStorage('node');
$field_name = mb_strtolower($this
->randomMachineName());
$this
->createImageField($field_name, 'article', [
'uri_scheme' => 'public',
]);
$test_image = current($this
->getTestFiles('image'));
$nid = $this
->uploadNodeImage($test_image, $field_name, 'article', $this
->randomMachineName());
$node_storage
->resetCache([
$nid,
]);
$display_options = [
'type' => 'responsive_image',
'settings' => [
'image_link' => '',
'responsive_image_style' => 'style_one',
],
];
$display = \Drupal::service('entity_display.repository')
->getViewDisplay('node', 'article');
$display
->setComponent($field_name, $display_options)
->save();
$this
->drupalGet('node/' . $nid);
$this
->assertSession()
->responseNotMatches('@srcset="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== 1x".+?media=".+?/><source@');
$thumbnail_style = ImageStyle::load('thumbnail');
$node = $node_storage
->load($nid);
$image_uri = File::load($node->{$field_name}->target_id)
->getFileUri();
$this
->assertPattern('/srcset="' . preg_quote(file_url_transform_relative($thumbnail_style
->buildUrl($image_uri)), '/') . ' 1x".+?media="\\(min-width: 0px\\)"/');
}
public function testResponsiveImageFieldFormattersOneSource() {
$this->responsiveImgStyle
->addImageStyleMapping('responsive_image_test_module.empty', '1x', [
'image_mapping_type' => 'image_style',
'image_mapping' => 'medium',
])
->addImageStyleMapping('responsive_image_test_module.empty', '2x', [
'image_mapping_type' => 'image_style',
'image_mapping' => 'large',
])
->save();
$node_storage = $this->container
->get('entity_type.manager')
->getStorage('node');
$field_name = mb_strtolower($this
->randomMachineName());
$this
->createImageField($field_name, 'article', [
'uri_scheme' => 'public',
]);
$test_image = current($this
->getTestFiles('image'));
$nid = $this
->uploadNodeImage($test_image, $field_name, 'article', $this
->randomMachineName());
$node_storage
->resetCache([
$nid,
]);
$display_options = [
'type' => 'responsive_image',
'settings' => [
'image_link' => '',
'responsive_image_style' => 'style_one',
],
];
$display = \Drupal::service('entity_display.repository')
->getViewDisplay('node', 'article');
$display
->setComponent($field_name, $display_options)
->save();
$this
->drupalGet('node/' . $nid);
$large_style = ImageStyle::load('large');
$medium_style = ImageStyle::load('medium');
$node = $node_storage
->load($nid);
$image_uri = File::load($node->{$field_name}->target_id)
->getFileUri();
$this
->assertRaw('<img srcset="' . file_url_transform_relative($medium_style
->buildUrl($image_uri)) . ' 1x, ' . file_url_transform_relative($large_style
->buildUrl($image_uri)) . ' 2x"');
}
private function assertResponsiveImageFieldFormattersLink($link_type) {
$field_name = mb_strtolower($this
->randomMachineName());
$field_settings = [
'alt_field_required' => 0,
];
$this
->createImageField($field_name, 'article', [
'uri_scheme' => 'public',
], $field_settings);
$test_image = current($this
->getTestFiles('image'));
$display_repository = \Drupal::service('entity_display.repository');
$display_options = [
'type' => 'responsive_image',
'settings' => [
'image_link' => $link_type,
'responsive_image_style' => 'style_one',
],
];
$display_repository
->getViewDisplay('node', 'article')
->setComponent($field_name, $display_options)
->save();
$this
->previewNodeImage($test_image, $field_name, 'article');
$this
->assertPattern('/picture/');
$nid = $this
->uploadNodeImage($test_image, $field_name, 'article');
$this->container
->get('entity_type.manager')
->getStorage('node')
->resetCache([
$nid,
]);
$node = Node::load($nid);
$display_options = [
'type' => 'responsive_image',
'settings' => [
'image_link' => $link_type,
'responsive_image_style' => 'style_one',
],
];
$display_repository
->getViewDisplay('node', 'article')
->setComponent($field_name, $display_options)
->save();
$large_style = ImageStyle::load('large');
$image_uri = File::load($node->{$field_name}->target_id)
->getFileUri();
$large_style
->createDerivative($image_uri, $large_style
->buildUri($image_uri));
$this
->drupalGet('node/' . $nid);
switch ($link_type) {
case 'file':
$this
->assertPattern('/<a(.*?)href="' . preg_quote(file_url_transform_relative(file_create_url($image_uri)), '/') . '"(.*?)>\\s*<picture/');
break;
case 'content':
$this
->assertPattern('/<a(.*?)href="' . preg_quote($node
->toUrl()
->toString(), '/') . '"(.*?)>\\s*<picture/');
break;
}
}
}