annotate core/modules/image/tests/src/Functional/ImageFieldValidateTest.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@16 1 <?php
Chris@16 2
Chris@16 3 namespace Drupal\Tests\image\Functional;
Chris@16 4
Chris@18 5 use Drupal\Core\Field\FieldStorageDefinitionInterface;
Chris@16 6 use Drupal\Tests\TestFileCreationTrait;
Chris@16 7
Chris@16 8 /**
Chris@16 9 * Tests validation functions such as min/max resolution.
Chris@16 10 *
Chris@16 11 * @group image
Chris@16 12 */
Chris@16 13 class ImageFieldValidateTest extends ImageFieldTestBase {
Chris@16 14
Chris@16 15 use TestFileCreationTrait {
Chris@16 16 getTestFiles as drupalGetTestFiles;
Chris@16 17 compareFiles as drupalCompareFiles;
Chris@16 18 }
Chris@16 19
Chris@16 20 /**
Chris@16 21 * Test image validity.
Chris@16 22 */
Chris@16 23 public function testValid() {
Chris@16 24 $file_system = $this->container->get('file_system');
Chris@16 25 $image_files = $this->drupalGetTestFiles('image');
Chris@16 26
Chris@16 27 $field_name = strtolower($this->randomMachineName());
Chris@16 28 $this->createImageField($field_name, 'article', [], ['file_directory' => 'test-upload']);
Chris@16 29 $expected_path = 'public://test-upload';
Chris@16 30
Chris@16 31 // Create alt text for the image.
Chris@16 32 $alt = $this->randomMachineName();
Chris@16 33
Chris@16 34 // Create a node with a valid image.
Chris@16 35 $node = $this->uploadNodeImage($image_files[0], $field_name, 'article', $alt);
Chris@16 36 $this->assertTrue(file_exists($expected_path . '/' . $image_files[0]->filename));
Chris@16 37
Chris@16 38 // Remove the image.
Chris@16 39 $this->drupalPostForm('node/' . $node . '/edit', [], t('Remove'));
Chris@16 40 $this->drupalPostForm(NULL, [], t('Save'));
Chris@16 41
Chris@16 42 // Get invalid image test files from simpletest.
Chris@16 43 $files = file_scan_directory(drupal_get_path('module', 'simpletest') . '/files', '/invalid-img-.*/');
Chris@16 44 $invalid_image_files = [];
Chris@16 45 foreach ($files as $file) {
Chris@16 46 $invalid_image_files[$file->filename] = $file;
Chris@16 47 }
Chris@16 48
Chris@16 49 // Try uploading a zero-byte image.
Chris@16 50 $zero_size_image = $invalid_image_files['invalid-img-zero-size.png'];
Chris@16 51 $edit = [
Chris@16 52 'files[' . $field_name . '_0]' => $file_system->realpath($zero_size_image->uri),
Chris@16 53 ];
Chris@16 54 $this->drupalPostForm('node/' . $node . '/edit', $edit, t('Upload'));
Chris@16 55 $this->assertFalse(file_exists($expected_path . '/' . $zero_size_image->filename));
Chris@16 56
Chris@16 57 // Try uploading an invalid image.
Chris@16 58 $invalid_image = $invalid_image_files['invalid-img-test.png'];
Chris@16 59 $edit = [
Chris@16 60 'files[' . $field_name . '_0]' => $file_system->realpath($invalid_image->uri),
Chris@16 61 ];
Chris@16 62 $this->drupalPostForm('node/' . $node . '/edit', $edit, t('Upload'));
Chris@16 63 $this->assertFalse(file_exists($expected_path . '/' . $invalid_image->filename));
Chris@16 64
Chris@16 65 // Upload a valid image again.
Chris@16 66 $valid_image = $image_files[0];
Chris@16 67 $edit = [
Chris@16 68 'files[' . $field_name . '_0]' => $file_system->realpath($valid_image->uri),
Chris@16 69 ];
Chris@16 70 $this->drupalPostForm('node/' . $node . '/edit', $edit, t('Upload'));
Chris@16 71 $this->assertTrue(file_exists($expected_path . '/' . $valid_image->filename));
Chris@16 72 }
Chris@16 73
Chris@16 74 /**
Chris@16 75 * Test min/max resolution settings.
Chris@16 76 */
Chris@16 77 public function testResolution() {
Chris@16 78 $field_names = [
Chris@16 79 0 => strtolower($this->randomMachineName()),
Chris@16 80 1 => strtolower($this->randomMachineName()),
Chris@16 81 2 => strtolower($this->randomMachineName()),
Chris@16 82 ];
Chris@16 83 $min_resolution = [
Chris@16 84 'width' => 50,
Chris@17 85 'height' => 50,
Chris@16 86 ];
Chris@16 87 $max_resolution = [
Chris@16 88 'width' => 100,
Chris@17 89 'height' => 100,
Chris@16 90 ];
Chris@16 91 $no_height_min_resolution = [
Chris@16 92 'width' => 50,
Chris@17 93 'height' => NULL,
Chris@16 94 ];
Chris@16 95 $no_height_max_resolution = [
Chris@16 96 'width' => 100,
Chris@17 97 'height' => NULL,
Chris@16 98 ];
Chris@16 99 $no_width_min_resolution = [
Chris@16 100 'width' => NULL,
Chris@17 101 'height' => 50,
Chris@16 102 ];
Chris@16 103 $no_width_max_resolution = [
Chris@16 104 'width' => NULL,
Chris@17 105 'height' => 100,
Chris@16 106 ];
Chris@16 107 $field_settings = [
Chris@16 108 0 => $this->getFieldSettings($min_resolution, $max_resolution),
Chris@16 109 1 => $this->getFieldSettings($no_height_min_resolution, $no_height_max_resolution),
Chris@16 110 2 => $this->getFieldSettings($no_width_min_resolution, $no_width_max_resolution),
Chris@16 111 ];
Chris@16 112 $this->createImageField($field_names[0], 'article', [], $field_settings[0]);
Chris@16 113 $this->createImageField($field_names[1], 'article', [], $field_settings[1]);
Chris@16 114 $this->createImageField($field_names[2], 'article', [], $field_settings[2]);
Chris@16 115
Chris@16 116 // We want a test image that is too small, and a test image that is too
Chris@16 117 // big, so cycle through test image files until we have what we need.
Chris@16 118 $image_that_is_too_big = FALSE;
Chris@16 119 $image_that_is_too_small = FALSE;
Chris@16 120 $image_factory = $this->container->get('image.factory');
Chris@16 121 foreach ($this->drupalGetTestFiles('image') as $image) {
Chris@16 122 $image_file = $image_factory->get($image->uri);
Chris@16 123 if ($image_file->getWidth() > $max_resolution['width']) {
Chris@16 124 $image_that_is_too_big = $image;
Chris@16 125 }
Chris@16 126 if ($image_file->getWidth() < $min_resolution['width']) {
Chris@16 127 $image_that_is_too_small = $image;
Chris@16 128 $image_that_is_too_small_file = $image_file;
Chris@16 129 }
Chris@16 130 if ($image_that_is_too_small && $image_that_is_too_big) {
Chris@16 131 break;
Chris@16 132 }
Chris@16 133 }
Chris@16 134 $this->uploadNodeImage($image_that_is_too_small, $field_names[0], 'article');
Chris@16 135 $this->assertRaw(t('The specified file %name could not be uploaded.', ['%name' => $image_that_is_too_small->filename]));
Chris@16 136 $this->assertRaw(t('The image is too small. The minimum dimensions are %dimensions pixels and the image size is %widthx%height pixels.', [
Chris@16 137 '%dimensions' => '50x50',
Chris@16 138 '%width' => $image_that_is_too_small_file->getWidth(),
Chris@16 139 '%height' => $image_that_is_too_small_file->getHeight(),
Chris@16 140 ]));
Chris@16 141 $this->uploadNodeImage($image_that_is_too_big, $field_names[0], 'article');
Chris@16 142 $this->assertText(t('The image was resized to fit within the maximum allowed dimensions of 100x100 pixels.'));
Chris@16 143 $this->uploadNodeImage($image_that_is_too_small, $field_names[1], 'article');
Chris@16 144 $this->assertRaw(t('The specified file %name could not be uploaded.', ['%name' => $image_that_is_too_small->filename]));
Chris@16 145 $this->uploadNodeImage($image_that_is_too_big, $field_names[1], 'article');
Chris@16 146 $this->assertText(t('The image was resized to fit within the maximum allowed width of 100 pixels.'));
Chris@16 147 $this->uploadNodeImage($image_that_is_too_small, $field_names[2], 'article');
Chris@16 148 $this->assertRaw(t('The specified file %name could not be uploaded.', ['%name' => $image_that_is_too_small->filename]));
Chris@16 149 $this->uploadNodeImage($image_that_is_too_big, $field_names[2], 'article');
Chris@16 150 $this->assertText(t('The image was resized to fit within the maximum allowed height of 100 pixels.'));
Chris@16 151 }
Chris@16 152
Chris@16 153 /**
Chris@16 154 * Test that required alt/title fields gets validated right.
Chris@16 155 */
Chris@16 156 public function testRequiredAttributes() {
Chris@16 157 $field_name = strtolower($this->randomMachineName());
Chris@16 158 $field_settings = [
Chris@16 159 'alt_field' => 1,
Chris@16 160 'alt_field_required' => 1,
Chris@16 161 'title_field' => 1,
Chris@16 162 'title_field_required' => 1,
Chris@16 163 'required' => 1,
Chris@16 164 ];
Chris@16 165 $instance = $this->createImageField($field_name, 'article', [], $field_settings);
Chris@16 166 $images = $this->drupalGetTestFiles('image');
Chris@16 167 // Let's just use the first image.
Chris@16 168 $image = $images[0];
Chris@16 169 $this->uploadNodeImage($image, $field_name, 'article');
Chris@16 170
Chris@16 171 // Look for form-required for the alt text.
Chris@16 172 $elements = $this->xpath('//label[@for="edit-' . $field_name . '-0-alt" and @class="js-form-required form-required"]/following-sibling::input[@id="edit-' . $field_name . '-0-alt"]');
Chris@16 173
Chris@16 174 $this->assertTrue(isset($elements[0]), 'Required marker is shown for the required alt text.');
Chris@16 175
Chris@16 176 $elements = $this->xpath('//label[@for="edit-' . $field_name . '-0-title" and @class="js-form-required form-required"]/following-sibling::input[@id="edit-' . $field_name . '-0-title"]');
Chris@16 177
Chris@16 178 $this->assertTrue(isset($elements[0]), 'Required marker is shown for the required title text.');
Chris@16 179
Chris@16 180 $this->assertText(t('Alternative text field is required.'));
Chris@16 181 $this->assertText(t('Title field is required.'));
Chris@16 182
Chris@16 183 $instance->setSetting('alt_field_required', 0);
Chris@16 184 $instance->setSetting('title_field_required', 0);
Chris@16 185 $instance->save();
Chris@16 186
Chris@16 187 $edit = [
Chris@16 188 'title[0][value]' => $this->randomMachineName(),
Chris@16 189 ];
Chris@16 190 $this->drupalPostForm('node/add/article', $edit, t('Save'));
Chris@16 191
Chris@16 192 $this->assertNoText(t('Alternative text field is required.'));
Chris@16 193 $this->assertNoText(t('Title field is required.'));
Chris@16 194
Chris@16 195 $instance->setSetting('required', 0);
Chris@16 196 $instance->setSetting('alt_field_required', 1);
Chris@16 197 $instance->setSetting('title_field_required', 1);
Chris@16 198 $instance->save();
Chris@16 199
Chris@16 200 $edit = [
Chris@16 201 'title[0][value]' => $this->randomMachineName(),
Chris@16 202 ];
Chris@16 203 $this->drupalPostForm('node/add/article', $edit, t('Save'));
Chris@16 204
Chris@16 205 $this->assertNoText(t('Alternative text field is required.'));
Chris@16 206 $this->assertNoText(t('Title field is required.'));
Chris@16 207 }
Chris@16 208
Chris@16 209 /**
Chris@18 210 * Tests creating an entity while leaving the image field empty.
Chris@18 211 *
Chris@18 212 * This is tested first with edit access to the image field allowed, and then
Chris@18 213 * with it forbidden.
Chris@18 214 *
Chris@18 215 * @dataProvider providerTestEmpty
Chris@18 216 */
Chris@18 217 public function testEmpty($field_name, $required, $cardinality, $form_element_name, $expected_page_text_when_edit_access_allowed, $expected_page_text_when_edit_access_forbidden) {
Chris@18 218 $this->createImageField($field_name, 'article', ['cardinality' => $cardinality], ['required' => $required]);
Chris@18 219
Chris@18 220 // Test with field edit access allowed.
Chris@18 221 $this->drupalGet('node/add/article');
Chris@18 222 $this->assertSession()->fieldExists($form_element_name);
Chris@18 223 $edit = [
Chris@18 224 'title[0][value]' => 'Article with edit-access-allowed image field',
Chris@18 225 ];
Chris@18 226 $this->drupalPostForm(NULL, $edit, t('Save'));
Chris@18 227 $this->assertSession()->pageTextContains($expected_page_text_when_edit_access_allowed);
Chris@18 228
Chris@18 229 // Test with field edit access forbidden.
Chris@18 230 \Drupal::service('module_installer')->install(['image_access_test_hidden']);
Chris@18 231 $this->drupalGet('node/add/article');
Chris@18 232 $this->assertSession()->fieldNotExists($form_element_name);
Chris@18 233 $edit = [
Chris@18 234 'title[0][value]' => 'Article with edit-access-forbidden image field',
Chris@18 235 ];
Chris@18 236 $this->drupalPostForm(NULL, $edit, t('Save'));
Chris@18 237 $this->assertSession()->pageTextContains($expected_page_text_when_edit_access_forbidden);
Chris@18 238 }
Chris@18 239
Chris@18 240 /**
Chris@18 241 * Data provider for ::testEmpty()
Chris@18 242 *
Chris@18 243 * @return array
Chris@18 244 * Test cases.
Chris@18 245 */
Chris@18 246 public function providerTestEmpty() {
Chris@18 247 return [
Chris@18 248 'optional-single' => ['field_image', FALSE, 1, 'files[field_image_0]', 'Article Article with edit-access-allowed image field has been created.', 'Article Article with edit-access-forbidden image field has been created.'],
Chris@18 249 'optional-unlimited' => ['field_image', FALSE, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, 'files[field_image_0][]', 'Article Article with edit-access-allowed image field has been created.', 'Article Article with edit-access-forbidden image field has been created.'],
Chris@18 250 'optional-multiple-limited' => ['field_image', FALSE, 2, 'files[field_image_0][]', 'Article Article with edit-access-allowed image field has been created.', 'Article Article with edit-access-forbidden image field has been created.'],
Chris@18 251 'required-single' => ['field_image', TRUE, 1, 'files[field_image_0]', 'field_image field is required.', 'field_image field is required.'],
Chris@18 252 'required-unlimited' => ['field_image', TRUE, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, 'files[field_image_0][]', 'field_image field is required.', 'field_image field is required.'],
Chris@18 253
Chris@18 254 // @todo Fix this discrepancy in https://www.drupal.org/project/drupal/issues/3011744.
Chris@18 255 'required-multiple-limited' => ['field_image', TRUE, 2, 'files[field_image_0][]', 'This value should not be null.', 'Article Article with edit-access-forbidden image field has been created.'],
Chris@18 256 ];
Chris@18 257 }
Chris@18 258
Chris@18 259 /**
Chris@16 260 * Returns field settings.
Chris@16 261 *
Chris@16 262 * @param int[] $min_resolution
Chris@16 263 * The minimum width and height resolution setting.
Chris@16 264 * @param int[] $max_resolution
Chris@16 265 * The maximum width and height resolution setting.
Chris@16 266 *
Chris@16 267 * @return array
Chris@16 268 */
Chris@16 269 protected function getFieldSettings($min_resolution, $max_resolution) {
Chris@16 270 return [
Chris@16 271 'max_resolution' => $max_resolution['width'] . 'x' . $max_resolution['height'],
Chris@16 272 'min_resolution' => $min_resolution['width'] . 'x' . $min_resolution['height'],
Chris@16 273 'alt_field' => 0,
Chris@16 274 ];
Chris@16 275 }
Chris@16 276
Chris@16 277 }