diff --git a/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonAnonTest.php b/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonAnonTest.php new file mode 100644 index 0000000000000000000000000000000000000000..1bd6eb803c167126e98962918af78e188eee0771 --- /dev/null +++ b/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonAnonTest.php @@ -0,0 +1,30 @@ +<?php + +namespace Drupal\Tests\hal\Functional\EntityResource\DateFormat; + +use Drupal\Tests\rest\Functional\AnonResourceTestTrait; +use Drupal\Tests\rest\Functional\EntityResource\DateFormat\DateFormatResourceTestBase; + +/** + * @group hal + */ +class DateFormatHalJsonAnonTest extends DateFormatResourceTestBase { + + use AnonResourceTestTrait; + + /** + * {@inheritdoc} + */ + public static $modules = ['hal']; + + /** + * {@inheritdoc} + */ + protected static $format = 'hal_json'; + + /** + * {@inheritdoc} + */ + protected static $mimeType = 'application/hal+json'; + +} diff --git a/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonBasicAuthTest.php b/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonBasicAuthTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2627c99dbb0c2db1a7441afc033b4f8b28dfded4 --- /dev/null +++ b/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonBasicAuthTest.php @@ -0,0 +1,35 @@ +<?php + +namespace Drupal\Tests\hal\Functional\EntityResource\DateFormat; + +use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; +use Drupal\Tests\rest\Functional\EntityResource\DateFormat\DateFormatResourceTestBase; + +/** + * @group hal + */ +class DateFormatHalJsonBasicAuthTest extends DateFormatResourceTestBase { + + 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'; + +} diff --git a/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonCookieTest.php b/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonCookieTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2367d6c0fa9fde2327424a48b8dd8567efc15270 --- /dev/null +++ b/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonCookieTest.php @@ -0,0 +1,35 @@ +<?php + +namespace Drupal\Tests\hal\Functional\EntityResource\DateFormat; + +use Drupal\Tests\rest\Functional\CookieResourceTestTrait; +use Drupal\Tests\rest\Functional\EntityResource\DateFormat\DateFormatResourceTestBase; + +/** + * @group hal + */ +class DateFormatHalJsonCookieTest extends DateFormatResourceTestBase { + + 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'; + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonAnonTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9fe8ea221c2e918abdeadc30a7ab6b140d883a9e --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonAnonTest.php @@ -0,0 +1,24 @@ +<?php + +namespace Drupal\Tests\rest\Functional\EntityResource\DateFormat; + +use Drupal\Tests\rest\Functional\AnonResourceTestTrait; + +/** + * @group rest + */ +class DateFormatJsonAnonTest extends DateFormatResourceTestBase { + + use AnonResourceTestTrait; + + /** + * {@inheritdoc} + */ + protected static $format = 'json'; + + /** + * {@inheritdoc} + */ + protected static $mimeType = 'application/json'; + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonBasicAuthTest.php new file mode 100644 index 0000000000000000000000000000000000000000..71f1f7fd659af1c53274911d7d4b79fec6c93f13 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonBasicAuthTest.php @@ -0,0 +1,34 @@ +<?php + +namespace Drupal\Tests\rest\Functional\EntityResource\DateFormat; + +use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; + +/** + * @group rest + */ +class DateFormatJsonBasicAuthTest extends DateFormatResourceTestBase { + + 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'; + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonCookieTest.php new file mode 100644 index 0000000000000000000000000000000000000000..07c305f7aad3c08fb374f5fc3f3393a35508e8ad --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonCookieTest.php @@ -0,0 +1,29 @@ +<?php + +namespace Drupal\Tests\rest\Functional\EntityResource\DateFormat; + +use Drupal\Tests\rest\Functional\CookieResourceTestTrait; + +/** + * @group rest + */ +class DateFormatJsonCookieTest extends DateFormatResourceTestBase { + + use CookieResourceTestTrait; + + /** + * {@inheritdoc} + */ + protected static $format = 'json'; + + /** + * {@inheritdoc} + */ + protected static $mimeType = 'application/json'; + + /** + * {@inheritdoc} + */ + protected static $auth = 'cookie'; + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatResourceTestBase.php new file mode 100644 index 0000000000000000000000000000000000000000..8fce0fed15eccfcea2c6e3753888a6bfa5bd6e80 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatResourceTestBase.php @@ -0,0 +1,76 @@ +<?php + +namespace Drupal\Tests\rest\Functional\EntityResource\DateFormat; + +use Drupal\Core\Datetime\Entity\DateFormat; +use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase; + +/** + * ResourceTestBase for DateFormat entity. + */ +abstract class DateFormatResourceTestBase extends EntityResourceTestBase { + + /** + * {@inheritdoc} + */ + public static $modules = []; + + /** + * {@inheritdoc} + */ + protected static $entityTypeId = 'date_format'; + + /** + * The DateFormat entity. + * + * @var \Drupal\Core\Datetime\DateFormatInterface + */ + protected $entity; + + /** + * {@inheritdoc} + */ + protected function setUpAuthorization($method) { + $this->grantPermissionsToTestedRole(['administer site configuration']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + // Create a date format. + $date_format = DateFormat::create([ + 'id' => 'llama', + 'label' => 'Llama', + 'pattern' => 'F d, Y', + ]); + + $date_format->save(); + + return $date_format; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [], + 'id' => 'llama', + 'label' => 'Llama', + 'langcode' => 'en', + 'locked' => FALSE, + 'pattern' => 'F d, Y', + 'status' => TRUE, + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + +} diff --git a/core/modules/system/src/DateFormatAccessControlHandler.php b/core/modules/system/src/DateFormatAccessControlHandler.php index c9cee601ec3896630c0b0d4a6a95720dd84c7549..e56fe92a46a0eb4c493126baf1c6301fc87ca4a9 100644 --- a/core/modules/system/src/DateFormatAccessControlHandler.php +++ b/core/modules/system/src/DateFormatAccessControlHandler.php @@ -14,18 +14,23 @@ */ class DateFormatAccessControlHandler extends EntityAccessControlHandler { + /** + * {@inheritdoc} + */ + protected $viewLabelOperation = TRUE; + /** * {@inheritdoc} */ protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { - // There are no restrictions on viewing a date format. - if ($operation == 'view') { + // There are no restrictions on viewing the label of a date format. + if ($operation === 'view label') { return AccessResult::allowed(); } // Locked date formats cannot be updated or deleted. elseif (in_array($operation, ['update', 'delete'])) { if ($entity->isLocked()) { - return AccessResult::forbidden()->addCacheableDependency($entity); + return AccessResult::forbidden('The DateFormat config entity is locked.')->addCacheableDependency($entity); } else { return parent::checkAccess($entity, $operation, $account)->addCacheableDependency($entity); diff --git a/core/modules/system/tests/src/Kernel/DateFormatAccessControlHandlerTest.php b/core/modules/system/tests/src/Kernel/DateFormatAccessControlHandlerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..01b09dc6bbd4cbb0bd424eb199f7a787f0ea4dcd --- /dev/null +++ b/core/modules/system/tests/src/Kernel/DateFormatAccessControlHandlerTest.php @@ -0,0 +1,149 @@ +<?php + +namespace Drupal\Tests\system\Kernel; + +use Drupal\Core\Access\AccessResult; +use Drupal\Core\Cache\Context\CacheContextsManager; +use Drupal\Core\Datetime\Entity\DateFormat; +use Drupal\Core\DependencyInjection\ContainerBuilder; +use Drupal\KernelTests\KernelTestBase; +use Drupal\simpletest\UserCreationTrait; + +/** + * @coversDefaultClass \Drupal\system\DateFormatAccessControlHandler + * @group system + */ +class DateFormatAccessControlHandlerTest extends KernelTestBase { + + use UserCreationTrait { + createUser as drupalCreateUser; + } + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = [ + 'system', + 'user', + ]; + + /** + * The date_format access control handler. + * + * @var \Drupal\Core\Entity\EntityAccessControlHandlerInterface + */ + protected $accessControlHandler; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + $this->installEntitySchema('date_format'); + $this->installEntitySchema('user'); + $this->installSchema('system', 'sequences'); + $this->accessControlHandler = $this->container->get('entity_type.manager')->getAccessControlHandler('date_format'); + } + + /** + * @covers ::checkAccess + * @covers ::checkCreateAccess + * @dataProvider testAccessProvider + */ + public function testAccess($which_user, $which_entity, $view_label_access_result, $view_access_result, $update_access_result, $delete_access_result, $create_access_result) { + // We must always create user 1, so that a "normal" user has a ID >1. + $root_user = $this->drupalCreateUser(); + + if ($which_user === 'user1') { + $user = $root_user; + } + else { + $permissions = ($which_user === 'admin') + ? ['administer site configuration'] + : []; + $user = $this->drupalCreateUser($permissions); + } + + $entity_values = ($which_entity === 'unlocked') + ? ['locked' => FALSE] + : ['locked' => TRUE]; + $entity_values['id'] = $this->randomMachineName(); + $entity = DateFormat::create($entity_values); + $entity->save(); + + static::assertEquals($view_label_access_result, $this->accessControlHandler->access($entity, 'view label', $user, TRUE)); + static::assertEquals($view_access_result, $this->accessControlHandler->access($entity, 'view', $user, TRUE)); + static::assertEquals($update_access_result, $this->accessControlHandler->access($entity, 'update', $user, TRUE)); + static::assertEquals($delete_access_result, $this->accessControlHandler->access($entity, 'delete', $user, TRUE)); + static::assertEquals($create_access_result, $this->accessControlHandler->createAccess(NULL, $user, [], TRUE)); + } + + public function testAccessProvider() { + $c = new ContainerBuilder(); + $cache_contexts_manager = $this->prophesize(CacheContextsManager::class); + $cache_contexts_manager->assertValidTokens()->willReturn(TRUE); + $cache_contexts_manager->reveal(); + $c->set('cache_contexts_manager', $cache_contexts_manager); + \Drupal::setContainer($c); + + return [ + 'permissionless + unlocked' => [ + 'permissionless', + 'unlocked', + AccessResult::allowed(), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required."), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required.")->addCacheTags(['rendered']), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required.")->addCacheTags(['rendered']), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required."), + ], + 'permissionless + locked' => [ + 'permissionless', + 'locked', + AccessResult::allowed(), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required."), + AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."), + AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required."), + ], + 'admin + unlocked' => [ + 'admin', + 'unlocked', + AccessResult::allowed(), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['rendered']), + AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['rendered']), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + 'admin + locked' => [ + 'admin', + 'locked', + AccessResult::allowed(), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."), + AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + 'user1 + unlocked' => [ + 'user1', + 'unlocked', + AccessResult::allowed(), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['rendered']), + AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['rendered']), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + 'user1 + locked' => [ + 'user1', + 'locked', + AccessResult::allowed(), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."), + AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + ]; + } + +}