cb7ae2ac5c152cd4dfe083d6646c10c42f1c9239
[yaffs-website] / web / core / modules / media / tests / src / FunctionalJavascript / MediaSourceOEmbedVideoTest.php
1 <?php
2
3 namespace Drupal\Tests\media\FunctionalJavascript;
4
5 use Drupal\Core\Session\AccountInterface;
6 use Drupal\media\Entity\Media;
7 use Drupal\media_test_oembed\Controller\ResourceController;
8 use Drupal\Tests\media\Traits\OEmbedTestTrait;
9 use Drupal\user\Entity\Role;
10 use Symfony\Component\DependencyInjection\ContainerInterface;
11
12 /**
13  * Tests the oembed:video media source.
14  *
15  * @group media
16  */
17 class MediaSourceOEmbedVideoTest extends MediaSourceTestBase {
18
19   /**
20    * {@inheritdoc}
21    */
22   public static $modules = ['media_test_oembed'];
23
24   use OEmbedTestTrait;
25
26   /**
27    * {@inheritdoc}
28    */
29   protected function setUp() {
30     parent::setUp();
31     $this->lockHttpClientToFixtures();
32   }
33
34   /**
35    * {@inheritdoc}
36    */
37   protected function initConfig(ContainerInterface $container) {
38     parent::initConfig($container);
39
40     // Enable twig debugging to make testing template usage easy.
41     $parameters = $container->getParameter('twig.config');
42     $parameters['debug'] = TRUE;
43     $this->setContainerParameter('twig.config', $parameters);
44   }
45
46   /**
47    * Tests the oembed media source.
48    */
49   public function testMediaOEmbedVideoSource() {
50     $media_type_id = 'test_media_oembed_type';
51     $provided_fields = [
52       'type',
53       'title',
54       'default_name',
55       'author_name',
56       'author_url',
57       'provider_name',
58       'provider_url',
59       'cache_age',
60       'thumbnail_uri',
61       'thumbnail_width',
62       'thumbnail_height',
63       'url',
64       'width',
65       'height',
66       'html',
67     ];
68
69     $session = $this->getSession();
70     $page = $session->getPage();
71     $assert_session = $this->assertSession();
72
73     $this->doTestCreateMediaType($media_type_id, 'oembed:video', $provided_fields);
74
75     // Create custom fields for the media type to store metadata attributes.
76     $fields = [
77       'field_string_width' => 'string',
78       'field_string_height' => 'string',
79       'field_string_author_name' => 'string',
80     ];
81     $this->createMediaTypeFields($fields, $media_type_id);
82
83     // Hide the name field widget to test default name generation.
84     $this->hideMediaTypeFieldWidget('name', $media_type_id);
85
86     $this->drupalGet("admin/structure/media/manage/$media_type_id");
87     // Only accept Vimeo videos.
88     $page->checkField("source_configuration[providers][Vimeo]");
89     $assert_session->selectExists('field_map[width]')->setValue('field_string_width');
90     $assert_session->selectExists('field_map[height]')->setValue('field_string_height');
91     $assert_session->selectExists('field_map[author_name]')->setValue('field_string_author_name');
92     $assert_session->buttonExists('Save')->press();
93
94     $this->hijackProviderEndpoints();
95     $video_url = 'https://vimeo.com/7073899';
96     ResourceController::setResourceUrl($video_url, $this->getFixturesDirectory() . '/video_vimeo.json');
97
98     // Create a media item.
99     $this->drupalGet("media/add/$media_type_id");
100     $assert_session->fieldExists('Remote video URL')->setValue($video_url);
101     $assert_session->buttonExists('Save')->press();
102
103     $assert_session->addressEquals('admin/content/media');
104
105     // Get the media entity view URL from the creation message.
106     $this->drupalGet($this->assertLinkToCreatedMedia());
107
108     /** @var \Drupal\media\MediaInterface $media */
109     $media = Media::load(1);
110
111     // The thumbnail should have been downloaded.
112     $thumbnail = $media->getSource()->getMetadata($media, 'thumbnail_uri');
113     $this->assertFileExists($thumbnail);
114
115     // Ensure the iframe exists and that its src attribute contains a coherent
116     // URL with the query parameters we expect.
117     $iframe_url = $assert_session->elementExists('css', 'iframe')->getAttribute('src');
118     $iframe_url = parse_url($iframe_url);
119     $this->assertStringEndsWith('/media/oembed', $iframe_url['path']);
120     $this->assertNotEmpty($iframe_url['query']);
121     $query = [];
122     parse_str($iframe_url['query'], $query);
123     $this->assertSame($video_url, $query['url']);
124     $this->assertNotEmpty($query['hash']);
125
126     // Make sure the thumbnail is displayed from uploaded image.
127     $assert_session->elementAttributeContains('css', '.image-style-thumbnail', 'src', '/oembed_thumbnails/' . basename($thumbnail));
128
129     // Load the media and check that all fields are properly populated.
130     $media = Media::load(1);
131     $this->assertSame('Drupal Rap Video - Schipulcon09', $media->getName());
132     $this->assertSame('480', $media->field_string_width->value);
133     $this->assertSame('360', $media->field_string_height->value);
134
135     // Try to create a media asset from a disallowed provider.
136     $this->drupalGet("media/add/$media_type_id");
137     $assert_session->fieldExists('Remote video URL')->setValue('http://www.collegehumor.com/video/40003213/grant-and-katie-are-starting-their-own-company');
138     $page->pressButton('Save');
139
140     $assert_session->pageTextContains('The CollegeHumor provider is not allowed.');
141
142     // Test anonymous access to media via iframe.
143     $this->drupalLogout();
144
145     // Without a hash should be denied.
146     $no_hash_query = array_diff_key($query, ['hash' => '']);
147     $this->drupalGet('media/oembed', ['query' => $no_hash_query]);
148     $assert_session->pageTextNotContains('By the power of Greyskull, Vimeo works!');
149     $assert_session->pageTextContains('Access denied');
150
151     // A correct query should be allowed because the anonymous role has the
152     // 'view media' permission.
153     $this->drupalGet('media/oembed', ['query' => $query]);
154     $assert_session->pageTextContains('By the power of Greyskull, Vimeo works!');
155     $this->assertRaw('core/themes/stable/templates/content/media-oembed-iframe.html.twig');
156     $this->assertNoRaw('core/modules/media/templates/media-oembed-iframe.html.twig');
157
158     // Test themes not inheriting from stable.
159     \Drupal::service('theme_handler')->install(['stark']);
160     $this->config('system.theme')->set('default', 'stark')->save();
161     $this->drupalGet('media/oembed', ['query' => $query]);
162     $assert_session->pageTextContains('By the power of Greyskull, Vimeo works!');
163     $this->assertNoRaw('core/themes/stable/templates/content/media-oembed-iframe.html.twig');
164     $this->assertRaw('core/modules/media/templates/media-oembed-iframe.html.twig');
165
166     // Remove the 'view media' permission to test that this restricts access.
167     $role = Role::load(AccountInterface::ANONYMOUS_ROLE);
168     $role->revokePermission('view media');
169     $role->save();
170     $this->drupalGet('media/oembed', ['query' => $query]);
171     $assert_session->pageTextNotContains('By the power of Greyskull, Vimeo works!');
172     $assert_session->pageTextContains('Access denied');
173   }
174
175   /**
176    * Test that a security warning appears if iFrame domain is not set.
177    */
178   public function testOEmbedSecurityWarning() {
179     $media_type_id = 'test_media_oembed_type';
180     $source_id = 'oembed:video';
181
182     $session = $this->getSession();
183     $page = $session->getPage();
184     $assert_session = $this->assertSession();
185
186     $this->drupalGet('admin/structure/media/add');
187     $page->fillField('label', $media_type_id);
188     $this->getSession()
189       ->wait(5000, "jQuery('.machine-name-value').text() === '{$media_type_id}'");
190
191     // Make sure the source is available.
192     $assert_session->fieldExists('Media source');
193     $assert_session->optionExists('Media source', $source_id);
194     $page->selectFieldOption('Media source', $source_id);
195     $result = $assert_session->waitForElementVisible('css', 'fieldset[data-drupal-selector="edit-source-configuration"]');
196     $this->assertNotEmpty($result);
197
198     $assert_session->pageTextContains('It is potentially insecure to display oEmbed content in a frame');
199
200     $this->config('media.settings')->set('iframe_domain', 'http://example.com')->save();
201
202     $this->drupalGet('admin/structure/media/add');
203     $page->fillField('label', $media_type_id);
204     $this->getSession()
205       ->wait(5000, "jQuery('.machine-name-value').text() === '{$media_type_id}'");
206
207     // Make sure the source is available.
208     $assert_session->fieldExists('Media source');
209     $assert_session->optionExists('Media source', $source_id);
210     $page->selectFieldOption('Media source', $source_id);
211     $result = $assert_session->waitForElementVisible('css', 'fieldset[data-drupal-selector="edit-source-configuration"]');
212     $this->assertNotEmpty($result);
213
214     $assert_session->pageTextNotContains('It is potentially insecure to display oEmbed content in a frame');
215   }
216
217 }