Further Drupal 8.6.4 changes. Some core files were not committed before a commit...
[yaffs-website] / web / core / modules / system / src / Tests / Cache / AssertPageCacheContextsAndTagsTrait.php
1 <?php
2
3 namespace Drupal\system\Tests\Cache;
4
5 use Drupal\Core\Cache\Cache;
6 use Drupal\Core\Url;
7
8 /**
9  * Provides test assertions for testing page-level cache contexts & tags.
10  *
11  * Can be used by test classes that extend \Drupal\simpletest\WebTestBase.
12  *
13  * @deprecated Scheduled for removal in Drupal 9.0.0. Use
14  *  \Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait
15  *  instead.
16  *
17  * @see https://www.drupal.org/node/2896632
18  */
19 trait AssertPageCacheContextsAndTagsTrait {
20
21   /**
22    * Enables page caching.
23    */
24   protected function enablePageCaching() {
25     $config = $this->config('system.performance');
26     $config->set('cache.page.max_age', 300);
27     $config->save();
28   }
29
30   /**
31    * Gets a specific header value as array.
32    *
33    * @param string $header_name
34    *   The header name.
35    *
36    * @return string[]
37    *   The header value, potentially exploded by spaces.
38    */
39   protected function getCacheHeaderValues($header_name) {
40     $header_value = $this->drupalGetHeader($header_name);
41     if (empty($header_value)) {
42       return [];
43     }
44     else {
45       return explode(' ', $header_value);
46     }
47   }
48
49   /**
50    * Asserts whether an expected cache context was present in the last response.
51    *
52    * @param string $expected_cache_context
53    *   The expected cache context.
54    */
55   protected function assertCacheContext($expected_cache_context) {
56     $cache_contexts = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Contexts'));
57     $this->assertTrue(in_array($expected_cache_context, $cache_contexts), "'" . $expected_cache_context . "' is present in the X-Drupal-Cache-Contexts header.");
58   }
59
60   /**
61    * Asserts that a cache context was not present in the last response.
62    *
63    * @param string $not_expected_cache_context
64    *   The expected cache context.
65    */
66   protected function assertNoCacheContext($not_expected_cache_context) {
67     $cache_contexts = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Contexts'));
68     $this->assertFalse(in_array($not_expected_cache_context, $cache_contexts), "'" . $not_expected_cache_context . "' is not present in the X-Drupal-Cache-Contexts header.");
69   }
70
71   /**
72    * Asserts page cache miss, then hit for the given URL; checks cache headers.
73    *
74    * @param \Drupal\Core\Url $url
75    *   The URL to test.
76    * @param string[] $expected_contexts
77    *   The expected cache contexts for the given URL.
78    * @param string[] $expected_tags
79    *   The expected cache tags for the given URL.
80    */
81   protected function assertPageCacheContextsAndTags(Url $url, array $expected_contexts, array $expected_tags) {
82     $absolute_url = $url->setAbsolute()->toString();
83     sort($expected_contexts);
84     sort($expected_tags);
85
86     // Assert cache miss + expected cache contexts + tags.
87     $this->drupalGet($absolute_url);
88     $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
89     $this->assertCacheTags($expected_tags);
90     $this->assertCacheContexts($expected_contexts);
91
92     // Assert cache hit + expected cache contexts + tags.
93     $this->drupalGet($absolute_url);
94     $this->assertCacheTags($expected_tags);
95     $this->assertCacheContexts($expected_contexts);
96
97     // Assert page cache item + expected cache tags.
98     $cid_parts = [$url->setAbsolute()->toString(), 'html'];
99     $cid = implode(':', $cid_parts);
100     $cache_entry = \Drupal::cache('page')->get($cid);
101     sort($cache_entry->tags);
102     $this->assertEqual($cache_entry->tags, $expected_tags);
103     $this->debugCacheTags($cache_entry->tags, $expected_tags);
104   }
105
106   /**
107    * Provides debug information for cache tags.
108    *
109    * @param string[] $actual_tags
110    *   The actual cache tags.
111    * @param string[] $expected_tags
112    *   The expected cache tags.
113    */
114   protected function debugCacheTags(array $actual_tags, array $expected_tags) {
115     if ($actual_tags !== $expected_tags) {
116       debug('Unwanted cache tags in response: ' . implode(',', array_diff($actual_tags, $expected_tags)));
117       debug('Missing cache tags in response: ' . implode(',', array_diff($expected_tags, $actual_tags)));
118     }
119   }
120
121   /**
122    * Ensures that some cache tags are present in the current response.
123    *
124    * @param string[] $expected_tags
125    *   The expected tags.
126    * @param bool $include_default_tags
127    *   (optional) Whether the default cache tags should be included.
128    */
129   protected function assertCacheTags(array $expected_tags, $include_default_tags = TRUE) {
130     // The anonymous role cache tag is only added if the user is anonymous.
131     if ($include_default_tags) {
132       if (\Drupal::currentUser()->isAnonymous()) {
133         $expected_tags = Cache::mergeTags($expected_tags, ['config:user.role.anonymous']);
134       }
135       $expected_tags[] = 'http_response';
136     }
137     $actual_tags = $this->getCacheHeaderValues('X-Drupal-Cache-Tags');
138     $expected_tags = array_unique($expected_tags);
139     sort($expected_tags);
140     sort($actual_tags);
141     $this->assertIdentical($actual_tags, $expected_tags);
142     $this->debugCacheTags($actual_tags, $expected_tags);
143   }
144
145   /**
146    * Ensures that some cache contexts are present in the current response.
147    *
148    * @param string[] $expected_contexts
149    *   The expected cache contexts.
150    * @param string $message
151    *   (optional) A verbose message to output.
152    * @param bool $include_default_contexts
153    *   (optional) Whether the default contexts should automatically be included.
154    *
155    * @return bool
156    *   TRUE if the assertion succeeded, FALSE otherwise.
157    */
158   protected function assertCacheContexts(array $expected_contexts, $message = NULL, $include_default_contexts = TRUE) {
159     if ($include_default_contexts) {
160       $default_contexts = ['languages:language_interface', 'theme'];
161       // Add the user.permission context to the list of default contexts except
162       // when user is already there.
163       if (!in_array('user', $expected_contexts)) {
164         $default_contexts[] = 'user.permissions';
165       }
166       $expected_contexts = Cache::mergeContexts($expected_contexts, $default_contexts);
167     }
168
169     $actual_contexts = $this->getCacheHeaderValues('X-Drupal-Cache-Contexts');
170     sort($expected_contexts);
171     sort($actual_contexts);
172     $match = $actual_contexts === $expected_contexts;
173     if (!$match) {
174       debug('Unwanted cache contexts in response: ' . implode(',', array_diff($actual_contexts, $expected_contexts)));
175       debug('Missing cache contexts in response: ' . implode(',', array_diff($expected_contexts, $actual_contexts)));
176     }
177
178     $this->assertIdentical($actual_contexts, $expected_contexts, $message);
179
180     // For compatibility with both BrowserTestBase and WebTestBase always return
181     // a boolean.
182     return $match;
183   }
184
185   /**
186    * Asserts the max age header.
187    *
188    * @param int $max_age
189    */
190   protected function assertCacheMaxAge($max_age) {
191     $cache_control_header = $this->drupalGetHeader('Cache-Control');
192     if (strpos($cache_control_header, 'max-age:' . $max_age) === FALSE) {
193       debug('Expected max-age:' . $max_age . '; Response max-age:' . $cache_control_header);
194     }
195     $this->assertTrue(strpos($cache_control_header, 'max-age:' . $max_age));
196   }
197
198 }