diff -u b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php --- b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php +++ b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php @@ -9,10 +9,7 @@ /** * @deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0. - * - * Access check for editing entity fields. */ - class EditEntityFieldAccessCheck extends QuickEditEntityFieldAccessCheck { } diff -u b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php --- b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php +++ b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php @@ -4,8 +4,6 @@ /** * @deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0. - * - * Access check for editing entity fields. */ interface EditEntityFieldAccessCheckInterface extends QuickEditEntityFieldAccessCheckInterface { diff -u b/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheck.php b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php --- b/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheck.php +++ b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php @@ -9,54 +9,7 @@ /** - * Access check for in-place editing entity fields. + * @deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0. */ -class QuickEditEntityFieldAccessCheck implements AccessInterface, QuickEditEntityFieldAccessCheckInterface { - - /** - * Checks Quick Edit access to the field. - * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity containing the field. - * @param string $field_name - * The field name. - * @param string $langcode - * The langcode. - * @param \Drupal\Core\Session\AccountInterface $account - * The currently logged in account. - * - * @return \Drupal\Core\Access\AccessResultInterface - * The access result. - * - * @todo Use the $account argument: https://www.drupal.org/node/2266809. - */ - public function access(EntityInterface $entity, $field_name, $langcode, AccountInterface $account) { - if (!$this->validateRequestAttributes($entity, $field_name, $langcode)) { - return AccessResult::forbidden(); - } - - return $this->accessEditEntityField($entity, $field_name); - } - - /** - * {@inheritdoc} - */ - public function accessEditEntityField(EntityInterface $entity, $field_name) { - return $entity->access('update', NULL, TRUE)->andIf($entity->get($field_name)->access('edit', NULL, TRUE)); - } - - /** - * Validates request attributes. - */ - protected function validateRequestAttributes(EntityInterface $entity, $field_name, $langcode) { - // Validate the field name and language. - if (!$field_name || !$entity->hasField($field_name)) { - return FALSE; - } - if (!$langcode || !$entity->hasTranslation($langcode)) { - return FALSE; - } - - return TRUE; - } +class EditEntityFieldAccessCheck extends QuickEditEntityFieldAccessCheck { } diff -u b/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheckInterface.php b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php --- b/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheckInterface.php +++ b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php @@ -3,23 +3,8 @@ namespace Drupal\quickedit\Access; -use Drupal\Core\Entity\EntityInterface; - /** - * Access check for in-place editing entity fields. + * @deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0. */ -interface QuickEditEntityFieldAccessCheckInterface { - - /** - * Checks access to edit the requested field of the requested entity. - * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity. - * @param string $field_name - * The field name. - * - * @return \Drupal\Core\Access\AccessResultInterface - * The access result. - */ - public function accessEditEntityField(EntityInterface $entity, $field_name); +interface EditEntityFieldAccessCheckInterface extends QuickEditEntityFieldAccessCheckInterface { } diff -u b/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php b/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php --- b/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php +++ b/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php @@ -2,13 +2,8 @@ namespace Drupal\quickedit_test; -use Drupal\Core\Entity\EntityInterface; -use Drupal\quickedit\Access\QuickEditEntityFieldAccessCheckInterface; - /** * @deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0. - * - * Access check for editing entity fields. */ class MockEditEntityFieldAccessCheck extends MockQuickEditEntityFieldAccessCheck { diff -u b/core/modules/quickedit/tests/modules/src/MockQuickEditEntityFieldAccessCheck.php b/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php --- b/core/modules/quickedit/tests/modules/src/MockQuickEditEntityFieldAccessCheck.php +++ b/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php @@ -3,18 +3,8 @@ namespace Drupal\quickedit_test; -use Drupal\Core\Entity\EntityInterface; -use Drupal\quickedit\Access\QuickEditEntityFieldAccessCheckInterface; - /** - * Access check for in-place editing entity fields. + * @deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0. */ -class MockQuickEditEntityFieldAccessCheck implements QuickEditEntityFieldAccessCheckInterface { - - /** - * {@inheritdoc} - */ - public function accessEditEntityField(EntityInterface $entity, $field_name) { - return TRUE; - } +class MockEditEntityFieldAccessCheck extends MockQuickEditEntityFieldAccessCheck { } diff -u b/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php b/core/modules/quickedit/tests/src/Unit/Access/QuickEditEntityFieldAccessCheckTest.php --- b/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php +++ b/core/modules/quickedit/tests/src/Unit/Access/QuickEditEntityFieldAccessCheckTest.php @@ -3,13 +3,147 @@ namespace Drupal\Tests\quickedit\Unit\Access; -/** - * @deprecated in Drupal 8.3.x, will be removed before Drupal 9.x - */ +use Drupal\Core\Access\AccessResult; +use Drupal\Core\Cache\Context\CacheContextsManager; +use Drupal\Core\DependencyInjection\Container; +use Drupal\quickedit\Access\QuickEditEntityFieldAccessCheck; +use Drupal\Tests\UnitTestCase; +use Drupal\Core\Language\LanguageInterface; + /** * @coversDefaultClass \Drupal\quickedit\Access\QuickEditEntityFieldAccessCheck * @group Access * @group quickedit */ -class EditEntityFieldAccessCheckTest extends QuickEditEntityFieldAccessCheckTest { +class QuickEditEntityFieldAccessCheckTest extends UnitTestCase { + + /** + * The tested access checker. + * + * @var \Drupal\quickedit\Access\QuickEditEntityFieldAccessCheck + */ + protected $editAccessCheck; + + /** + * {@inheritdoc} + */ + protected function setUp() { + $this->editAccessCheck = new QuickEditEntityFieldAccessCheck(); + + $cache_contexts_manager = $this->prophesize(CacheContextsManager::class); + $cache_contexts_manager->assertValidTokens()->willReturn(TRUE); + $cache_contexts_manager->reveal(); + $container = new Container(); + $container->set('cache_contexts_manager', $cache_contexts_manager); + \Drupal::setContainer($container); + } + + /** + * Provides test data for testAccess(). + * + * @see \Drupal\Tests\edit\Unit\quickedit\Access\QuickEditEntityFieldAccessCheckTest::testAccess() + */ + public function providerTestAccess() { + $data = array(); + $data[] = array(TRUE, TRUE, AccessResult::allowed()); + $data[] = array(FALSE, TRUE, AccessResult::neutral()); + $data[] = array(TRUE, FALSE, AccessResult::neutral()); + $data[] = array(FALSE, FALSE, AccessResult::neutral()); + + return $data; + } + + /** + * Tests the method for checking access to routes. + * + * @param bool $entity_is_editable + * Whether the subject entity is editable. + * @param bool $field_storage_is_accessible + * Whether the user has access to the field storage entity. + * @param \Drupal\Core\Access\AccessResult $expected_result + * The expected result of the access call. + * + * @dataProvider providerTestAccess + */ + public function testAccess($entity_is_editable, $field_storage_is_accessible, AccessResult $expected_result) { + $entity = $this->createMockEntity(); + $entity->expects($this->any()) + ->method('access') + ->willReturn(AccessResult::allowedIf($entity_is_editable)->cachePerPermissions()); + + $field_storage = $this->getMock('Drupal\field\FieldStorageConfigInterface'); + $field_storage->expects($this->any()) + ->method('access') + ->willReturn(AccessResult::allowedIf($field_storage_is_accessible)); + + $expected_result->cachePerPermissions(); + + $field_name = 'valid'; + $entity_with_field = clone $entity; + $entity_with_field->expects($this->any()) + ->method('get') + ->with($field_name) + ->will($this->returnValue($field_storage)); + $entity_with_field->expects($this->once()) + ->method('hasTranslation') + ->with(LanguageInterface::LANGCODE_NOT_SPECIFIED) + ->will($this->returnValue(TRUE)); + + $account = $this->getMock('Drupal\Core\Session\AccountInterface'); + $access = $this->editAccessCheck->access($entity_with_field, $field_name, LanguageInterface::LANGCODE_NOT_SPECIFIED, $account); + $this->assertEquals($expected_result, $access); + } + + /** + * Tests checking access to routes that result in AccessResult::isForbidden(). + * + * @dataProvider providerTestAccessForbidden + */ + public function testAccessForbidden($field_name, $langcode) { + $account = $this->getMock('Drupal\Core\Session\AccountInterface'); + $entity = $this->createMockEntity(); + $this->assertEquals(AccessResult::forbidden(), $this->editAccessCheck->access($entity, $field_name, $langcode, $account)); + } + + /** + * Provides test data for testAccessForbidden. + */ + public function providerTestAccessForbidden() { + $data = array(); + // Tests the access method without a field_name. + $data[] = array(NULL, LanguageInterface::LANGCODE_NOT_SPECIFIED); + // Tests the access method with a non-existent field. + $data[] = array('not_valid', LanguageInterface::LANGCODE_NOT_SPECIFIED); + // Tests the access method without a langcode. + $data[] = array('valid', NULL); + // Tests the access method with an invalid langcode. + $data[] = array('valid', 'xx-lolspeak'); + return $data; + } + + /** + * Returns a mock entity. + * + * @return \Drupal\Core\Entity\EntityInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected function createMockEntity() { + $entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest') + ->disableOriginalConstructor() + ->getMock(); + + $entity->expects($this->any()) + ->method('hasTranslation') + ->will($this->returnValueMap(array( + array(LanguageInterface::LANGCODE_NOT_SPECIFIED, TRUE), + array('xx-lolspeak', FALSE), + ))); + $entity->expects($this->any()) + ->method('hasField') + ->will($this->returnValueMap(array( + array('valid', TRUE), + array('not_valid', FALSE), + ))); + + return $entity; + } }