Commit a6b84bfb authored by alexpott's avatar alexpott

Issue #2843756 by vaplas, Wim Leers, brentschuddinck, jamesdesq:...

Issue #2843756 by vaplas, Wim Leers, brentschuddinck, jamesdesq: EntityResource: Provide comprehensive test coverage for FieldStorageConfig entity
parent e31a0430
......@@ -18,6 +18,7 @@
* id = "field_storage_config",
* label = @Translation("Field storage"),
* handlers = {
* "access" = "Drupal\field\FieldStorageConfigAccessControlHandler",
* "storage" = "Drupal\field\FieldStorageConfigStorage"
* },
* config_prefix = "storage",
......
......@@ -2,13 +2,12 @@
namespace Drupal\field;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Defines the access control handler for the field entity type.
* Defines the access control handler for the field config entity type.
*
* @see \Drupal\field\Entity\FieldConfig
*/
......@@ -18,16 +17,16 @@ class FieldConfigAccessControlHandler extends EntityAccessControlHandler {
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
if ($operation == 'delete') {
$field_storage_entity = $entity->getFieldStorageDefinition();
if ($field_storage_entity->isLocked()) {
return AccessResult::forbidden()->addCacheableDependency($field_storage_entity);
}
else {
return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields')->addCacheableDependency($field_storage_entity);
}
}
return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields');
// Delegate access control to the underlying field storage config entity:
// the field config entity merely handles configuration for a particular
// bundle of an entity type, the bulk of the logic and configuration is with
// the field storage config entity. Therefore, if an operation is allowed on
// a certain field storage config entity, it should also be allowed for all
// associated field config entities.
// @see \Drupal\Core\Field\FieldDefinitionInterface
/** \Drupal\field\FieldConfigInterface $entity */
$field_storage_entity = $entity->getFieldStorageDefinition();
return $field_storage_entity->access($operation, $account, TRUE);
}
}
<?php
namespace Drupal\field;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Defines the access control handler for the field storage config entity type.
*
* @see \Drupal\field\Entity\FieldStorageConfig
*/
class FieldStorageConfigAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
/** \Drupal\field\FieldStorageConfigInterface $entity */
if ($operation === 'delete') {
if ($entity->isLocked()) {
return AccessResult::forbidden()->addCacheableDependency($entity);
}
else {
return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields')->addCacheableDependency($entity);
}
}
return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields');
}
}
<?php
namespace Drupal\Tests\field\Unit;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\FieldConfigAccessControlHandler;
/**
* Tests the field config access controller.
*
* @group field
*
* @coversDefaultClass \Drupal\field\FieldConfigAccessControlHandler
*/
class FieldConfigAccessControlHandlerTest extends FieldStorageConfigAccessControlHandlerTest {
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->entity = new FieldConfig([
'field_name' => $this->fieldStorage->getName(),
'entity_type' => 'node',
'fieldStorage' => $this->fieldStorage,
'bundle' => 'test_bundle',
'field_type' => 'test_field',
], 'node');
$this->accessControlHandler = new FieldConfigAccessControlHandler($this->entity->getEntityType());
$this->accessControlHandler->setModuleHandler($this->moduleHandler);
}
/**
* Ensures field config access is working properly.
*/
public function testAccess() {
$this->assertAllowOperations([], $this->anon);
$this->assertAllowOperations(['view', 'update', 'delete'], $this->member);
}
}
<?php
namespace Drupal\Tests\field\Unit;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Cache\Context\CacheContextsManager;
use Drupal\Core\Config\Entity\ConfigEntityTypeInterface;
use Drupal\Core\DependencyInjection\Container;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\FieldStorageConfigAccessControlHandler;
use Drupal\Tests\UnitTestCase;
/**
* Tests the field storage config access controller.
*
* @group field
*
* @coversDefaultClass \Drupal\field\FieldStorageConfigAccessControlHandler
*/
class FieldStorageConfigAccessControlHandlerTest extends UnitTestCase {
/**
* The field storage config access controller to test.
*
* @var \Drupal\field\FieldStorageConfigAccessControlHandler
*/
protected $accessControlHandler;
/**
* The mock module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The mock account without field storage config access.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $anon;
/**
* The mock account with field storage config access.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $member;
/**
* The mocked test field storage config.
*
* @var \Drupal\field\FieldStorageConfigInterface
*/
protected $fieldStorage;
/**
* The main entity used for testing.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityInterface
*/
protected $entity;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->anon = $this->getMock(AccountInterface::class);
$this->anon
->expects($this->any())
->method('hasPermission')
->will($this->returnValue(FALSE));
$this->anon
->expects($this->any())
->method('id')
->will($this->returnValue(0));
$this->member = $this->getMock(AccountInterface::class);
$this->member
->expects($this->any())
->method('hasPermission')
->will($this->returnValueMap([
['administer node fields', TRUE],
]));
$this->member
->expects($this->any())
->method('id')
->will($this->returnValue(2));
$storageType = $this->getMock(ConfigEntityTypeInterface::class);
$storageType
->expects($this->any())
->method('getProvider')
->will($this->returnValue('field'));
$storageType
->expects($this->any())
->method('getConfigPrefix')
->will($this->returnValue('field.storage'));
$entityType = $this->getMock(ConfigEntityTypeInterface::class);
$entityType
->expects($this->any())
->method('getProvider')
->will($this->returnValue('node'));
$entityType
->expects($this->any())
->method('getConfigPrefix')
->willReturn('node');
$this->moduleHandler = $this->getMock(ModuleHandlerInterface::class);
$this->moduleHandler
->expects($this->any())
->method('getImplementations')
->will($this->returnValue([]));
$this->moduleHandler
->expects($this->any())
->method('invokeAll')
->will($this->returnValue([]));
$storage_access_control_handler = new FieldStorageConfigAccessControlHandler($storageType);
$storage_access_control_handler->setModuleHandler($this->moduleHandler);
$entityManager = $this->getMock(EntityManagerInterface::class);
$entityManager
->expects($this->any())
->method('getDefinition')
->willReturnMap([
['field_storage_config', TRUE, $storageType],
['node', TRUE, $entityType],
]);
$entityManager
->expects($this->any())
->method('getStorage')
->willReturnMap([
['field_storage_config', $this->getMock(EntityStorageInterface::class)],
]);
$entityManager
->expects($this->any())
->method('getAccessControlHandler')
->willReturnMap([
['field_storage_config', $storage_access_control_handler],
]);
$container = new Container();
$container->set('entity.manager', $entityManager);
$container->set('uuid', $this->getMock(UuidInterface::class));
$container->set('cache_contexts_manager', $this->prophesize(CacheContextsManager::class));
\Drupal::setContainer($container);
$this->fieldStorage = new FieldStorageConfig([
'field_name' => 'test_field',
'entity_type' => 'node',
'type' => 'boolean',
'id' => 'node.test_field',
'uuid' => '6f2f259a-f3c7-42ea-bdd5-111ad1f85ed1',
]);
$this->entity = $this->fieldStorage;
$this->accessControlHandler = $storage_access_control_handler;
}
/**
* Assert method to verify the access by operations.
*
* @param array $allow_operations
* A list of allowed operations.
* @param \Drupal\Core\Session\AccountInterface $user
* The account to use for get access.
*/
public function assertAllowOperations(array $allow_operations, AccountInterface $user) {
foreach (['view', 'update', 'delete'] as $operation) {
$expected = in_array($operation, $allow_operations);
$actual = $this->accessControlHandler->access($this->entity, $operation, $user);
$this->assertSame($expected, $actual, "Access problem with '$operation' operation.");
}
}
/**
* Ensures field storage config access is working properly.
*/
public function testAccess() {
$this->assertAllowOperations([], $this->anon);
$this->assertAllowOperations(['view', 'update', 'delete'], $this->member);
$this->fieldStorage->setLocked(TRUE)->save();
// Unfortunately, EntityAccessControlHandler has a static cache, which we
// therefore must reset manually.
$this->accessControlHandler->resetCache();
$this->assertAllowOperations([], $this->anon);
$this->assertAllowOperations(['view', 'update'], $this->member);
}
}
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\FieldStorageConfig;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig\FieldStorageConfigResourceTestBase;
/**
* @group hal
*/
class FieldStorageConfigHalJsonAnonTest extends FieldStorageConfigResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
}
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\FieldStorageConfig;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig\FieldStorageConfigResourceTestBase;
/**
* @group hal
*/
class FieldStorageConfigHalJsonBasicAuthTest extends FieldStorageConfigResourceTestBase {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal', 'basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\FieldStorageConfig;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig\FieldStorageConfigResourceTestBase;
/**
* @group hal
*/
class FieldStorageConfigHalJsonCookieTest extends FieldStorageConfigResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
/**
* @group rest
*/
class FieldStorageConfigJsonAnonTest extends FieldStorageConfigResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
}
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group rest
*/
class FieldStorageConfigJsonBasicAuthTest extends FieldStorageConfigResourceTestBase {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group rest
*/
class FieldStorageConfigJsonCookieTest extends FieldStorageConfigResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
abstract class FieldStorageConfigResourceTestBase extends EntityResourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['node'];
/**
* {@inheritdoc}
*/
protected static $entityTypeId = 'field_storage_config';
/**
* @var \Drupal\field\FieldConfigStorage
*/
protected $entity;
/**
* {@inheritdoc}
*/
protected function setUpAuthorization($method) {
$this->grantPermissionsToTestedRole(['administer node fields']);
}
/**
* {@inheritdoc}
*/
protected function createEntity() {
$field_storage = FieldStorageConfig::create([
'field_name' => 'true_llama',
'entity_type' => 'node',
'type' => 'boolean',
]);
$field_storage->save();
return $field_storage;
}
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
return [
'cardinality' => 1,
'custom_storage' => FALSE,
'dependencies' => [
'module' => ['node'],
],
'entity_type' => 'node',
'field_name' => 'true_llama',
'id' => 'node.true_llama',
'indexes' => [],
'langcode' => 'en',
'locked' => FALSE,
'module' => 'core',
'persist_with_no_fields' => FALSE,
'settings' => [],
'status' => TRUE,
'translatable' => TRUE,
'type' => 'boolean',
'uuid' => $this->entity->uuid(),
];
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
// @todo Update in https://www.drupal.org/node/2300677.
}
/**
* {@inheritdoc}
*/
protected function getExpectedUnauthorizedAccessMessage($method) {
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
return parent::getExpectedUnauthorizedAccessMessage($method);
}
switch ($method) {
case 'GET':
return "The 'administer node fields' permission is required.";
default:
return parent::getExpectedUnauthorizedAccessMessage($method);
}
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheContexts() {
return [
'user.permissions',
];
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment