function VariationCacheTest::testSplitVariationsSelfHealing

Same name and namespace in other branches
  1. 11.x core/tests/Drupal/Tests/Core/Cache/VariationCacheTest.php \Drupal\Tests\Core\Cache\VariationCacheTest::testSplitVariationsSelfHealing()

Tests self-healing for a cache item that has split variations.

@covers ::get
@covers ::set

File

core/tests/Drupal/Tests/Core/Cache/VariationCacheTest.php, line 333

Class

VariationCacheTest
@coversDefaultClass \Drupal\Core\Cache\VariationCache[[api-linebreak]] @group Cache

Namespace

Drupal\Tests\Core\Cache

Code

public function testSplitVariationsSelfHealing() : void {
  // This is an edge case. Something varies by AB where some values of B
  // trigger the whole to vary by either C, D or nothing extra. But due to an
  // unfortunate series of requests, only ABC and ABD variations were cached.
  //
  // In this case, the cache should be smart enough to generate a redirect for
  // AB, followed by redirects for ABC and ABD.
  //
  // For the sake of this test, we'll vary by housing and orientation, but:
  // - Only vary by garden type for south-facing houses.
  // - Only vary by solar panel type for north-facing houses.
  $this->housingType = 'house';
  $this->gardenType = 'garden';
  $this->solarType = 'solar';
  $initial_cacheability = (new CacheableMetadata())->setCacheTags([
    'foo',
  ])
    ->setCacheContexts([
    'house.type',
  ]);
  $south_cacheability = (new CacheableMetadata())->setCacheTags([
    'foo',
  ])
    ->setCacheContexts([
    'house.type',
    'house.orientation',
    'garden.type',
  ]);
  $north_cacheability = (new CacheableMetadata())->setCacheTags([
    'foo',
  ])
    ->setCacheContexts([
    'house.type',
    'house.orientation',
    'solar.type',
  ]);
  $common_cacheability = (new CacheableMetadata())->setCacheContexts([
    'house.type',
    'house.orientation',
  ]);
  // Calculate the cache IDs once beforehand for readability.
  $cache_id = $this->getSortedCacheId([
    'ht.house',
  ]);
  $cache_id_north = $this->getSortedCacheId([
    'ht.house',
    'ho.north',
  ]);
  $cache_id_south = $this->getSortedCacheId([
    'ht.house',
    'ho.south',
  ]);
  // Set the first scenario.
  $this->houseOrientation = 'south';
  $this->setVariationCacheItem('You have a south-facing house with a garden!', $south_cacheability, $initial_cacheability);
  // Verify that the overly specific redirect is stored at the first possible
  // redirect location, i.e.: The base cache ID.
  $this->assertCacheBackendItem($cache_id, new CacheRedirect($south_cacheability));
  // Store a split variation, and verify that the common contexts are now used
  // for the first cache redirect and the actual contexts for the next step of
  // the redirect chain.
  $this->houseOrientation = 'north';
  $this->setVariationCacheItem('You have a north-facing house with solar panels!', $north_cacheability, $initial_cacheability);
  $this->assertCacheBackendItem($cache_id, new CacheRedirect($common_cacheability));
  $this->assertCacheBackendItem($cache_id_north, new CacheRedirect($north_cacheability));
  // Verify that the initially set scenario is inaccessible now.
  $this->houseOrientation = 'south';
  $this->assertVariationCacheMiss($initial_cacheability);
  // Reset the initial scenario and verify that its redirects are accessible.
  $this->setVariationCacheItem('You have a south-facing house with a garden!', $south_cacheability, $initial_cacheability);
  $this->assertCacheBackendItem($cache_id, new CacheRedirect($common_cacheability));
  $this->assertCacheBackendItem($cache_id_south, new CacheRedirect($south_cacheability));
  // Double-check that the split scenario redirects are left untouched.
  $this->houseOrientation = 'north';
  $this->assertCacheBackendItem($cache_id, new CacheRedirect($common_cacheability));
  $this->assertCacheBackendItem($cache_id_north, new CacheRedirect($north_cacheability));
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.