Skip to content

Commit 643e5dc

Browse files
authored
Merge pull request #3 from drupaltest/page-cache
Add a PageCacheTrait that provides ways to inspect the page cache
2 parents 0e129fd + ee9daf5 commit 643e5dc

26 files changed

+278
-17
lines changed

behat.yml.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ default:
66
contexts:
77
- DrupalTest\BehatTraits\Context\BrowserCapabilityDetectionContext
88
- DrupalTest\BehatTraits\Context\EntityContext
9+
- DrupalTest\BehatTraits\Context\PageCacheContext
910
- Drupal\DrupalExtension\Context\MinkContext
1011
- Drupal\DrupalExtension\Context\DrupalContext
1112
extensions:

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+
}

tests/config/sync/block.block.stark_admin.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ _core:
1313
id: stark_admin
1414
theme: stark
1515
region: sidebar_first
16-
weight: 1
16+
weight: -1
1717
provider: null
1818
plugin: 'system_menu_block:admin'
1919
settings:
@@ -23,4 +23,5 @@ settings:
2323
label_display: visible
2424
level: 1
2525
depth: 0
26+
expand_all_items: false
2627
visibility: { }

tests/config/sync/block.block.stark_login.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ _core:
1111
id: stark_login
1212
theme: stark
1313
region: sidebar_first
14-
weight: 0
14+
weight: -3
1515
provider: null
1616
plugin: user_login_block
1717
settings:

tests/config/sync/block.block.stark_tools.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ _core:
1313
id: stark_tools
1414
theme: stark
1515
region: sidebar_first
16-
weight: 0
16+
weight: -4
1717
provider: null
1818
plugin: 'system_menu_block:tools'
1919
settings:
@@ -23,4 +23,5 @@ settings:
2323
label_display: visible
2424
level: 1
2525
depth: 0
26+
expand_all_items: false
2627
visibility: { }
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
uuid: 1a65b0b4-a306-49a8-a499-4d4caa313d26
2+
langcode: en
3+
status: true
4+
dependencies:
5+
config:
6+
- system.menu.account
7+
module:
8+
- system
9+
- user
10+
theme:
11+
- stark
12+
id: useraccountmenu
13+
theme: stark
14+
region: sidebar_first
15+
weight: -2
16+
provider: null
17+
plugin: 'system_menu_block:account'
18+
settings:
19+
id: 'system_menu_block:account'
20+
label: 'User account menu'
21+
provider: system
22+
label_display: visible
23+
level: 1
24+
depth: 0
25+
expand_all_items: false
26+
visibility:
27+
user_role:
28+
id: user_role
29+
roles:
30+
authenticated: authenticated
31+
negate: false
32+
context_mapping:
33+
user: '@user.current_user_context:current_user'

tests/config/sync/core.entity_form_display.node.blog_post.default.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ content:
3434
match_operator: CONTAINS
3535
size: 60
3636
placeholder: ''
37+
match_limit: 10
3738
third_party_settings: { }
3839
type: entity_reference_autocomplete
3940
region: content
@@ -73,6 +74,7 @@ content:
7374
match_operator: CONTAINS
7475
size: 60
7576
placeholder: ''
77+
match_limit: 10
7678
region: content
7779
third_party_settings: { }
7880
hidden: { }

tests/config/sync/core.entity_form_display.node.news.default.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ content:
3434
match_operator: CONTAINS
3535
size: 60
3636
placeholder: ''
37+
match_limit: 10
3738
third_party_settings: { }
3839
type: entity_reference_autocomplete
3940
region: content
@@ -73,6 +74,7 @@ content:
7374
match_operator: CONTAINS
7475
size: 60
7576
placeholder: ''
77+
match_limit: 10
7678
region: content
7779
third_party_settings: { }
7880
hidden: { }

tests/config/sync/core.entity_view_display.node.blog_post.teaser.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ content:
2727
settings: { }
2828
third_party_settings: { }
2929
region: content
30-
hidden: { }
30+
hidden:
31+
field_tags: true

0 commit comments

Comments
 (0)