3 namespace Drupal\Tests\image\Functional;
5 use Drupal\Tests\TestFileCreationTrait;
8 * Tests validation functions such as min/max resolution.
12 class ImageFieldValidateTest extends ImageFieldTestBase {
14 use TestFileCreationTrait {
15 getTestFiles as drupalGetTestFiles;
16 compareFiles as drupalCompareFiles;
20 * Test image validity.
22 public function testValid() {
23 $file_system = $this->container->get('file_system');
24 $image_files = $this->drupalGetTestFiles('image');
26 $field_name = strtolower($this->randomMachineName());
27 $this->createImageField($field_name, 'article', [], ['file_directory' => 'test-upload']);
28 $expected_path = 'public://test-upload';
30 // Create alt text for the image.
31 $alt = $this->randomMachineName();
33 // Create a node with a valid image.
34 $node = $this->uploadNodeImage($image_files[0], $field_name, 'article', $alt);
35 $this->assertTrue(file_exists($expected_path . '/' . $image_files[0]->filename));
38 $this->drupalPostForm('node/' . $node . '/edit', [], t('Remove'));
39 $this->drupalPostForm(NULL, [], t('Save'));
41 // Get invalid image test files from simpletest.
42 $files = file_scan_directory(drupal_get_path('module', 'simpletest') . '/files', '/invalid-img-.*/');
43 $invalid_image_files = [];
44 foreach ($files as $file) {
45 $invalid_image_files[$file->filename] = $file;
48 // Try uploading a zero-byte image.
49 $zero_size_image = $invalid_image_files['invalid-img-zero-size.png'];
51 'files[' . $field_name . '_0]' => $file_system->realpath($zero_size_image->uri),
53 $this->drupalPostForm('node/' . $node . '/edit', $edit, t('Upload'));
54 $this->assertFalse(file_exists($expected_path . '/' . $zero_size_image->filename));
56 // Try uploading an invalid image.
57 $invalid_image = $invalid_image_files['invalid-img-test.png'];
59 'files[' . $field_name . '_0]' => $file_system->realpath($invalid_image->uri),
61 $this->drupalPostForm('node/' . $node . '/edit', $edit, t('Upload'));
62 $this->assertFalse(file_exists($expected_path . '/' . $invalid_image->filename));
64 // Upload a valid image again.
65 $valid_image = $image_files[0];
67 'files[' . $field_name . '_0]' => $file_system->realpath($valid_image->uri),
69 $this->drupalPostForm('node/' . $node . '/edit', $edit, t('Upload'));
70 $this->assertTrue(file_exists($expected_path . '/' . $valid_image->filename));
74 * Test min/max resolution settings.
76 public function testResolution() {
78 0 => strtolower($this->randomMachineName()),
79 1 => strtolower($this->randomMachineName()),
80 2 => strtolower($this->randomMachineName()),
90 $no_height_min_resolution = [
94 $no_height_max_resolution = [
98 $no_width_min_resolution = [
102 $no_width_max_resolution = [
107 0 => $this->getFieldSettings($min_resolution, $max_resolution),
108 1 => $this->getFieldSettings($no_height_min_resolution, $no_height_max_resolution),
109 2 => $this->getFieldSettings($no_width_min_resolution, $no_width_max_resolution),
111 $this->createImageField($field_names[0], 'article', [], $field_settings[0]);
112 $this->createImageField($field_names[1], 'article', [], $field_settings[1]);
113 $this->createImageField($field_names[2], 'article', [], $field_settings[2]);
115 // We want a test image that is too small, and a test image that is too
116 // big, so cycle through test image files until we have what we need.
117 $image_that_is_too_big = FALSE;
118 $image_that_is_too_small = FALSE;
119 $image_factory = $this->container->get('image.factory');
120 foreach ($this->drupalGetTestFiles('image') as $image) {
121 $image_file = $image_factory->get($image->uri);
122 if ($image_file->getWidth() > $max_resolution['width']) {
123 $image_that_is_too_big = $image;
125 if ($image_file->getWidth() < $min_resolution['width']) {
126 $image_that_is_too_small = $image;
127 $image_that_is_too_small_file = $image_file;
129 if ($image_that_is_too_small && $image_that_is_too_big) {
133 $this->uploadNodeImage($image_that_is_too_small, $field_names[0], 'article');
134 $this->assertRaw(t('The specified file %name could not be uploaded.', ['%name' => $image_that_is_too_small->filename]));
135 $this->assertRaw(t('The image is too small. The minimum dimensions are %dimensions pixels and the image size is %widthx%height pixels.', [
136 '%dimensions' => '50x50',
137 '%width' => $image_that_is_too_small_file->getWidth(),
138 '%height' => $image_that_is_too_small_file->getHeight(),
140 $this->uploadNodeImage($image_that_is_too_big, $field_names[0], 'article');
141 $this->assertText(t('The image was resized to fit within the maximum allowed dimensions of 100x100 pixels.'));
142 $this->uploadNodeImage($image_that_is_too_small, $field_names[1], 'article');
143 $this->assertRaw(t('The specified file %name could not be uploaded.', ['%name' => $image_that_is_too_small->filename]));
144 $this->uploadNodeImage($image_that_is_too_big, $field_names[1], 'article');
145 $this->assertText(t('The image was resized to fit within the maximum allowed width of 100 pixels.'));
146 $this->uploadNodeImage($image_that_is_too_small, $field_names[2], 'article');
147 $this->assertRaw(t('The specified file %name could not be uploaded.', ['%name' => $image_that_is_too_small->filename]));
148 $this->uploadNodeImage($image_that_is_too_big, $field_names[2], 'article');
149 $this->assertText(t('The image was resized to fit within the maximum allowed height of 100 pixels.'));
153 * Test that required alt/title fields gets validated right.
155 public function testRequiredAttributes() {
156 $field_name = strtolower($this->randomMachineName());
159 'alt_field_required' => 1,
161 'title_field_required' => 1,
164 $instance = $this->createImageField($field_name, 'article', [], $field_settings);
165 $images = $this->drupalGetTestFiles('image');
166 // Let's just use the first image.
168 $this->uploadNodeImage($image, $field_name, 'article');
170 // Look for form-required for the alt text.
171 $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"]');
173 $this->assertTrue(isset($elements[0]), 'Required marker is shown for the required alt text.');
175 $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"]');
177 $this->assertTrue(isset($elements[0]), 'Required marker is shown for the required title text.');
179 $this->assertText(t('Alternative text field is required.'));
180 $this->assertText(t('Title field is required.'));
182 $instance->setSetting('alt_field_required', 0);
183 $instance->setSetting('title_field_required', 0);
187 'title[0][value]' => $this->randomMachineName(),
189 $this->drupalPostForm('node/add/article', $edit, t('Save'));
191 $this->assertNoText(t('Alternative text field is required.'));
192 $this->assertNoText(t('Title field is required.'));
194 $instance->setSetting('required', 0);
195 $instance->setSetting('alt_field_required', 1);
196 $instance->setSetting('title_field_required', 1);
200 'title[0][value]' => $this->randomMachineName(),
202 $this->drupalPostForm('node/add/article', $edit, t('Save'));
204 $this->assertNoText(t('Alternative text field is required.'));
205 $this->assertNoText(t('Title field is required.'));
209 * Returns field settings.
211 * @param int[] $min_resolution
212 * The minimum width and height resolution setting.
213 * @param int[] $max_resolution
214 * The maximum width and height resolution setting.
218 protected function getFieldSettings($min_resolution, $max_resolution) {
220 'max_resolution' => $max_resolution['width'] . 'x' . $max_resolution['height'],
221 'min_resolution' => $min_resolution['width'] . 'x' . $min_resolution['height'],