first commit
This commit is contained in:
+15
@@ -0,0 +1,15 @@
|
||||
image.effect.image_module_test_ajax:
|
||||
type: mapping
|
||||
label: 'Ajax test'
|
||||
mapping:
|
||||
test_parameter:
|
||||
type: integer
|
||||
label: 'Test Parameter'
|
||||
|
||||
image.style.*.third_party.image_module_test:
|
||||
type: mapping
|
||||
label: 'Schema for image_module_test module additions to image_style entity'
|
||||
mapping:
|
||||
foo:
|
||||
type: string
|
||||
label: 'Label for foo'
|
||||
@@ -0,0 +1,12 @@
|
||||
name: 'Image test'
|
||||
type: module
|
||||
description: 'Provides hook implementations for testing Image module functionality.'
|
||||
package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-04-19
|
||||
version: '8.3.1'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1492622988
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Provides Image module hook implementations for testing purposes.
|
||||
*/
|
||||
|
||||
use Drupal\image\ImageStyleInterface;
|
||||
|
||||
function image_module_test_file_download($uri) {
|
||||
$default_uri = \Drupal::state()->get('image.test_file_download') ?: FALSE;
|
||||
if ($default_uri == $uri) {
|
||||
return ['X-Image-Owned-By' => 'image_module_test'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_image_effect_info_alter().
|
||||
*
|
||||
* Used to keep a count of cache misses in \Drupal\image\ImageEffectManager.
|
||||
*/
|
||||
function image_module_test_image_effect_info_alter(&$effects) {
|
||||
$image_effects_definition_called = &drupal_static(__FUNCTION__, 0);
|
||||
$image_effects_definition_called++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_image_style_presave().
|
||||
*
|
||||
* Used to save test third party settings in the image style entity.
|
||||
*/
|
||||
function image_module_test_image_style_presave(ImageStyleInterface $style) {
|
||||
$style->setThirdPartySetting('image_module_test', 'foo', 'bar');
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\image_module_test\Plugin\ImageEffect;
|
||||
|
||||
use Drupal\Core\Ajax\AjaxResponse;
|
||||
use Drupal\Core\Ajax\HtmlCommand;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Image\ImageInterface;
|
||||
use Drupal\image\ConfigurableImageEffectBase;
|
||||
|
||||
/**
|
||||
* Provides a test effect using Ajax in the configuration form.
|
||||
*
|
||||
* @ImageEffect(
|
||||
* id = "image_module_test_ajax",
|
||||
* label = @Translation("Ajax test")
|
||||
* )
|
||||
*/
|
||||
class AjaxTestImageEffect extends ConfigurableImageEffectBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'test_parameter' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$form['test_parameter'] = [
|
||||
'#type' => 'number',
|
||||
'#title' => t('Test parameter'),
|
||||
'#default_value' => $this->configuration['test_parameter'],
|
||||
'#min' => 0,
|
||||
];
|
||||
$form['ajax_refresh'] = [
|
||||
'#type' => 'button',
|
||||
'#value' => $this->t('Ajax refresh'),
|
||||
'#ajax' => ['callback' => [$this, 'ajaxCallback']],
|
||||
];
|
||||
$form['ajax_value'] = [
|
||||
'#id' => 'ajax-value',
|
||||
'#type' => 'item',
|
||||
'#title' => $this->t('Ajax value'),
|
||||
'#markup' => 'bar',
|
||||
];
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX callback.
|
||||
*/
|
||||
public function ajaxCallback($form, FormStateInterface $form_state) {
|
||||
$item = [
|
||||
'#type' => 'item',
|
||||
'#title' => $this->t('Ajax value'),
|
||||
'#markup' => microtime(),
|
||||
];
|
||||
$response = new AjaxResponse();
|
||||
$response->addCommand(new HtmlCommand('#ajax-value', $item));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
|
||||
parent::submitConfigurationForm($form, $form_state);
|
||||
|
||||
$this->configuration['test_parameter'] = $form_state->getValue('test_parameter');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function applyEffect(ImageInterface $image) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\image_module_test\Plugin\ImageEffect;
|
||||
|
||||
use Drupal\Core\Image\ImageInterface;
|
||||
use Drupal\image\ImageEffectBase;
|
||||
|
||||
/**
|
||||
* Performs no operation on an image resource.
|
||||
*
|
||||
* @ImageEffect(
|
||||
* id = "image_module_test_null",
|
||||
* label = @Translation("Image module test")
|
||||
* )
|
||||
*/
|
||||
class NullTestImageEffect extends ImageEffectBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transformDimensions(array &$dimensions, $uri) {
|
||||
// Unset image dimensions.
|
||||
$dimensions['width'] = $dimensions['height'] = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function applyEffect(ImageInterface $image) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\image_module_test\Plugin\ImageEffect;
|
||||
|
||||
use Drupal\Core\Image\ImageInterface;
|
||||
use Drupal\image\ImageEffectBase;
|
||||
|
||||
/**
|
||||
* Performs an image operation that depends on the URI of the original image.
|
||||
*
|
||||
* @ImageEffect(
|
||||
* id = "image_module_test_uri_dependent",
|
||||
* label = @Translation("URI dependent test image effect")
|
||||
* )
|
||||
*/
|
||||
class UriDependentTestImageEffect extends ImageEffectBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transformDimensions(array &$dimensions, $uri) {
|
||||
$dimensions = $this->getUriDependentDimensions($uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function applyEffect(ImageInterface $image) {
|
||||
$dimensions = $this->getUriDependentDimensions($image->getSource());
|
||||
return $image->resize($dimensions['width'], $dimensions['height']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the image dimensions dependent on the image file extension.
|
||||
*
|
||||
* @param string $uri
|
||||
* Original image file URI.
|
||||
*
|
||||
* @return array
|
||||
* Associative array.
|
||||
* - width: Integer with the derivative image width.
|
||||
* - height: Integer with the derivative image height.
|
||||
*/
|
||||
protected function getUriDependentDimensions($uri) {
|
||||
$dimensions = [];
|
||||
$extension = pathinfo($uri, PATHINFO_EXTENSION);
|
||||
switch (strtolower($extension)) {
|
||||
case 'png':
|
||||
$dimensions['width'] = $dimensions['height'] = 100;
|
||||
break;
|
||||
|
||||
case 'gif':
|
||||
$dimensions['width'] = $dimensions['height'] = 50;
|
||||
break;
|
||||
|
||||
default:
|
||||
$dimensions['width'] = $dimensions['height'] = 20;
|
||||
break;
|
||||
|
||||
}
|
||||
return $dimensions;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
name: 'Image test views'
|
||||
type: module
|
||||
description: 'Provides default views for views image tests.'
|
||||
package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
dependencies:
|
||||
- image
|
||||
- views
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-04-19
|
||||
version: '8.3.1'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1492622988
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- file
|
||||
- user
|
||||
id: test_image_user_image_data
|
||||
label: test_image_user_image_data
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: users_field_data
|
||||
base_field: uid
|
||||
core: 8.x
|
||||
display:
|
||||
default:
|
||||
display_plugin: default
|
||||
id: default
|
||||
display_title: Master
|
||||
position: 0
|
||||
display_options:
|
||||
access:
|
||||
type: perm
|
||||
options:
|
||||
perm: 'access user profiles'
|
||||
cache:
|
||||
type: tag
|
||||
style:
|
||||
type: table
|
||||
options:
|
||||
grouping: { }
|
||||
row_class: ''
|
||||
default_row_class: true
|
||||
override: true
|
||||
sticky: false
|
||||
caption: ''
|
||||
summary: ''
|
||||
description: ''
|
||||
columns:
|
||||
name: name
|
||||
fid: fid
|
||||
info:
|
||||
name:
|
||||
sortable: false
|
||||
default_sort_order: asc
|
||||
align: ''
|
||||
separator: ''
|
||||
empty_column: false
|
||||
responsive: ''
|
||||
fid:
|
||||
sortable: false
|
||||
default_sort_order: asc
|
||||
align: ''
|
||||
separator: ''
|
||||
empty_column: false
|
||||
responsive: ''
|
||||
default: '-1'
|
||||
empty_table: false
|
||||
row:
|
||||
type: fields
|
||||
options:
|
||||
inline: { }
|
||||
separator: ''
|
||||
hide_empty: false
|
||||
default_field_elements: true
|
||||
relationships:
|
||||
user_picture_target_id:
|
||||
id: user_picture_target_id
|
||||
table: user__user_picture
|
||||
field: user_picture_target_id
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: 'image from user_picture'
|
||||
required: true
|
||||
plugin_id: standard
|
||||
arguments: { }
|
||||
display_extenders: { }
|
||||
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Functional;
|
||||
|
||||
use Drupal\image\Entity\ImageStyle;
|
||||
use Drupal\system\Tests\Image\ToolkitTestBase;
|
||||
|
||||
/**
|
||||
* Tests that the image effects pass parameters to the toolkit correctly.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class ImageEffectsTest extends ToolkitTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['image', 'image_test', 'image_module_test'];
|
||||
|
||||
/**
|
||||
* The image effect manager.
|
||||
*
|
||||
* @var \Drupal\image\ImageEffectManager
|
||||
*/
|
||||
protected $manager;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->manager = $this->container->get('plugin.manager.image.effect');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the image_resize_effect() function.
|
||||
*/
|
||||
public function testResizeEffect() {
|
||||
$this->assertImageEffect('image_resize', [
|
||||
'width' => 1,
|
||||
'height' => 2,
|
||||
]);
|
||||
$this->assertToolkitOperationsCalled(['resize']);
|
||||
|
||||
// Check the parameters.
|
||||
$calls = $this->imageTestGetAllCalls();
|
||||
$this->assertEqual($calls['resize'][0][0], 1, 'Width was passed correctly');
|
||||
$this->assertEqual($calls['resize'][0][1], 2, 'Height was passed correctly');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the image_scale_effect() function.
|
||||
*/
|
||||
public function testScaleEffect() {
|
||||
// @todo: need to test upscaling.
|
||||
$this->assertImageEffect('image_scale', [
|
||||
'width' => 10,
|
||||
'height' => 10,
|
||||
]);
|
||||
$this->assertToolkitOperationsCalled(['scale']);
|
||||
|
||||
// Check the parameters.
|
||||
$calls = $this->imageTestGetAllCalls();
|
||||
$this->assertEqual($calls['scale'][0][0], 10, 'Width was passed correctly');
|
||||
$this->assertEqual($calls['scale'][0][1], 10, 'Height was based off aspect ratio and passed correctly');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the image_crop_effect() function.
|
||||
*/
|
||||
public function testCropEffect() {
|
||||
// @todo should test the keyword offsets.
|
||||
$this->assertImageEffect('image_crop', [
|
||||
'anchor' => 'top-1',
|
||||
'width' => 3,
|
||||
'height' => 4,
|
||||
]);
|
||||
$this->assertToolkitOperationsCalled(['crop']);
|
||||
|
||||
// Check the parameters.
|
||||
$calls = $this->imageTestGetAllCalls();
|
||||
$this->assertEqual($calls['crop'][0][0], 0, 'X was passed correctly');
|
||||
$this->assertEqual($calls['crop'][0][1], 1, 'Y was passed correctly');
|
||||
$this->assertEqual($calls['crop'][0][2], 3, 'Width was passed correctly');
|
||||
$this->assertEqual($calls['crop'][0][3], 4, 'Height was passed correctly');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the ConvertImageEffect plugin.
|
||||
*/
|
||||
public function testConvertEffect() {
|
||||
// Test jpeg.
|
||||
$this->assertImageEffect('image_convert', [
|
||||
'extension' => 'jpeg',
|
||||
]);
|
||||
$this->assertToolkitOperationsCalled(['convert']);
|
||||
|
||||
// Check the parameters.
|
||||
$calls = $this->imageTestGetAllCalls();
|
||||
$this->assertEqual($calls['convert'][0][0], 'jpeg', 'Extension was passed correctly');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the image_scale_and_crop_effect() function.
|
||||
*/
|
||||
public function testScaleAndCropEffect() {
|
||||
$this->assertImageEffect('image_scale_and_crop', [
|
||||
'width' => 5,
|
||||
'height' => 10,
|
||||
]);
|
||||
$this->assertToolkitOperationsCalled(['scale_and_crop']);
|
||||
|
||||
// Check the parameters.
|
||||
$calls = $this->imageTestGetAllCalls();
|
||||
$this->assertEqual($calls['scale_and_crop'][0][0], 5, 'Width was computed and passed correctly');
|
||||
$this->assertEqual($calls['scale_and_crop'][0][1], 10, 'Height was computed and passed correctly');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the image_desaturate_effect() function.
|
||||
*/
|
||||
public function testDesaturateEffect() {
|
||||
$this->assertImageEffect('image_desaturate', []);
|
||||
$this->assertToolkitOperationsCalled(['desaturate']);
|
||||
|
||||
// Check the parameters.
|
||||
$calls = $this->imageTestGetAllCalls();
|
||||
$this->assertEqual(count($calls['desaturate'][0]), 0, 'No parameters were passed.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the image_rotate_effect() function.
|
||||
*/
|
||||
public function testRotateEffect() {
|
||||
// @todo: need to test with 'random' => TRUE
|
||||
$this->assertImageEffect('image_rotate', [
|
||||
'degrees' => 90,
|
||||
'bgcolor' => '#fff',
|
||||
]);
|
||||
$this->assertToolkitOperationsCalled(['rotate']);
|
||||
|
||||
// Check the parameters.
|
||||
$calls = $this->imageTestGetAllCalls();
|
||||
$this->assertEqual($calls['rotate'][0][0], 90, 'Degrees were passed correctly');
|
||||
$this->assertEqual($calls['rotate'][0][1], '#fff', 'Background color was passed correctly');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test image effect caching.
|
||||
*/
|
||||
public function testImageEffectsCaching() {
|
||||
$image_effect_definitions_called = &drupal_static('image_module_test_image_effect_info_alter');
|
||||
|
||||
// First call should grab a fresh copy of the data.
|
||||
$manager = $this->container->get('plugin.manager.image.effect');
|
||||
$effects = $manager->getDefinitions();
|
||||
$this->assertTrue($image_effect_definitions_called === 1, 'image_effect_definitions() generated data.');
|
||||
|
||||
// Second call should come from cache.
|
||||
drupal_static_reset('image_module_test_image_effect_info_alter');
|
||||
$cached_effects = $manager->getDefinitions();
|
||||
$this->assertTrue($image_effect_definitions_called === 0, 'image_effect_definitions() returned data from cache.');
|
||||
|
||||
$this->assertTrue($effects == $cached_effects, 'Cached effects are the same as generated effects.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if validation errors are passed plugin form to the parent form.
|
||||
*/
|
||||
public function testEffectFormValidationErrors() {
|
||||
$account = $this->drupalCreateUser(['administer image styles']);
|
||||
$this->drupalLogin($account);
|
||||
/** @var \Drupal\image\ImageStyleInterface $style */
|
||||
$style = ImageStyle::load('thumbnail');
|
||||
// Image Scale is the only effect shipped with 'thumbnail', by default.
|
||||
$uuids = $style->getEffects()->getInstanceIds();
|
||||
$uuid = key($uuids);
|
||||
|
||||
// We are posting the form with both, width and height, empty.
|
||||
$edit = ['data[width]' => '', 'data[height]' => ''];
|
||||
$path = 'admin/config/media/image-styles/manage/thumbnail/effects/' . $uuid;
|
||||
$this->drupalPostForm($path, $edit, t('Update effect'));
|
||||
// Check that the error message has been displayed.
|
||||
$this->assertText(t('Width and height can not both be blank.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts the effect processing of an image effect plugin.
|
||||
*
|
||||
* @param string $effect_name
|
||||
* The name of the image effect to test.
|
||||
* @param array $data
|
||||
* The data to pass to the image effect.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the assertion succeeded, FALSE otherwise.
|
||||
*/
|
||||
protected function assertImageEffect($effect_name, array $data) {
|
||||
$effect = $this->manager->createInstance($effect_name, ['data' => $data]);
|
||||
return $this->assertTrue($effect->applyEffect($this->image), 'Function returned the expected value.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Functional;
|
||||
|
||||
use Drupal\Tests\image\Kernel\ImageFieldCreationTrait;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* TODO: Test the following functions.
|
||||
*
|
||||
* image.effects.inc:
|
||||
* image_style_generate()
|
||||
* \Drupal\image\ImageStyleInterface::createDerivative()
|
||||
*
|
||||
* image.module:
|
||||
* image_style_options()
|
||||
* \Drupal\image\ImageStyleInterface::flush()
|
||||
* image_filter_keyword()
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class provides methods specifically for testing Image's field handling.
|
||||
*/
|
||||
abstract class ImageFieldTestBase extends BrowserTestBase {
|
||||
|
||||
use ImageFieldCreationTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'image', 'field_ui', 'image_module_test'];
|
||||
|
||||
/**
|
||||
* An user with permissions to administer content types and image styles.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create Basic page and Article node types.
|
||||
if ($this->profile != 'standard') {
|
||||
$this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
|
||||
$this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
|
||||
}
|
||||
|
||||
$this->adminUser = $this->drupalCreateUser(['access content', 'access administration pages', 'administer site configuration', 'administer content types', 'administer node fields', 'administer nodes', 'create article content', 'edit any article content', 'delete any article content', 'administer image styles', 'administer node display']);
|
||||
$this->drupalLogin($this->adminUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Preview an image in a node.
|
||||
*
|
||||
* @param \Drupal\Core\Image\ImageInterface $image
|
||||
* A file object representing the image to upload.
|
||||
* @param string $field_name
|
||||
* Name of the image field the image should be attached to.
|
||||
* @param string $type
|
||||
* The type of node to create.
|
||||
*/
|
||||
public function previewNodeImage($image, $field_name, $type) {
|
||||
$edit = [
|
||||
'title[0][value]' => $this->randomMachineName(),
|
||||
];
|
||||
$edit['files[' . $field_name . '_0]'] = drupal_realpath($image->uri);
|
||||
$this->drupalPostForm('node/add/' . $type, $edit, t('Preview'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload an image to a node.
|
||||
*
|
||||
* @param $image
|
||||
* A file object representing the image to upload.
|
||||
* @param $field_name
|
||||
* Name of the image field the image should be attached to.
|
||||
* @param $type
|
||||
* The type of node to create.
|
||||
* @param $alt
|
||||
* The alt text for the image. Use if the field settings require alt text.
|
||||
*/
|
||||
public function uploadNodeImage($image, $field_name, $type, $alt = '') {
|
||||
$edit = [
|
||||
'title[0][value]' => $this->randomMachineName(),
|
||||
];
|
||||
$edit['files[' . $field_name . '_0]'] = drupal_realpath($image->uri);
|
||||
$this->drupalPostForm('node/add/' . $type, $edit, t('Save and publish'));
|
||||
if ($alt) {
|
||||
// Add alt text.
|
||||
$this->drupalPostForm(NULL, [$field_name . '[0][alt]' => $alt], t('Save and publish'));
|
||||
}
|
||||
|
||||
// Retrieve ID of the newly created node from the current URL.
|
||||
$matches = [];
|
||||
preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
|
||||
return isset($matches[1]) ? $matches[1] : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the fid of the last inserted file.
|
||||
*/
|
||||
protected function getLastFileId() {
|
||||
return (int) db_query('SELECT MAX(fid) FROM {file_managed}')->fetchField();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Functional;
|
||||
|
||||
/**
|
||||
* Tests the image field widget.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class ImageFieldWidgetTest extends ImageFieldTestBase {
|
||||
|
||||
/**
|
||||
* Tests file widget element.
|
||||
*/
|
||||
public function testWidgetElement() {
|
||||
// Check for image widget in add/node/article page
|
||||
$field_name = strtolower($this->randomMachineName());
|
||||
$min_resolution = 50;
|
||||
$max_resolution = 100;
|
||||
$field_settings = [
|
||||
'max_resolution' => $max_resolution . 'x' . $max_resolution,
|
||||
'min_resolution' => $min_resolution . 'x' . $min_resolution,
|
||||
'alt_field' => 0,
|
||||
];
|
||||
$this->createImageField($field_name, 'article', [], $field_settings, [], [], 'Image test on [site:name]');
|
||||
$this->drupalGet('node/add/article');
|
||||
$this->assertNotEqual(0, count($this->xpath('//div[contains(@class, "field--widget-image-image")]')), 'Image field widget found on add/node page', 'Browser');
|
||||
$this->assertNotEqual(0, count($this->xpath('//input[contains(@accept, "image/*")]')), 'Image field widget limits accepted files.', 'Browser');
|
||||
$this->assertNoText('Image test on [site:name]');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Functional;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Core\Entity\Entity\EntityViewDisplay;
|
||||
|
||||
/**
|
||||
* Tests image style deletion using the UI.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class ImageStyleDeleteTest extends ImageFieldTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Create an image field 'foo' having the image style 'medium' as widget
|
||||
// preview and as formatter.
|
||||
$this->createImageField('foo', 'page', [], [], ['preview_image_style' => 'medium'], ['image_style' => 'medium']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests image style deletion.
|
||||
*/
|
||||
public function testDelete() {
|
||||
$this->drupalGet('admin/config/media/image-styles/manage/medium/delete');
|
||||
// Checks that the 'replacement' select element is displayed.
|
||||
$this->assertFieldByName('replacement');
|
||||
// Checks that UI messages are correct.
|
||||
$this->assertRaw(t('If this style is in use on the site, you may select another style to replace it. All images that have been generated for this style will be permanently deleted. If no replacement style is selected, the dependent configurations might need manual reconfiguration.'));
|
||||
$this->assertNoRaw(t('All images that have been generated for this style will be permanently deleted. The dependent configurations might need manual reconfiguration.'));
|
||||
|
||||
// Delete 'medium' image style but replace it with 'thumbnail'. This style
|
||||
// is involved in 'node.page.default' display view and form.
|
||||
$this->drupalPostForm(NULL, ['replacement' => 'thumbnail'], t('Delete'));
|
||||
|
||||
/** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $view_display */
|
||||
$view_display = EntityViewDisplay::load('node.page.default');
|
||||
// Checks that the formatter setting is replaced.
|
||||
if ($this->assertNotNull($component = $view_display->getComponent('foo'))) {
|
||||
$this->assertIdentical($component['settings']['image_style'], 'thumbnail');
|
||||
}
|
||||
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
|
||||
$form_display = EntityFormDisplay::load('node.page.default');
|
||||
// Check that the widget setting is replaced.
|
||||
if ($this->assertNotNull($component = $form_display->getComponent('foo'))) {
|
||||
$this->assertIdentical($component['settings']['preview_image_style'], 'thumbnail');
|
||||
}
|
||||
|
||||
$this->drupalGet('admin/config/media/image-styles/manage/thumbnail/delete');
|
||||
// Checks that the 'replacement' select element is displayed.
|
||||
$this->assertFieldByName('replacement');
|
||||
// Checks that UI messages are correct.
|
||||
$this->assertRaw(t('If this style is in use on the site, you may select another style to replace it. All images that have been generated for this style will be permanently deleted. If no replacement style is selected, the dependent configurations might need manual reconfiguration.'));
|
||||
$this->assertNoRaw(t('All images that have been generated for this style will be permanently deleted. The dependent configurations might need manual reconfiguration.'));
|
||||
|
||||
// Delete 'thumbnail' image style. Provide no replacement.
|
||||
$this->drupalPostForm(NULL, [], t('Delete'));
|
||||
|
||||
$view_display = EntityViewDisplay::load('node.page.default');
|
||||
// Checks that the formatter setting is disabled.
|
||||
$this->assertNull($view_display->getComponent('foo'));
|
||||
$this->assertNotNull($view_display->get('hidden')['foo']);
|
||||
// Checks that widget setting is preserved with the image preview disabled.
|
||||
$form_display = EntityFormDisplay::load('node.page.default');
|
||||
$this->assertNotNull($widget = $form_display->getComponent('foo'));
|
||||
$this->assertIdentical($widget['settings']['preview_image_style'], '');
|
||||
|
||||
// Now, there's only one image style configured on the system: 'large'.
|
||||
$this->drupalGet('admin/config/media/image-styles/manage/large/delete');
|
||||
// Checks that the 'replacement' select element is not displayed.
|
||||
$this->assertNoFieldByName('replacement');
|
||||
// Checks that UI messages are correct.
|
||||
$this->assertNoRaw(t('If this style is in use on the site, you may select another style to replace it. All images that have been generated for this style will be permanently deleted. If no replacement style is selected, the dependent configurations might need manual reconfiguration.'));
|
||||
$this->assertRaw(t('All images that have been generated for this style will be permanently deleted. The dependent configurations might need manual reconfiguration.'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\FunctionalJavascript;
|
||||
|
||||
use Drupal\file\Entity\File;
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
use Drupal\Tests\image\Kernel\ImageFieldCreationTrait;
|
||||
use Drupal\Tests\TestFileCreationTrait;
|
||||
|
||||
/**
|
||||
* Tests the JavaScript functionality of the "image" in-place editor.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class QuickEditImageTest extends JavascriptTestBase {
|
||||
|
||||
use ImageFieldCreationTrait;
|
||||
use TestFileCreationTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'image', 'field_ui', 'contextual', 'quickedit', 'toolbar'];
|
||||
|
||||
/**
|
||||
* A user with permissions to edit Articles and use Quick Edit.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $contentAuthorUser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create the Article node type.
|
||||
$this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
|
||||
|
||||
// Log in as a content author who can use Quick Edit and edit Articles.
|
||||
$this->contentAuthorUser = $this->drupalCreateUser([
|
||||
'access contextual links',
|
||||
'access toolbar',
|
||||
'access in-place editing',
|
||||
'access content',
|
||||
'create article content',
|
||||
'edit any article content',
|
||||
'delete any article content',
|
||||
]);
|
||||
$this->drupalLogin($this->contentAuthorUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if an image can be uploaded inline with Quick Edit.
|
||||
*/
|
||||
public function testUpload() {
|
||||
// Create a field with a basic filetype restriction.
|
||||
$field_name = strtolower($this->randomMachineName());
|
||||
$field_settings = [
|
||||
'file_extensions' => 'png',
|
||||
];
|
||||
$formatter_settings = [
|
||||
'image_style' => 'large',
|
||||
'image_link' => '',
|
||||
];
|
||||
$this->createImageField($field_name, 'article', [], $field_settings, [], $formatter_settings);
|
||||
|
||||
// Find images that match our field settings.
|
||||
$valid_images = [];
|
||||
foreach ($this->getTestFiles('image') as $image) {
|
||||
// This regex is taken from file_validate_extensions().
|
||||
$regex = '/\.(' . preg_replace('/ +/', '|', preg_quote($field_settings['file_extensions'])) . ')$/i';
|
||||
if (preg_match($regex, $image->filename)) {
|
||||
$valid_images[] = $image;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure we have at least two valid images.
|
||||
$this->assertGreaterThanOrEqual(2, count($valid_images));
|
||||
|
||||
// Create a File entity for the initial image.
|
||||
$file = File::create([
|
||||
'uri' => $valid_images[0]->uri,
|
||||
'uid' => $this->contentAuthorUser->id(),
|
||||
'status' => FILE_STATUS_PERMANENT,
|
||||
]);
|
||||
$file->save();
|
||||
|
||||
// Use the first valid image to create a new Node.
|
||||
$image_factory = $this->container->get('image.factory');
|
||||
$image = $image_factory->get($valid_images[0]->uri);
|
||||
$node = $this->drupalCreateNode([
|
||||
'type' => 'article',
|
||||
'title' => t('Test Node'),
|
||||
$field_name => [
|
||||
'target_id' => $file->id(),
|
||||
'alt' => 'Hello world',
|
||||
'title' => '',
|
||||
'width' => $image->getWidth(),
|
||||
'height' => $image->getHeight(),
|
||||
],
|
||||
]);
|
||||
|
||||
// Visit the new Node.
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
|
||||
// Assemble common CSS selectors.
|
||||
$entity_selector = '[data-quickedit-entity-id="node/' . $node->id() . '"]';
|
||||
$field_selector = '[data-quickedit-field-id="node/' . $node->id() . '/' . $field_name . '/' . $node->language()->getId() . '/full"]';
|
||||
$original_image_selector = 'img[src*="' . $valid_images[0]->filename . '"][alt="Hello world"]';
|
||||
$new_image_selector = 'img[src*="' . $valid_images[1]->filename . '"][alt="New text"]';
|
||||
|
||||
// Assert that the initial image is present.
|
||||
$this->assertSession()->elementExists('css', $entity_selector . ' ' . $field_selector . ' ' . $original_image_selector);
|
||||
|
||||
// Wait until Quick Edit loads.
|
||||
$condition = "jQuery('" . $entity_selector . " .quickedit').length > 0";
|
||||
$this->assertJsCondition($condition, 10000);
|
||||
|
||||
// Initiate Quick Editing.
|
||||
$this->click('.contextual-toolbar-tab button');
|
||||
$this->click($entity_selector . ' [data-contextual-id] > button');
|
||||
$this->click($entity_selector . ' [data-contextual-id] .quickedit > a');
|
||||
$this->click($field_selector);
|
||||
|
||||
// Wait for the field info to load and set new alt text.
|
||||
$condition = "jQuery('.quickedit-image-field-info').length > 0";
|
||||
$this->assertJsCondition($condition, 10000);
|
||||
$input = $this->assertSession()->elementExists('css', '.quickedit-image-field-info input[name="alt"]');
|
||||
$input->setValue('New text');
|
||||
|
||||
// Check that our Dropzone element exists.
|
||||
$this->assertSession()->elementExists('css', $field_selector . ' .quickedit-image-dropzone');
|
||||
|
||||
// Our headless browser can't drag+drop files, but we can mock the event.
|
||||
// Append a hidden upload element to the DOM.
|
||||
$script = 'jQuery("<input id=\"quickedit-image-test-input\" type=\"file\" />").appendTo("body")';
|
||||
$this->getSession()->executeScript($script);
|
||||
|
||||
// Find the element, and set its value to our new image.
|
||||
$input = $this->assertSession()->elementExists('css', '#quickedit-image-test-input');
|
||||
$filepath = $this->container->get('file_system')->realpath($valid_images[1]->uri);
|
||||
$input->attachFile($filepath);
|
||||
|
||||
// Trigger the upload logic with a mock "drop" event.
|
||||
$script = 'var e = jQuery.Event("drop");'
|
||||
. 'e.originalEvent = {dataTransfer: {files: jQuery("#quickedit-image-test-input").get(0).files}};'
|
||||
. 'e.preventDefault = e.stopPropagation = function () {};'
|
||||
. 'jQuery(".quickedit-image-dropzone").trigger(e);';
|
||||
$this->getSession()->executeScript($script);
|
||||
|
||||
// Wait for the dropzone element to be removed (i.e. loading is done).
|
||||
$condition = "jQuery('" . $field_selector . " .quickedit-image-dropzone').length == 0";
|
||||
$this->assertJsCondition($condition, 20000);
|
||||
|
||||
// To prevent 403s on save, we re-set our request (cookie) state.
|
||||
$this->prepareRequest();
|
||||
|
||||
// Save the change.
|
||||
$this->click('.quickedit-button.action-save');
|
||||
$this->assertSession()->assertWaitOnAjaxRequest();
|
||||
|
||||
// Re-visit the page to make sure the edit worked.
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
|
||||
// Check that the new image appears as expected.
|
||||
$this->assertSession()->elementNotExists('css', $entity_selector . ' ' . $field_selector . ' ' . $original_image_selector);
|
||||
$this->assertSession()->elementExists('css', $entity_selector . ' ' . $field_selector . ' ' . $new_image_selector);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Kernel;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Provides a helper method for creating Image fields.
|
||||
*/
|
||||
trait ImageFieldCreationTrait {
|
||||
|
||||
/**
|
||||
* Create a new image field.
|
||||
*
|
||||
* @param string $name
|
||||
* The name of the new field (all lowercase), exclude the "field_" prefix.
|
||||
* @param string $type_name
|
||||
* The node type that this field will be added to.
|
||||
* @param array $storage_settings
|
||||
* (optional) A list of field storage settings that will be added to the
|
||||
* defaults.
|
||||
* @param array $field_settings
|
||||
* (optional) A list of instance settings that will be added to the instance
|
||||
* defaults.
|
||||
* @param array $widget_settings
|
||||
* (optional) Widget settings to be added to the widget defaults.
|
||||
* @param array $formatter_settings
|
||||
* (optional) Formatter settings to be added to the formatter defaults.
|
||||
* @param string $description
|
||||
* (optional) A description for the field. Defaults to ''.
|
||||
*/
|
||||
protected function createImageField($name, $type_name, $storage_settings = [], $field_settings = [], $widget_settings = [], $formatter_settings = [], $description = '') {
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $name,
|
||||
'entity_type' => 'node',
|
||||
'type' => 'image',
|
||||
'settings' => $storage_settings,
|
||||
'cardinality' => !empty($storage_settings['cardinality']) ? $storage_settings['cardinality'] : 1,
|
||||
])->save();
|
||||
|
||||
$field_config = FieldConfig::create([
|
||||
'field_name' => $name,
|
||||
'label' => $name,
|
||||
'entity_type' => 'node',
|
||||
'bundle' => $type_name,
|
||||
'required' => !empty($field_settings['required']),
|
||||
'settings' => $field_settings,
|
||||
'description' => $description,
|
||||
]);
|
||||
$field_config->save();
|
||||
|
||||
entity_get_form_display('node', $type_name, 'default')
|
||||
->setComponent($name, [
|
||||
'type' => 'image_image',
|
||||
'settings' => $widget_settings,
|
||||
])
|
||||
->save();
|
||||
|
||||
entity_get_display('node', $type_name, 'default')
|
||||
->setComponent($name, [
|
||||
'type' => 'image',
|
||||
'settings' => $formatter_settings,
|
||||
])
|
||||
->save();
|
||||
|
||||
return $field_config;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Kernel;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the image field rendering using entity fields of the image field type.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class ImageFormatterTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['file', 'image'];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $bundle;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldName;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface
|
||||
*/
|
||||
protected $display;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installConfig(['field']);
|
||||
$this->installEntitySchema('entity_test');
|
||||
$this->installEntitySchema('file');
|
||||
$this->installSchema('file', ['file_usage']);
|
||||
|
||||
$this->entityType = 'entity_test';
|
||||
$this->bundle = $this->entityType;
|
||||
$this->fieldName = Unicode::strtolower($this->randomMachineName());
|
||||
|
||||
FieldStorageConfig::create([
|
||||
'entity_type' => $this->entityType,
|
||||
'field_name' => $this->fieldName,
|
||||
'type' => 'image',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => $this->entityType,
|
||||
'field_name' => $this->fieldName,
|
||||
'bundle' => $this->bundle,
|
||||
'settings' => [
|
||||
'file_extensions' => 'jpg',
|
||||
],
|
||||
])->save();
|
||||
|
||||
$this->display = entity_get_display($this->entityType, $this->bundle, 'default')
|
||||
->setComponent($this->fieldName, [
|
||||
'type' => 'image',
|
||||
'label' => 'hidden',
|
||||
]);
|
||||
$this->display->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the cache tags from image formatters.
|
||||
*/
|
||||
public function testImageFormatterCacheTags() {
|
||||
// Create a test entity with the image field set.
|
||||
$entity = EntityTest::create([
|
||||
'name' => $this->randomMachineName(),
|
||||
]);
|
||||
$entity->{$this->fieldName}->generateSampleItems(2);
|
||||
$entity->save();
|
||||
|
||||
// Generate the render array to verify if the cache tags are as expected.
|
||||
$build = $this->display->build($entity);
|
||||
|
||||
$this->assertEquals($entity->{$this->fieldName}[0]->entity->getCacheTags(), $build[$this->fieldName][0]['#cache']['tags'], 'First image cache tags is as expected');
|
||||
$this->assertEquals($entity->{$this->fieldName}[1]->entity->getCacheTags(), $build[$this->fieldName][1]['#cache']['tags'], 'Second image cache tags is as expected');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Kernel;
|
||||
|
||||
use Drupal\image\Entity\ImageStyle;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests config import for Image styles.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class ImageImportTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system', 'image', 'image_module_test'];
|
||||
|
||||
/**
|
||||
* Tests importing image styles.
|
||||
*/
|
||||
public function testImport() {
|
||||
$style = ImageStyle::create([
|
||||
'name' => 'test'
|
||||
]);
|
||||
|
||||
$style->addImageEffect(['id' => 'image_module_test_null']);
|
||||
$style->addImageEffect(['id' => 'image_module_test_null']);
|
||||
$style->save();
|
||||
|
||||
$this->assertEqual(count($style->getEffects()), 2);
|
||||
|
||||
$uuid = \Drupal::service('uuid')->generate();
|
||||
$style->set('effects', [
|
||||
$uuid => [
|
||||
'id' => 'image_module_test_null',
|
||||
],
|
||||
]);
|
||||
$style->save();
|
||||
|
||||
$style = ImageStyle::load('test');
|
||||
$this->assertEqual(count($style->getEffects()), 1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Kernel;
|
||||
|
||||
use Drupal\Core\Field\FieldItemInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\file\Entity\File;
|
||||
|
||||
/**
|
||||
* Tests using entity fields of the image field type.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class ImageItemTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['file', 'image'];
|
||||
|
||||
/**
|
||||
* Created file entity.
|
||||
*
|
||||
* @var \Drupal\file\Entity\File
|
||||
*/
|
||||
protected $image;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Image\ImageFactory
|
||||
*/
|
||||
protected $imageFactory;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('file');
|
||||
$this->installSchema('file', ['file_usage']);
|
||||
|
||||
FieldStorageConfig::create([
|
||||
'entity_type' => 'entity_test',
|
||||
'field_name' => 'image_test',
|
||||
'type' => 'image',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => 'entity_test',
|
||||
'field_name' => 'image_test',
|
||||
'bundle' => 'entity_test',
|
||||
'settings' => [
|
||||
'file_extensions' => 'jpg',
|
||||
],
|
||||
])->save();
|
||||
file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', 'public://example.jpg');
|
||||
$this->image = File::create([
|
||||
'uri' => 'public://example.jpg',
|
||||
]);
|
||||
$this->image->save();
|
||||
$this->imageFactory = $this->container->get('image.factory');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests using entity fields of the image field type.
|
||||
*/
|
||||
public function testImageItem() {
|
||||
// Create a test entity with the image field set.
|
||||
$entity = EntityTest::create();
|
||||
$entity->image_test->target_id = $this->image->id();
|
||||
$entity->image_test->alt = $alt = $this->randomMachineName();
|
||||
$entity->image_test->title = $title = $this->randomMachineName();
|
||||
$entity->name->value = $this->randomMachineName();
|
||||
$entity->save();
|
||||
|
||||
$entity = EntityTest::load($entity->id());
|
||||
$this->assertTrue($entity->image_test instanceof FieldItemListInterface, 'Field implements interface.');
|
||||
$this->assertTrue($entity->image_test[0] instanceof FieldItemInterface, 'Field item implements interface.');
|
||||
$this->assertEqual($entity->image_test->target_id, $this->image->id());
|
||||
$this->assertEqual($entity->image_test->alt, $alt);
|
||||
$this->assertEqual($entity->image_test->title, $title);
|
||||
$image = $this->imageFactory->get('public://example.jpg');
|
||||
$this->assertEqual($entity->image_test->width, $image->getWidth());
|
||||
$this->assertEqual($entity->image_test->height, $image->getHeight());
|
||||
$this->assertEqual($entity->image_test->entity->id(), $this->image->id());
|
||||
$this->assertEqual($entity->image_test->entity->uuid(), $this->image->uuid());
|
||||
|
||||
// Make sure the computed entity reflects updates to the referenced file.
|
||||
file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', 'public://example-2.jpg');
|
||||
$image2 = File::create([
|
||||
'uri' => 'public://example-2.jpg',
|
||||
]);
|
||||
$image2->save();
|
||||
|
||||
$entity->image_test->target_id = $image2->id();
|
||||
$entity->image_test->alt = $new_alt = $this->randomMachineName();
|
||||
// The width and height is only updated when width is not set.
|
||||
$entity->image_test->width = NULL;
|
||||
$entity->save();
|
||||
$this->assertEqual($entity->image_test->entity->id(), $image2->id());
|
||||
$this->assertEqual($entity->image_test->entity->getFileUri(), $image2->getFileUri());
|
||||
$image = $this->imageFactory->get('public://example-2.jpg');
|
||||
$this->assertEqual($entity->image_test->width, $image->getWidth());
|
||||
$this->assertEqual($entity->image_test->height, $image->getHeight());
|
||||
$this->assertEqual($entity->image_test->alt, $new_alt);
|
||||
|
||||
// Check that the image item can be set to the referenced file directly.
|
||||
$entity->image_test = $this->image;
|
||||
$this->assertEqual($entity->image_test->target_id, $this->image->id());
|
||||
|
||||
// Delete the image and try to save the entity again.
|
||||
$this->image->delete();
|
||||
$entity = EntityTest::create(['mame' => $this->randomMachineName()]);
|
||||
$entity->save();
|
||||
|
||||
// Test image item properties.
|
||||
$expected = ['target_id', 'entity', 'alt', 'title', 'width', 'height'];
|
||||
$properties = $entity->getFieldDefinition('image_test')->getFieldStorageDefinition()->getPropertyDefinitions();
|
||||
$this->assertEqual(array_keys($properties), $expected);
|
||||
|
||||
// Test the generateSampleValue() method.
|
||||
$entity = EntityTest::create();
|
||||
$entity->image_test->generateSampleItems();
|
||||
$this->entityValidateAndSave($entity);
|
||||
$this->assertEqual($entity->image_test->entity->get('filemime')->value, 'image/jpeg');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Kernel;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\StreamWrapper\PrivateStream;
|
||||
use Drupal\Core\StreamWrapper\PublicStream;
|
||||
use Drupal\file_test\StreamWrapper\DummyReadOnlyStreamWrapper;
|
||||
use Drupal\file_test\StreamWrapper\DummyRemoteReadOnlyStreamWrapper;
|
||||
use Drupal\file_test\StreamWrapper\DummyStreamWrapper;
|
||||
use Drupal\image\Entity\ImageStyle;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests derivative generation with source images using stream wrappers.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class ImageStyleCustomStreamWrappersTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public static $modules = ['system', 'image'];
|
||||
|
||||
/**
|
||||
* A testing image style entity.
|
||||
*
|
||||
* @var \Drupal\image\ImageStyleInterface
|
||||
*/
|
||||
protected $imageStyle;
|
||||
|
||||
/**
|
||||
* The file system service.
|
||||
*
|
||||
* @var \Drupal\Core\File\FileSystemInterface
|
||||
*/
|
||||
protected $fileSystem;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->fileSystem = $this->container->get('file_system');
|
||||
$this->config('system.file')->set('default_scheme', 'public')->save();
|
||||
$this->imageStyle = ImageStyle::create(['name' => 'test']);
|
||||
$this->imageStyle->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function register(ContainerBuilder $container) {
|
||||
parent::register($container);
|
||||
foreach ($this->providerTestCustomStreamWrappers() as $stream_wrapper) {
|
||||
$scheme = $stream_wrapper[0];
|
||||
$class = $stream_wrapper[2];
|
||||
$container->register("stream_wrapper.$scheme", $class)
|
||||
->addTag('stream_wrapper', ['scheme' => $scheme]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests derivative creation with several source on a local writable stream.
|
||||
*
|
||||
* @dataProvider providerTestCustomStreamWrappers
|
||||
*
|
||||
* @param string $source_scheme
|
||||
* The source stream wrapper scheme.
|
||||
* @param string $expected_scheme
|
||||
* The derivative expected stream wrapper scheme.
|
||||
*/
|
||||
public function testCustomStreamWrappers($source_scheme, $expected_scheme) {
|
||||
$derivative_uri = $this->imageStyle->buildUri("$source_scheme://some/path/image.png");
|
||||
$derivative_scheme = $this->fileSystem->uriScheme($derivative_uri);
|
||||
|
||||
// Check that the derivative scheme is the expected scheme.
|
||||
$this->assertSame($expected_scheme, $derivative_scheme);
|
||||
|
||||
// Check that the derivative URI is the expected one.
|
||||
$expected_uri = "$expected_scheme://styles/{$this->imageStyle->id()}/$source_scheme/some/path/image.png";
|
||||
$this->assertSame($expected_uri, $derivative_uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide test cases for testCustomStreamWrappers().
|
||||
*
|
||||
* Derivatives created from writable source stream wrappers will inherit the
|
||||
* scheme from source. Derivatives created from read-only stream wrappers will
|
||||
* fall-back to the default scheme.
|
||||
*
|
||||
* @return array[]
|
||||
* An array having each element an array with three items:
|
||||
* - The source stream wrapper scheme.
|
||||
* - The derivative expected stream wrapper scheme.
|
||||
* - The stream wrapper service class.
|
||||
*/
|
||||
public function providerTestCustomStreamWrappers() {
|
||||
return [
|
||||
['public', 'public', PublicStream::class],
|
||||
['private', 'private', PrivateStream::class],
|
||||
['dummy', 'dummy', DummyStreamWrapper::class],
|
||||
['dummy-readonly', 'public', DummyReadOnlyStreamWrapper::class],
|
||||
['dummy-remote-readonly', 'public', DummyRemoteReadOnlyStreamWrapper::class],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Kernel;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Core\Entity\Entity\EntityViewDisplay;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\image\Entity\ImageStyle;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
|
||||
/**
|
||||
* Tests the integration of ImageStyle with the core.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class ImageStyleIntegrationTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['image', 'file', 'field', 'system', 'user', 'node'];
|
||||
|
||||
/**
|
||||
* Tests the dependency between ImageStyle and entity display components.
|
||||
*/
|
||||
public function testEntityDisplayDependency() {
|
||||
// Create two image styles.
|
||||
/** @var \Drupal\image\ImageStyleInterface $style */
|
||||
$style = ImageStyle::create(['name' => 'main_style']);
|
||||
$style->save();
|
||||
/** @var \Drupal\image\ImageStyleInterface $replacement */
|
||||
$replacement = ImageStyle::create(['name' => 'replacement_style']);
|
||||
$replacement->save();
|
||||
|
||||
// Create a node-type, named 'note'.
|
||||
$node_type = NodeType::create(['type' => 'note']);
|
||||
$node_type->save();
|
||||
|
||||
// Create an image field and attach it to the 'note' node-type.
|
||||
FieldStorageConfig::create([
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'sticker',
|
||||
'type' => 'image',
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'sticker',
|
||||
'bundle' => 'note',
|
||||
])->save();
|
||||
|
||||
// Create the default entity view display and set the 'sticker' field to use
|
||||
// the 'main_style' images style in formatter.
|
||||
/** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $view_display */
|
||||
$view_display = EntityViewDisplay::create([
|
||||
'targetEntityType' => 'node',
|
||||
'bundle' => 'note',
|
||||
'mode' => 'default',
|
||||
'status' => TRUE,
|
||||
])->setComponent('sticker', ['settings' => ['image_style' => 'main_style']]);
|
||||
$view_display->save();
|
||||
|
||||
// Create the default entity form display and set the 'sticker' field to use
|
||||
// the 'main_style' images style in the widget.
|
||||
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
|
||||
$form_display = EntityFormDisplay::create([
|
||||
'targetEntityType' => 'node',
|
||||
'bundle' => 'note',
|
||||
'mode' => 'default',
|
||||
'status' => TRUE,
|
||||
])->setComponent('sticker', ['settings' => ['preview_image_style' => 'main_style']]);
|
||||
$form_display->save();
|
||||
|
||||
// Check that the entity displays exists before dependency removal.
|
||||
$this->assertNotNull(EntityViewDisplay::load($view_display->id()));
|
||||
$this->assertNotNull(EntityFormDisplay::load($form_display->id()));
|
||||
|
||||
// Delete the 'main_style' image style. Before that, emulate the UI process
|
||||
// of selecting a replacement style by setting the replacement image style
|
||||
// ID in the image style storage.
|
||||
/** @var \Drupal\image\ImageStyleStorageInterface $storage */
|
||||
$storage = $this->container->get('entity.manager')->getStorage($style->getEntityTypeId());
|
||||
$storage->setReplacementId('main_style', 'replacement_style');
|
||||
$style->delete();
|
||||
|
||||
// Check that the entity displays exists after dependency removal.
|
||||
$this->assertNotNull($view_display = EntityViewDisplay::load($view_display->id()));
|
||||
$this->assertNotNull($form_display = EntityFormDisplay::load($form_display->id()));
|
||||
// Check that the 'sticker' formatter component exists in both displays.
|
||||
$this->assertNotNull($formatter = $view_display->getComponent('sticker'));
|
||||
$this->assertNotNull($widget = $form_display->getComponent('sticker'));
|
||||
// Check that both displays are using now 'replacement_style' for images.
|
||||
$this->assertSame('replacement_style', $formatter['settings']['image_style']);
|
||||
$this->assertSame('replacement_style', $widget['settings']['preview_image_style']);
|
||||
|
||||
// Delete the 'replacement_style' without setting a replacement image style.
|
||||
$replacement->delete();
|
||||
|
||||
// The entity view and form displays exists after dependency removal.
|
||||
$this->assertNotNull($view_display = EntityViewDisplay::load($view_display->id()));
|
||||
$this->assertNotNull($form_display = EntityFormDisplay::load($form_display->id()));
|
||||
// The 'sticker' formatter component should be hidden in view display.
|
||||
$this->assertNull($view_display->getComponent('sticker'));
|
||||
$this->assertTrue($view_display->get('hidden')['sticker']);
|
||||
// The 'sticker' widget component should be active in form displays, but the
|
||||
// image preview should be disabled.
|
||||
$this->assertNotNull($widget = $form_display->getComponent('sticker'));
|
||||
$this->assertSame('', $widget['settings']['preview_image_style']);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\image\Entity\ImageStyle;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Exception\RequirementsException;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Tests migration of ImageCache presets to image styles.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class MigrateImageCacheTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(['image']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that an exception is thrown when ImageCache is not installed.
|
||||
*/
|
||||
public function testMissingTable() {
|
||||
$this->sourceDatabase->update('system')
|
||||
->fields([
|
||||
'status' => 0,
|
||||
])
|
||||
->condition('name', 'imagecache')
|
||||
->condition('type', 'module')
|
||||
->execute();
|
||||
|
||||
try {
|
||||
$this->getMigration('d6_imagecache_presets')
|
||||
->getSourcePlugin()
|
||||
->checkRequirements();
|
||||
$this->fail('Did not catch expected RequirementsException.');
|
||||
}
|
||||
catch (RequirementsException $e) {
|
||||
$this->pass('Caught expected RequirementsException: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test basic passing migrations.
|
||||
*/
|
||||
public function testPassingMigration() {
|
||||
$this->executeMigration('d6_imagecache_presets');
|
||||
|
||||
/** @var \Drupal\image\Entity\ImageStyle $style */
|
||||
$style = ImageStyle::load('big_blue_cheese');
|
||||
|
||||
// Check basic Style info.
|
||||
$this->assertIdentical('big_blue_cheese', $style->get('name'), 'ImageStyle name set correctly');
|
||||
$this->assertIdentical('big_blue_cheese', $style->get('label'), 'ImageStyle label set correctly');
|
||||
|
||||
// Test effects.
|
||||
$effects = $style->getEffects();
|
||||
|
||||
// Check crop effect.
|
||||
$this->assertImageEffect($effects, 'image_crop', [
|
||||
'width' => 555,
|
||||
'height' => 5555,
|
||||
'anchor' => 'center-center',
|
||||
]);
|
||||
|
||||
// Check resize effect.
|
||||
$this->assertImageEffect($effects, 'image_resize', [
|
||||
'width' => 55,
|
||||
'height' => 55,
|
||||
]);
|
||||
|
||||
// Check rotate effect.
|
||||
$this->assertImageEffect($effects, 'image_rotate', [
|
||||
'degrees' => 55,
|
||||
'random' => FALSE,
|
||||
'bgcolor' => '',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that missing actions causes failures.
|
||||
*/
|
||||
public function testMissingEffectPlugin() {
|
||||
Database::getConnection('default', 'migrate')->insert("imagecache_action")
|
||||
->fields([
|
||||
'presetid',
|
||||
'weight',
|
||||
'module',
|
||||
'action',
|
||||
'data',
|
||||
])
|
||||
->values([
|
||||
'presetid' => '1',
|
||||
'weight' => '0',
|
||||
'module' => 'imagecache',
|
||||
'action' => 'imagecache_deprecated_scale',
|
||||
'data' => 'a:3:{s:3:"fit";s:7:"outside";s:5:"width";s:3:"200";s:6:"height";s:3:"200";}',
|
||||
])->execute();
|
||||
|
||||
$this->startCollectingMessages();
|
||||
$this->executeMigration('d6_imagecache_presets');
|
||||
$messages = $this->migration->getIdMap()->getMessageIterator();
|
||||
$count = 0;
|
||||
foreach ($messages as $message) {
|
||||
$count++;
|
||||
$this->assertEqual($message->message, 'The "image_deprecated_scale" plugin does not exist.');
|
||||
$this->assertEqual($message->level, MigrationInterface::MESSAGE_ERROR);
|
||||
}
|
||||
// There should be only the one message.
|
||||
$this->assertEqual($count, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that missing action's causes failures.
|
||||
*/
|
||||
public function testInvalidCropValues() {
|
||||
Database::getConnection('default', 'migrate')->insert("imagecache_action")
|
||||
->fields([
|
||||
'presetid',
|
||||
'weight',
|
||||
'module',
|
||||
'action',
|
||||
'data',
|
||||
])
|
||||
->values([
|
||||
'presetid' => '1',
|
||||
'weight' => '0',
|
||||
'module' => 'imagecache',
|
||||
'action' => 'imagecache_crop',
|
||||
'data' => serialize([
|
||||
'xoffset' => '10',
|
||||
'yoffset' => '10',
|
||||
]),
|
||||
])->execute();
|
||||
|
||||
$this->startCollectingMessages();
|
||||
$this->executeMigration('d6_imagecache_presets');
|
||||
$this->assertEqual(['error' => [
|
||||
'The Drupal 8 image crop effect does not support numeric values for x and y offsets. Use keywords to set crop effect offsets instead.'
|
||||
]], $this->migrateMessages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that a given image effect is migrated.
|
||||
*
|
||||
* @param array $collection
|
||||
* Collection of effects
|
||||
* @param $id
|
||||
* Id that should exist in the collection.
|
||||
* @param $config
|
||||
* Expected configuration for the collection.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function assertImageEffect($collection, $id, $config) {
|
||||
/** @var \Drupal\image\ConfigurableImageEffectBase $effect */
|
||||
foreach ($collection as $key => $effect) {
|
||||
$effect_config = $effect->getConfiguration();
|
||||
|
||||
if ($effect_config['id'] == $id && $effect_config['data'] == $config) {
|
||||
// We found this effect so succeed and return.
|
||||
return $this->pass('Effect ' . $id . ' imported correctly');
|
||||
}
|
||||
}
|
||||
// The loop did not find the effect so we it was not imported correctly.
|
||||
return $this->fail('Effect ' . $id . ' did not import correctly');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Tests migration of Image variables to configuration.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class MigrateImageSettingsTest extends MigrateDrupal7TestBase {
|
||||
|
||||
public static $modules = ['image'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d7_image_settings');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the migration.
|
||||
*/
|
||||
public function testMigration() {
|
||||
$config = $this->config('image.settings');
|
||||
// These settings are not recommended...
|
||||
$this->assertTrue($config->get('allow_insecure_derivatives'));
|
||||
$this->assertTrue($config->get('suppress_itok_output'));
|
||||
$this->assertIdentical("core/modules/image/testsample.png", $config->get('preview_image'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\image\Entity\ImageStyle;
|
||||
use Drupal\image\ImageStyleInterface;
|
||||
use Drupal\image\ImageEffectBase;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Test image styles migration to config entities.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class MigrateImageStylesTest extends MigrateDrupal7TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['image'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(static::$modules);
|
||||
$this->executeMigration('d7_image_styles');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the image styles migration.
|
||||
*/
|
||||
public function testImageStylesMigration() {
|
||||
$this->assertEntity('custom_image_style_1', "Custom image style 1", ['image_scale_and_crop', 'image_desaturate'], [['width' => 55, 'height' => 55], []]);
|
||||
$this->assertEntity('custom_image_style_2', "Custom image style 2", ['image_resize', 'image_rotate'], [['width' => 55, 'height' => 100], ['degrees' => 45, 'bgcolor' => '#FFFFFF', 'random' => FALSE]]);
|
||||
$this->assertEntity('custom_image_style_3', "Custom image style 3", ['image_scale', 'image_crop'], [['width' => 150, 'height' => NULL, 'upscale' => FALSE], ['width' => 50, 'height' => 50, 'anchor' => 'left-top']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts various aspects of an ImageStyle entity.
|
||||
*
|
||||
* @param string $id
|
||||
* The expected image style ID.
|
||||
* @param string $label
|
||||
* The expected image style label.
|
||||
* @param array $expected_effect_plugins
|
||||
* An array of expected plugins attached to the image style entity
|
||||
* @param array $expected_effect_config
|
||||
* An array of expected configuration for each effect in the image style
|
||||
*/
|
||||
protected function assertEntity($id, $label, array $expected_effect_plugins, array $expected_effect_config) {
|
||||
$style = ImageStyle::load($id);
|
||||
$this->assertTrue($style instanceof ImageStyleInterface);
|
||||
/** @var \Drupal\image\ImageStyleInterface $style */
|
||||
$this->assertIdentical($id, $style->id());
|
||||
$this->assertIdentical($label, $style->label());
|
||||
|
||||
// Check the number of effects associated with the style.
|
||||
$effects = $style->getEffects();
|
||||
$this->assertIdentical(count($effects), count($expected_effect_plugins));
|
||||
|
||||
$index = 0;
|
||||
foreach ($effects as $effect) {
|
||||
$this->assertTrue($effect instanceof ImageEffectBase);
|
||||
$this->assertIdentical($expected_effect_plugins[$index], $effect->getPluginId());
|
||||
$config = $effect->getConfiguration();
|
||||
$this->assertIdentical($expected_effect_config[$index], $config['data']);
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Kernel\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests the d6_imagecache_presets source plugin.
|
||||
*
|
||||
* @covers \Drupal\image\Plugin\migrate\source\d6\ImageCachePreset
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class ImageCachePresetTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['image', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$tests = [];
|
||||
|
||||
// The source data.
|
||||
$tests[0]['source_data']['imagecache_preset'] = [
|
||||
[
|
||||
'presetid' => '1',
|
||||
'presetname' => 'slackjaw_boys',
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['imagecache_action'] = [
|
||||
[
|
||||
'actionid' => '3',
|
||||
'presetid' => '1',
|
||||
'weight' => '0',
|
||||
'module' => 'imagecache',
|
||||
'action' => 'imagecache_scale_and_crop',
|
||||
'data' => 'a:2:{s:5:"width";s:4:"100%";s:6:"height";s:4:"100%";}',
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'presetid' => '1',
|
||||
'presetname' => 'slackjaw_boys',
|
||||
'actions' => [
|
||||
[
|
||||
'actionid' => '3',
|
||||
'presetid' => '1',
|
||||
'weight' => '0',
|
||||
'module' => 'imagecache',
|
||||
'action' => 'imagecache_scale_and_crop',
|
||||
'data' => [
|
||||
'width' => '100%',
|
||||
'height' => '100%',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Kernel\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests the D7 ImageStyles source plugin.
|
||||
*
|
||||
* @covers \Drupal\image\Plugin\migrate\source\d7\ImageStyles
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class ImageStylesTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['image', 'migrate_drupal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$tests = [];
|
||||
|
||||
// The source data.
|
||||
$tests[0]['source_data']['image_styles'] = [
|
||||
[
|
||||
'isid' => 1,
|
||||
'name' => 'custom_image_style_1',
|
||||
'label' => 'Custom image style 1',
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['image_effects'] = [
|
||||
[
|
||||
'ieid' => 1,
|
||||
'isid' => 1,
|
||||
'weight' => 1,
|
||||
'name' => 'image_desaturate',
|
||||
'data' => serialize([]),
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'isid' => 1,
|
||||
'name' => 'custom_image_style_1',
|
||||
'label' => 'Custom image style 1',
|
||||
'effects' => [
|
||||
[
|
||||
'ieid' => 1,
|
||||
'isid' => 1,
|
||||
'weight' => 1,
|
||||
'name' => 'image_desaturate',
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Kernel\Views;
|
||||
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests image views data.
|
||||
*
|
||||
* @group image
|
||||
*/
|
||||
class ImageViewsDataTest extends ViewsKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['image', 'file', 'views', 'entity_test', 'user', 'field'];
|
||||
|
||||
/**
|
||||
* Tests views data generated for image field relationship.
|
||||
*
|
||||
* @see image_field_views_data()
|
||||
* @see image_field_views_data_views_data_alter()
|
||||
*/
|
||||
public function testRelationshipViewsData() {
|
||||
// Create image field to entity_test.
|
||||
FieldStorageConfig::create([
|
||||
'entity_type' => 'entity_test',
|
||||
'field_name' => 'field_base_image',
|
||||
'type' => 'image',
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => 'entity_test',
|
||||
'field_name' => 'field_base_image',
|
||||
'bundle' => 'entity_test',
|
||||
])->save();
|
||||
// Check the generated views data.
|
||||
$views_data = Views::viewsData()->get('entity_test__field_base_image');
|
||||
$relationship = $views_data['field_base_image_target_id']['relationship'];
|
||||
$this->assertEqual($relationship['id'], 'standard');
|
||||
$this->assertEqual($relationship['base'], 'file_managed');
|
||||
$this->assertEqual($relationship['base field'], 'fid');
|
||||
$this->assertEqual($relationship['entity type'], 'file');
|
||||
// Check the backwards reference.
|
||||
$views_data = Views::viewsData()->get('file_managed');
|
||||
$relationship = $views_data['reverse_field_base_image_entity_test']['relationship'];
|
||||
$this->assertEqual($relationship['id'], 'entity_reverse');
|
||||
$this->assertEqual($relationship['base'], 'entity_test');
|
||||
$this->assertEqual($relationship['base field'], 'id');
|
||||
$this->assertEqual($relationship['field table'], 'entity_test__field_base_image');
|
||||
$this->assertEqual($relationship['field field'], 'field_base_image_target_id');
|
||||
$this->assertEqual($relationship['field_name'], 'field_base_image');
|
||||
$this->assertEqual($relationship['entity_type'], 'entity_test');
|
||||
$this->assertEqual($relationship['join_extra'][0], ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE]);
|
||||
|
||||
// Create image field to entity_test_mul.
|
||||
FieldStorageConfig::create([
|
||||
'entity_type' => 'entity_test_mul',
|
||||
'field_name' => 'field_data_image',
|
||||
'type' => 'image',
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => 'entity_test_mul',
|
||||
'field_name' => 'field_data_image',
|
||||
'bundle' => 'entity_test_mul',
|
||||
])->save();
|
||||
// Check the generated views data.
|
||||
$views_data = Views::viewsData()->get('entity_test_mul__field_data_image');
|
||||
$relationship = $views_data['field_data_image_target_id']['relationship'];
|
||||
$this->assertEqual($relationship['id'], 'standard');
|
||||
$this->assertEqual($relationship['base'], 'file_managed');
|
||||
$this->assertEqual($relationship['base field'], 'fid');
|
||||
$this->assertEqual($relationship['entity type'], 'file');
|
||||
// Check the backwards reference.
|
||||
$views_data = Views::viewsData()->get('file_managed');
|
||||
$relationship = $views_data['reverse_field_data_image_entity_test_mul']['relationship'];
|
||||
$this->assertEqual($relationship['id'], 'entity_reverse');
|
||||
$this->assertEqual($relationship['base'], 'entity_test_mul_property_data');
|
||||
$this->assertEqual($relationship['base field'], 'id');
|
||||
$this->assertEqual($relationship['field table'], 'entity_test_mul__field_data_image');
|
||||
$this->assertEqual($relationship['field field'], 'field_data_image_target_id');
|
||||
$this->assertEqual($relationship['field_name'], 'field_data_image');
|
||||
$this->assertEqual($relationship['entity_type'], 'entity_test_mul');
|
||||
$this->assertEqual($relationship['join_extra'][0], ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Unit;
|
||||
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\image\Entity\ImageStyle
|
||||
*
|
||||
* @group Image
|
||||
*/
|
||||
class ImageStyleTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* The entity type used for testing.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
/**
|
||||
* The entity manager used for testing.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The ID of the type of the entity under test.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $entityTypeId;
|
||||
|
||||
/**
|
||||
* Gets a mocked image style for testing.
|
||||
*
|
||||
* @param string $image_effect_id
|
||||
* The image effect ID.
|
||||
* @param \Drupal\image\ImageEffectInterface|\PHPUnit_Framework_MockObject_MockObject $image_effect
|
||||
* The image effect used for testing.
|
||||
*
|
||||
* @return \Drupal\image\ImageStyleInterface
|
||||
* The mocked image style.
|
||||
*/
|
||||
protected function getImageStyleMock($image_effect_id, $image_effect, $stubs = []) {
|
||||
$effectManager = $this->getMockBuilder('\Drupal\image\ImageEffectManager')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$effectManager->expects($this->any())
|
||||
->method('createInstance')
|
||||
->with($image_effect_id)
|
||||
->will($this->returnValue($image_effect));
|
||||
$default_stubs = [
|
||||
'getImageEffectPluginManager',
|
||||
'fileUriScheme',
|
||||
'fileUriTarget',
|
||||
'fileDefaultScheme',
|
||||
];
|
||||
$image_style = $this->getMockBuilder('\Drupal\image\Entity\ImageStyle')
|
||||
->setConstructorArgs([
|
||||
['effects' => [$image_effect_id => ['id' => $image_effect_id]]],
|
||||
$this->entityTypeId,
|
||||
])
|
||||
->setMethods(array_merge($default_stubs, $stubs))
|
||||
->getMock();
|
||||
|
||||
$image_style->expects($this->any())
|
||||
->method('getImageEffectPluginManager')
|
||||
->will($this->returnValue($effectManager));
|
||||
$image_style->expects($this->any())
|
||||
->method('fileUriScheme')
|
||||
->will($this->returnCallback([$this, 'fileUriScheme']));
|
||||
$image_style->expects($this->any())
|
||||
->method('fileUriTarget')
|
||||
->will($this->returnCallback([$this, 'fileUriTarget']));
|
||||
$image_style->expects($this->any())
|
||||
->method('fileDefaultScheme')
|
||||
->will($this->returnCallback([$this, 'fileDefaultScheme']));
|
||||
|
||||
return $image_style;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->entityTypeId = $this->randomMachineName();
|
||||
$this->provider = $this->randomMachineName();
|
||||
$this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
|
||||
$this->entityType->expects($this->any())
|
||||
->method('getProvider')
|
||||
->will($this->returnValue($this->provider));
|
||||
$this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
|
||||
$this->entityManager->expects($this->any())
|
||||
->method('getDefinition')
|
||||
->with($this->entityTypeId)
|
||||
->will($this->returnValue($this->entityType));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getDerivativeExtension
|
||||
*/
|
||||
public function testGetDerivativeExtension() {
|
||||
$image_effect_id = $this->randomMachineName();
|
||||
$logger = $this->getMockBuilder('\Psr\Log\LoggerInterface')->getMock();
|
||||
$image_effect = $this->getMockBuilder('\Drupal\image\ImageEffectBase')
|
||||
->setConstructorArgs([[], $image_effect_id, [], $logger])
|
||||
->getMock();
|
||||
$image_effect->expects($this->any())
|
||||
->method('getDerivativeExtension')
|
||||
->will($this->returnValue('png'));
|
||||
|
||||
$image_style = $this->getImageStyleMock($image_effect_id, $image_effect);
|
||||
|
||||
$extensions = ['jpeg', 'gif', 'png'];
|
||||
foreach ($extensions as $extension) {
|
||||
$extensionReturned = $image_style->getDerivativeExtension($extension);
|
||||
$this->assertEquals($extensionReturned, 'png');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::buildUri
|
||||
*/
|
||||
public function testBuildUri() {
|
||||
// Image style that changes the extension.
|
||||
$image_effect_id = $this->randomMachineName();
|
||||
$logger = $this->getMockBuilder('\Psr\Log\LoggerInterface')->getMock();
|
||||
$image_effect = $this->getMockBuilder('\Drupal\image\ImageEffectBase')
|
||||
->setConstructorArgs([[], $image_effect_id, [], $logger])
|
||||
->getMock();
|
||||
$image_effect->expects($this->any())
|
||||
->method('getDerivativeExtension')
|
||||
->will($this->returnValue('png'));
|
||||
|
||||
$image_style = $this->getImageStyleMock($image_effect_id, $image_effect);
|
||||
$this->assertEquals($image_style->buildUri('public://test.jpeg'), 'public://styles/' . $image_style->id() . '/public/test.jpeg.png');
|
||||
|
||||
// Image style that doesn't change the extension.
|
||||
$image_effect_id = $this->randomMachineName();
|
||||
$image_effect = $this->getMockBuilder('\Drupal\image\ImageEffectBase')
|
||||
->setConstructorArgs([[], $image_effect_id, [], $logger])
|
||||
->getMock();
|
||||
$image_effect->expects($this->any())
|
||||
->method('getDerivativeExtension')
|
||||
->will($this->returnArgument(0));
|
||||
|
||||
$image_style = $this->getImageStyleMock($image_effect_id, $image_effect);
|
||||
$this->assertEquals($image_style->buildUri('public://test.jpeg'), 'public://styles/' . $image_style->id() . '/public/test.jpeg');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getPathToken
|
||||
*/
|
||||
public function testGetPathToken() {
|
||||
$logger = $this->getMockBuilder('\Psr\Log\LoggerInterface')->getMock();
|
||||
$private_key = $this->randomMachineName();
|
||||
$hash_salt = $this->randomMachineName();
|
||||
|
||||
// Image style that changes the extension.
|
||||
$image_effect_id = $this->randomMachineName();
|
||||
$image_effect = $this->getMockBuilder('\Drupal\image\ImageEffectBase')
|
||||
->setConstructorArgs([[], $image_effect_id, [], $logger])
|
||||
->getMock();
|
||||
$image_effect->expects($this->any())
|
||||
->method('getDerivativeExtension')
|
||||
->will($this->returnValue('png'));
|
||||
|
||||
$image_style = $this->getImageStyleMock($image_effect_id, $image_effect, ['getPrivateKey', 'getHashSalt']);
|
||||
$image_style->expects($this->any())
|
||||
->method('getPrivateKey')
|
||||
->will($this->returnValue($private_key));
|
||||
$image_style->expects($this->any())
|
||||
->method('getHashSalt')
|
||||
->will($this->returnValue($hash_salt));
|
||||
|
||||
// Assert the extension has been added to the URI before creating the token.
|
||||
$this->assertEquals($image_style->getPathToken('public://test.jpeg.png'), $image_style->getPathToken('public://test.jpeg'));
|
||||
$this->assertEquals(substr(Crypt::hmacBase64($image_style->id() . ':' . 'public://test.jpeg.png', $private_key . $hash_salt), 0, 8), $image_style->getPathToken('public://test.jpeg'));
|
||||
$this->assertNotEquals(substr(Crypt::hmacBase64($image_style->id() . ':' . 'public://test.jpeg', $private_key . $hash_salt), 0, 8), $image_style->getPathToken('public://test.jpeg'));
|
||||
|
||||
// Image style that doesn't change the extension.
|
||||
$image_effect_id = $this->randomMachineName();
|
||||
$image_effect = $this->getMockBuilder('\Drupal\image\ImageEffectBase')
|
||||
->setConstructorArgs([[], $image_effect_id, [], $logger])
|
||||
->getMock();
|
||||
$image_effect->expects($this->any())
|
||||
->method('getDerivativeExtension')
|
||||
->will($this->returnArgument(0));
|
||||
|
||||
$image_style = $this->getImageStyleMock($image_effect_id, $image_effect, ['getPrivateKey', 'getHashSalt']);
|
||||
$image_style->expects($this->any())
|
||||
->method('getPrivateKey')
|
||||
->will($this->returnValue($private_key));
|
||||
$image_style->expects($this->any())
|
||||
->method('getHashSalt')
|
||||
->will($this->returnValue($hash_salt));
|
||||
// Assert no extension has been added to the uri before creating the token.
|
||||
$this->assertNotEquals($image_style->getPathToken('public://test.jpeg.png'), $image_style->getPathToken('public://test.jpeg'));
|
||||
$this->assertNotEquals(substr(Crypt::hmacBase64($image_style->id() . ':' . 'public://test.jpeg.png', $private_key . $hash_salt), 0, 8), $image_style->getPathToken('public://test.jpeg'));
|
||||
$this->assertEquals(substr(Crypt::hmacBase64($image_style->id() . ':' . 'public://test.jpeg', $private_key . $hash_salt), 0, 8), $image_style->getPathToken('public://test.jpeg'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock function for ImageStyle::fileUriScheme().
|
||||
*/
|
||||
public function fileUriScheme($uri) {
|
||||
if (preg_match('/^([\w\-]+):\/\/|^(data):/', $uri, $matches)) {
|
||||
// The scheme will always be the last element in the matches array.
|
||||
return array_pop($matches);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock function for ImageStyle::fileUriTarget().
|
||||
*/
|
||||
public function fileUriTarget($uri) {
|
||||
// Remove the scheme from the URI and remove erroneous leading or trailing,
|
||||
// forward-slashes and backslashes.
|
||||
$target = trim(preg_replace('/^[\w\-]+:\/\/|^data:/', '', $uri), '\/');
|
||||
|
||||
// If nothing was replaced, the URI doesn't have a valid scheme.
|
||||
return $target !== $uri ? $target : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock function for ImageStyle::fileDefaultScheme().
|
||||
*/
|
||||
public function fileDefaultScheme() {
|
||||
return 'public';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\image\Unit\PageCache;
|
||||
|
||||
use Drupal\Core\PageCache\ResponsePolicyInterface;
|
||||
use Drupal\image\PageCache\DenyPrivateImageStyleDownload;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\image\PageCache\DenyPrivateImageStyleDownload
|
||||
* @group image
|
||||
*/
|
||||
class DenyPrivateImageStyleDownloadTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* The response policy under test.
|
||||
*
|
||||
* @var \Drupal\image\PageCache\DenyPrivateImageStyleDownload
|
||||
*/
|
||||
protected $policy;
|
||||
|
||||
/**
|
||||
* A request object.
|
||||
*
|
||||
* @var \Symfony\Component\HttpFoundation\Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* A response object.
|
||||
*
|
||||
* @var \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* The current route match.
|
||||
*
|
||||
* @var \Drupal\Core\Routing\RouteMatch|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $routeMatch;
|
||||
|
||||
protected function setUp() {
|
||||
$this->routeMatch = $this->getMock('Drupal\Core\Routing\RouteMatchInterface');
|
||||
$this->policy = new DenyPrivateImageStyleDownload($this->routeMatch);
|
||||
$this->response = new Response();
|
||||
$this->request = new Request();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that caching is denied on the private image style download route.
|
||||
*
|
||||
* @dataProvider providerPrivateImageStyleDownloadPolicy
|
||||
* @covers ::check
|
||||
*/
|
||||
public function testPrivateImageStyleDownloadPolicy($expected_result, $route_name) {
|
||||
$this->routeMatch->expects($this->once())
|
||||
->method('getRouteName')
|
||||
->will($this->returnValue($route_name));
|
||||
|
||||
$actual_result = $this->policy->check($this->response, $this->request);
|
||||
$this->assertSame($expected_result, $actual_result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides data and expected results for the test method.
|
||||
*
|
||||
* @return array
|
||||
* Data and expected results.
|
||||
*/
|
||||
public function providerPrivateImageStyleDownloadPolicy() {
|
||||
return [
|
||||
[ResponsePolicyInterface::DENY, 'image.style_private'],
|
||||
[NULL, 'some.other.route'],
|
||||
[NULL, NULL],
|
||||
[NULL, FALSE],
|
||||
[NULL, TRUE],
|
||||
[NULL, new \StdClass()],
|
||||
[NULL, [1, 2, 3]],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user