Issue #2831936 by marcoscano, seanB, chr.fritsch, l0ke, Wim Leers, vijaycs85, phenaproxima, pguillard, johndevman, drubb: Add "File" MediaSource plugin
parent
fde3369b6c
commit
8c3613227a
|
@ -0,0 +1,44 @@
|
||||||
|
langcode: en
|
||||||
|
status: true
|
||||||
|
dependencies:
|
||||||
|
config:
|
||||||
|
- field.field.media.file.field_media_file
|
||||||
|
- media.type.file
|
||||||
|
module:
|
||||||
|
- file
|
||||||
|
id: media.file.default
|
||||||
|
targetEntityType: media
|
||||||
|
bundle: file
|
||||||
|
mode: default
|
||||||
|
content:
|
||||||
|
created:
|
||||||
|
type: datetime_timestamp
|
||||||
|
weight: 10
|
||||||
|
region: content
|
||||||
|
settings: { }
|
||||||
|
third_party_settings: { }
|
||||||
|
field_media_file:
|
||||||
|
settings:
|
||||||
|
progress_indicator: throbber
|
||||||
|
third_party_settings: { }
|
||||||
|
type: file_generic
|
||||||
|
weight: 26
|
||||||
|
region: content
|
||||||
|
name:
|
||||||
|
type: string_textfield
|
||||||
|
weight: -5
|
||||||
|
region: content
|
||||||
|
settings:
|
||||||
|
size: 60
|
||||||
|
placeholder: ''
|
||||||
|
third_party_settings: { }
|
||||||
|
uid:
|
||||||
|
type: entity_reference_autocomplete
|
||||||
|
weight: 5
|
||||||
|
settings:
|
||||||
|
match_operator: CONTAINS
|
||||||
|
size: 60
|
||||||
|
placeholder: ''
|
||||||
|
region: content
|
||||||
|
third_party_settings: { }
|
||||||
|
hidden: { }
|
|
@ -0,0 +1,50 @@
|
||||||
|
langcode: en
|
||||||
|
status: true
|
||||||
|
dependencies:
|
||||||
|
config:
|
||||||
|
- field.field.media.file.field_media_file
|
||||||
|
- image.style.thumbnail
|
||||||
|
- media.type.file
|
||||||
|
module:
|
||||||
|
- file
|
||||||
|
- image
|
||||||
|
- user
|
||||||
|
id: media.file.default
|
||||||
|
targetEntityType: media
|
||||||
|
bundle: file
|
||||||
|
mode: default
|
||||||
|
content:
|
||||||
|
created:
|
||||||
|
label: hidden
|
||||||
|
type: timestamp
|
||||||
|
weight: 0
|
||||||
|
region: content
|
||||||
|
settings:
|
||||||
|
date_format: medium
|
||||||
|
custom_date_format: ''
|
||||||
|
timezone: ''
|
||||||
|
third_party_settings: { }
|
||||||
|
field_media_file:
|
||||||
|
label: above
|
||||||
|
settings: { }
|
||||||
|
third_party_settings: { }
|
||||||
|
type: file_default
|
||||||
|
weight: 6
|
||||||
|
region: content
|
||||||
|
thumbnail:
|
||||||
|
type: image
|
||||||
|
weight: 5
|
||||||
|
label: hidden
|
||||||
|
settings:
|
||||||
|
image_style: thumbnail
|
||||||
|
image_link: ''
|
||||||
|
region: content
|
||||||
|
third_party_settings: { }
|
||||||
|
uid:
|
||||||
|
label: hidden
|
||||||
|
type: author
|
||||||
|
weight: 0
|
||||||
|
region: content
|
||||||
|
settings: { }
|
||||||
|
third_party_settings: { }
|
||||||
|
hidden: { }
|
|
@ -0,0 +1,29 @@
|
||||||
|
langcode: en
|
||||||
|
status: true
|
||||||
|
dependencies:
|
||||||
|
config:
|
||||||
|
- field.storage.media.field_media_file
|
||||||
|
- media.type.file
|
||||||
|
enforced:
|
||||||
|
module:
|
||||||
|
- media
|
||||||
|
module:
|
||||||
|
- file
|
||||||
|
id: media.file.field_media_file
|
||||||
|
field_name: field_media_file
|
||||||
|
entity_type: media
|
||||||
|
bundle: file
|
||||||
|
label: File
|
||||||
|
description: ''
|
||||||
|
required: true
|
||||||
|
translatable: true
|
||||||
|
default_value: { }
|
||||||
|
default_value_callback: ''
|
||||||
|
settings:
|
||||||
|
file_directory: '[date:custom:Y]-[date:custom:m]'
|
||||||
|
file_extensions: 'txt doc docx pdf'
|
||||||
|
max_filesize: ''
|
||||||
|
handler: 'default:file'
|
||||||
|
handler_settings: { }
|
||||||
|
description_field: false
|
||||||
|
field_type: file
|
|
@ -0,0 +1,25 @@
|
||||||
|
langcode: en
|
||||||
|
status: true
|
||||||
|
dependencies:
|
||||||
|
enforced:
|
||||||
|
module:
|
||||||
|
- media
|
||||||
|
module:
|
||||||
|
- file
|
||||||
|
- media
|
||||||
|
id: media.field_media_file
|
||||||
|
field_name: field_media_file
|
||||||
|
entity_type: media
|
||||||
|
type: file
|
||||||
|
settings:
|
||||||
|
uri_scheme: public
|
||||||
|
target_type: file
|
||||||
|
display_field: false
|
||||||
|
display_default: false
|
||||||
|
module: file
|
||||||
|
locked: true
|
||||||
|
cardinality: 1
|
||||||
|
translatable: true
|
||||||
|
indexes: { }
|
||||||
|
persist_with_no_fields: false
|
||||||
|
custom_storage: false
|
|
@ -0,0 +1,12 @@
|
||||||
|
langcode: en
|
||||||
|
status: true
|
||||||
|
dependencies: { }
|
||||||
|
id: file
|
||||||
|
label: File
|
||||||
|
description: "Use local files for reusable media."
|
||||||
|
source: file
|
||||||
|
queue_thumbnail_downloads: false
|
||||||
|
new_revision: true
|
||||||
|
source_configuration:
|
||||||
|
source_field: field_media_file
|
||||||
|
field_map: { }
|
|
@ -44,6 +44,10 @@ media.source.*:
|
||||||
type: mapping
|
type: mapping
|
||||||
label: 'Media source settings'
|
label: 'Media source settings'
|
||||||
|
|
||||||
|
media.source.file:
|
||||||
|
type: media.source.field_aware
|
||||||
|
label: '"File" media source configuration'
|
||||||
|
|
||||||
media.source.field_aware:
|
media.source.field_aware:
|
||||||
type: mapping
|
type: mapping
|
||||||
mapping:
|
mapping:
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 670 B After Width: | Height: | Size: 669 B |
|
@ -27,6 +27,15 @@ function media_install() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_uninstall().
|
||||||
|
*
|
||||||
|
* @TODO Remove when https://www.drupal.org/node/2884202 is fixed.
|
||||||
|
*/
|
||||||
|
function media_uninstall() {
|
||||||
|
\Drupal::moduleHandler()->invoke('field', 'cron');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements hook_requirements().
|
* Implements hook_requirements().
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\media\Plugin\media\Source;
|
||||||
|
|
||||||
|
use Drupal\file\FileInterface;
|
||||||
|
use Drupal\media\MediaInterface;
|
||||||
|
use Drupal\media\MediaTypeInterface;
|
||||||
|
use Drupal\media\MediaSourceBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File entity media source.
|
||||||
|
*
|
||||||
|
* @see \Drupal\file\FileInterface
|
||||||
|
*
|
||||||
|
* @MediaSource(
|
||||||
|
* id = "file",
|
||||||
|
* label = @Translation("File"),
|
||||||
|
* description = @Translation("Use local files for reusable media."),
|
||||||
|
* allowed_field_types = {"file"},
|
||||||
|
* default_thumbnail_filename = "generic.png"
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
class File extends MediaSourceBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getMetadataAttributes() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getMetadata(MediaInterface $media, $attribute_name) {
|
||||||
|
/** @var \Drupal\file\FileInterface $file */
|
||||||
|
$file = $media->get($this->configuration['source_field'])->entity;
|
||||||
|
// If the source field is not required, it may be empty.
|
||||||
|
if (!$file) {
|
||||||
|
return parent::getMetadata($media, $attribute_name);
|
||||||
|
}
|
||||||
|
switch ($attribute_name) {
|
||||||
|
case 'default_name':
|
||||||
|
return $file->getFilename();
|
||||||
|
|
||||||
|
case 'thumbnail_uri':
|
||||||
|
return $this->getThumbnail($file) ?: parent::getMetadata($media, $attribute_name);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return parent::getMetadata($media, $attribute_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the thumbnail image URI based on a file entity.
|
||||||
|
*
|
||||||
|
* @param \Drupal\file\FileInterface $file
|
||||||
|
* A file entity.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* File URI of the thumbnail image or NULL if there is no specific icon.
|
||||||
|
*/
|
||||||
|
protected function getThumbnail(FileInterface $file) {
|
||||||
|
$icon_base = $this->configFactory->get('media.settings')->get('icon_base_uri');
|
||||||
|
|
||||||
|
// We try to automatically use the most specific icon present in the
|
||||||
|
// $icon_base directory, based on the MIME type. For instance, if an
|
||||||
|
// icon file named "pdf.png" is present, it will be used if the file
|
||||||
|
// matches this MIME type.
|
||||||
|
$mimetype = $file->getMimeType();
|
||||||
|
$mimetype = explode('/', $mimetype);
|
||||||
|
|
||||||
|
$icon_names = [
|
||||||
|
$mimetype[0] . '--' . $mimetype[1],
|
||||||
|
$mimetype[1],
|
||||||
|
$mimetype[0],
|
||||||
|
];
|
||||||
|
foreach ($icon_names as $icon_name) {
|
||||||
|
$thumbnail = $icon_base . '/' . $icon_name . '.png';
|
||||||
|
if (is_file($thumbnail)) {
|
||||||
|
return $thumbnail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function createSourceField(MediaTypeInterface $type) {
|
||||||
|
return parent::createSourceField($type)->set('settings', ['file_extensions' => 'txt doc docx pdf']);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests\media\Functional;
|
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the revisionability of media entities.
|
||||||
|
*
|
||||||
|
* @group media
|
||||||
|
*/
|
||||||
|
class MediaRevisionTest extends MediaFunctionalTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests creating revisions of a File media item.
|
||||||
|
*/
|
||||||
|
public function testFileMediaRevision() {
|
||||||
|
$assert = $this->assertSession();
|
||||||
|
|
||||||
|
$uri = 'temporary://foo.txt';
|
||||||
|
file_put_contents($uri, $this->randomString(128));
|
||||||
|
|
||||||
|
// Create a media item.
|
||||||
|
$this->drupalGet('/media/add/file');
|
||||||
|
$page = $this->getSession()->getPage();
|
||||||
|
$page->fillField('Name', 'Foobar');
|
||||||
|
$page->attachFileToField('File', $this->container->get('file_system')->realpath($uri));
|
||||||
|
$page->pressButton('Save and publish');
|
||||||
|
$assert->addressMatches('/^\/media\/[0-9]+$/');
|
||||||
|
|
||||||
|
// The media item was just created, so it should only have one revision.
|
||||||
|
$media = $this->container
|
||||||
|
->get('entity_type.manager')
|
||||||
|
->getStorage('media')
|
||||||
|
->load(1);
|
||||||
|
$this->assertRevisionCount($media, 1);
|
||||||
|
|
||||||
|
// If we edit the item, we should get a new revision.
|
||||||
|
$this->drupalGet('/media/1/edit');
|
||||||
|
$assert->checkboxChecked('Create new revision');
|
||||||
|
$page = $this->getSession()->getPage();
|
||||||
|
$page->fillField('Name', 'Foobaz');
|
||||||
|
$page->pressButton('Save and keep published');
|
||||||
|
$this->assertRevisionCount($media, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that an entity has a certain number of revisions.
|
||||||
|
*
|
||||||
|
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||||
|
* The entity in question.
|
||||||
|
* @param int $expected_revisions
|
||||||
|
* The expected number of revisions.
|
||||||
|
*/
|
||||||
|
protected function assertRevisionCount(EntityInterface $entity, $expected_revisions) {
|
||||||
|
$entity_type = $entity->getEntityType();
|
||||||
|
|
||||||
|
$count = $this->container
|
||||||
|
->get('entity.query')
|
||||||
|
->get($entity_type->id())
|
||||||
|
->count()
|
||||||
|
->allRevisions()
|
||||||
|
->condition($entity_type->getKey('id'), $entity->id())
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$this->assertSame($expected_revisions, (int) $count);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
namespace Drupal\Tests\media\Functional;
|
namespace Drupal\Tests\media\Functional;
|
||||||
|
|
||||||
use Drupal\media\Entity\Media;
|
use Drupal\media\Entity\Media;
|
||||||
|
use Drupal\media\Entity\MediaType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that media UI works correctly.
|
* Ensures that media UI works correctly.
|
||||||
|
@ -28,6 +29,10 @@ class MediaUiFunctionalTest extends MediaFunctionalTestBase {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
$this->drupalPlaceBlock('local_actions_block');
|
$this->drupalPlaceBlock('local_actions_block');
|
||||||
$this->drupalPlaceBlock('local_tasks_block');
|
$this->drupalPlaceBlock('local_tasks_block');
|
||||||
|
|
||||||
|
// We need to test without any default configuration in place.
|
||||||
|
// @TODO: Remove this when https://www.drupal.org/node/2883813 lands.
|
||||||
|
MediaType::load('file')->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests\media\FunctionalJavascript;
|
||||||
|
|
||||||
|
use Drupal\media\Entity\Media;
|
||||||
|
use Drupal\media\Entity\MediaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the file media source.
|
||||||
|
*
|
||||||
|
* @group media
|
||||||
|
*/
|
||||||
|
class MediaSourceFileTest extends MediaSourceTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
// We need to test without any default configuration in place.
|
||||||
|
// @TODO: Remove this as part of https://www.drupal.org/node/2883813.
|
||||||
|
MediaType::load('file')->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the file media source.
|
||||||
|
*/
|
||||||
|
public function testMediaFileSource() {
|
||||||
|
$media_type_id = 'test_media_file_type';
|
||||||
|
$source_field_id = 'field_media_file';
|
||||||
|
|
||||||
|
$session = $this->getSession();
|
||||||
|
$page = $session->getPage();
|
||||||
|
$assert_session = $this->assertSession();
|
||||||
|
|
||||||
|
$this->doTestCreateMediaType($media_type_id, 'file');
|
||||||
|
|
||||||
|
// Hide the name field widget to test default name generation.
|
||||||
|
$this->hideMediaTypeFieldWidget('name', $media_type_id);
|
||||||
|
|
||||||
|
$test_filename = $this->randomMachineName() . '.txt';
|
||||||
|
$test_filepath = 'public://' . $test_filename;
|
||||||
|
file_put_contents($test_filepath, $this->randomMachineName());
|
||||||
|
|
||||||
|
// Create a media item.
|
||||||
|
$this->drupalGet("media/add/{$media_type_id}");
|
||||||
|
$page->attachFileToField("files[{$source_field_id}_0]", \Drupal::service('file_system')->realpath($test_filepath));
|
||||||
|
$assert_session->assertWaitOnAjaxRequest();
|
||||||
|
$page->pressButton('Save and publish');
|
||||||
|
|
||||||
|
$assert_session->addressEquals('media/1');
|
||||||
|
|
||||||
|
// Make sure the thumbnail is displayed.
|
||||||
|
$assert_session->elementAttributeContains('css', '.image-style-thumbnail', 'src', 'generic.png');
|
||||||
|
|
||||||
|
// Load the media and check if the label was properly populated.
|
||||||
|
$media = Media::load(1);
|
||||||
|
$this->assertEquals($test_filename, $media->label());
|
||||||
|
|
||||||
|
// Test the MIME type icon.
|
||||||
|
$icon_base = \Drupal::config('media.settings')->get('icon_base_uri');
|
||||||
|
file_unmanaged_copy($icon_base . '/generic.png', $icon_base . '/text--plain.png');
|
||||||
|
$this->drupalGet("media/add/{$media_type_id}");
|
||||||
|
$page->attachFileToField("files[{$source_field_id}_0]", \Drupal::service('file_system')->realpath($test_filepath));
|
||||||
|
$assert_session->assertWaitOnAjaxRequest();
|
||||||
|
$page->pressButton('Save and publish');
|
||||||
|
$assert_session->elementAttributeContains('css', '.image-style-thumbnail', 'src', 'text--plain.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests\media\FunctionalJavascript;
|
||||||
|
|
||||||
|
use Drupal\field\Entity\FieldConfig;
|
||||||
|
use Drupal\field\Entity\FieldStorageConfig;
|
||||||
|
use Drupal\media\Entity\MediaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for media source tests.
|
||||||
|
*/
|
||||||
|
abstract class MediaSourceTestBase extends MediaJavascriptTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates storage and field instance, attached to a given media type.
|
||||||
|
*
|
||||||
|
* @param string $field_name
|
||||||
|
* The field name.
|
||||||
|
* @param string $field_type
|
||||||
|
* The field type.
|
||||||
|
* @param string $media_type_id
|
||||||
|
* The media type config entity ID.
|
||||||
|
*/
|
||||||
|
protected function createMediaTypeField($field_name, $field_type, $media_type_id) {
|
||||||
|
$storage = FieldStorageConfig::create([
|
||||||
|
'field_name' => $field_name,
|
||||||
|
'entity_type' => 'media',
|
||||||
|
'type' => $field_type,
|
||||||
|
]);
|
||||||
|
$storage->save();
|
||||||
|
|
||||||
|
FieldConfig::create([
|
||||||
|
'field_storage' => $storage,
|
||||||
|
'bundle' => $media_type_id,
|
||||||
|
])->save();
|
||||||
|
|
||||||
|
// Make the field widget visible in the form display.
|
||||||
|
$component = \Drupal::service('plugin.manager.field.widget')
|
||||||
|
->prepareConfiguration($field_type, []);
|
||||||
|
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $entity_form_display */
|
||||||
|
$entity_form_display = entity_get_form_display('media', $media_type_id, 'default');
|
||||||
|
$entity_form_display->setComponent($field_name, $component)
|
||||||
|
->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a set of fields in a media type.
|
||||||
|
*
|
||||||
|
* @param array $fields
|
||||||
|
* An associative array where keys are field names and values field types.
|
||||||
|
* @param string $media_type_id
|
||||||
|
* The media type config entity ID.
|
||||||
|
*/
|
||||||
|
protected function createMediaTypeFields(array $fields, $media_type_id) {
|
||||||
|
foreach ($fields as $field_name => $field_type) {
|
||||||
|
$this->createMediaTypeField($field_name, $field_type, $media_type_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides a widget in the default form display config.
|
||||||
|
*
|
||||||
|
* @param string $field_name
|
||||||
|
* The field name.
|
||||||
|
* @param string $media_type_id
|
||||||
|
* The media type config entity ID.
|
||||||
|
*/
|
||||||
|
protected function hideMediaTypeFieldWidget($field_name, $media_type_id) {
|
||||||
|
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $entity_form_display */
|
||||||
|
$entity_form_display = entity_get_form_display('media', $media_type_id, 'default');
|
||||||
|
if ($entity_form_display->getComponent($field_name)) {
|
||||||
|
$entity_form_display->removeComponent($field_name)->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test generic media type creation.
|
||||||
|
*
|
||||||
|
* @param string $media_type_id
|
||||||
|
* The media type config entity ID.
|
||||||
|
* @param string $source_id
|
||||||
|
* The media source ID.
|
||||||
|
* @param array $provided_fields
|
||||||
|
* (optional) An array of field machine names this type provides.
|
||||||
|
*
|
||||||
|
* @return \Drupal\media\MediaTypeInterface
|
||||||
|
* The created media type.
|
||||||
|
*/
|
||||||
|
public function doTestCreateMediaType($media_type_id, $source_id, array $provided_fields = []) {
|
||||||
|
$session = $this->getSession();
|
||||||
|
$page = $session->getPage();
|
||||||
|
$assert_session = $this->assertSession();
|
||||||
|
|
||||||
|
$this->drupalGet('admin/structure/media/add');
|
||||||
|
$page->fillField('label', $media_type_id);
|
||||||
|
$this->getSession()
|
||||||
|
->wait(5000, "jQuery('.machine-name-value').text() === '{$media_type_id}'");
|
||||||
|
|
||||||
|
// Make sure the source is available.
|
||||||
|
$assert_session->fieldExists('Media source');
|
||||||
|
$assert_session->optionExists('Media source', $source_id);
|
||||||
|
$page->selectFieldOption('Media source', $source_id);
|
||||||
|
$assert_session->assertWaitOnAjaxRequest();
|
||||||
|
|
||||||
|
// Make sure the provided fields are visible on the form.
|
||||||
|
foreach ($provided_fields as $provided_field) {
|
||||||
|
$assert_session->selectExists("field_map[{$provided_field}]");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the form to create the type.
|
||||||
|
$page->pressButton('Save');
|
||||||
|
$assert_session->statusCodeEquals(200);
|
||||||
|
$assert_session->pageTextContains('The media type ' . $media_type_id . ' has been added.');
|
||||||
|
$this->drupalGet('admin/structure/media');
|
||||||
|
$assert_session->pageTextContains($media_type_id);
|
||||||
|
|
||||||
|
// Bundle definitions are statically cached in the context of the test, we
|
||||||
|
// need to make sure we have updated information before proceeding with the
|
||||||
|
// actions on the UI.
|
||||||
|
\Drupal::service('entity_type.bundle.info')->clearCachedBundles();
|
||||||
|
|
||||||
|
return MediaType::load($media_type_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -38,6 +38,10 @@ class MediaUiJavascriptTest extends MediaJavascriptTestBase {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
$this->drupalPlaceBlock('local_actions_block');
|
$this->drupalPlaceBlock('local_actions_block');
|
||||||
$this->drupalPlaceBlock('local_tasks_block');
|
$this->drupalPlaceBlock('local_tasks_block');
|
||||||
|
|
||||||
|
// We need to test without any default configuration in place.
|
||||||
|
// @TODO: Remove this as part of https://www.drupal.org/node/2883813.
|
||||||
|
MediaType::load('file')->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
|
|
||||||
namespace Drupal\Tests\media\Kernel;
|
namespace Drupal\Tests\media\Kernel;
|
||||||
|
|
||||||
|
use Drupal\file\Entity\File;
|
||||||
use Drupal\KernelTests\KernelTestBase;
|
use Drupal\KernelTests\KernelTestBase;
|
||||||
|
use Drupal\media\Entity\Media;
|
||||||
use Drupal\media\Entity\MediaType;
|
use Drupal\media\Entity\MediaType;
|
||||||
|
use Drupal\media\MediaTypeInterface;
|
||||||
|
use org\bovigo\vfs\vfsStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for Media kernel tests.
|
* Base class for Media kernel tests.
|
||||||
|
@ -88,4 +92,42 @@ abstract class MediaKernelTestBase extends KernelTestBase {
|
||||||
return $media_type;
|
return $media_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to generate media entity.
|
||||||
|
*
|
||||||
|
* @param string $filename
|
||||||
|
* String filename with extension.
|
||||||
|
* @param \Drupal\media\MediaTypeInterface $media_type
|
||||||
|
* The the media type.
|
||||||
|
*
|
||||||
|
* @return \Drupal\media\Entity\Media
|
||||||
|
* A media entity.
|
||||||
|
*/
|
||||||
|
protected function generateMedia($filename, MediaTypeInterface $media_type) {
|
||||||
|
vfsStream::setup('drupal_root');
|
||||||
|
vfsStream::create([
|
||||||
|
'sites' => [
|
||||||
|
'default' => [
|
||||||
|
'files' => [
|
||||||
|
$filename => str_repeat('a', 3000),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$file = File::create([
|
||||||
|
'uri' => 'vfs://drupal_root/sites/default/files/' . $filename,
|
||||||
|
]);
|
||||||
|
$file->setPermanent();
|
||||||
|
$file->save();
|
||||||
|
|
||||||
|
return Media::create([
|
||||||
|
'bundle' => $media_type->id(),
|
||||||
|
'name' => 'Mr. Jones',
|
||||||
|
'field_media_file' => [
|
||||||
|
'target_id' => $file->id(),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests\media\Kernel;
|
||||||
|
|
||||||
|
use Drupal\media\Entity\MediaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the file media source.
|
||||||
|
*
|
||||||
|
* @group media
|
||||||
|
*/
|
||||||
|
class MediaSourceFileTest extends MediaKernelTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
// We need to test without any default configuration in place.
|
||||||
|
// @TODO: Remove this as part of https://www.drupal.org/node/2883813.
|
||||||
|
MediaType::load('file')->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the file extension constraint.
|
||||||
|
*/
|
||||||
|
public function testFileExtensionConstraint() {
|
||||||
|
$mediaType = $this->createMediaType('file');
|
||||||
|
// Create a random file that should fail.
|
||||||
|
$media = $this->generateMedia('test.patch', $mediaType);
|
||||||
|
$result = $media->validate();
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertEquals('field_media_file.0', $result->get(0)->getPropertyPath());
|
||||||
|
$this->assertContains('Only files with the following extensions are allowed:', (string) $result->get(0)->getMessage());
|
||||||
|
|
||||||
|
// Create a random file that should pass.
|
||||||
|
$media = $this->generateMedia('test.txt', $mediaType);
|
||||||
|
$result = $media->validate();
|
||||||
|
$this->assertCount(0, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue