Further Drupal 8.6.4 changes. Some core files were not committed before a commit...
[yaffs-website] / web / core / modules / media_library / tests / src / FunctionalJavascript / MediaLibraryTest.php
1 <?php
2
3 namespace Drupal\Tests\media_library\FunctionalJavascript;
4
5 use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
6 use Drupal\media\Entity\Media;
7 use Drupal\Tests\TestFileCreationTrait;
8 use Drupal\user\Entity\Role;
9 use Drupal\user\RoleInterface;
10
11 /**
12  * Contains Media library integration tests.
13  *
14  * @group media_library
15  */
16 class MediaLibraryTest extends WebDriverTestBase {
17
18   use TestFileCreationTrait;
19
20   /**
21    * {@inheritdoc}
22    */
23   protected static $modules = ['block', 'media_library_test'];
24
25   /**
26    * {@inheritdoc}
27    */
28   protected function setUp() {
29     parent::setUp();
30
31     // Create a few example media items for use in selection.
32     $media = [
33       'type_one' => [
34         'Horse',
35         'Bear',
36         'Cat',
37         'Dog',
38       ],
39       'type_two' => [
40         'Crocodile',
41         'Lizard',
42         'Snake',
43         'Turtle',
44       ],
45     ];
46
47     $time = time();
48     foreach ($media as $type => $names) {
49       foreach ($names as $name) {
50         $entity = Media::create(['name' => $name, 'bundle' => $type]);
51         $source_field = $type === 'type_one' ? 'field_media_test' : 'field_media_test_1';
52         $entity->setCreatedTime(++$time);
53         $entity->set($source_field, $name);
54         $entity->save();
55       }
56     }
57
58     // Create a user who can use the Media library.
59     $user = $this->drupalCreateUser([
60       'access administration pages',
61       'access content',
62       'access media overview',
63       'edit own basic_page content',
64       'create basic_page content',
65       'create media',
66       'delete any media',
67       'view media',
68     ]);
69     $this->drupalLogin($user);
70     $this->drupalPlaceBlock('local_tasks_block');
71     $this->drupalPlaceBlock('local_actions_block');
72   }
73
74   /**
75    * Tests that the Media library's administration page works as expected.
76    */
77   public function testAdministrationPage() {
78     $session = $this->getSession();
79     $page = $session->getPage();
80     $assert_session = $this->assertSession();
81
82     // Visit the administration page.
83     $this->drupalGet('admin/content/media');
84
85     // Verify that the "Add media" link is present.
86     $assert_session->linkExists('Add media');
87
88     // Verify that media from two separate types is present.
89     $assert_session->pageTextContains('Dog');
90     $assert_session->pageTextContains('Turtle');
91
92     // Test that users can filter by type.
93     $page->selectFieldOption('Media type', 'Type One');
94     $page->pressButton('Apply Filters');
95     $assert_session->assertWaitOnAjaxRequest();
96     $assert_session->pageTextContains('Dog');
97     $assert_session->pageTextNotContains('Turtle');
98     $page->selectFieldOption('Media type', 'Type Two');
99     $page->pressButton('Apply Filters');
100     $assert_session->assertWaitOnAjaxRequest();
101     $assert_session->pageTextNotContains('Dog');
102     $assert_session->pageTextContains('Turtle');
103
104     // Test that selecting elements as a part of bulk operations works.
105     $page->selectFieldOption('Media type', '- Any -');
106     $page->pressButton('Apply Filters');
107     $assert_session->assertWaitOnAjaxRequest();
108     // This tests that anchor tags clicked inside the preview are suppressed.
109     $this->getSession()->executeScript('jQuery(".js-click-to-select-trigger a")[0].click()');
110     $this->submitForm([], 'Apply to selected items');
111     $assert_session->pageTextContains('Dog');
112     $assert_session->pageTextNotContains('Cat');
113     $this->submitForm([], 'Delete');
114     $assert_session->pageTextNotContains('Dog');
115     $assert_session->pageTextContains('Cat');
116
117     // Test 'Select all media'.
118     $this->getSession()->getPage()->checkField('Select all media');
119     $this->getSession()->getPage()->selectFieldOption('Action', 'media_delete_action');
120     $this->submitForm([], 'Apply to selected items');
121     $this->getSession()->getPage()->pressButton('Delete');
122
123     $assert_session->pageTextNotContains('Cat');
124     $assert_session->pageTextNotContains('Turtle');
125     $assert_session->pageTextNotContains('Snake');
126
127     // Test empty text.
128     $assert_session->pageTextContains('No media available.');
129
130     // Verify that the "Table" link is present, click it and check address.
131     $assert_session->linkExists('Table');
132     $page->clickLink('Table');
133     $assert_session->addressEquals('admin/content/media-table');
134     // Verify that the "Add media" link is present.
135     $assert_session->linkExists('Add media');
136   }
137
138   /**
139    * Tests that the Media library's widget works as expected.
140    */
141   public function testWidget() {
142     $assert_session = $this->assertSession();
143     $page = $this->getSession()->getPage();
144
145     // Visit a node create page.
146     $this->drupalGet('node/add/basic_page');
147
148     // Verify that both media widget instances are present.
149     $assert_session->pageTextContains('Unlimited media');
150     $assert_session->pageTextContains('Twin media');
151
152     // Add to the unlimited cardinality field.
153     $unlimited_button = $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]');
154     $unlimited_button->click();
155     $assert_session->assertWaitOnAjaxRequest();
156     // Assert that only type_one media items exist, since this field only
157     // accepts items of that type.
158     $assert_session->pageTextContains('Media library');
159     $assert_session->pageTextContains('Dog');
160     $assert_session->pageTextContains('Bear');
161     $assert_session->pageTextNotContains('Turtle');
162     // Ensure that the "Select all" checkbox is not visible.
163     $this->assertFalse($assert_session->elementExists('css', '.media-library-select-all')->isVisible());
164     // Use an exposed filter.
165     $session = $this->getSession();
166     $session->getPage()->fillField('Name', 'Dog');
167     $session->getPage()->pressButton('Apply Filters');
168     $assert_session->assertWaitOnAjaxRequest();
169     $assert_session->pageTextContains('Dog');
170     $assert_session->pageTextNotContains('Bear');
171     // Clear the exposed filter.
172     $session->getPage()->fillField('Name', '');
173     $session->getPage()->pressButton('Apply Filters');
174     $assert_session->assertWaitOnAjaxRequest();
175     // Select the first three media items (should be Dog/Cat/Bear).
176     $checkbox_selector = '.media-library-view .js-click-to-select-checkbox input';
177     $checkboxes = $page->findAll('css', $checkbox_selector);
178     $checkboxes[0]->click();
179     $checkboxes[1]->click();
180     $checkboxes[2]->click();
181     $assert_session->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Select media');
182     $assert_session->assertWaitOnAjaxRequest();
183     // Ensure that the selection completed successfully.
184     $assert_session->pageTextNotContains('Media library');
185     $assert_session->pageTextContains('Dog');
186     $assert_session->pageTextContains('Cat');
187     $assert_session->pageTextContains('Bear');
188     // Remove "Dog" (happens to be the first remove button on the page).
189     $assert_session->elementExists('css', '.media-library-item__remove')->click();
190     $assert_session->assertWaitOnAjaxRequest();
191     $assert_session->pageTextNotContains('Dog');
192     $assert_session->pageTextContains('Cat');
193     $assert_session->pageTextContains('Bear');
194
195     // Open another Media library on the same page.
196     $twin_button = $assert_session->elementExists('css', '.media-library-open-button[href*="field_twin_media"]');
197     $twin_button->click();
198     $assert_session->assertWaitOnAjaxRequest();
199     // This field allows both media types.
200     $assert_session->pageTextContains('Media library');
201     $assert_session->pageTextContains('Dog');
202     $assert_session->pageTextContains('Turtle');
203     // Attempt to select three items - the cardinality of this field is two so
204     // the third selection should be disabled.
205     $checkbox_selector = '.media-library-view .js-click-to-select-checkbox input';
206     $checkboxes = $page->findAll('css', $checkbox_selector);
207     $this->assertFalse($checkboxes[5]->hasAttribute('disabled'));
208     $checkboxes[0]->click();
209     $checkboxes[7]->click();
210     $this->assertTrue($checkboxes[5]->hasAttribute('disabled'));
211     $assert_session->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Select media');
212     $assert_session->assertWaitOnAjaxRequest();
213     // Ensure that the selection completed successfully, and we have only two
214     // media items of two different types.
215     $assert_session->pageTextNotContains('Media library');
216     $assert_session->pageTextContains('Horse');
217     $assert_session->pageTextContains('Turtle');
218     $assert_session->pageTextNotContains('Snake');
219
220     // Finally, save the form.
221     $assert_session->elementExists('css', '.js-media-library-widget-toggle-weight')->click();
222     $this->submitForm([
223       'title[0][value]' => 'My page',
224       'field_unlimited_media[selection][0][weight]' => '2',
225     ], 'Save');
226     $assert_session->pageTextContains('Basic Page My page has been created');
227     // We removed this item earlier.
228     $assert_session->pageTextNotContains('Dog');
229     // This item should not have been selected due to cardinality constraints.
230     $assert_session->pageTextNotContains('Snake');
231     // "Cat" should come after "Bear", since we changed the weight.
232     $assert_session->elementExists('css', '.field--name-field-unlimited-media > .field__items > .field__item:last-child:contains("Cat")');
233     // Make sure everything that was selected shows up.
234     $assert_session->pageTextContains('Cat');
235     $assert_session->pageTextContains('Bear');
236     $assert_session->pageTextContains('Horse');
237     $assert_session->pageTextContains('Turtle');
238
239     // Re-edit the content and make a new selection.
240     $this->drupalGet('node/1/edit');
241     $assert_session->pageTextNotContains('Dog');
242     $assert_session->pageTextContains('Cat');
243     $assert_session->pageTextContains('Bear');
244     $assert_session->pageTextContains('Horse');
245     $assert_session->pageTextContains('Turtle');
246     $unlimited_button = $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]');
247     $unlimited_button->click();
248     $assert_session->assertWaitOnAjaxRequest();
249     $assert_session->pageTextContains('Media library');
250     // Select the first media items (should be Dog, again).
251     $checkbox_selector = '.media-library-view .js-click-to-select-checkbox input';
252     $checkboxes = $page->findAll('css', $checkbox_selector);
253     $checkboxes[0]->click();
254     $assert_session->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Select media');
255     $assert_session->assertWaitOnAjaxRequest();
256     // "Dog" and the existing selection should still exist.
257     $assert_session->pageTextContains('Dog');
258     $assert_session->pageTextContains('Cat');
259     $assert_session->pageTextContains('Bear');
260     $assert_session->pageTextContains('Horse');
261     $assert_session->pageTextContains('Turtle');
262   }
263
264   /**
265    * Tests that the widget works as expected for anonymous users.
266    */
267   public function testWidgetAnonymous() {
268     $assert_session = $this->assertSession();
269
270     $this->drupalLogout();
271
272     $role = Role::load(RoleInterface::ANONYMOUS_ID);
273     $role->revokePermission('view media');
274     $role->save();
275
276     // Verify that unprivileged users can't access the widget view.
277     $this->drupalGet('admin/content/media-widget');
278     $assert_session->responseContains('Access denied');
279
280     // Allow the anonymous user to create pages and view media.
281     $this->grantPermissions($role, [
282       'access content',
283       'create basic_page content',
284       'view media',
285     ]);
286
287     // Ensure the widget works as an anonymous user.
288     $this->drupalGet('node/add/basic_page');
289
290     // Add to the unlimited cardinality field.
291     $unlimited_button = $assert_session->elementExists('css', '.media-library-open-button[href*="field_unlimited_media"]');
292     $unlimited_button->click();
293     $assert_session->assertWaitOnAjaxRequest();
294
295     // Select the first media item (should be Dog).
296     $checkbox_selector = '.media-library-view .js-click-to-select-checkbox input';
297     $checkboxes = $this->getSession()->getPage()->findAll('css', $checkbox_selector);
298     $checkboxes[0]->click();
299     $assert_session->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Select media');
300     $assert_session->assertWaitOnAjaxRequest();
301
302     // Ensure that the selection completed successfully.
303     $assert_session->pageTextNotContains('Media library');
304     $assert_session->pageTextContains('Dog');
305
306     // Save the form.
307     $assert_session->elementExists('css', '.js-media-library-widget-toggle-weight')->click();
308     $this->submitForm([
309       'title[0][value]' => 'My page',
310       'field_unlimited_media[selection][0][weight]' => '0',
311     ], 'Save');
312     $assert_session->pageTextContains('Basic Page My page has been created');
313     $assert_session->pageTextContains('Dog');
314   }
315
316   /**
317    * Tests that uploads in the Media library's widget works as expected.
318    */
319   public function testWidgetUpload() {
320     $assert_session = $this->assertSession();
321     $page = $this->getSession()->getPage();
322
323     foreach ($this->getTestFiles('image') as $image) {
324       $extension = pathinfo($image->filename, PATHINFO_EXTENSION);
325       if ($extension === 'png') {
326         $png_image = $image;
327       }
328       elseif ($extension === 'jpg') {
329         $jpg_image = $image;
330       }
331     }
332
333     if (!isset($png_image) || !isset($jpg_image)) {
334       $this->fail('Expected test files not present.');
335     }
336
337     // Visit a node create page.
338     $this->drupalGet('node/add/basic_page');
339
340     $file_storage = $this->container->get('entity_type.manager')->getStorage('file');
341     /** @var \Drupal\Core\File\FileSystemInterface $file_system */
342     $file_system = $this->container->get('file_system');
343
344     // Ensure that the add button is not present if no media can be created.
345     $assert_session->elementNotExists('css', '.media-library-add-button[href*="field_noadd_media"]');
346
347     // Add to the twin media field using the add button directly on the widget.
348     $twin_button = $assert_session->elementExists('css', '.media-library-add-button[href*="field_twin_media"]');
349     $twin_button->click();
350     $assert_session->assertWaitOnAjaxRequest();
351
352     $page->attachFileToField('Upload', $this->container->get('file_system')->realpath($png_image->uri));
353     $assert_session->assertWaitOnAjaxRequest();
354
355     // Files are temporary until the form is saved.
356     $files = $file_storage->loadMultiple();
357     $file = array_pop($files);
358     $this->assertSame('public://type-three-dir', $file_system->dirname($file->getFileUri()));
359     $this->assertTrue($file->isTemporary());
360
361     $this->assertSame($assert_session->fieldExists('Name')->getValue(), $png_image->filename);
362     $assert_session->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Save');
363     $assert_session->assertWaitOnAjaxRequest();
364     $assert_session->pageTextContains('Alternative text field is required');
365     $page->fillField('Alternative text', $this->randomString());
366     $assert_session->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Save');
367     $assert_session->assertWaitOnAjaxRequest();
368
369     // The file should be permanent now.
370     $files = $file_storage->loadMultiple();
371     $file = array_pop($files);
372     $this->assertFalse($file->isTemporary());
373
374     // Ensure the media item was added.
375     $assert_session->pageTextNotContains('Media library');
376     $assert_session->pageTextContains($png_image->filename);
377
378     // Also make sure that we can upload to the unlimited cardinality field.
379     $unlimited_button = $assert_session->elementExists('css', '.media-library-add-button[href*="field_unlimited_media"]');
380     $unlimited_button->click();
381     $assert_session->assertWaitOnAjaxRequest();
382
383     // Multiple uploads should be allowed.
384     // @todo Add test when https://github.com/minkphp/Mink/issues/358 is closed
385     $this->assertTrue($assert_session->fieldExists('Upload')->hasAttribute('multiple'));
386
387     $page->attachFileToField('Upload', $this->container->get('file_system')->realpath($png_image->uri));
388     $assert_session->assertWaitOnAjaxRequest();
389     $page->fillField('Name', 'Unlimited Cardinality Image');
390     $page->fillField('Alternative text', $this->randomString());
391     $assert_session->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Save');
392     $assert_session->assertWaitOnAjaxRequest();
393
394     // Ensure the media item was added.
395     $assert_session->pageTextNotContains('Media library');
396     $assert_session->pageTextContains('Unlimited Cardinality Image');
397
398     // Open the browser again to test type resolution.
399     $twin_button = $assert_session->elementExists('css', '.media-library-open-button[href*="field_twin_media"]');
400     $twin_button->click();
401     $assert_session->assertWaitOnAjaxRequest();
402     $assert_session->pageTextContains('Media library');
403     $assert_session->elementExists('css', '#drupal-modal')->clickLink('Add media');
404     $assert_session->assertWaitOnAjaxRequest();
405
406     $page->attachFileToField('Upload', $file_system->realpath($jpg_image->uri));
407     $assert_session->assertWaitOnAjaxRequest();
408
409     $assert_session->pageTextContains('Select a media type for ' . $jpg_image->filename);
410
411     // Before the type is determined, the file lives in the default upload
412     // location (temporary://).
413     $files = $file_storage->loadMultiple();
414     $file = array_pop($files);
415     $this->assertSame('temporary', $file_system->uriScheme($file->getFileUri()));
416
417     // Both the type_three and type_four media types accept jpg images.
418     $assert_session->buttonExists('Type Three');
419     $assert_session->buttonExists('Type Four')->click();
420     $assert_session->assertWaitOnAjaxRequest();
421
422     // The file should have been moved when the type was selected.
423     $files = $file_storage->loadMultiple();
424     $file = array_pop($files);
425     $this->assertSame('public://type-four-dir', $file_system->dirname($file->getFileUri()));
426     $this->assertSame($assert_session->fieldExists('Name')->getValue(), $jpg_image->filename);
427     $page->fillField('Alternative text', $this->randomString());
428
429     // The type_four media type has another optional image field.
430     $assert_session->pageTextContains('Extra Image');
431     $page->attachFileToField('Extra Image', $this->container->get('file_system')->realpath($jpg_image->uri));
432     $assert_session->assertWaitOnAjaxRequest();
433     // Ensure that the extra image was uploaded to the correct directory.
434     $files = $file_storage->loadMultiple();
435     $file = array_pop($files);
436     $this->assertSame('public://type-four-extra-dir', $file_system->dirname($file->getFileUri()));
437
438     $assert_session->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Save');
439     $assert_session->assertWaitOnAjaxRequest();
440
441     $assert_session->pageTextNotContains('Media library');
442     $assert_session->pageTextContains($jpg_image->filename);
443   }
444
445 }