views_cache.test 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <?php
  2. /**
  3. * @file
  4. * Definition of ViewsCacheTest.
  5. */
  6. /**
  7. * Basic test for pluggable caching.
  8. *
  9. * @see views_plugin_cache
  10. */
  11. class ViewsCacheTest extends ViewsSqlTest {
  12. /**
  13. *
  14. */
  15. public static function getInfo() {
  16. return array(
  17. 'name' => 'Cache',
  18. 'description' => 'Tests pluggable caching for views.',
  19. 'group' => 'Views Plugins',
  20. );
  21. }
  22. /**
  23. * Build and return a basic view of the views_test table.
  24. *
  25. * @return view
  26. */
  27. protected function getBasicView() {
  28. views_include('view');
  29. // Create the basic view.
  30. $view = new view();
  31. $view->name = 'test_view';
  32. $view->add_display('default');
  33. $view->base_table = 'views_test';
  34. // Set up the fields we need.
  35. $display = $view->new_display('default', 'Master', 'default');
  36. $display->override_option('fields', array(
  37. 'id' => array(
  38. 'id' => 'id',
  39. 'table' => 'views_test',
  40. 'field' => 'id',
  41. 'relationship' => 'none',
  42. ),
  43. 'name' => array(
  44. 'id' => 'name',
  45. 'table' => 'views_test',
  46. 'field' => 'name',
  47. 'relationship' => 'none',
  48. ),
  49. 'age' => array(
  50. 'id' => 'age',
  51. 'table' => 'views_test',
  52. 'field' => 'age',
  53. 'relationship' => 'none',
  54. ),
  55. ));
  56. // Set up the sort order.
  57. $display->override_option('sorts', array(
  58. 'id' => array(
  59. 'order' => 'ASC',
  60. 'id' => 'id',
  61. 'table' => 'views_test',
  62. 'field' => 'id',
  63. 'relationship' => 'none',
  64. ),
  65. ));
  66. return $view;
  67. }
  68. /**
  69. * Tests time based caching.
  70. *
  71. * @see views_plugin_cache_time
  72. */
  73. function testTimeCaching() {
  74. // Create a basic result which just 2 results.
  75. $view = $this->getBasicView();
  76. $view->set_display();
  77. $view->display_handler->override_option('cache', array(
  78. 'type' => 'time',
  79. 'results_lifespan' => '3600',
  80. 'output_lifespan' => '3600',
  81. ));
  82. $this->executeView($view);
  83. // Verify the result.
  84. $this->assertEqual(5, count($view->result), t('The number of returned rows match.'));
  85. // Add another man to the beatles.
  86. $record = array(
  87. 'name' => 'Rod Davis',
  88. 'age' => 29,
  89. 'job' => 'Banjo',
  90. );
  91. drupal_write_record('views_test', $record);
  92. // The Result should be the same as before, because of the caching.
  93. $view = $this->getBasicView();
  94. $view->set_display();
  95. $view->display_handler->override_option('cache', array(
  96. 'type' => 'time',
  97. 'results_lifespan' => '3600',
  98. 'output_lifespan' => '3600',
  99. ));
  100. $this->executeView($view);
  101. // Verify the result.
  102. $this->assertEqual(5, count($view->result), t('The number of returned rows match.'));
  103. }
  104. /**
  105. * Tests no caching.
  106. *
  107. * @see views_plugin_cache_time
  108. */
  109. function testNoneCaching() {
  110. // Create a basic result which just 2 results.
  111. $view = $this->getBasicView();
  112. $view->set_display();
  113. $view->display_handler->override_option('cache', array(
  114. 'type' => 'none',
  115. ));
  116. $this->executeView($view);
  117. // Verify the result.
  118. $this->assertEqual(5, count($view->result), t('The number of returned rows match.'));
  119. // Add another man to the beatles.
  120. $record = array(
  121. 'name' => 'Rod Davis',
  122. 'age' => 29,
  123. 'job' => 'Banjo',
  124. );
  125. drupal_write_record('views_test', $record);
  126. // The Result changes, because the view is not cached.
  127. $view = $this->getBasicView();
  128. $view->set_display();
  129. $view->display_handler->override_option('cache', array(
  130. 'type' => 'none',
  131. ));
  132. $this->executeView($view);
  133. // Verify the result.
  134. $this->assertEqual(6, count($view->result), t('The number of returned rows match.'));
  135. }
  136. /**
  137. * Tests css/js storage and restoring mechanism.
  138. */
  139. function testHeaderStorage() {
  140. // Create a view with output caching enabled. Some hook_views_pre_render in
  141. // views_test.module adds the test css/js file, so they should be added to
  142. // the css/js storage.
  143. $view = $this->getBasicView();
  144. $view->init_display();
  145. $view->name = 'test_cache_header_storage';
  146. $view->display_handler->override_option('cache', array(
  147. 'type' => 'time',
  148. 'output_lifespan' => '3600',
  149. ));
  150. $view->preview();
  151. $view->destroy();
  152. unset($view->pre_render_called);
  153. drupal_static_reset('drupal_add_css');
  154. drupal_static_reset('drupal_add_js');
  155. $view->init_display();
  156. $view->preview();
  157. $css = drupal_add_css();
  158. $css_path = drupal_get_path('module', 'views_test') . '/views_cache.test.css';
  159. $js_path = drupal_get_path('module', 'views_test') . '/views_cache.test.js';
  160. $js = drupal_add_js();
  161. $this->assertTrue(isset($css[$css_path]), 'Make sure the css is added for cached views.');
  162. $this->assertTrue(isset($js[$js_path]), 'Make sure the js is added for cached views.');
  163. $this->assertFalse(!empty($view->pre_render_called), 'Make sure hook_views_pre_render is not called for the cached view.');
  164. $view->destroy();
  165. // Now add some css/jss before running the view.
  166. // Make sure that this css is not added when running the cached view.
  167. $view->name = 'test_cache_header_storage_2';
  168. $system_css_path = drupal_get_path('module', 'system') . '/system.maintenance.css';
  169. drupal_add_css($system_css_path);
  170. $system_js_path = drupal_get_path('module', 'system') . '/system.cron.js';
  171. drupal_add_js($system_js_path);
  172. $view->init_display();
  173. $view->preview();
  174. $view->destroy();
  175. drupal_static_reset('drupal_add_css');
  176. drupal_static_reset('drupal_add_js');
  177. $view->init_display();
  178. $view->preview();
  179. $css = drupal_add_css();
  180. $js = drupal_add_js();
  181. $this->assertFalse(isset($css[$system_css_path]), 'Make sure that unrelated css is not added.');
  182. $this->assertFalse(isset($js[$system_js_path]), 'Make sure that unrelated js is not added.');
  183. }
  184. /**
  185. * Check that HTTP headers are cached for views.
  186. */
  187. function testHttpHeadersCaching() {
  188. // Create a few nodes to appear in RSS feed.
  189. for ($i = 0; $i < 5; $i++) {
  190. $this->drupalCreateNode();
  191. }
  192. // Make the first request and check returned content type.
  193. $this->drupalGet('test_feed_http_headers_caching');
  194. $first_content = $this->drupalGetContent();
  195. $first_content_type = $this->drupalGetHeader('content-type');
  196. $expected_type = 'application/rss+xml';
  197. $this->assertIdentical(0, strpos(trim($first_content_type), $expected_type), t('Expected content type returned.'));
  198. // Check that we have 5 items in RSS feed returned by the first request.
  199. $xml = simplexml_load_string($first_content);
  200. $items = $xml->xpath('/rss/channel/item');
  201. $this->assertEqual(5, count($items), t('The number of RSS feed items matched.'));
  202. // Create another node to be sure we get cached results on the second
  203. // request.
  204. $this->drupalCreateNode();
  205. // Make the second request, check content type and content matching.
  206. $this->drupalGet('test_feed_http_headers_caching');
  207. $second_content = $this->drupalGetContent();
  208. $this->assertEqual($first_content, $second_content, t('The second result fetched from cache.'));
  209. $second_content_type = $this->drupalGetHeader('content-type');
  210. $this->assertEqual($first_content_type, $second_content_type, t('Content types of responses are equal.'));
  211. }
  212. /**
  213. * Test caching of different exposed filter values with the same view result.
  214. *
  215. * Make sure the output is different.
  216. */
  217. function testExposedFilterSameResultsCaching() {
  218. // Create the view with time-based cache with hour lifetimes and add exposed
  219. // filter to it with "Starts with" operator.
  220. $view = $this->getBasicView();
  221. $view->set_display();
  222. $view->display_handler->override_option('cache', array(
  223. 'type' => 'time',
  224. 'results_lifespan' => '3600',
  225. 'output_lifespan' => '3600',
  226. ));
  227. $view->display_handler->override_option('filters', array(
  228. 'name' => array(
  229. 'id' => 'name',
  230. 'table' => 'views_test',
  231. 'field' => 'name',
  232. 'relationship' => 'none',
  233. 'operator' => 'starts',
  234. 'exposed' => TRUE,
  235. 'expose' => array(
  236. 'operator_id' => 'name_op',
  237. 'operator' => 'name_op',
  238. 'identifier' => 'name',
  239. ),
  240. ),
  241. ));
  242. // Clone the view before setting exposed input.
  243. $clone = $view->copy();
  244. // Pass "Rin" to the exposed filter and check that only one row returned.
  245. $view->set_exposed_input(array(
  246. 'name' => 'Rin',
  247. ));
  248. $this->executeView($view);
  249. $first_result = $view->result;
  250. $first_output = $view->render();
  251. $this->assertEqual(1, count($first_result), t('The number of rows returned by the first view match.'));
  252. // Pass full "Ringo" to the exposed filter at the second time and make sure
  253. // results are the same.
  254. $clone->set_exposed_input(array(
  255. 'name' => 'Ringo',
  256. ));
  257. $this->executeView($clone);
  258. $second_result = $clone->result;
  259. $second_output = $clone->render();
  260. $this->assertEqual($first_result, $second_result, t('Results of both views are the same.'));
  261. // Check that output is not the same and it contains full "Ringo" word in
  262. // default value of exposed input.
  263. $this->assertNotEqual($first_output, $second_output, t('Output of the second view is different.'));
  264. $this->drupalSetContent($second_output);
  265. $element = $this->xpath('//input[@name="name" and @value="Ringo"]');
  266. $this->assertTrue(!empty($element), t('Input field of exposed filter has the second value.'));
  267. $view->destroy();
  268. $clone->destroy();
  269. }
  270. }