3 namespace Drupal\Tests\entity_browser\FunctionalJavascript;
5 use Drupal\Core\Field\FieldStorageDefinitionInterface;
6 use Drupal\entity_browser\Element\EntityBrowserElement;
7 use Drupal\field\Entity\FieldConfig;
8 use Drupal\field\Entity\FieldStorageConfig;
9 use Drupal\file\Entity\File;
10 use Drupal\node\Entity\Node;
13 * Tests the image field widget.
15 * @group entity_browser
17 class ImageFieldTest extends EntityBrowserJavascriptTestBase {
20 * Created file entity.
22 * @var \Drupal\file\Entity\File
29 public function setUp() {
32 FieldStorageConfig::create([
33 'field_name' => 'field_image',
35 'entity_type' => 'node',
36 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
40 'field_name' => 'field_image',
41 'entity_type' => 'node',
42 'bundle' => 'article',
45 'file_extensions' => 'jpg',
46 'file_directory' => 'entity-browser-test',
47 'max_resolution' => '40x40',
48 'title_field' => TRUE,
52 file_unmanaged_copy(\Drupal::root() . '/core/modules/simpletest/files/image-test.jpg', 'public://example.jpg');
53 $this->image = File::create([
54 'uri' => 'public://example.jpg',
57 // Register usage for this file to avoid validation erros when referencing
58 // this file on node save.
59 \Drupal::service('file.usage')->add($this->image, 'entity_browser', 'test', '1');
61 /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
62 $form_display = $this->container->get('entity_type.manager')
63 ->getStorage('entity_form_display')
64 ->load('node.article.default');
66 $form_display->setComponent('field_image', [
67 'type' => 'entity_browser_file',
69 'entity_browser' => 'test_entity_browser_iframe_view',
71 'field_widget_edit' => FALSE,
72 'field_widget_remove' => TRUE,
73 'field_widget_replace' => TRUE,
74 'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
75 'view_mode' => 'default',
76 'preview_image_style' => 'thumbnail',
83 'link_text' => 'Select images',
85 /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */
86 $browser = $this->container->get('entity_type.manager')
87 ->getStorage('entity_browser')
88 ->load('test_entity_browser_iframe_view');
89 $browser->setDisplay('iframe');
90 $browser->getDisplay()->setConfiguration($display_config);
92 // These settings should get overridden by our field settings.
94 'upload_location' => 'public://',
95 'extensions' => 'png',
98 'label' => 'Upload images',
101 $browser->setWidgetSelector('tabs');
104 $account = $this->drupalCreateUser([
105 'access test_entity_browser_iframe_view entity browser pages',
106 'create article content',
107 'edit own article content',
110 $this->drupalLogin($account);
114 * Tests basic usage for an image field.
116 public function testImageFieldUsage() {
117 $this->drupalGet('node/add/article');
118 $this->assertSession()->linkExists('Select images');
119 $this->getSession()->getPage()->clickLink('Select images');
120 $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_view');
121 $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $this->image->id() . ']');
122 $this->getSession()->getPage()->pressButton('Select entities');
123 $this->getSession()->getPage()->pressButton('Use selected');
124 $this->assertSession()->pageTextContains('example.jpg');
125 // Switch back to the main page.
126 $this->getSession()->switchToIFrame();
127 $this->waitForAjaxToFinish();
128 // Check if the image thumbnail exists.
129 $this->assertSession()->elementExists('xpath', '//*[@data-drupal-selector="edit-field-image-current-' . $this->image->id() . '-display"]');
130 // Test if the image filename is present.
131 $this->assertSession()->pageTextContains('example.jpg');
132 // Test specifying Alt and Title texts and saving the node.
133 $alt_text = 'Test alt text.';
134 $title_text = 'Test title text.';
135 $this->getSession()->getPage()->fillField('field_image[current][1][meta][alt]', $alt_text);
136 $this->getSession()->getPage()->fillField('field_image[current][1][meta][title]', $title_text);
137 $this->getSession()->getPage()->fillField('title[0][value]', 'Node 1');
138 $this->getSession()->getPage()->pressButton('Save');
139 $this->assertSession()->pageTextContains('Article Node 1 has been created.');
140 $node = Node::load(1);
141 $saved_alt = $node->get('field_image')[0]->alt;
142 $this->assertEquals($saved_alt, $alt_text);
143 $saved_title = $node->get('field_image')[0]->title;
144 $this->assertEquals($saved_title, $title_text);
145 // Test the Delete functionality.
146 $this->drupalGet('node/1/edit');
147 $this->assertSession()->buttonExists('Remove');
148 $this->getSession()->getPage()->pressButton('Remove');
149 $this->waitForAjaxToFinish();
150 // Image filename should not be present.
151 $this->assertSession()->pageTextNotContains('example.jpg');
152 $this->assertSession()->linkExists('Select entities');
153 // Test the Replace functionality.
154 file_unmanaged_copy(\Drupal::root() . '/core/modules/simpletest/files/image-test.jpg', 'public://example2.jpg');
155 $image2 = File::create(['uri' => 'public://example2.jpg']);
157 \Drupal::service('file.usage')->add($image2, 'entity_browser', 'test', '1');
158 $this->drupalGet('node/1/edit');
159 $this->assertSession()->buttonExists('Replace');
160 $this->getSession()->getPage()->pressButton('Replace');
161 $this->waitForAjaxToFinish();
162 $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_view');
163 $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $image2->id() . ']');
164 $this->getSession()->getPage()->pressButton('Select entities');
165 $this->getSession()->getPage()->pressButton('Use selected');
166 $this->getSession()->wait(1000);
167 $this->getSession()->switchToIFrame();
168 $this->waitForAjaxToFinish();
169 // Initial image should not be present, the new one should be there instead.
170 $this->assertSession()->pageTextNotContains('example.jpg');
171 $this->assertSession()->pageTextContains('example2.jpg');
175 * Tests that settings are passed from the image field to the upload widget.
177 public function testImageFieldSettings() {
178 $root = \Drupal::root();
179 $file_wrong_type = $root . '/core/misc/druplicon.png';
180 $file_too_big = $root . '/core/modules/simpletest/files/image-2.jpg';
181 $file_just_right = $root . '/core/modules/simpletest/files/image-test.jpg';
182 $this->drupalGet('node/add/article');
183 $this->assertSession()->linkExists('Select images');
184 $this->getSession()->getPage()->clickLink('Select images');
185 $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_iframe_view');
186 // Switch to the image tab.
187 $this->clickLink('Upload images');
188 // Attempt to upload an invalid image type. The upload widget is configured
189 // to allow png but the field widget is configured to allow jpg, so we
190 // expect the field to override the widget.
191 $this->getSession()->getPage()->attachFileToField('files[upload][]', $file_wrong_type);
192 $this->waitForAjaxToFinish();
193 $this->assertSession()->pageTextContains('Only files with the following extensions are allowed: jpg');
194 $this->assertSession()->pageTextContains('The specified file druplicon.png could not be uploaded');
195 // Upload an image bigger than the field widget's configured max size.
196 $this->getSession()->getPage()->attachFileToField('files[upload][]', $file_too_big);
197 $this->waitForAjaxToFinish();
198 $this->assertSession()->pageTextContains('The image was resized to fit within the maximum allowed dimensions of 40x40 pixels.');
199 // Upload an image that passes validation and finish the upload.
200 $this->getSession()->getPage()->attachFileToField('files[upload][]', $file_just_right);
201 $this->waitForAjaxToFinish();
202 $this->getSession()->getPage()->pressButton('Select files');
203 $this->getSession()->getPage()->pressButton('Use selected');
204 $this->assertSession()->pageTextContains('image-test.jpg');
205 // Check that the file has uploaded to the correct sub-directory.
206 $this->getSession()->switchToIFrame();
207 $this->waitForAjaxToFinish();
208 $entity_id = $this->getSession()->evaluateScript('jQuery("#edit-field-image-wrapper [data-entity-id]").data("entity-id")');
209 $this->assertStringStartsWith('file:', $entity_id);
210 /** @var \Drupal\file\Entity\File $file */
211 $fid = explode(':', $entity_id)[1];
212 $file = File::load($fid);
213 $this->assertContains('entity-browser-test', $file->getFileUri());