1. 8.3.x core/tests/Drupal/Tests/Core/Cache/CacheTest.php
  2. 8.3.x core/modules/views/tests/src/Kernel/Plugin/CacheTest.php
  3. 8.0.x core/modules/views/src/Tests/Plugin/CacheTest.php
  4. 8.0.x core/tests/Drupal/Tests/Core/Cache/CacheTest.php
  5. 8.1.x core/modules/views/tests/src/Kernel/Plugin/CacheTest.php
  6. 8.1.x core/tests/Drupal/Tests/Core/Cache/CacheTest.php
  7. 8.2.x core/modules/views/tests/src/Kernel/Plugin/CacheTest.php
  8. 8.2.x core/tests/Drupal/Tests/Core/Cache/CacheTest.php
  9. 8.4.x core/modules/views/tests/src/Kernel/Plugin/CacheTest.php
  10. 8.4.x core/tests/Drupal/Tests/Core/Cache/CacheTest.php

Namespace

Drupal\Tests\views\Kernel\Plugin

File

core/modules/views/tests/src/Kernel/Plugin/CacheTest.php
View source
  1. <?php
  2. namespace Drupal\Tests\views\Kernel\Plugin;
  3. use Drupal\Core\Render\RenderContext;
  4. use Drupal\node\Entity\Node;
  5. use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
  6. use Drupal\views\Views;
  7. use Drupal\views_test_data\Plugin\views\filter\FilterTest as FilterPlugin;
  8. /**
  9. * Tests pluggable caching for views.
  10. *
  11. * @group views
  12. * @see views_plugin_cache
  13. */
  14. class CacheTest extends ViewsKernelTestBase {
  15. /**
  16. * Views used by this test.
  17. *
  18. * @var array
  19. */
  20. public static $testViews = array('test_view', 'test_cache', 'test_groupwise_term_ui', 'test_display', 'test_filter');
  21. /**
  22. * Modules to enable.
  23. *
  24. * @var array
  25. */
  26. public static $modules = array('taxonomy', 'text', 'user', 'node');
  27. /**
  28. * {@inheritdoc}
  29. */
  30. protected function setUp($import_test_views = TRUE) {
  31. parent::setUp($import_test_views);
  32. $this->installEntitySchema('node');
  33. $this->installEntitySchema('taxonomy_term');
  34. $this->installEntitySchema('user');
  35. // Setup the current time properly.
  36. \Drupal::request()->server->set('REQUEST_TIME', time());
  37. }
  38. /**
  39. * {@inheritdoc}
  40. */
  41. protected function viewsData() {
  42. $data = parent::viewsData();
  43. $data['views_test_data']['test_cache_context'] = [
  44. 'real field' => 'name',
  45. 'title' => 'Test cache context',
  46. 'filter' => [
  47. 'id' => 'views_test_test_cache_context',
  48. ],
  49. ];
  50. return $data;
  51. }
  52. /**
  53. * Tests time based caching.
  54. *
  55. * @see views_plugin_cache_time
  56. */
  57. public function testTimeResultCaching() {
  58. $view = Views::getView('test_cache');
  59. $view->setDisplay();
  60. $view->display_handler->overrideOption('cache', array(
  61. 'type' => 'time',
  62. 'options' => array(
  63. 'results_lifespan' => '3600',
  64. 'output_lifespan' => '3600',
  65. )
  66. ));
  67. // Test the default (non-paged) display.
  68. $this->executeView($view);
  69. // Verify the result.
  70. $this->assertEqual(5, count($view->result), 'The number of returned rows match.');
  71. // Add another man to the beatles.
  72. $record = array(
  73. 'name' => 'Rod Davis',
  74. 'age' => 29,
  75. 'job' => 'Banjo',
  76. );
  77. db_insert('views_test_data')->fields($record)->execute();
  78. // The result should be the same as before, because of the caching. (Note
  79. // that views_test_data records don't have associated cache tags, and hence
  80. // the results cache items aren't invalidated.)
  81. $view->destroy();
  82. $this->executeView($view);
  83. // Verify the result.
  84. $this->assertEqual(5, count($view->result), 'The number of returned rows match.');
  85. }
  86. /**
  87. * Tests result caching with filters.
  88. *
  89. * @see views_plugin_cache_time
  90. */
  91. public function testTimeResultCachingWithFilter() {
  92. // Check that we can find the test filter plugin.
  93. $plugin = $this->container->get('plugin.manager.views.filter')->createInstance('test_filter');
  94. $this->assertTrue($plugin instanceof FilterPlugin, 'Test filter plugin found.');
  95. $view = Views::getView('test_filter');
  96. $view->initDisplay();
  97. $view->display_handler->overrideOption('cache', array(
  98. 'type' => 'time',
  99. 'options' => array(
  100. 'results_lifespan' => '3600',
  101. 'output_lifespan' => '3600',
  102. ),
  103. ));
  104. // Change the filtering.
  105. $view->displayHandlers->get('default')->overrideOption('filters', array(
  106. 'test_filter' => array(
  107. 'id' => 'test_filter',
  108. 'table' => 'views_test_data',
  109. 'field' => 'name',
  110. 'operator' => '=',
  111. 'value' => 'John',
  112. 'group' => 0,
  113. ),
  114. ));
  115. $this->executeView($view);
  116. // Get the cache item.
  117. $cid1 = $view->display_handler->getPlugin('cache')->generateResultsKey();
  118. // Build the expected result.
  119. $dataset = array(array('name' => 'John'));
  120. // Verify the result.
  121. $this->assertEqual(1, count($view->result), 'The number of returned rows match.');
  122. $this->assertIdenticalResultSet($view, $dataset, array(
  123. 'views_test_data_name' => 'name',
  124. ));
  125. $view->destroy();
  126. $view->initDisplay();
  127. // Change the filtering.
  128. $view->displayHandlers->get('default')->overrideOption('filters', array(
  129. 'test_filter' => array(
  130. 'id' => 'test_filter',
  131. 'table' => 'views_test_data',
  132. 'field' => 'name',
  133. 'operator' => '=',
  134. 'value' => 'Ringo',
  135. 'group' => 0,
  136. ),
  137. ));
  138. $this->executeView($view);
  139. // Get the cache item.
  140. $cid2 = $view->display_handler->getPlugin('cache')->generateResultsKey();
  141. $this->assertNotEqual($cid1, $cid2, "Results keys are different.");
  142. // Build the expected result.
  143. $dataset = array(array('name' => 'Ringo'));
  144. // Verify the result.
  145. $this->assertEqual(1, count($view->result), 'The number of returned rows match.');
  146. $this->assertIdenticalResultSet($view, $dataset, array(
  147. 'views_test_data_name' => 'name',
  148. ));
  149. }
  150. /**
  151. * Tests result caching with a pager.
  152. */
  153. public function testTimeResultCachingWithPager() {
  154. $view = Views::getView('test_cache');
  155. $view->setDisplay();
  156. $view->display_handler->overrideOption('cache', array(
  157. 'type' => 'time',
  158. 'options' => array(
  159. 'results_lifespan' => '3600',
  160. 'output_lifespan' => '3600',
  161. )
  162. ));
  163. $mapping = ['views_test_data_name' => 'name'];
  164. $view->setDisplay('page_1');
  165. $view->setCurrentPage(0);
  166. $this->executeView($view);
  167. $this->assertIdenticalResultset($view, [['name' => 'John'], ['name' => 'George']], $mapping);
  168. $view->destroy();
  169. $view->setDisplay('page_1');
  170. $view->setCurrentPage(1);
  171. $this->executeView($view);
  172. $this->assertIdenticalResultset($view, [['name' => 'Ringo'], ['name' => 'Paul']], $mapping);
  173. $view->destroy();
  174. $view->setDisplay('page_1');
  175. $view->setCurrentPage(0);
  176. $this->executeView($view);
  177. $this->assertIdenticalResultset($view, [['name' => 'John'], ['name' => 'George']], $mapping);
  178. $view->destroy();
  179. $view->setDisplay('page_1');
  180. $view->setCurrentPage(2);
  181. $this->executeView($view);
  182. $this->assertIdenticalResultset($view, [['name' => 'Meredith']], $mapping);
  183. $view->destroy();
  184. }
  185. /**
  186. * Tests no caching.
  187. *
  188. * @see views_plugin_cache_time
  189. */
  190. function testNoneResultCaching() {
  191. // Create a basic result which just 2 results.
  192. $view = Views::getView('test_cache');
  193. $view->setDisplay();
  194. $view->display_handler->overrideOption('cache', array(
  195. 'type' => 'none',
  196. 'options' => array(),
  197. ));
  198. $this->executeView($view);
  199. // Verify the result.
  200. $this->assertEqual(5, count($view->result), 'The number of returned rows match.');
  201. // Add another man to the beatles.
  202. $record = array(
  203. 'name' => 'Rod Davis',
  204. 'age' => 29,
  205. 'job' => 'Banjo',
  206. );
  207. db_insert('views_test_data')->fields($record)->execute();
  208. // The Result changes, because the view is not cached.
  209. $view = Views::getView('test_cache');
  210. $view->setDisplay();
  211. $view->display_handler->overrideOption('cache', array(
  212. 'type' => 'none',
  213. 'options' => array(),
  214. ));
  215. $this->executeView($view);
  216. // Verify the result.
  217. $this->assertEqual(6, count($view->result), 'The number of returned rows match.');
  218. }
  219. /**
  220. * Tests css/js storage and restoring mechanism.
  221. */
  222. function testHeaderStorage() {
  223. // Create a view with output caching enabled.
  224. // Some hook_views_pre_render in views_test_data.module adds the test css/js file.
  225. // so they should be added to the css/js storage.
  226. $view = Views::getView('test_view');
  227. $view->setDisplay();
  228. $view->storage->set('id', 'test_cache_header_storage');
  229. $view->display_handler->overrideOption('cache', array(
  230. 'type' => 'time',
  231. 'options' => array(
  232. 'output_lifespan' => '3600',
  233. )
  234. ));
  235. $output = $view->buildRenderable();
  236. /** @var \Drupal\Core\Render\RendererInterface $renderer */
  237. $renderer = \Drupal::service('renderer');
  238. $renderer->executeInRenderContext(new RenderContext(), function () use (&$output, $renderer) {
  239. return $renderer->render($output);
  240. });
  241. unset($view->pre_render_called);
  242. $view->destroy();
  243. $view->setDisplay();
  244. $output = $view->buildRenderable();
  245. $renderer->executeInRenderContext(new RenderContext(), function () use (&$output, $renderer) {
  246. return $renderer->render($output);
  247. });
  248. $this->assertTrue(in_array('views_test_data/test', $output['#attached']['library']), 'Make sure libraries are added for cached views.');
  249. $this->assertEqual(['foo' => 'bar'], $output['#attached']['drupalSettings'], 'Make sure drupalSettings are added for cached views.');
  250. // Note: views_test_data_views_pre_render() adds some cache tags.
  251. $this->assertEqual(['config:views.view.test_cache_header_storage', 'views_test_data:1'], $output['#cache']['tags']);
  252. $this->assertEqual(['non-existing-placeholder-just-for-testing-purposes' => ['#lazy_builder' => ['views_test_data_placeholders', ['bar']]]], $output['#attached']['placeholders']);
  253. $this->assertFalse(!empty($view->build_info['pre_render_called']), 'Make sure hook_views_pre_render is not called for the cached view.');
  254. }
  255. /**
  256. * Tests that Subqueries are cached as expected.
  257. */
  258. public function testSubqueryStringCache() {
  259. // Execute the view.
  260. $view = Views::getView('test_groupwise_term_ui');
  261. $view->setDisplay();
  262. $this->executeView($view);
  263. // Request for the cache.
  264. $cid = 'views_relationship_groupwise_max:test_groupwise_term_ui:default:tid_representative';
  265. $cache = \Drupal::cache('data')->get($cid);
  266. $this->assertEqual($cid, $cache->cid, 'Subquery String cached as expected.');
  267. }
  268. /**
  269. * Tests the data contained in cached items.
  270. */
  271. public function testCacheData() {
  272. for ($i = 1; $i <= 5; $i++) {
  273. Node::create([
  274. 'title' => $this->randomMachineName(8),
  275. 'type' => 'page',
  276. ])->save();
  277. }
  278. $view = Views::getView('test_display');
  279. $view->setDisplay();
  280. $view->display_handler->overrideOption('cache', array(
  281. 'type' => 'time',
  282. 'options' => array(
  283. 'results_lifespan' => '3600',
  284. 'output_lifespan' => '3600',
  285. )
  286. ));
  287. $this->executeView($view);
  288. // Get the cache item.
  289. $cid = $view->display_handler->getPlugin('cache')->generateResultsKey();
  290. $cache = \Drupal::cache('data')->get($cid);
  291. // Assert there are results, empty results would mean this test case would
  292. // pass otherwise.
  293. $this->assertTrue(count($cache->data['result']), 'Results saved in cached data.');
  294. // Assert each row doesn't contain '_entity' or '_relationship_entities'
  295. // items.
  296. foreach ($cache->data['result'] as $row) {
  297. $this->assertIdentical($row->_entity, NULL, 'Cached row "_entity" property is NULL');
  298. $this->assertIdentical($row->_relationship_entities, [], 'Cached row "_relationship_entities" property is empty');
  299. }
  300. }
  301. /**
  302. * Tests the cache context integration for views result cache.
  303. */
  304. public function testCacheContextIntegration() {
  305. $view = Views::getView('test_cache');
  306. $view->setDisplay('page_2');
  307. \Drupal::state()->set('views_test_cache_context', 'George');
  308. $this->executeView($view);
  309. $map = ['views_test_data_name' => 'name'];
  310. $this->assertIdenticalResultset($view, [['name' => 'George']], $map);
  311. // Update the entry in the DB to ensure that result caching works.
  312. \Drupal::database()->update('views_test_data')
  313. ->condition('name', 'George')
  314. ->fields(['name' => 'egroeG'])
  315. ->execute();
  316. $view = Views::getView('test_cache');
  317. $view->setDisplay('page_2');
  318. $this->executeView($view);
  319. $this->assertIdenticalResultset($view, [['name' => 'George']], $map);
  320. // Now change the cache context value, a different query should be executed.
  321. $view = Views::getView('test_cache');
  322. $view->setDisplay('page_2');
  323. \Drupal::state()->set('views_test_cache_context', 'Paul');
  324. $this->executeView($view);
  325. $this->assertIdenticalResultset($view, [['name' => 'Paul']], $map);
  326. }
  327. }

Classes

Namesort descending Description
CacheTest Tests pluggable caching for views.