Move into nested docroot

This commit is contained in:
Rob Davies 2017-02-13 15:31:17 +00:00
parent 83a0d3a149
commit c8b70abde9
13405 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,35 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Block;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\Block\BlockResourceTestBase;
/**
* @group hal
*/
class BlockHalJsonAnonTest extends BlockResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $expectedErrorMimeType = 'application/json';
}

View file

@ -0,0 +1,46 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Block;
use Drupal\Tests\hal\Functional\HalJsonBasicAuthWorkaroundFor2805281Trait;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\Block\BlockResourceTestBase;
/**
* @group hal
*/
class BlockHalJsonBasicAuthTest extends BlockResourceTestBase {
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 $expectedErrorMimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
// @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage.
use HalJsonBasicAuthWorkaroundFor2805281Trait {
HalJsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait;
}
}

View file

@ -0,0 +1,40 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Block;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\Block\BlockResourceTestBase;
/**
* @group hal
*/
class BlockHalJsonCookieTest extends BlockResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $expectedErrorMimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}

View file

@ -0,0 +1,35 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Comment;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
/**
* @group hal
*/
class CommentHalJsonAnonTest extends CommentHalJsonTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*
* Anononymous users cannot edit their own comments.
*
* @see \Drupal\comment\CommentAccessControlHandler::checkAccess
*
* Therefore we grant them the 'administer comments' permission for the
* purpose of this test. Then they are able to edit their own comments, but
* some fields are still not editable, even with that permission.
*
* @see ::setUpAuthorization
*/
protected static $patchProtectedFieldNames = [
'changed',
'thread',
'entity_type',
'field_name',
'entity_id',
];
}

View file

@ -0,0 +1,30 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Comment;
use Drupal\Tests\hal\Functional\HalJsonBasicAuthWorkaroundFor2805281Trait;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group hal
*/
class CommentHalJsonBasicAuthTest extends CommentHalJsonTestBase {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
// @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage.
use HalJsonBasicAuthWorkaroundFor2805281Trait {
HalJsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait;
}
}

View file

@ -0,0 +1,19 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Comment;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group hal
*/
class CommentHalJsonCookieTest extends CommentHalJsonTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}

View file

