.../rest/tests/modules/rest_test/rest_test.module | 32 ++++++++++++++-- .../EntityResource/EntityResourceTestBase.php | 44 +++++++++++++++++++--- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/core/modules/rest/tests/modules/rest_test/rest_test.module b/core/modules/rest/tests/modules/rest_test/rest_test.module index 272603d..946d401 100644 --- a/core/modules/rest/tests/modules/rest_test/rest_test.module +++ b/core/modules/rest/tests/modules/rest_test/rest_test.module @@ -1,9 +1,9 @@ getName() === 'field_rest_test') { + switch ($operation) { + case 'view': + // Never ever allow this field to be viewed: this lets EntityResourceTestBase::testGet() test in a "vanilla" way. + return AccessResult::forbidden(); + case 'edit': + if ($items && $items->value === 'no access value') { + return AccessResult::forbidden(); + } + break; + } + } + + // No opinion. + return AccessResult::neutral(); +} \ No newline at end of file diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php index 60de61a..7875c8d 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php @@ -3,7 +3,10 @@ namespace Drupal\Tests\rest\Functional\EntityResource; use Drupal\Core\Config\Entity\ConfigEntityInterface; +use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Url; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldStorageConfig; use Drupal\Tests\rest\Functional\ResourceTestBase; use GuzzleHttp\RequestOptions; use Psr\Http\Message\ResponseInterface; @@ -74,6 +77,13 @@ protected $entity; /** + * Modules to install. + * + * @var array + */ + public static $modules = ['rest_test', 'text']; + + /** * {@inheritdoc} */ protected function provisionEntityResource() { @@ -95,15 +105,28 @@ public function setUp() { $this->httpClient = $this->container->get('http_client_factory') ->fromOptions(['base_uri' => $this->baseUrl]); - // Add field with specific allowed value. - // (allows testing invalid vs valid field value) - - // Add access-protected field to entity type. - // (allows testing with field that cannot be modified) - // Create an entity. $this->entity = $this->createEntity(); + if ($this->entity instanceof FieldableEntityInterface) { + // Add access-protected field. + FieldStorageConfig::create([ + 'entity_type' => static::$entityType, + 'field_name' => 'field_rest_test', + 'type' => 'text', + ]) + ->setCardinality(1) + ->save(); + FieldConfig::create([ + 'entity_type' => static::$entityType, + 'field_name' => 'field_rest_test', + 'bundle' => $this->entity->bundle(), + ]) + ->setLabel('Test field') + ->setTranslatable(FALSE) + ->save(); + } + // @todo Remove this in https://www.drupal.org/node/2815845. drupal_flush_all_caches(); } @@ -313,6 +336,7 @@ public function testPost() { $parseable_invalid_request_body = $this->serializer->encode($this->getInvalidNormalizedEntityToCreate(), static::$format); // @todo Change to ['uuid' => UUID] when https://www.drupal.org/node/2820743 lands. $parseable_invalid_request_body_2 = $this->serializer->encode($this->getNormalizedEntityToCreate() + ['uuid' => [['value' => $this->randomMachineName(129)]]], static::$format); + $parseable_invalid_request_body_3 = $this->serializer->encode($this->getNormalizedEntityToCreate() + ['field_rest_test' => [['value' => 'no access value']]], static::$format); // The URL and Guzzle request options that will be used in this test. The // request options will be modified/expanded throughout this test: @@ -435,6 +459,14 @@ public function testPost() { $this->assertSame($this->serializer->encode(['message' => "Unprocessable Entity: validation failed.\nuuid.0.value: UUID: may not be longer than 128 characters.\n"], static::$format), (string) $response->getBody()); + $request_options[RequestOptions::BODY] = $parseable_invalid_request_body_3; + + + // DX: 403 when entity contains field without 'edit' access. + $response = $this->request('POST', $url, $request_options); + $this->assertResourceErrorResponse(403, "Access denied on creating field 'field_rest_test'", $response); + + $request_options[RequestOptions::BODY] = $parseable_valid_request_body;