3 namespace Drupal\Tests\dynamic_page_cache\Functional;
5 use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
7 use Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber;
8 use Drupal\Tests\BrowserTestBase;
11 * Enables the Dynamic Page Cache and tests it in various scenarios.
13 * This does not test the self-healing of the redirect with conditional cache
14 * contexts, because Dynamic Page Cache just reuses
15 * \Drupal\Core\Render\RenderCache so that it doesn't have to implement and test
16 * all of that again. It is tested in
17 * RendererBubblingTest::testConditionalCacheContextBubblingSelfHealing().
19 * @group dynamic_page_cache
21 * @see \Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber
23 class DynamicPageCacheIntegrationTest extends BrowserTestBase {
28 protected $dumpHeaders = TRUE;
33 protected static $modules = ['dynamic_page_cache_test'];
38 protected function setUp() {
41 // Uninstall the page_cache module; we want to test the Dynamic Page Cache
43 \Drupal::service('module_installer')->uninstall(['page_cache']);
47 * Tests that Dynamic Page Cache works correctly, and verifies the edge cases.
49 public function testDynamicPageCache() {
50 // Controllers returning plain response objects are ignored by Dynamic Page
52 $url = Url::fromUri('route:dynamic_page_cache_test.response');
53 $this->drupalGet($url);
54 $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Response object returned: Dynamic Page Cache is ignoring.');
56 // Controllers returning CacheableResponseInterface (cacheable response)
57 // objects are handled by Dynamic Page Cache.
58 $url = Url::fromUri('route:dynamic_page_cache_test.cacheable_response');
59 $this->drupalGet($url);
60 $this->assertEqual('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Cacheable response object returned: Dynamic Page Cache is active, Dynamic Page Cache MISS.');
61 $this->drupalGet($url);
62 $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Cacheable response object returned: Dynamic Page Cache is active, Dynamic Page Cache HIT.');
64 // Controllers returning render arrays, rendered as HTML responses, are
65 // handled by Dynamic Page Cache.
66 $url = Url::fromUri('route:dynamic_page_cache_test.html');
67 $this->drupalGet($url);
68 $this->assertEqual('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response: Dynamic Page Cache is active, Dynamic Page Cache MISS.');
69 $this->drupalGet($url);
70 $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response: Dynamic Page Cache is active, Dynamic Page Cache HIT.');
72 // The above is the simple case, where the render array returned by the
73 // response contains no cache contexts. So let's now test a route/controller
74 // that *does* vary by a cache context whose value we can easily control: it
75 // varies by the 'animal' query argument.
76 foreach (['llama', 'piggy', 'unicorn', 'kitten'] as $animal) {
77 $url = Url::fromUri('route:dynamic_page_cache_test.html.with_cache_contexts', ['query' => ['animal' => $animal]]);
78 $this->drupalGet($url);
79 $this->assertRaw($animal);
80 $this->assertEqual('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response: Dynamic Page Cache is active, Dynamic Page Cache MISS.');
81 $this->drupalGet($url);
82 $this->assertRaw($animal);
83 $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response: Dynamic Page Cache is active, Dynamic Page Cache HIT.');
85 // Finally, let's also verify that the 'dynamic_page_cache_test.html'
86 // route continued to see cache hits if we specify a query argument,
87 // because it *should* ignore it and continue to provide Dynamic Page
89 $url = Url::fromUri('route:dynamic_page_cache_test.html', ['query' => ['animal' => 'piglet']]);
90 $this->drupalGet($url);
91 $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response: Dynamic Page Cache is active, Dynamic Page Cache HIT.');
94 // Controllers returning render arrays, rendered as anything except a HTML
95 // response, are ignored by Dynamic Page Cache (but only because those
96 // wrapper formats' responses do not implement CacheableResponseInterface).
97 $this->drupalGet('dynamic-page-cache-test/html', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
98 $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as AJAX response: Dynamic Page Cache is ignoring.');
99 $this->drupalGet('dynamic-page-cache-test/html', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_dialog']]);
100 $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as dialog response: Dynamic Page Cache is ignoring.');
101 $this->drupalGet('dynamic-page-cache-test/html', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_modal']]);
102 $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as modal response: Dynamic Page Cache is ignoring.');
104 // Admin routes are ignored by Dynamic Page Cache.
105 $this->drupalGet('dynamic-page-cache-test/html/admin');
106 $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Response returned, rendered as HTML response, admin route: Dynamic Page Cache is ignoring');
107 $this->drupalGet('dynamic-page-cache-test/response/admin');
108 $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Response returned, plain response, admin route: Dynamic Page Cache is ignoring');
109 $this->drupalGet('dynamic-page-cache-test/cacheable-response/admin');
110 $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Response returned, cacheable response, admin route: Dynamic Page Cache is ignoring');
112 // Max-age = 0 responses are ignored by Dynamic Page Cache.
113 $this->drupalGet('dynamic-page-cache-test/html/uncacheable/max-age');
114 $this->assertEqual('UNCACHEABLE', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response, but uncacheable: Dynamic Page Cache is running, but not caching.');
116 // 'user' cache context responses are ignored by Dynamic Page Cache.
117 $this->drupalGet('dynamic-page-cache-test/html/uncacheable/contexts');
118 $this->assertEqual('UNCACHEABLE', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response, but uncacheable: Dynamic Page Cache is running, but not caching.');
120 // 'current-temperature' cache tag responses are ignored by Dynamic Page
122 $this->drupalGet('dynamic-page-cache-test/html/uncacheable/tags');
123 $this->assertEqual('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'By default, Drupal has no auto-placeholdering cache tags.');