You are here

protected function ResourceTestBase::doTestSparseFieldSets in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php \Drupal\Tests\jsonapi\Functional\ResourceTestBase::doTestSparseFieldSets()

Tests sparse field sets.

Parameters

\Drupal\Core\Url $url: The base URL with which to test includes.

array $request_options: Request options to apply.

See also

\GuzzleHttp\ClientInterface::request()

1 call to ResourceTestBase::doTestSparseFieldSets()
ResourceTestBase::testGetIndividual in core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php
Tests GETting an individual resource, plus edge cases to ensure good DX.

File

core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php, line 2641

Class

ResourceTestBase
Subclass this for every JSON:API resource type.

Namespace

Drupal\Tests\jsonapi\Functional

Code

protected function doTestSparseFieldSets(Url $url, array $request_options) {
  $field_sets = $this
    ->getSparseFieldSets();
  $expected_cacheability = new CacheableMetadata();
  foreach ($field_sets as $type => $field_set) {
    if ($type === 'all') {
      assert($this
        ->getExpectedCacheTags($field_set) === $this
        ->getExpectedCacheTags());
      assert($this
        ->getExpectedCacheContexts($field_set) === $this
        ->getExpectedCacheContexts());
    }
    $query = [
      'fields[' . static::$resourceTypeName . ']' => implode(',', $field_set),
    ];
    $expected_document = $this
      ->getExpectedDocument();
    $expected_cacheability
      ->setCacheTags($this
      ->getExpectedCacheTags($field_set));
    $expected_cacheability
      ->setCacheContexts($this
      ->getExpectedCacheContexts($field_set));

    // This tests sparse field sets on included entities.
    if (strpos($type, 'nested') === 0) {
      $this
        ->grantPermissionsToTestedRole([
        'access user profiles',
      ]);
      $query['fields[user--user]'] = implode(',', $field_set);
      $query['include'] = 'uid';
      $owner = $this->entity
        ->getOwner();
      $owner_resource = static::toResourceIdentifier($owner);
      foreach ($field_set as $field_name) {
        $owner_resource['attributes'][$field_name] = $this->serializer
          ->normalize($owner
          ->get($field_name)[0]
          ->get('value'), 'api_json');
      }
      $owner_resource['links']['self']['href'] = static::getResourceLink($owner_resource);
      $expected_document['included'] = [
        $owner_resource,
      ];
      $expected_cacheability
        ->addCacheableDependency($owner);
      $expected_cacheability
        ->addCacheableDependency(static::entityAccess($owner, 'view', $this->account));
    }

    // Remove fields not in the sparse field set.
    foreach ([
      'attributes',
      'relationships',
    ] as $member) {
      if (!empty($expected_document['data'][$member])) {
        $remaining = array_intersect_key($expected_document['data'][$member], array_flip($field_set));
        if (empty($remaining)) {
          unset($expected_document['data'][$member]);
        }
        else {
          $expected_document['data'][$member] = $remaining;
        }
      }
    }
    $url
      ->setOption('query', $query);

    // 'self' link should include the 'fields' query param.
    $expected_document['links']['self']['href'] = $url
      ->setAbsolute()
      ->toString();
    $response = $this
      ->request('GET', $url, $request_options);

    // Dynamic Page Cache MISS because cache should vary based on the 'field'
    // query param. (Or uncacheable if expensive cache context.)
    $dynamic_cache = !empty(array_intersect([
      'user',
      'session',
    ], $expected_cacheability
      ->getCacheContexts())) ? 'UNCACHEABLE' : 'MISS';
    $this
      ->assertResourceResponse(200, $expected_document, $response, $expected_cacheability
      ->getCacheTags(), $expected_cacheability
      ->getCacheContexts(), FALSE, $dynamic_cache);
  }

  // Test Dynamic Page Cache HIT for a query with the same field set (unless
  // expensive cache context is present).
  $response = $this
    ->request('GET', $url, $request_options);
  $this
    ->assertResourceResponse(200, FALSE, $response, $expected_cacheability
    ->getCacheTags(), $expected_cacheability
    ->getCacheContexts(), FALSE, $dynamic_cache === 'MISS' ? 'HIT' : 'UNCACHEABLE');
}