@ -0,0 +1,144 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Comment;
use Drupal\Core\Cache\Cache;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\Tests\hal\Functional\EntityResource\HalEntityNormalizationTrait;
use Drupal\Tests\rest\Functional\EntityResource\Comment\CommentResourceTestBase;
use Drupal\user\Entity\User;
abstract class CommentHalJsonTestBase extends CommentResourceTestBase {
use HalEntityNormalizationTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $expectedErrorMimeType = 'application/json';
/**
* {@inheritdoc}
*
* The HAL+JSON format causes different PATCH-protected fields. For some
* reason, the 'pid' and 'homepage' fields are NOT PATCH-protected, even
* though they are for non-HAL+JSON serializations.
*
* @todo fix in https://www.drupal.org/node/2824271
*/
protected static $patchProtectedFieldNames = [
'created',
'changed',
'status',
'thread',
'entity_type',
'field_name',
'entity_id',
'uid',
];
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
$default_normalization = parent::getExpectedNormalizedEntity();
$normalization = $this->applyHalFieldNormalization($default_normalization);
// Because \Drupal\comment\Entity\Comment::getOwner() generates an in-memory
// User entity without a UUID, we cannot use it.
$author = User::load($this->entity->getOwnerId());
$commented_entity = EntityTest::load(1);
return $normalization + [
'_links' => [
'self' => [
'href' => $this->baseUrl . '/comment/1?_format=hal_json',
],
'type' => [
'href' => $this->baseUrl . '/rest/type/comment/comment',
],
$this->baseUrl . '/rest/relation/comment/comment/entity_id' => [
[
'href' => $this->baseUrl . '/entity_test/1?_format=hal_json',
],
],
$this->baseUrl . '/rest/relation/comment/comment/uid' => [
[
'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
'lang' => 'en',
],
],
],
'_embedded' => [
$this->baseUrl . '/rest/relation/comment/comment/entity_id' => [
[
'_links' => [
'self' => [
'href' => $this->baseUrl . '/entity_test/1?_format=hal_json',
],
'type' => [
'href' => $this->baseUrl . '/rest/type/entity_test/bar',
],
],
'uuid' => [
['value' => $commented_entity->uuid()]
],
],
],
$this->baseUrl . '/rest/relation/comment/comment/uid' => [
[
'_links' => [
'self' => [
'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
],
'type' => [
'href' => $this->baseUrl . '/rest/type/user/user',
],
],
'uuid' => [
['value' => $author->uuid()]
],
'lang' => 'en',
],
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
return parent::getNormalizedPostEntity() + [
'_links' => [
'type' => [
'href' => $this->baseUrl . '/rest/type/comment/comment',
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheContexts() {
// The 'url.site' cache context is added for '_links' in the response.
return Cache::mergeTags(parent::getExpectedCacheContexts(), ['url.site']);
}
}

View file

@ -0,0 +1,35 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\ConfigTest;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\ConfigTest\ConfigTestResourceTestBase;
/**
* @group hal
*/
class ConfigTestHalJsonAnonTest extends ConfigTestResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $expectedErrorMimeType = 'application/json';
}

View file

@ -0,0 +1,46 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\ConfigTest;
use Drupal\Tests\hal\Functional\HalJsonBasicAuthWorkaroundFor2805281Trait;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\ConfigTest\ConfigTestResourceTestBase;
/**
* @group hal
*/
class ConfigTestHalJsonBasicAuthTest extends ConfigTestResourceTestBase {
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 $expectedErrorMimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
// @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage.
use HalJsonBasicAuthWorkaroundFor2805281Trait {
HalJsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait;
}
}

View file

@ -0,0 +1,40 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\ConfigTest;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\ConfigTest\ConfigTestResourceTestBase;
/**
* @group hal
*/
class ConfigTestHalJsonCookieTest extends ConfigTestResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $expectedErrorMimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}

View file

@ -0,0 +1,105 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\EntityTest;
use Drupal\Core\Cache\Cache;
use Drupal\Tests\hal\Functional\EntityResource\HalEntityNormalizationTrait;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\EntityTest\EntityTestResourceTestBase;
use Drupal\user\Entity\User;
/**
* @group hal
*/
class EntityTestHalJsonAnonTest extends EntityTestResourceTestBase {
use HalEntityNormalizationTrait;
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $expectedErrorMimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
$default_normalization = parent::getExpectedNormalizedEntity();
$normalization = $this->applyHalFieldNormalization($default_normalization);
$author = User::load(0);
return $normalization + [
'_links' => [
'self' => [
'href' => $this->baseUrl . '/entity_test/1?_format=hal_json',
],
'type' => [
'href' => $this->baseUrl . '/rest/type/entity_test/entity_test',
],
$this->baseUrl . '/rest/relation/entity_test/entity_test/user_id' => [
[
'href' => $this->baseUrl . '/user/0?_format=hal_json',
'lang' => 'en',
],
],
],
'_embedded' => [
$this->baseUrl . '/rest/relation/entity_test/entity_test/user_id' => [
[
'_links' => [
'self' => [
'href' => $this->baseUrl . '/user/0?_format=hal_json',
],
'type' => [
'href' => $this->baseUrl . '/rest/type/user/user',
],
],
'uuid' => [
['value' => $author->uuid()]
],
'lang' => 'en',
],
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
return parent::getNormalizedPostEntity() + [
'_links' => [
'type' => [
'href' => $this->baseUrl . '/rest/type/entity_test/entity_test',
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheContexts() {
// The 'url.site' cache context is added for '_links' in the response.
return Cache::mergeTags(parent::getExpectedCacheContexts(), ['url.site']);
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\EntityTest;
use Drupal\Tests\hal\Functional\HalJsonBasicAuthWorkaroundFor2805281Trait;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group hal
*/
class EntityTestHalJsonBasicAuthTest extends EntityTestHalJsonAnonTest {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
// @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage.
use HalJsonBasicAuthWorkaroundFor2805281Trait {
HalJsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait;
}
}

View file

@ -0,0 +1,19 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\EntityTest;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group hal
*/
class EntityTestHalJsonCookieTest extends EntityTestHalJsonAnonTest {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}

View file

@ -0,0 +1,127 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Url;
use GuzzleHttp\RequestOptions;
/**
* Trait for EntityResourceTestBase subclasses testing formats using HAL.
*/
trait HalEntityNormalizationTrait {
/**
* Applies the HAL entity field normalization to an entity normalization.
*
* The HAL normalization:
* - adds a 'lang' attribute to every translatable field
* - omits reference fields, since references are stored in _links & _embedded
* - omits empty fields (fields without value)
*
* @param array $normalization
* An entity normalization.
*
* @return array
* The updated entity normalization.
*/
protected function applyHalFieldNormalization(array $normalization) {
if (!$this->entity instanceof FieldableEntityInterface) {
throw new \LogicException('This trait should only be used for fieldable entity types.');
}
// In the HAL normalization, all translatable fields get a 'lang' attribute.
$translatable_non_reference_fields = array_keys(array_filter($this->entity->getTranslatableFields(), function (FieldItemListInterface $field) {
return !$field instanceof EntityReferenceFieldItemListInterface;
}));
foreach ($translatable_non_reference_fields as $field_name) {
if (isset($normalization[$field_name])) {
$normalization[$field_name][0]['lang'] = 'en';
}
}
// In the HAL normalization, reference fields are omitted, except for the
// bundle field.
$bundle_key = $this->entity->getEntityType()->getKey('bundle');
$reference_fields = array_keys(array_filter($this->entity->getFields(), function (FieldItemListInterface $field) use ($bundle_key) {
return $field instanceof EntityReferenceFieldItemListInterface && $field->getName() !== $bundle_key;
}));
foreach ($reference_fields as $field_name) {
unset($normalization[$field_name]);
}
// In the HAL normalization, the bundle field omits the 'target_type' and
// 'target_uuid' properties, because it's encoded in the '_links' section.
if ($bundle_key) {
unset($normalization[$bundle_key][0]['target_type']);
unset($normalization[$bundle_key][0]['target_uuid']);
}
// In the HAL normalization, empty fields are omitted.
$empty_fields = array_keys(array_filter($this->entity->getFields(), function (FieldItemListInterface $field) {
return $field->isEmpty();
}));
foreach ($empty_fields as $field_name) {
unset($normalization[$field_name]);
}
return $normalization;
}
/**
* {@inheritdoc}
*/
protected function removeFieldsFromNormalization(array $normalization, $field_names) {
$normalization = parent::removeFieldsFromNormalization($normalization, $field_names);
foreach ($field_names as $field_name) {
$relation_url = Url::fromUri('base:rest/relation/' . static::$entityTypeId . '/' . $this->entity->bundle() . '/' . $field_name)
->setAbsolute(TRUE)
->toString();
$normalization['_links'] = array_diff_key($normalization['_links'], [$relation_url => TRUE]);
if (isset($normalization['_embedded'])) {
$normalization['_embedded'] = array_diff_key($normalization['_embedded'], [$relation_url => TRUE]);
}
}
return array_diff_key($normalization, array_flip($field_names));
}
/**
* {@inheritdoc}
*/
protected function assertNormalizationEdgeCases($method, Url $url, array $request_options) {
// \Drupal\serialization\Normalizer\EntityNormalizer::denormalize(): entity
// types with bundles MUST send their bundle field to be denormalizable.
if ($this->entity->getEntityType()->hasKey('bundle')) {
$normalization = $this->getNormalizedPostEntity();
$normalization['_links']['type'] = Url::fromUri('base:rest/type/' . static::$entityTypeId . '/bad_bundle_name');
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
// DX: 400 when incorrect entity type bundle is specified.
$response = $this->request($method, $url, $request_options);
// @todo Uncomment, remove next 3 in https://www.drupal.org/node/2813853.
// $this->assertResourceErrorResponse(400, 'No entity type(s) specified', $response);
$this->assertSame(400, $response->getStatusCode());
$this->assertSame([static::$mimeType], $response->getHeader('Content-Type'));
$this->assertSame($this->serializer->encode(['error' => 'No entity type(s) specified'], static::$format), (string) $response->getBody());
unset($normalization['_links']['type']);
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
// DX: 400 when no entity type bundle is specified.
$response = $this->request($method, $url, $request_options);
// @todo Uncomment, remove next 3 in https://www.drupal.org/node/2813853.
// $this->assertResourceErrorResponse(400, 'The type link relation must be specified.', $response);
$this->assertSame(400, $response->getStatusCode());
$this->assertSame([static::$mimeType], $response->getHeader('Content-Type'));
$this->assertSame($this->serializer->encode(['error' => 'The type link relation must be specified.'], static::$format), (string) $response->getBody());
}
}
}

View file

@ -0,0 +1,137 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Node;
use Drupal\Core\Cache\Cache;
use Drupal\Tests\hal\Functional\EntityResource\HalEntityNormalizationTrait;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\Node\NodeResourceTestBase;
use Drupal\user\Entity\User;
/**
* @group hal
*/
class NodeHalJsonAnonTest extends NodeResourceTestBase {
use HalEntityNormalizationTrait;
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $expectedErrorMimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $patchProtectedFieldNames = [
'created',
'changed',
'promote',
'sticky',
'revision_timestamp',
'revision_uid',
];
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
$default_normalization = parent::getExpectedNormalizedEntity();
$normalization = $this->applyHalFieldNormalization($default_normalization);
$author = User::load($this->entity->getOwnerId());
return $normalization + [
'_links' => [
'self' => [
'href' => $this->baseUrl . '/node/1?_format=hal_json',
],
'type' => [
'href' => $this->baseUrl . '/rest/type/node/camelids',
],
$this->baseUrl . '/rest/relation/node/camelids/uid' => [
[
'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
'lang' => 'en',
],
],
$this->baseUrl . '/rest/relation/node/camelids/revision_uid' => [
[
'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
],
],
],
'_embedded' => [
$this->baseUrl . '/rest/relation/node/camelids/uid' => [
[
'_links' => [
'self' => [
'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
],
'type' => [
'href' => $this->baseUrl . '/rest/type/user/user',
],
],
'uuid' => [
['value' => $author->uuid()]
],
'lang' => 'en',
],
],
$this->baseUrl . '/rest/relation/node/camelids/revision_uid' => [
[
'_links' => [
'self' => [
'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
],
'type' => [
'href' => $this->baseUrl . '/rest/type/user/user',
],
],
'uuid' => [
['value' => $author->uuid()]
],
],
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
return parent::getNormalizedPostEntity() + [
'_links' => [
'type' => [
'href' => $this->baseUrl . '/rest/type/node/camelids',
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheContexts() {
// The 'url.site' cache context is added for '_links' in the response.
return Cache::mergeContexts(parent::getExpectedCacheContexts(), ['url.site']);
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Node;
use Drupal\Tests\hal\Functional\HalJsonBasicAuthWorkaroundFor2805281Trait;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group hal
*/
class NodeHalJsonBasicAuthTest extends NodeHalJsonAnonTest {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
// @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage.
use HalJsonBasicAuthWorkaroundFor2805281Trait {
HalJsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait;
}
}

View file

@ -0,0 +1,19 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Node;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group hal
*/
class NodeHalJsonCookieTest extends NodeHalJsonAnonTest {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}

View file

@ -0,0 +1,35 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Role;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\Role\RoleResourceTestBase;
/**
* @group hal
*/
class RoleHalJsonAnonTest extends RoleResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $expectedErrorMimeType = 'application/json';
}

View file

@ -0,0 +1,46 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Role;
use Drupal\Tests\hal\Functional\HalJsonBasicAuthWorkaroundFor2805281Trait;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\Role\RoleResourceTestBase;
/**
* @group hal
*/
class RoleHalJsonBasicAuthTest extends RoleResourceTestBase {
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 $expectedErrorMimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
// @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage.
use HalJsonBasicAuthWorkaroundFor2805281Trait {
HalJsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait;
}
}

View file

@ -0,0 +1,40 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Role;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\Role\RoleResourceTestBase;
/**
* @group hal
*/
class RoleHalJsonCookieTest extends RoleResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $expectedErrorMimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}

View file

@ -0,0 +1,79 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Term;
use Drupal\Core\Cache\Cache;
use Drupal\Tests\hal\Functional\EntityResource\HalEntityNormalizationTrait;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\Term\TermResourceTestBase;
/**
* @group hal
*/
class TermHalJsonAnonTest extends TermResourceTestBase {
use HalEntityNormalizationTrait;
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $expectedErrorMimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
$default_normalization = parent::getExpectedNormalizedEntity();
$normalization = $this->applyHalFieldNormalization($default_normalization);
return $normalization + [
'_links' => [
'self' => [
'href' => $this->baseUrl . '/taxonomy/term/1?_format=hal_json',
],
'type' => [
'href' => $this->baseUrl . '/rest/type/taxonomy_term/camelids',
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
return parent::getNormalizedPostEntity() + [
'_links' => [
'type' => [
'href' => $this->baseUrl . '/rest/type/taxonomy_term/camelids',
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheContexts() {
// The 'url.site' cache context is added for '_links' in the response.
return Cache::mergeContexts(parent::getExpectedCacheContexts(), ['url.site']);
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Term;
use Drupal\Tests\hal\Functional\HalJsonBasicAuthWorkaroundFor2805281Trait;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group hal
*/
class TermHalJsonBasicAuthTest extends TermHalJsonAnonTest {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
// @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage.
use HalJsonBasicAuthWorkaroundFor2805281Trait {
HalJsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait;
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Term;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group hal
*/
class TermHalJsonCookieTest extends TermHalJsonAnonTest {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}

View file

@ -0,0 +1,79 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\User;
use Drupal\Core\Cache\Cache;
use Drupal\Tests\hal\Functional\EntityResource\HalEntityNormalizationTrait;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\User\UserResourceTestBase;
/**
* @group hal
*/
class UserHalJsonAnonTest extends UserResourceTestBase {
use HalEntityNormalizationTrait;
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $expectedErrorMimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
$default_normalization = parent::getExpectedNormalizedEntity();
$normalization = $this->applyHalFieldNormalization($default_normalization);
return $normalization + [
'_links' => [
'self' => [
'href' => $this->baseUrl . '/user/3?_format=hal_json',
],
'type' => [
'href' => $this->baseUrl . '/rest/type/user/user',
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
return parent::getNormalizedPostEntity() + [
'_links' => [
'type' => [
'href' => $this->baseUrl . '/rest/type/user/user',
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheContexts() {
// The 'url.site' cache context is added for '_links' in the response.
return Cache::mergeContexts(parent::getExpectedCacheContexts(), ['url.site']);
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\User;
use Drupal\Tests\hal\Functional\HalJsonBasicAuthWorkaroundFor2805281Trait;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group hal
*/
class UserHalJsonBasicAuthTest extends UserHalJsonAnonTest {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
// @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage.
use HalJsonBasicAuthWorkaroundFor2805281Trait {
HalJsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait;
}
}

View file

@ -0,0 +1,19 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\User;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group hal
*/
class UserHalJsonCookieTest extends UserHalJsonAnonTest {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}

View file

@ -0,0 +1,42 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Vocabulary;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\Vocabulary\VocabularyResourceTestBase;
/**
* @group hal
*/
class VocabularyHalJsonAnonTest extends VocabularyResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $expectedErrorMimeType = 'application/json';
/**
* @todo Remove this override in https://www.drupal.org/node/2805281.
*/
public function testGet() {
$this->markTestSkipped();
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Vocabulary;
use Drupal\Tests\hal\Functional\HalJsonBasicAuthWorkaroundFor2805281Trait;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\Vocabulary\VocabularyResourceTestBase;
/**
* @group hal
*/
class VocabularyHalJsonBasicAuthTest extends VocabularyResourceTestBase {
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 $expectedErrorMimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
// @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage.
use HalJsonBasicAuthWorkaroundFor2805281Trait {
HalJsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait;
}
}

View file

@ -0,0 +1,40 @@
<?php
namespace Drupal\Tests\hal\Functional\EntityResource\Vocabulary;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\Vocabulary\VocabularyResourceTestBase;
/**
* @group hal
*/
class VocabularyHalJsonCookieTest extends VocabularyResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $expectedErrorMimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}

View file

@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\hal\Functional;
use Psr\Http\Message\ResponseInterface;
trait HalJsonBasicAuthWorkaroundFor2805281Trait {
/**
* {@inheritdoc}
*
* Note how the response claims it contains a application/hal+json body, but
* in reality it contains a text/plain body! Also, the correct error MIME type
* is application/json.
*
* @todo Fix in https://www.drupal.org/node/2805281: remove this trait.
*/
protected function assertResponseWhenMissingAuthentication(ResponseInterface $response) {
$this->assertSame(401, $response->getStatusCode());
// @todo this works fine locally, but on testbot it comes back with
// 'text/plain; charset=UTF-8'. WTF.
// $this->assertSame(['application/hal+json'], $response->getHeader('Content-Type'));
$this->assertSame('No authentication credentials provided.', (string) $response->getBody());
}
}

View file

@ -0,0 +1,143 @@
<?php
namespace Drupal\Tests\hal\Kernel;
use Drupal\Core\Url;
use Drupal\field\Entity\FieldConfig;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
/**
* Tests HAL denormalization edge cases for EntityResource.
*
* @group hal
*/
class DenormalizeTest extends NormalizerTestBase {
/**
* Tests that the type link relation in incoming data is handled correctly.
*/
public function testTypeHandling() {
// Valid type.
$data_with_valid_type = array(
'_links' => array(
'type' => array(
'href' => Url::fromUri('base:rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
),
),
);
$denormalized = $this->serializer->denormalize($data_with_valid_type, $this->entityClass, $this->format);
$this->assertEqual(get_class($denormalized), $this->entityClass, 'Request with valid type results in creation of correct bundle.');
// Multiple types.
$data_with_multiple_types = array(
'_links' => array(
'type' => array(
array(
'href' => Url::fromUri('base:rest/types/foo', array('absolute' => TRUE))->toString(),
),
array(
'href' => Url::fromUri('base:rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
),
),
),
);
$denormalized = $this->serializer->denormalize($data_with_multiple_types, $this->entityClass, $this->format);
$this->assertEqual(get_class($denormalized), $this->entityClass, 'Request with multiple types results in creation of correct bundle.');
// Invalid type.
$data_with_invalid_type = array(
'_links' => array(
'type' => array(
'href' => Url::fromUri('base:rest/types/foo', array('absolute' => TRUE))->toString(),
),
),
);
try {
$this->serializer->denormalize($data_with_invalid_type, $this->entityClass, $this->format);
$this->fail('Exception should be thrown when type is invalid.');
}
catch (UnexpectedValueException $e) {
$this->pass('Exception thrown when type is invalid.');
}
// No type.
$data_with_no_type = array(
'_links' => array(
),
);
try {
$this->serializer->denormalize($data_with_no_type, $this->entityClass, $this->format);
$this->fail('Exception should be thrown when no type is provided.');
}
catch (UnexpectedValueException $e) {
$this->pass('Exception thrown when no type is provided.');
}
}
/**
* Tests link relation handling with an invalid type.
*/
public function testTypeHandlingWithInvalidType() {
$data_with_invalid_type = array(
'_links' => array(
'type' => array(
'href' => Url::fromUri('base:rest/type/entity_test/entity_test_invalid', array('absolute' => TRUE))->toString(),
),
),
);
$this->setExpectedException(UnexpectedValueException::class);
$this->serializer->denormalize($data_with_invalid_type, $this->entityClass, $this->format);
}
/**
* Tests link relation handling with no types.
*/
public function testTypeHandlingWithNoTypes() {
$data_with_no_types = array(
'_links' => array(
'type' => array(),
),
);
$this->setExpectedException(UnexpectedValueException::class);
$this->serializer->denormalize($data_with_no_types, $this->entityClass, $this->format);
}
/**
* Test that a field set to an empty array is different than an absent field.
*/
public function testMarkFieldForDeletion() {
// Add a default value for a field.
$field = FieldConfig::loadByName('entity_test', 'entity_test', 'field_test_text');
$field->setDefaultValue(array(array('value' => 'Llama')));
$field->save();
// Denormalize data that contains no entry for the field, and check that
// the default value is present in the resulting entity.
$data = array(
'_links' => array(
'type' => array(
'href' => Url::fromUri('base:rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
),
),
);
$entity = $this->serializer->denormalize($data, $this->entityClass, $this->format);
$this->assertEqual($entity->field_test_text->count(), 1);
$this->assertEqual($entity->field_test_text->value, 'Llama');
// Denormalize data that contains an empty entry for the field, and check
// that the field is empty in the resulting entity.
$data = array(
'_links' => array(
'type' => array(
'href' => Url::fromUri('base:rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
),
),
'field_test_text' => array(),
);
$entity = $this->serializer->denormalize($data, get_class($entity), $this->format, [ 'target_instance' => $entity ]);
$this->assertEqual($entity->field_test_text->count(), 0);
}
}

View file

@ -0,0 +1,89 @@
<?php
namespace Drupal\Tests\hal\Kernel;
use Drupal\node\Entity\Node;
use Drupal\user\Entity\User;
use Drupal\node\Entity\NodeType;
/**
* Tests that translated nodes are correctly (de-)normalized.
*
* @group hal
*/
class EntityTranslationNormalizeTest extends NormalizerTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('node', 'content_translation');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installSchema('system', array('sequences'));
$this->installConfig(['node', 'content_translation']);
}
/**
* Tests the normalization of node translations.
*/
public function testNodeTranslation() {
$node_type = NodeType::create(['type' => 'example_type']);
$node_type->save();
$this->container->get('content_translation.manager')->setEnabled('node', 'example_type', TRUE);
$user = User::create(['name' => $this->randomMachineName()]);
$user->save();
$node = Node::create([
'title' => $this->randomMachineName(),
'uid' => $user->id(),
'type' => $node_type->id(),
'status' => NODE_PUBLISHED,
'langcode' => 'en',
'promote' => 1,
'sticky' => 0,
'body' => [
'value' => $this->randomMachineName(),
'format' => $this->randomMachineName()
],
'revision_log' => $this->randomString(),
]);
$node->addTranslation('de', [
'title' => 'German title',
'body' => [
'value' => $this->randomMachineName(),
'format' => $this->randomMachineName()
],
]);
$node->save();
$original_values = $node->toArray();
$translation = $node->getTranslation('de');
$original_translation_values = $node->getTranslation('en')->toArray();
$normalized = $this->serializer->normalize($node, $this->format);
$this->assertContains(['lang' => 'en', 'value' => $node->getTitle()], $normalized['title'], 'Original language title has been normalized.');
$this->assertContains(['lang' => 'de', 'value' => $translation->getTitle()], $normalized['title'], 'Translation language title has been normalized.');
/** @var \Drupal\node\NodeInterface $denormalized_node */
$denormalized_node = $this->serializer->denormalize($normalized, 'Drupal\node\Entity\Node', $this->format);
$this->assertSame($denormalized_node->language()->getId(), $denormalized_node->getUntranslated()->language()->getId(), 'Untranslated object is returned from serializer.');
$this->assertSame('en', $denormalized_node->language()->getId());
$this->assertTrue($denormalized_node->hasTranslation('de'));
$this->assertSame($node->getTitle(), $denormalized_node->getTitle());
$this->assertSame($translation->getTitle(), $denormalized_node->getTranslation('de')->getTitle());
$this->assertEquals($original_values, $denormalized_node->toArray(), 'Node values are restored after normalizing and denormalizing.');
$this->assertEquals($original_translation_values, $denormalized_node->getTranslation('en')->toArray(), 'Node values are restored after normalizing and denormalizing.');
}
}

View file

@ -0,0 +1,80 @@
<?php
namespace Drupal\Tests\hal\Kernel;
use Drupal\Core\Cache\MemoryBackend;
use Drupal\file\Entity\File;
use Drupal\hal\Encoder\JsonEncoder;
use Drupal\hal\Normalizer\FieldItemNormalizer;
use Drupal\hal\Normalizer\FileEntityNormalizer;
use Drupal\rest\LinkManager\LinkManager;
use Drupal\rest\LinkManager\RelationLinkManager;
use Drupal\rest\LinkManager\TypeLinkManager;
use Symfony\Component\Serializer\Serializer;
/**
* Tests that file entities can be normalized in HAL.
*
* @group hal
*/
class FileNormalizeTest extends NormalizerTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('file');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('file');
$entity_manager = \Drupal::entityManager();
$link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default'), \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack'), \Drupal::service('entity_type.bundle.info')), new RelationLinkManager(new MemoryBackend('default'), $entity_manager, \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack')));
// Set up the mock serializer.
$normalizers = array(
new FieldItemNormalizer(),
new FileEntityNormalizer($entity_manager, \Drupal::httpClient(), $link_manager, \Drupal::moduleHandler()),
);
$encoders = array(
new JsonEncoder(),
);
$this->serializer = new Serializer($normalizers, $encoders);
}
/**
* Tests the normalize function.
*/
public function testNormalize() {
$file_params = array(
'filename' => 'test_1.txt',
'uri' => 'public://test_1.txt',
'filemime' => 'text/plain',
'status' => FILE_STATUS_PERMANENT,
);
// Create a new file entity.
$file = File::create($file_params);
file_put_contents($file->getFileUri(), 'hello world');
$file->save();
$expected_array = array(
'uri' => array(
array(
'value' => file_create_url($file->getFileUri())),
),
);
$normalized = $this->serializer->normalize($file, $this->format);
$this->assertEqual($normalized['uri'], $expected_array['uri'], 'URI is normalized.');
}
}

View file

@ -0,0 +1,185 @@
<?php
namespace Drupal\Tests\hal\Kernel;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Url;
use Drupal\entity_test\Entity\EntityTest;
/**
* Tests HAL normalization edge cases for EntityResource.
*
* @group hal
*/
class NormalizeTest extends NormalizerTestBase {
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
\Drupal::service('router.builder')->rebuild();
}
/**
* Tests the normalize function.
*/
public function testNormalize() {
$target_entity_de = EntityTest::create((array('langcode' => 'de', 'field_test_entity_reference' => NULL)));
$target_entity_de->save();
$target_entity_en = EntityTest::create((array('langcode' => 'en', 'field_test_entity_reference' => NULL)));
$target_entity_en->save();
// Create a German entity.
$values = array(
'langcode' => 'de',
'name' => $this->randomMachineName(),
'field_test_text' => array(
'value' => $this->randomMachineName(),
'format' => 'full_html',
),
'field_test_entity_reference' => array(
'target_id' => $target_entity_de->id(),
),
);
// Array of translated values.
$translation_values = array(
'name' => $this->randomMachineName(),
'field_test_entity_reference' => array(
'target_id' => $target_entity_en->id(),
)
);
$entity = EntityTest::create($values);
$entity->save();
// Add an English value for name and entity reference properties.
$entity->addTranslation('en')->set('name', array(0 => array('value' => $translation_values['name'])));
$entity->getTranslation('en')->set('field_test_entity_reference', array(0 => $translation_values['field_test_entity_reference']));
$entity->save();
$type_uri = Url::fromUri('base:rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString();
$relation_uri = Url::fromUri('base:rest/relation/entity_test/entity_test/field_test_entity_reference', array('absolute' => TRUE))->toString();
$expected_array = array(
'_links' => array(
'curies' => array(
array(
'href' => '/relations',
'name' => 'site',
'templated' => TRUE,
),
),
'self' => array(
'href' => $this->getEntityUri($entity),
),
'type' => array(
'href' => $type_uri,
),
$relation_uri => array(
array(
'href' => $this->getEntityUri($target_entity_de),
'lang' => 'de',
),
array(
'href' => $this->getEntityUri($target_entity_en),
'lang' => 'en',
),
),
),
'_embedded' => array(
$relation_uri => array(
array(
'_links' => array(
'self' => array(
'href' => $this->getEntityUri($target_entity_de),
),
'type' => array(
'href' => $type_uri,
),
),
'uuid' => array(
array(
'value' => $target_entity_de->uuid(),
),
),
'lang' => 'de',
),
array(
'_links' => array(
'self' => array(
'href' => $this->getEntityUri($target_entity_en),
),
'type' => array(
'href' => $type_uri,
),
),
'uuid' => array(
array(
'value' => $target_entity_en->uuid(),
),
),
'lang' => 'en',
),
),
),
'id' => array(
array(
'value' => $entity->id(),
),
),
'uuid' => array(
array(
'value' => $entity->uuid(),
),
),
'langcode' => array(
array(
'value' => 'de',
),
),
'name' => array(
array(
'value' => $values['name'],
'lang' => 'de',
),
array(
'value' => $translation_values['name'],
'lang' => 'en',
),
),
'field_test_text' => array(
array(
'value' => $values['field_test_text']['value'],
'format' => $values['field_test_text']['format'],
),
),
);
$normalized = $this->serializer->normalize($entity, $this->format);
$this->assertEqual($normalized['_links']['self'], $expected_array['_links']['self'], 'self link placed correctly.');
// @todo Test curies.
// @todo Test type.
$this->assertEqual($normalized['id'], $expected_array['id'], 'Internal id is exposed.');
$this->assertEqual($normalized['uuid'], $expected_array['uuid'], 'Non-translatable fields is normalized.');
$this->assertEqual($normalized['name'], $expected_array['name'], 'Translatable field with multiple language values is normalized.');
$this->assertEqual($normalized['field_test_text'], $expected_array['field_test_text'], 'Field with properties is normalized.');
$this->assertEqual($normalized['_embedded'][$relation_uri], $expected_array['_embedded'][$relation_uri], 'Entity reference field is normalized.');
$this->assertEqual($normalized['_links'][$relation_uri], $expected_array['_links'][$relation_uri], 'Links are added for entity reference field.');
}
/**
* Constructs the entity URI.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity.
*
* @return string
* The entity URI.
*/
protected function getEntityUri(EntityInterface $entity) {
$url = $entity->urlInfo('canonical', ['absolute' => TRUE]);
return $url->setRouteParameter('_format', 'hal_json')->toString();
}
}

View file

@ -0,0 +1,152 @@
<?php
namespace Drupal\Tests\hal\Kernel;
use Drupal\Core\Cache\MemoryBackend;
use Drupal\field\Entity\FieldConfig;
use Drupal\hal\Encoder\JsonEncoder;
use Drupal\hal\Normalizer\ContentEntityNormalizer;
use Drupal\hal\Normalizer\EntityReferenceItemNormalizer;
use Drupal\hal\Normalizer\FieldItemNormalizer;
use Drupal\hal\Normalizer\FieldNormalizer;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\rest\LinkManager\LinkManager;
use Drupal\rest\LinkManager\RelationLinkManager;
use Drupal\rest\LinkManager\TypeLinkManager;
use Drupal\serialization\EntityResolver\ChainEntityResolver;
use Drupal\serialization\EntityResolver\TargetIdResolver;
use Drupal\serialization\EntityResolver\UuidResolver;
use Drupal\KernelTests\KernelTestBase;
use Symfony\Component\Serializer\Serializer;
use Drupal\field\Entity\FieldStorageConfig;
/**
* Test the HAL normalizer.
*/
abstract class NormalizerTestBase extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['entity_test', 'field', 'hal', 'language', 'rest', 'serialization', 'system', 'text', 'user', 'filter'];
/**
* The mock serializer.
*
* @var \Symfony\Component\Serializer\Serializer
*/
protected $serializer;
/**
* The format being tested.
*
* @var string
*/
protected $format = 'hal_json';
/**
* The class name of the test class.
*
* @var string
*/
protected $entityClass = 'Drupal\entity_test\Entity\EntityTest';
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('user');
$this->installEntitySchema('entity_test');
// If the concrete test sub-class installs the Node or Comment modules,
// ensure that the node and comment entity schema are created before the
// field configurations are installed. This is because the entity tables
// need to be created before the body field storage tables. This prevents
// trying to create the body field tables twice.
$class = get_class($this);
while ($class) {
if (property_exists($class, 'modules')) {
// Only check the modules, if the $modules property was not inherited.
$rp = new \ReflectionProperty($class, 'modules');
if ($rp->class == $class) {
foreach (array_intersect(array('node', 'comment'), $class::$modules) as $module) {
$this->installEntitySchema($module);
}
}
}
$class = get_parent_class($class);
}
$this->installConfig(array('field', 'language'));
\Drupal::service('router.builder')->rebuild();
// Add German as a language.
ConfigurableLanguage::create(array(
'id' => 'de',
'label' => 'Deutsch',
'weight' => -1,
))->save();
// Create the test text field.
FieldStorageConfig::create(array(
'field_name' => 'field_test_text',
'entity_type' => 'entity_test',
'type' => 'text',
))->save();
FieldConfig::create([
'entity_type' => 'entity_test',
'field_name' => 'field_test_text',
'bundle' => 'entity_test',
'translatable' => FALSE,
])->save();
// Create the test translatable field.
FieldStorageConfig::create(array(
'field_name' => 'field_test_translatable_text',
'entity_type' => 'entity_test',
'type' => 'text',
))->save();
FieldConfig::create([
'entity_type' => 'entity_test',
'field_name' => 'field_test_translatable_text',
'bundle' => 'entity_test',
'translatable' => TRUE,
])->save();
// Create the test entity reference field.
FieldStorageConfig::create(array(
'field_name' => 'field_test_entity_reference',
'entity_type' => 'entity_test',
'type' => 'entity_reference',
'settings' => array(
'target_type' => 'entity_test',
),
))->save();
FieldConfig::create([
'entity_type' => 'entity_test',
'field_name' => 'field_test_entity_reference',
'bundle' => 'entity_test',
'translatable' => TRUE,
])->save();
$entity_manager = \Drupal::entityManager();
$link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('default'), \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack'), \Drupal::service('entity_type.bundle.info')), new RelationLinkManager(new MemoryBackend('default'), $entity_manager, \Drupal::moduleHandler(), \Drupal::service('config.factory'), \Drupal::service('request_stack')));
$chain_resolver = new ChainEntityResolver(array(new UuidResolver($entity_manager), new TargetIdResolver()));
// Set up the mock serializer.
$normalizers = array(
new ContentEntityNormalizer($link_manager, $entity_manager, \Drupal::moduleHandler()),
new EntityReferenceItemNormalizer($link_manager, $chain_resolver),
new FieldItemNormalizer(),
new FieldNormalizer(),
);
$encoders = array(
new JsonEncoder(),
);
$this->serializer = new Serializer($normalizers, $encoders);
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace Drupal\Tests\hal\Unit;
use Drupal\hal\Normalizer\FieldItemNormalizer;
/**
* @coversDefaultClass \Drupal\hal\Normalizer\FieldItemNormalizer
* @group hal
*/
class FieldItemNormalizerDenormalizeExceptionsUnitTest extends NormalizerDenormalizeExceptionsUnitTestBase {
/**
* Tests that the FieldItemNormalizer::denormalize() throws proper exceptions.
*
* @param array $context
* Context for FieldItemNormalizer::denormalize().
*
* @dataProvider providerNormalizerDenormalizeExceptions
* @expectedException \Symfony\Component\Serializer\Exception\InvalidArgumentException
*/
public function testFieldItemNormalizerDenormalizeExceptions($context) {
$field_item_normalizer = new FieldItemNormalizer();
$data = array();
$class = array();
$field_item_normalizer->denormalize($data, $class, NULL, $context);
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace Drupal\Tests\hal\Unit;
use Drupal\hal\Normalizer\FieldNormalizer;
/**
* @coversDefaultClass \Drupal\hal\Normalizer\FieldNormalizer
* @group hal
*/
class FieldNormalizerDenormalizeExceptionsUnitTest extends NormalizerDenormalizeExceptionsUnitTestBase {
/**
* Tests that the FieldNormalizer::denormalize() throws proper exceptions.
*
* @param array $context
* Context for FieldNormalizer::denormalize().
*
* @dataProvider providerNormalizerDenormalizeExceptions
* @expectedException \Symfony\Component\Serializer\Exception\InvalidArgumentException
*/
public function testFieldNormalizerDenormalizeExceptions($context) {
$field_item_normalizer = new FieldNormalizer();
$data = array();
$class = array();
$field_item_normalizer->denormalize($data, $class, NULL, $context);
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\hal\Unit;
use Drupal\Tests\UnitTestCase;
/**
* Common ancestor for FieldItemNormalizerDenormalizeExceptionsUnitTest and
* FieldNormalizerDenormalizeExceptionsUnitTest as they have the same
* dataProvider.
*/
abstract class NormalizerDenormalizeExceptionsUnitTestBase extends UnitTestCase {
/**
* Provides data for FieldItemNormalizerDenormalizeExceptionsUnitTest::testFieldItemNormalizerDenormalizeExceptions()
* and for FieldNormalizerDenormalizeExceptionsUnitTest::testFieldNormalizerDenormalizeExceptions().
*
* @return array Test data.
*/
public function providerNormalizerDenormalizeExceptions() {
$mock = $this->getMock('\Drupal\Core\Field\Plugin\DataType\FieldItem', array('getParent'));
$mock->expects($this->any())
->method('getParent')
->will($this->returnValue(NULL));
return array(
array(array()),
array(array('target_instance' => $mock)),
);
}
}