Yaffs site version 1.1
[yaffs-website] / web / modules / contrib / image_widget_crop / src / Tests / ImageWidgetCropTest.php
1 <?php
2
3 namespace Drupal\image_widget_crop\Tests;
4
5 use Drupal\crop\Entity\CropType;
6 use Drupal\file\Entity\File;
7 use Drupal\image\Entity\ImageStyle;
8 use Drupal\node\Entity\Node;
9 use Drupal\simpletest\WebTestBase;
10
11 /**
12  * Minimal test case for the image_widget_crop module.
13  *
14  * @group image_widget_crop
15  *
16  * @ingroup media
17  */
18 class ImageWidgetCropTest extends WebTestBase {
19
20   /**
21    * User with permissions to create content.
22    *
23    * @var \Drupal\user\Entity\User
24    */
25   protected $user;
26
27   /**
28    * Modules to enable.
29    *
30    * @var array
31    */
32   public static $modules = [
33     'node',
34     'crop',
35     'image',
36     'image_widget_crop',
37     'file_entity',
38   ];
39
40   /**
41    * Prepares environment for the tests.
42    */
43   protected function setUp() {
44     parent::setUp();
45
46     $this->drupalCreateContentType(['name' => 'Crop test', 'type' => 'crop_test']);
47
48     $this->user = $this->createUser([
49       'access content overview',
50       'administer content types',
51       'edit any crop_test content',
52       'edit any image files',
53       'administer files',
54     ]);
55     $this->drupalLogin($this->user);
56   }
57
58   /**
59    * Test Image Widget Crop UI.
60    */
61   public function testCropUi() {
62     // Test that when a crop has more than one usage we have a warning.
63     $this->createImageField('field_image_crop_test', 'crop_test', 'image_widget_crop', [], [], ['crop_list' => ['crop_16_9' => 'crop_16_9']]);
64     $this->drupalGetTestFiles('image');
65
66     $this->drupalGet('node/add/crop_test');
67     $edit = [
68       'title[0][value]' => $this->randomMachineName(),
69       'files[field_image_crop_test_0]' => \Drupal::service('file_system')->realpath('public://image-test.jpg'),
70     ];
71     $this->drupalPostAjaxForm(NULL, $edit, $this->getButtonName('//input[@type="submit" and @value="Upload" and @data-drupal-selector="edit-field-image-crop-test-0-upload-button"]'));
72
73     $node = Node::create([
74       'title' => '2nd node using it',
75       'type' => 'crop_test',
76       'field_image_crop_test' => 1,
77       'alt' => $this->randomMachineName(),
78     ]);
79     $node->save();
80
81     /** @var \Drupal\file\FileUsage\FileUsageInterface $usage */
82     $usage = \Drupal::service('file.usage');
83     $usage->add(\Drupal::service('entity_type.manager')->getStorage('file')->load(1), 'image_widget_crop', 'node', $node->id());
84
85     $this->drupalGet('node/1/edit');
86
87     $this->assertRaw(t('This crop definition affects more usages of this image'));
88
89   }
90
91   /**
92    * Test Image Widget Crop.
93    */
94   public function testImageWidgetCrop() {
95     // Test that crop widget works properly.
96     $this->createImageField('field_image_crop_test', 'crop_test', 'image_widget_crop', [], [], ['crop_list' => ['crop_16_9' => 'crop_16_9']]);
97     $this->drupalGetTestFiles('image');
98
99     $this->drupalGet('node/add/crop_test');
100
101     // Assert that there is no crop widget, neither 'Alternative text' text
102     // filed nor 'Remove' button yet.
103     $raw = '<summary role="button" aria-controls="edit-field-image-crop-test-0-image-crop-crop-wrapper" aria-expanded="false" aria-pressed="false">Crop image</summary>';
104     $this->assertNoRaw($raw);
105     $this->assertNoText('Alternative text');
106     $this->assertNoFieldByName('field_image_crop_test_0_remove_button');
107
108     // Upload an image in field_image_crop_test_0.
109     $image['files[field_image_crop_test_0]'] = $this->container->get('file_system')->realpath('public://image-test.jpg');
110     $this->drupalPostAjaxForm(NULL, $image, $this->getButtonName('//input[@type="submit" and @value="Upload" and @data-drupal-selector="edit-field-image-crop-test-0-upload-button"]'));
111
112     // Assert that now crop widget and 'Alternative text' text field appear and
113     // that 'Remove' button exists.
114     $this->assertRaw($raw);
115     $this->assertText('Alternative text');
116     $this->assertFieldByName('field_image_crop_test_0_remove_button');
117
118     // Set title and 'Alternative text' text field and save.
119     $title = $this->randomMachineName();
120     $edit = [
121       'title[0][value]' => $title,
122       'field_image_crop_test[0][alt]' => $this->randomMachineName(),
123     ];
124     $this->drupalPostForm(NULL, $edit, 'Save');
125     $this->assertText('Crop test ' . $title . ' has been created.');
126     $url = $this->getUrl();
127     $nid = substr($url, -1, strrpos($url, '/'));
128
129     // Edit crop image.
130     $this->drupalGet('node/' . $nid . '/edit');
131
132     // Verify that the 'Remove' button works properly.
133     $this->assertText('Alternative text');
134     $this->drupalPostForm(NULL, NULL, 'Remove');
135     $this->assertNoText('Alternative text');
136
137     // Re-upload the image and set the 'Alternative text'.
138     $this->drupalPostAjaxForm(NULL, $image, $this->getButtonName('//input[@type="submit" and @value="Upload" and @data-drupal-selector="edit-field-image-crop-test-0-upload-button"]'));
139
140     // Verify that the 'Preview' button works properly.
141     $this->drupalPostForm(NULL, $edit, 'Preview');
142     $this->assertLink('Back to content editing');
143     $this->clickLink('Back to content editing');
144
145     // Verify that there is an image style preview.
146     $this->assertFieldByName('field_image_crop_test[0][width]', '40');
147     $this->assertFieldByName('field_image_crop_test[0][height]', '20');
148
149   }
150
151   /**
152    * Tests integration with file_entity module.
153    */
154   public function testFileEntityIntegration() {
155     $this->createImageField('field_image_file_entity', 'crop_test', 'file_editable');
156
157     $image = current($this->drupalGetTestFiles('image'));
158     $image = File::create((array) $image);
159     $image->save();
160
161     $node_title = $this->randomMachineName();
162     $this->drupalGet('node/add/crop_test');
163     $edit = [
164       'title[0][value]' => $node_title,
165       'files[field_image_file_entity_0]' => \Drupal::service('file_system')
166         ->realpath('public://image-test.jpg'),
167     ];
168     $this->drupalPostForm(NULL, $edit, 'Save');
169
170     $node = $this->drupalGetNodeByTitle($node_title);
171
172     $this->drupalGet('node/' . $node->id() . '/edit');
173     $ajax_response = $this->drupalPostAjaxForm(NULL, [], ['file_editable_2' => t('Edit')]);
174     $this->assertTrue(preg_match('/Crop image/', $ajax_response[3]['data']), 'Cropping tool is available on inline edit.');
175
176     // Create a sample crop type.
177     $crop_type = CropType::create([
178       'label' => '16_9',
179       'id' => '16_9',
180       'aspect_ratio' => '16:9',
181     ]);
182     $crop_type->save();
183
184     // Add a created crop type to an image style.
185     $crop_image_style = ImageStyle::load('large');
186     $crop_image_style->addImageEffect([
187       'id' => 'crop_crop',
188       'data' => ['crop_type' => '16_9'],
189     ]);
190     $crop_image_style->save();
191
192     // Assert that crop widget is displayed by default, even if there are no
193     // crop types selected in the global image widget crop configuration.
194     $image_widget_crop_settings = \Drupal::config('image_widget_crop.settings')->get('crop_list');
195     $this->assertEqual($image_widget_crop_settings, []);
196     $this->drupalGet('file/' . $image->id() . '/edit');
197     $this->assertRaw('edit-image-crop-crop-wrapper-16-9');
198     $this->assertRaw('16_9');
199
200     $this->assertText('Crop image', 'Cropping tool available on file edit.');
201   }
202
203   /**
204    * Gets IEF button name.
205    *
206    * @param string $xpath
207    *   Xpath of the button.
208    *
209    * @return string
210    *   The name of the button.
211    */
212   protected function getButtonName($xpath) {
213     $retval = '';
214     /** @var \SimpleXMLElement[] $elements */
215     if ($elements = $this->xpath($xpath)) {
216       foreach ($elements[0]->attributes() as $name => $value) {
217         if ($name == 'name') {
218           $retval = (string) $value;
219           break;
220         }
221       }
222     }
223     return $retval;
224   }
225
226   /**
227    * Create a new image field.
228    *
229    * @param string $name
230    *   The name of the new field (all lowercase), exclude the "field_" prefix.
231    * @param string $type_name
232    *   The node type that this field will be added to.
233    * @param string $widget_name
234    *   The name of the widget.
235    * @param array $storage_settings
236    *   A list of field storage settings that will be added to the defaults.
237    * @param array $field_settings
238    *   A list of instance settings that will be added to the instance defaults.
239    * @param array $widget_settings
240    *   A list of widget settings that will be added to the widget defaults.
241    */
242   protected function createImageField($name, $type_name, $widget_name, array $storage_settings = [], array $field_settings = [], array $widget_settings = []) {
243     \Drupal::entityTypeManager()->getStorage('field_storage_config')->create([
244       'field_name' => $name,
245       'entity_type' => 'node',
246       'type' => 'image',
247       'settings' => $storage_settings,
248       'cardinality' => !empty($storage_settings['cardinality']) ? $storage_settings['cardinality'] : 1,
249     ])->save();
250
251     $field_config = \Drupal::entityTypeManager()->getStorage('field_config')->create([
252       'field_name' => $name,
253       'label' => $name,
254       'entity_type' => 'node',
255       'bundle' => $type_name,
256       'required' => !empty($field_settings['required']),
257       'settings' => $field_settings,
258     ]);
259     $field_config->save();
260
261     /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
262     $form_display = \Drupal::entityTypeManager()->getStorage('entity_form_display')->load('node.' . $type_name . '.default');
263     $form_display->setComponent($name, [
264       'type' => $widget_name,
265       'settings' => $widget_settings,
266     ])->save();
267
268     /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $view_display */
269     $view_display = \Drupal::entityTypeManager()->getStorage('entity_view_display')->load('node.' . $type_name . '.default');
270     $view_display->setComponent($name)
271       ->save();
272
273   }
274
275 }