You are here

public function PageCacheTest::testPageCacheAnonymous403404 in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/page_cache/tests/src/Functional/PageCacheTest.php \Drupal\Tests\page_cache\Functional\PageCacheTest::testPageCacheAnonymous403404()
  2. 10 core/modules/page_cache/tests/src/Functional/PageCacheTest.php \Drupal\Tests\page_cache\Functional\PageCacheTest::testPageCacheAnonymous403404()

Tests the 4xx-response cache tag is added and invalidated.

File

core/modules/page_cache/tests/src/Functional/PageCacheTest.php, line 370

Class

PageCacheTest
Enables the page cache and tests it with various HTTP requests.

Namespace

Drupal\Tests\page_cache\Functional

Code

public function testPageCacheAnonymous403404() {
  $admin_url = Url::fromRoute('system.admin');
  $invalid_url = 'foo/does_not_exist';
  $tests = [
    403 => $admin_url,
    404 => $invalid_url,
  ];
  $cache_ttl_4xx = Settings::get('cache_ttl_4xx', 3600);
  foreach ($tests as $code => $content_url) {

    // Anonymous user, without permissions.
    $this
      ->drupalGet($content_url);
    $this
      ->assertSession()
      ->statusCodeEquals($code);
    $this
      ->assertSession()
      ->responseHeaderEquals('X-Drupal-Cache', 'MISS');
    $this
      ->assertSession()
      ->responseHeaderContains('X-Drupal-Cache-Tags', '4xx-response');
    $this
      ->drupalGet($content_url);
    $this
      ->assertSession()
      ->statusCodeEquals($code);
    $this
      ->assertSession()
      ->responseHeaderEquals('X-Drupal-Cache', 'HIT');
    $entity_values = [
      'name' => $this
        ->randomMachineName(),
      'user_id' => 1,
      'field_test_text' => [
        0 => [
          'value' => $this
            ->randomString(),
          'format' => 'plain_text',
        ],
      ],
    ];
    $entity = EntityTest::create($entity_values);
    $entity
      ->save();

    // Saving an entity clears 4xx cache tag.
    $this
      ->drupalGet($content_url);
    $this
      ->assertSession()
      ->statusCodeEquals($code);
    $this
      ->assertSession()
      ->responseHeaderEquals('X-Drupal-Cache', 'MISS');
    $this
      ->drupalGet($content_url);
    $this
      ->assertSession()
      ->statusCodeEquals($code);
    $this
      ->assertSession()
      ->responseHeaderEquals('X-Drupal-Cache', 'HIT');

    // Rebuilding the router should invalidate the 4xx cache tag.
    $this->container
      ->get('router.builder')
      ->rebuild();
    $this
      ->drupalGet($content_url);
    $this
      ->assertSession()
      ->statusCodeEquals($code);
    $this
      ->assertSession()
      ->responseHeaderEquals('X-Drupal-Cache', 'MISS');

    // Ensure the 'expire' field on the cache entry uses cache_ttl_4xx.
    $cache_item = \Drupal::service('cache.page')
      ->get($this
      ->getUrl() . ':');
    $difference = $cache_item->expire - (int) $cache_item->created;

    // Given that a second might have passed we cannot be sure that
    // $difference will exactly equal the default cache_ttl_4xx setting.
    // Account for any timing difference or rounding errors by ensuring the
    // value is within 10 seconds.
    $this
      ->assertTrue($difference > $cache_ttl_4xx - 10 && $difference < $cache_ttl_4xx + 10, "The cache entry expiry time uses the cache_ttl_4xx setting. Expire: {$cache_item->expire} Created: {$cache_item->created}");
  }

  // Disable 403 and 404 caching.
  $settings['settings']['cache_ttl_4xx'] = (object) [
    'value' => 0,
    'required' => TRUE,
  ];
  $this
    ->writeSettings($settings);
  \Drupal::service('cache.page')
    ->deleteAll();
  foreach ($tests as $code => $content_url) {

    // Getting the 404 page twice should still result in a cache miss.
    $this
      ->drupalGet($content_url);
    $this
      ->drupalGet($content_url);
    $this
      ->assertSession()
      ->statusCodeEquals($code);
    $this
      ->assertSession()
      ->responseHeaderEquals('X-Drupal-Cache', 'MISS');
  }
}