ResponsiveImageFieldDisplayTest.php 8.42 KB
Newer Older
1 2 3 4
<?php

/**
 * @file
5
 * Definition of Drupal\responsive_image\Tests\ResponsiveImageFieldDisplayTest.
6 7
 */

8
namespace Drupal\responsive_image\Tests;
9

10
use Drupal\Component\Utility\Unicode;
11 12 13
use Drupal\image\Tests\ImageFieldTestBase;

/**
14 15 16
 * Tests responsive image display formatter.
 *
 * @group responsive_image
17
 */
18
class ResponsiveImageFieldDisplayTest extends ImageFieldTestBase {
19

20 21
  protected $dumpHeaders = TRUE;

22 23 24 25 26 27 28
  /**
   * Responsive image mapping entity instance we test with.
   *
   * @var \Drupal\responsive_image\Entity\ResponsiveImageMapping
   */
  protected $responsiveImgMapping;

29 30 31 32 33
  /**
   * Modules to enable.
   *
   * @var array
   */
34
  public static $modules = array('field_ui', 'responsive_image', 'responsive_image_test_module');
35 36

  /**
37
   * Drupal\simpletest\WebTestBase\setUp().
38
   */
39
  protected function setUp() {
40 41 42
    parent::setUp();

    // Create user.
43
    $this->adminUser = $this->drupalCreateUser(array(
44
      'administer responsive images',
45 46 47 48
      'access content',
      'access administration pages',
      'administer site configuration',
      'administer content types',
49
      'administer node display',
50 51 52 53 54 55
      'administer nodes',
      'create article content',
      'edit any article content',
      'delete any article content',
      'administer image styles'
    ));
56
    $this->drupalLogin($this->adminUser);
57
    // Add responsive image mapping.
58
    $this->responsiveImgMapping = entity_create('responsive_image_mapping', array(
59 60
      'id' => 'mapping_one',
      'label' => 'Mapping One',
61
      'breakpointGroup' => 'responsive_image_test_module',
62 63 64 65
    ));
  }

  /**
66
   * Test responsive image formatters on node display for public files.
67
   */
68
  public function testResponsiveImageFieldFormattersPublic() {
69 70
    $this->addTestMappings();
    $this->doTestResponsiveImageFieldFormatters('public');
71 72 73
  }

  /**
74
   * Test responsive image formatters on node display for private files.
75
   */
76
  public function testResponsiveImageFieldFormattersPrivate() {
77
    $this->addTestMappings();
78 79
    // Remove access content permission from anonymous users.
    user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array('access content' => FALSE));
80
    $this->doTestResponsiveImageFieldFormatters('private');
81 82
  }

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
  /**
   * Test responsive image formatters when image style is empty.
   */
  public function testResponsiveImageFieldFormattersEmptyStyle() {
    $this->addTestMappings(TRUE);
    $this->doTestResponsiveImageFieldFormatters('public', TRUE);
  }

  /**
   * Add mappings to the responsive image mapping entity.
   *
   * @param bool $empty_styles
   *   If true, the mappings will get empty image styles.
   */
  protected function addTestMappings($empty_styles = FALSE) {
    if ($empty_styles) {
      $this->responsiveImgMapping
        ->addMapping('responsive_image_test_module.mobile', '1x', '')
        ->addMapping('responsive_image_test_module.narrow', '1x', '')
        ->addMapping('responsive_image_test_module.wide', '1x', '')
        ->save();
    }
    else {
      $this->responsiveImgMapping
        ->addMapping('responsive_image_test_module.mobile', '1x', 'thumbnail')
        ->addMapping('responsive_image_test_module.narrow', '1x', 'medium')
        ->addMapping('responsive_image_test_module.wide', '1x', 'large')
        ->save();
    }
  }
113
  /**
114
   * Test responsive image formatters on node display.
115 116 117 118 119 120 121 122 123
   *
   * If the empty styles param is set, then the function only tests for the
   * fallback image style (large).
   *
   * @param string $scheme
   *   File scheme to use.
   * @param bool $empty_styles
   *   If true, use an empty string for image style names.
   * Defaults to false.
124
   */
