tests/src/Functional/ResourceTestBase.php | 53 ++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/tests/src/Functional/ResourceTestBase.php b/tests/src/Functional/ResourceTestBase.php index 862423b..98496a4 100644 --- a/tests/src/Functional/ResourceTestBase.php +++ b/tests/src/Functional/ResourceTestBase.php @@ -19,6 +19,7 @@ use Drupal\Core\Url; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\jsonapi\Normalizer\HttpExceptionNormalizer; +use Drupal\jsonapi\Resource\JsonApiDocumentTopLevel; use Drupal\jsonapi\ResourceResponse; use Drupal\path\Plugin\Field\FieldType\PathItem; use Drupal\Tests\BrowserTestBase; @@ -26,6 +27,7 @@ use Drupal\user\Entity\Role; use Drupal\user\RoleInterface; use GuzzleHttp\RequestOptions; use Psr\Http\Message\ResponseInterface; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** @@ -145,6 +147,43 @@ abstract class ResourceTestBase extends BrowserTestBase { */ protected $entityToJsonApi; + + protected function normalize(EntityInterface $entity) { + // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463. + $url = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), [static::$entityTypeId => $this->entity->uuid()]); + /* $url = $this->entity->toUrl('jsonapi'); */ + + $request = Request::create($url->toString(TRUE)->getGeneratedUrl(), 'GET', [], [], [], $this->container->get('request_stack')->getCurrentRequest()->server->all()); + $request->headers->set('Authorization', 'Basic ' . base64_encode($this->account->name->value . ':' . $this->account->passRaw)); + // Ensure the request time is REQUEST_TIME to ensure that API calls + // in the test use the right timestamp. + $request->server->set('REQUEST_TIME', REQUEST_TIME); + $this->container->get('request_stack')->push($request); + + // The request context is normally set by the router_listener from within + // its KernelEvents::REQUEST listener. In the simpletest parent site this + // event is not fired, therefore it is necessary to updated the request + // context manually here. + $this->container->get('router.request_context')->fromRequest($request); + + + return $this->entityToJsonApi->normalize($entity); + + // We can't use \Drupal\jsonapi\EntityToJsonApi because that requires a + return $this->serializer->normalize(new JsonApiDocumentTopLevel($entity), 'api_json', [ + // @todo remove when JSON API no longer has a current contet service + 'resource_type' => $this->container->get('jsonapi.resource_type.repository')->getByTypeName(static::$resourceTypeName), + // Don't perform context expansion in \Drupal\jsonapi\Normalizer\JsonApiDocumentTopLevelNormalizer::expandContext(). + 'expanded' => TRUE, + // Respect access checking. + 'account' => $this->account, + // If we'd pass something here, it'd have to be with the necessary cookies + // for the account. It does mean the top-level "self" will be omitted. + 'request' => FALSE, + 'cacheable_metadata' => new CacheableMetadata(), + ]); + } + /** * {@inheritdoc} */ @@ -1000,7 +1039,7 @@ abstract class ResourceTestBase extends BrowserTestBase { // Assert that the entity was indeed created, and that the response body // contains the serialized created entity. $created_entity = $this->entityStorage->loadUnchanged(static::$firstCreatedEntityId); - $created_entity_document = $this->entityToJsonApi->normalize($created_entity); + $created_entity_document = $this->normalize($created_entity); // @todo Remove this if-test in https://www.drupal.org/node/2543726: execute // its body unconditionally. if (static::$entityTypeId !== 'taxonomy_term') { @@ -1284,7 +1323,11 @@ abstract class ResourceTestBase extends BrowserTestBase { // response, change the modified entity field that caused the error response // back to its original value, repeat. foreach (static::$patchProtectedFieldNames as $patch_protected_field_name => $reason) { - $request_options[RequestOptions::BODY] = $this->entityToJsonApi->serialize($modified_entity); +// var_dump($patch_protected_field_name); +// var_dump($modified_entity->get($patch_protected_field_name)->getValue()); +// var_dump($this->normalize($modified_entity)); +// var_dump($this->serializer->normalize($modified_entity->get($patch_protected_field_name), 'api_json')->rasterizeValue()); + $request_options[RequestOptions::BODY] = Json::encode($this->normalize($modified_entity)); $response = $this->request('PATCH', $url, $request_options); // @todo Remove $expected + assertResourceResponse() in favor of the commented line below once https://www.drupal.org/project/jsonapi/issues/2943176 lands. $expected = [ @@ -1313,7 +1356,7 @@ abstract class ResourceTestBase extends BrowserTestBase { // 200 for well-formed PATCH request that sends all fields (even including // read-only ones, but with unchanged values). - $valid_request_body = NestedArray::mergeDeep($this->entityToJsonApi->normalize($this->entity), $this->getPatchDocument()); + $valid_request_body = NestedArray::mergeDeep($this->normalize($this->entity), $this->getPatchDocument()); $request_options[RequestOptions::BODY] = Json::encode($valid_request_body); $response = $this->request('PATCH', $url, $request_options); $this->assertResourceResponse(200, FALSE, $response); @@ -1340,8 +1383,8 @@ abstract class ResourceTestBase extends BrowserTestBase { // Assert that the entity was indeed updated, and that the response body // contains the serialized updated entity. $updated_entity = $this->entityStorage->loadUnchanged($this->entity->id()); - $updated_entity_document = $this->entityToJsonApi->normalize($updated_entity); - $this->assertSame($updated_entity_document, Json::decode((string) $response->getBody())); + $updated_entity_document = $this->normalize($updated_entity); + $this->assertSame($updated_entity_document, array_diff_key(Json::decode((string) $response->getBody()), ['links' => TRUE])); // Assert that the entity was indeed created using the PATCHed values. foreach ($this->getPatchDocument() as $field_name => $field_normalization) { // Some top-level keys in the normalization may not be fields on the