Skip to content

Commit c18b940

Browse files
committed
Create initial versions of the context and trait that allow to inspect the page cache.
1 parent 0e129fd commit c18b940

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

src/Context/PageCacheContext.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace DrupalTest\BehatTraits\Context;
6+
7+
use Behat\MinkExtension\Context\RawMinkContext;
8+
use DrupalTest\BehatTraits\Traits\PageCacheTrait;
9+
use PHPUnit\Framework\Assert;
10+
11+
/**
12+
* Provides example step definitions that interact with the page cache.
13+
*
14+
* These step definitions are mainly intended as an example implementation, and
15+
* for verifying that the trait is working correctly. They might however also be
16+
* useful in real life projects. If this is the case, feel free to include this
17+
* context class in your `behat.yml` file so you can use the provided steps in
18+
* your user scenarios.
19+
*
20+
* @see \DrupalTest\BehatTraits\Traits\PageCacheTrait
21+
*/
22+
class PageCacheContext extends RawMinkContext {
23+
24+
use PageCacheTrait;
25+
26+
/**
27+
* Checks that the page is cacheable.
28+
*
29+
* @Then the page should be cacheable
30+
*/
31+
public function assertPageCacheable(): void {
32+
Assert::assertTrue($this->isPageCacheable());
33+
}
34+
35+
/**
36+
* Checks that the page is not cacheable.
37+
*
38+
* @Then the page should not be cacheable
39+
*/
40+
public function assertPageNotCacheable(): void {
41+
Assert::assertFalse($this->isPageCacheable());
42+
}
43+
44+
/**
45+
* Checks that the page is cached.
46+
*
47+
* @Then the page should be cached
48+
*/
49+
public function assertPageCached(): void {
50+
Assert::assertTrue($this->isPageCached());
51+
}
52+
53+
/**
54+
* Checks that the page is not cached.
55+
*
56+
* @Then the page should not be cached
57+
*/
58+
public function assertPageNotCached(): void {
59+
Assert::assertFalse($this->isPageCached());
60+
}
61+
62+
}

src/Traits/PageCacheTrait.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace DrupalTest\BehatTraits\Traits;
6+
7+
use Behat\MinkExtension\Context\RawMinkContext;
8+
9+
/**
10+
* Helper methods to inspect the cache status of the current page.
11+
*
12+
* These methods report if the current page is cached or cacheable by Drupal's
13+
* page cache and dynamic page cache. The standard page cache is used for
14+
* anonymous users without a session, while the dynamic page cache is used for
15+
* authenticated users and anonymous users with a session (e.g. anonymous users
16+
* with a shopping cart).
17+
*
18+
* This relies on the following setting to be enabled in `services.yml`:
19+
* http.response.debug_cacheability_headers: true
20+
*/
21+
trait PageCacheTrait {
22+
23+
/**
24+
* Returns the cache status of Drupal's page cache and dynamic page cache.
25+
*
26+
* @return array
27+
* An associative array with the following keys:
28+
* - X-Drupal-Cache: the status of Drupal's page cache. Can be one of:
29+
* - 'HIT': The page is served from the page cache.
30+
* - 'MISS': The page is not currently served from the page cache, but is
31+
* cacheable and subsequent requests will be served from cache.
32+
* - NULL: The page could not be served from the page cache. This may be
33+
* because either the page_cache module is not enabled, the user has a
34+
* session, or the page is not cacheable.
35+
* - X-Drupal-Dynamic-Cache: the status of the dynamic page cache. One of:
36+
* - 'HIT': The page is served from the dynamic page cache.
37+
* - 'MISS': The page is not currently served from the page cache, but is
38+
* cacheable and subsequent requests will be served from cache.
39+
* - 'UNCACHEABLE': The page is uncacheable because it meets one or more
40+
* of the conditions as defined in the `auto_placeholder_conditions`
41+
* setting in `services.yml`.
42+
* - NULL: The page could not be handled by the dynamic page cache. This
43+
* can be because of various reasons: the dynamic_page_cache module is
44+
* not enabled, the page has a 403 or 404 status, or one of the request
45+
* or response policies are not met.
46+
*/
47+
protected function getPageCacheStatus(): array {
48+
assert($this instanceof RawMinkContext, __METHOD__ . ' should only be included in Context classes that extend RawMinkContext.');
49+
50+
/** @var \Behat\Mink\Session $session */
51+
$session = $this->getSession();
52+
53+
return [
54+
'X-Drupal-Cache' => $session->getResponseHeader('X-Drupal-Cache'),
55+
'X-Drupal-Dynamic-Cache' => $session->getResponseHeader('X-Drupal-Dynamic-Cache'),
56+
];
57+
}
58+
59+
/**
60+
* Returns whether the current page is served from the cache.
61+
*
62+
* This can be either from the page cache or dynamic page cache.
63+
*
64+
* @return bool
65+
* TRUE if the current page is served from the cache.
66+
*/
67+
protected function isPageCached(): bool {
68+
return in_array('HIT', $this->getPageCacheStatus());
69+
}
70+
71+
/**
72+
* Returns whether the current page is cacheable.
73+
*
74+
* @return bool
75+
* TRUE if the current page is served from the cache, or eligible to be
76+
* served from the cache on subsequent requests.
77+
*/
78+
protected function isPageCacheable(): bool {
79+
return $this->isPageCached() || in_array('MISS', $this->getPageCacheStatus());
80+
}
81+
82+
}

0 commit comments

Comments
 (0)