125
  protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = FALSE) {
126
    $node_storage = $this->container->get('entity.manager')->getStorage('node');
127
    $field_name = Unicode::strtolower($this->randomMachineName());
128 129 130 131
    $this->createImageField($field_name, 'article', array('uri_scheme' => $scheme));
    // Create a new node with an image attached.
    $test_image = current($this->drupalGetTestFiles('image'));
    $nid = $this->uploadNodeImage($test_image, $field_name, 'article');
132 133
    $node_storage->resetCache(array($nid));
    $node = $node_storage->load($nid);
134 135

    // Test that the default formatter is being used.
136
    $image_uri = file_load($node->{$field_name}->target_id)->getFileUri();
137 138 139 140 141
    $image = array(
      '#theme' => 'image',
      '#uri' => $image_uri,
      '#width' => 40,
      '#height' => 20,
142
    );
143
    $default_output = str_replace("\n", NULL, drupal_render($image));
144 145
    $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');

146
    // Use the responsive image formatter linked to file formatter.
147
    $display_options = array(
148
      'type' => 'responsive_image',
149 150 151
      'settings' => array(
        'image_link' => 'file'
      ),
152 153 154 155 156
    );
    $display = entity_get_display('node', 'article', 'default');
    $display->setComponent($field_name, $display_options)
      ->save();

157 158 159 160 161 162
    $image = array(
      '#theme' => 'image',
      '#uri' => $image_uri,
      '#width' => 40,
      '#height' => 20,
    );
163
    $default_output = '<a href="' . file_create_url($image_uri) . '">' . drupal_render($image) . '</a>';
164
    $this->drupalGet('node/' . $nid);
165 166 167
    $cache_tags_header = $this->drupalGetHeader('X-Drupal-Cache-Tags');
    $this->assertTrue(!preg_match('/ image_style\:/', $cache_tags_header), 'No image style cache tag found.');

168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
    $this->assertRaw($default_output, 'Image linked to file formatter displaying correctly on full node view.');
    // Verify that the image can be downloaded.
    $this->assertEqual(file_get_contents($test_image->uri), $this->drupalGet(file_create_url($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->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.');

      // Log out and try to access the file.
      $this->drupalLogout();
      $this->drupalGet(file_create_url($image_uri));
      $this->assertResponse('403', 'Access denied to original image as anonymous user.');

      // Log in again.
183
      $this->drupalLogin($this->adminUser);
184 185
    }

186 187
    // Use the responsive image formatter with a responsive image mapping.
    $display_options['settings']['responsive_image_mapping'] = 'mapping_one';
188 189 190
    $display_options['settings']['image_link'] = '';
    // Also set the fallback image style.
    $display_options['settings']['fallback_image_style'] = 'large';
191 192 193
    $display->setComponent($field_name, $display_options)
      ->save();

194 195
    // Output should contain all image styles and all breakpoints.
    $this->drupalGet('node/' . $nid);
196 197 198 199
    if (!$empty_styles) {
      $this->assertRaw('/styles/thumbnail/');
      $this->assertRaw('/styles/medium/');
    }
200
    $this->assertRaw('/styles/large/');
201 202 203
    $this->assertRaw('media="(min-width: 0px)"');
    $this->assertRaw('media="(min-width: 560px)"');
    $this->assertRaw('media="(min-width: 851px)"');
204
    $cache_tags = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Tags'));
205
    $this->assertTrue(in_array('config:responsive_image.mappings.mapping_one', $cache_tags));
206
    if (!$empty_styles) {
207 208
      $this->assertTrue(in_array('config:image.style.thumbnail', $cache_tags));
      $this->assertTrue(in_array('config:image.style.medium', $cache_tags));
209
    }
210
    $this->assertTrue(in_array('config:image.style.large', $cache_tags));
211 212

    // Test the fallback image style.
213
    $large_style = entity_load('image_style', 'large');
214 215 216
    $fallback_image = array(
      '#theme' => 'responsive_image_source',
      '#src' => $large_style->buildUrl($image_uri),
217
      '#dimensions' => array('width' => 40, 'height' => 20),
218
    );
219
    $default_output = drupal_render($fallback_image);
220 221 222 223 224
    $this->assertRaw($default_output, 'Image style thumbnail formatter displaying correctly on full node view.');

    if ($scheme == 'private') {
      // Log out and try to access the file.
      $this->drupalLogout();
225
      $this->drupalGet($large_style->buildUrl($image_uri));
226
      $this->assertResponse('403', 'Access denied to image style thumbnail as anonymous user.');
227 228
      $cache_tags_header = $this->drupalGetHeader('X-Drupal-Cache-Tags');
      $this->assertTrue(!preg_match('/ image_style\:/', $cache_tags_header), 'No image style cache tag found.');
229 230 231 232
    }
  }

}