CacheHelperTest.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. <?php
  2. /**
  3. * CacheHelperTest file
  4. *
  5. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  6. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  7. *
  8. * Licensed under The MIT License
  9. * For full copyright and license information, please see the LICENSE.txt
  10. * Redistributions of files must retain the above copyright notice
  11. *
  12. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  13. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  14. * @since 1.2.0
  15. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  16. */
  17. namespace Cake\Test\TestCase\View\Helper;
  18. use Cake\Cache\Cache;
  19. use Cake\Controller\Controller;
  20. use Cake\Core\App;
  21. use Cake\Core\Configure;
  22. use Cake\Model\Model;
  23. use Cake\Network\Request;
  24. use Cake\Routing\Router;
  25. use Cake\TestSuite\TestCase;
  26. use Cake\View\Helper\CacheHelper;
  27. use Cake\View\View;
  28. /**
  29. * CacheTestController class
  30. *
  31. */
  32. class CacheTestController extends Controller {
  33. /**
  34. * helpers property
  35. *
  36. * @var array
  37. */
  38. public $helpers = array('Html', 'Cache');
  39. /**
  40. * cache_parsing method
  41. *
  42. * @return void
  43. */
  44. public function cache_parsing() {
  45. $this->viewPath = 'Posts';
  46. $this->layout = 'cache_layout';
  47. $this->set('variable', 'variableValue');
  48. $this->set('superman', 'clark kent');
  49. $this->set('batman', 'bruce wayne');
  50. $this->set('spiderman', 'peter parker');
  51. }
  52. }
  53. /**
  54. * CacheHelperTest class
  55. *
  56. */
  57. class CacheHelperTest extends TestCase {
  58. /**
  59. * Checks if TMP/views is writable, and skips the case if it is not.
  60. *
  61. * @return void
  62. */
  63. public function skip() {
  64. if (!is_writable(TMP . 'cache/views/')) {
  65. $this->markTestSkipped('TMP/views is not writable.');
  66. }
  67. }
  68. /**
  69. * setUp method
  70. *
  71. * @return void
  72. */
  73. public function setUp() {
  74. parent::setUp();
  75. $_GET = [];
  76. $request = new Request();
  77. $this->Controller = new CacheTestController($request);
  78. $View = $this->Controller->createView();
  79. $this->Cache = new CacheHelper($View);
  80. Configure::write('Cache.check', true);
  81. Cache::enable();
  82. }
  83. /**
  84. * tearDown method
  85. *
  86. * @return void
  87. */
  88. public function tearDown() {
  89. clearCache();
  90. unset($this->Cache);
  91. parent::tearDown();
  92. }
  93. /**
  94. * test cache parsing with no cake:nocache tags in view file.
  95. *
  96. * @return void
  97. */
  98. public function testLayoutCacheParsingNoTagsInView() {
  99. $this->Controller->cache_parsing();
  100. $this->Controller->request->addParams(array(
  101. 'controller' => 'cache_test',
  102. 'action' => 'cache_parsing',
  103. 'pass' => array(),
  104. ));
  105. $this->Controller->cacheAction = 21600;
  106. $this->Controller->request->here = '/cacheTest/cache_parsing';
  107. $this->Controller->request->action = 'cache_parsing';
  108. $View = $this->Controller->createView();
  109. $result = $View->render('index');
  110. $this->assertNotContains('cake:nocache', $result);
  111. $this->assertNotContains('<?php echo', $result);
  112. $filename = CACHE . 'views/cachetest_cache_parsing.php';
  113. $this->assertTrue(file_exists($filename));
  114. $contents = file_get_contents($filename);
  115. $this->assertContains('<?= $variable', $contents);
  116. $this->assertContains('<?= microtime()', $contents);
  117. $this->assertContains('clark kent', $result);
  118. unlink($filename);
  119. }
  120. /**
  121. * test cache parsing with non-latin characters in current route
  122. *
  123. * @return void
  124. */
  125. public function testCacheNonLatinCharactersInRoute() {
  126. $this->Controller->cache_parsing();
  127. $this->Controller->request->addParams(array(
  128. 'controller' => 'cache_test',
  129. 'action' => 'cache_parsing',
  130. 'pass' => array('風街ろまん'),
  131. ));
  132. $this->Controller->cacheAction = 21600;
  133. $this->Controller->request->here = '/posts/view/風街ろまん';
  134. $this->Controller->action = 'view';
  135. $View = $this->Controller->createView();
  136. $View->render('index');
  137. $filename = CACHE . 'views/posts_view_風街ろまん.php';
  138. $this->assertTrue(file_exists($filename));
  139. unlink($filename);
  140. }
  141. /**
  142. * Test cache parsing with cake:nocache tags in view file.
  143. *
  144. * @return void
  145. */
  146. public function testLayoutCacheParsingWithTagsInView() {
  147. $this->Controller->cache_parsing();
  148. $this->Controller->request->addParams(array(
  149. 'controller' => 'cache_test',
  150. 'action' => 'cache_parsing',
  151. 'pass' => array(),
  152. ));
  153. $this->Controller->cacheAction = 21600;
  154. $this->Controller->request->here = '/cacheTest/cache_parsing';
  155. $this->Controller->action = 'cache_parsing';
  156. $View = $this->Controller->createView();
  157. $result = $View->render('test_nocache_tags');
  158. $this->assertNotRegExp('/cake:nocache/', $result);
  159. $this->assertNotRegExp('/php echo/', $result);
  160. $filename = CACHE . 'views/cachetest_cache_parsing.php';
  161. $this->assertTrue(file_exists($filename));
  162. $contents = file_get_contents($filename);
  163. $this->assertRegExp('/if \(is_writable\(TMP\)\)\:/', $contents);
  164. $this->assertRegExp('/= \$variable/', $contents);
  165. $this->assertRegExp('/= microtime()/', $contents);
  166. $this->assertNotRegExp('/cake:nocache/', $contents);
  167. unlink($filename);
  168. }
  169. /**
  170. * test that multiple <!--nocache--> tags function with multiple nocache tags in the layout.
  171. *
  172. * @return void
  173. */
  174. public function testMultipleNoCacheTagsInViewfile() {
  175. $this->Controller->cache_parsing();
  176. $this->Controller->request->addParams(array(
  177. 'controller' => 'cache_test',
  178. 'action' => 'cache_parsing',
  179. 'pass' => array(),
  180. ));
  181. $this->Controller->cacheAction = 21600;
  182. $this->Controller->request->here = '/cacheTest/cache_parsing';
  183. $this->Controller->action = 'cache_parsing';
  184. $View = $this->Controller->createView();
  185. $result = $View->render('multiple_nocache');
  186. $this->assertNotRegExp('/cake:nocache/', $result);
  187. $this->assertNotRegExp('/php echo/', $result);
  188. $filename = CACHE . 'views/cachetest_cache_parsing.php';
  189. $this->assertTrue(file_exists($filename));
  190. $contents = file_get_contents($filename);
  191. $this->assertNotRegExp('/cake:nocache/', $contents);
  192. unlink($filename);
  193. }
  194. /**
  195. * testComplexNoCache method
  196. *
  197. * @return void
  198. */
  199. public function testComplexNoCache() {
  200. $this->Controller->cache_parsing();
  201. $this->Controller->request->addParams(array(
  202. 'controller' => 'cache_test',
  203. 'action' => 'cache_complex',
  204. 'pass' => array(),
  205. ));
  206. $this->Controller->action = 'cache_complex';
  207. $this->Controller->request->here = '/cacheTest/cache_complex';
  208. $this->Controller->cacheAction = array('cache_complex' => 21600);
  209. $this->Controller->layout = 'multi_cache';
  210. $this->Controller->viewPath = 'Posts';
  211. $View = $this->Controller->createView();
  212. $result = $View->render('sequencial_nocache');
  213. $this->assertNotRegExp('/cake:nocache/', $result);
  214. $this->assertNotRegExp('/php echo/', $result);
  215. $this->assertRegExp('/A\. Layout Before Content/', $result);
  216. $this->assertRegExp('/B\. In Plain Element/', $result);
  217. $this->assertRegExp('/C\. Layout After Test Element/', $result);
  218. $this->assertRegExp('/D\. In View File/', $result);
  219. $this->assertRegExp('/E\. Layout After Content/', $result);
  220. $this->assertRegExp('/F\. In Element With No Cache Tags/', $result);
  221. $this->assertRegExp('/G\. Layout After Content And After Element With No Cache Tags/', $result);
  222. $this->assertNotRegExp('/1\. layout before content/', $result);
  223. $this->assertNotRegExp('/2\. in plain element/', $result);
  224. $this->assertNotRegExp('/3\. layout after test element/', $result);
  225. $this->assertNotRegExp('/4\. in view file/', $result);
  226. $this->assertNotRegExp('/5\. layout after content/', $result);
  227. $this->assertNotRegExp('/6\. in element with no cache tags/', $result);
  228. $this->assertNotRegExp('/7\. layout after content and after element with no cache tags/', $result);
  229. $filename = CACHE . 'views/cachetest_cache_complex.php';
  230. $this->assertTrue(file_exists($filename));
  231. $contents = file_get_contents($filename);
  232. unlink($filename);
  233. $this->assertRegExp('/A\. Layout Before Content/', $contents);
  234. $this->assertNotRegExp('/B\. In Plain Element/', $contents);
  235. $this->assertRegExp('/C\. Layout After Test Element/', $contents);
  236. $this->assertRegExp('/D\. In View File/', $contents);
  237. $this->assertRegExp('/E\. Layout After Content/', $contents);
  238. $this->assertRegExp('/F\. In Element With No Cache Tags/', $contents);
  239. $this->assertRegExp('/G\. Layout After Content And After Element With No Cache Tags/', $contents);
  240. $this->assertRegExp('/1\. layout before content/', $contents);
  241. $this->assertNotRegExp('/2\. in plain element/', $contents);
  242. $this->assertRegExp('/3\. layout after test element/', $contents);
  243. $this->assertRegExp('/4\. in view file/', $contents);
  244. $this->assertRegExp('/5\. layout after content/', $contents);
  245. $this->assertRegExp('/6\. in element with no cache tags/', $contents);
  246. $this->assertRegExp('/7\. layout after content and after element with no cache tags/', $contents);
  247. }
  248. /**
  249. * test cache of view vars
  250. *
  251. * @return void
  252. */
  253. public function testCacheViewVars() {
  254. $this->Controller->cache_parsing();
  255. $this->Controller->request->addParams(array(
  256. 'controller' => 'cache_test',
  257. 'action' => 'cache_parsing',
  258. 'pass' => array(),
  259. ));
  260. $this->Controller->request->here = '/cacheTest/cache_parsing';
  261. $this->Controller->cacheAction = 21600;
  262. $View = $this->Controller->createView();
  263. $result = $View->render('index');
  264. $this->assertNotRegExp('/cake:nocache/', $result);
  265. $this->assertNotRegExp('/php echo/', $result);
  266. $filename = CACHE . 'views/cachetest_cache_parsing.php';
  267. $this->assertTrue(file_exists($filename));
  268. $contents = file_get_contents($filename);
  269. $this->assertRegExp('/\$this\-\>viewVars/', $contents);
  270. $this->assertRegExp('/extract\(\$this\-\>viewVars, EXTR_SKIP\);/', $contents);
  271. $this->assertRegExp('/= \$variable/', $contents);
  272. unlink($filename);
  273. }
  274. /**
  275. * Test that callback code is generated correctly.
  276. *
  277. * @return void
  278. */
  279. public function testCacheCallbacks() {
  280. $this->Controller->request->addParams(array(
  281. 'controller' => 'cache_test',
  282. 'action' => 'cache_parsing',
  283. 'pass' => array(),
  284. ));
  285. $this->Controller->cacheAction = array(
  286. 'cache_parsing' => array(
  287. 'duration' => 21600,
  288. 'callbacks' => true)
  289. );
  290. $this->Controller->request->here = '/cacheTest/cache_parsing';
  291. $this->Controller->cache_parsing();
  292. $View = $this->Controller->createView();
  293. $View->render('index');
  294. $filename = CACHE . 'views/cachetest_cache_parsing.php';
  295. $this->assertTrue(file_exists($filename));
  296. $contents = file_get_contents($filename);
  297. $this->assertRegExp('/\$controller->startupProcess\(\);/', $contents);
  298. unlink($filename);
  299. }
  300. /**
  301. * test cacheAction set to a boolean
  302. *
  303. * @return void
  304. */
  305. public function testCacheActionArray() {
  306. $this->Controller->request->addParams(array(
  307. 'controller' => 'cache_test',
  308. 'action' => 'cache_parsing',
  309. 'pass' => array(),
  310. ));
  311. $this->Controller->request->here = '/cache_test/cache_parsing';
  312. $this->Controller->cacheAction = array(
  313. 'cache_parsing' => 21600
  314. );
  315. $this->Controller->cache_parsing();
  316. $View = $this->Controller->createView();
  317. $result = $View->render('index');
  318. $this->assertNotRegExp('/cake:nocache/', $result);
  319. $this->assertNotRegExp('/php echo/', $result);
  320. $filename = CACHE . 'views/cache_test_cache_parsing.php';
  321. $this->assertTrue(file_exists($filename));
  322. unlink($filename);
  323. }
  324. /**
  325. * Test that cacheAction works with camelcased controller names.
  326. *
  327. * @return void
  328. */
  329. public function testCacheActionArrayCamelCase() {
  330. $this->Controller->request->addParams(array(
  331. 'controller' => 'cache_test',
  332. 'action' => 'cache_parsing',
  333. 'pass' => array(),
  334. ));
  335. $this->Controller->cacheAction = array(
  336. 'cache_parsing' => 21600
  337. );
  338. $this->Controller->request->here = '/cacheTest/cache_parsing';
  339. $this->Controller->cache_parsing();
  340. $View = $this->Controller->createView();
  341. $result = $View->render('index');
  342. $this->assertNotRegExp('/cake:nocache/', $result);
  343. $this->assertNotRegExp('/php echo/', $result);
  344. $filename = CACHE . 'views/cachetest_cache_parsing.php';
  345. $this->assertTrue(file_exists($filename));
  346. unlink($filename);
  347. }
  348. /**
  349. * test with named and pass args.
  350. *
  351. * @return void
  352. */
  353. public function testCacheWithNamedAndPassedArgs() {
  354. Router::reload();
  355. $this->Controller->cache_parsing();
  356. $this->Controller->request->addParams(array(
  357. 'controller' => 'cache_test',
  358. 'action' => 'cache_parsing',
  359. 'pass' => array(1, 2),
  360. ));
  361. $this->Controller->cacheAction = array(
  362. 'cache_parsing' => 21600
  363. );
  364. $this->Controller->request->here = '/cache_test/cache_parsing/1/2/name:mark/ice:cream';
  365. $View = $this->Controller->createView();
  366. $result = $View->render('index');
  367. $this->assertNotRegExp('/cake:nocache/', $result);
  368. $this->assertNotRegExp('/php echo/', $result);
  369. $filename = CACHE . 'views/cache_test_cache_parsing_1_2_name_mark_ice_cream.php';
  370. $this->assertTrue(file_exists($filename));
  371. unlink($filename);
  372. }
  373. /**
  374. * Test that query string parameters are included in the cache filename.
  375. *
  376. * @return void
  377. */
  378. public function testCacheWithQueryStringParams() {
  379. Router::reload();
  380. $this->Controller->cache_parsing();
  381. $this->Controller->request->addParams(array(
  382. 'controller' => 'cache_test',
  383. 'action' => 'cache_parsing',
  384. 'pass' => array(),
  385. ));
  386. $this->Controller->request->query = array('q' => 'cakephp');
  387. $this->Controller->request->here = '/cache_test/cache_parsing';
  388. $this->Controller->cacheAction = array(
  389. 'cache_parsing' => 21600
  390. );
  391. $View = $this->Controller->createView();
  392. $result = $View->render('index');
  393. $this->assertNotRegExp('/cake:nocache/', $result);
  394. $this->assertNotRegExp('/php echo/', $result);
  395. $filename = CACHE . 'views/cache_test_cache_parsing_q_cakephp.php';
  396. $this->assertTrue(file_exists($filename), 'Missing cache file ' . $filename);
  397. unlink($filename);
  398. }
  399. /**
  400. * test that custom routes are respected when generating cache files.
  401. *
  402. * @return void
  403. */
  404. public function testCacheWithCustomRoutes() {
  405. Router::reload();
  406. Router::connect('/:lang/:controller/:action/*', array(), array('lang' => '[a-z]{3}'));
  407. $this->Controller->cache_parsing();
  408. $this->Controller->request->addParams(array(
  409. 'lang' => 'en',
  410. 'controller' => 'cache_test',
  411. 'action' => 'cache_parsing',
  412. 'pass' => array(),
  413. ));
  414. $this->Controller->cacheAction = array(
  415. 'cache_parsing' => 21600
  416. );
  417. $this->Controller->request->here = '/en/cache_test/cache_parsing';
  418. $this->Controller->action = 'cache_parsing';
  419. $View = $this->Controller->createView();
  420. $result = $View->render('index');
  421. $this->assertNotRegExp('/cake:nocache/', $result);
  422. $this->assertNotRegExp('/php echo/', $result);
  423. $filename = CACHE . 'views/en_cache_test_cache_parsing.php';
  424. $this->assertTrue(file_exists($filename));
  425. unlink($filename);
  426. }
  427. /**
  428. * test ControllerName contains AppName
  429. *
  430. * This test verifies view cache is created correctly when the app name is contained in part of the controller name.
  431. * (webapp Name) base name is 'cache' controller is 'cacheTest' action is 'cache_name'
  432. * apps URL would look something like http://localhost/cache/cacheTest/cache_name
  433. *
  434. * @return void
  435. */
  436. public function testCacheBaseNameControllerName() {
  437. $this->Controller->cache_parsing();
  438. $this->Controller->cacheAction = array(
  439. 'cache_name' => 21600
  440. );
  441. $request = $this->Controller->request;
  442. $request->params = array(
  443. 'controller' => 'cacheTest',
  444. 'action' => 'cache_name',
  445. 'pass' => array(),
  446. );
  447. $request->here = '/cache/cacheTest/cache_name';
  448. $request->base = '/cache';
  449. $View = $this->Controller->createView();
  450. $result = $View->render('index');
  451. $this->assertNotRegExp('/cake:nocache/', $result);
  452. $this->assertNotRegExp('/php echo/', $result);
  453. $filename = CACHE . 'views/cache_cachetest_cache_name.php';
  454. $this->assertTrue(file_exists($filename));
  455. unlink($filename);
  456. }
  457. /**
  458. * test that afterRender checks the conditions correctly.
  459. *
  460. * @return void
  461. */
  462. public function testAfterRenderConditions() {
  463. Configure::write('Cache.check', true);
  464. $View = $this->Controller->createView();
  465. $View->cacheAction = '+1 day';
  466. $View->assign('content', 'test');
  467. $Cache = $this->getMock('Cake\View\Helper\CacheHelper', array('_parseContent'), array($View));
  468. $Cache->expects($this->once())
  469. ->method('_parseContent')
  470. ->with('posts/index', 'content')
  471. ->will($this->returnValue(''));
  472. $event = $this->getMock('Cake\Event\Event', [], ['View.afterRenderFile']);
  473. $Cache->afterRenderFile($event, 'posts/index', 'content');
  474. }
  475. /**
  476. * test that afterRender checks the conditions correctly.
  477. *
  478. * @return void
  479. */
  480. public function testAfterLayoutConditions() {
  481. Configure::write('Cache.check', true);
  482. $View = $this->Controller->createView();
  483. $View->cacheAction = '+1 day';
  484. $View->set('content', 'test');
  485. $Cache = $this->getMock('Cake\View\Helper\CacheHelper', array('cache'), array($View));
  486. $Cache->expects($this->once())
  487. ->method('cache')
  488. ->with('posts/index', $View->fetch('content'))
  489. ->will($this->returnValue(''));
  490. $event = $this->getMock('Cake\Event\Event', [], ['View.afterLayout']);
  491. $Cache->afterLayout($event, 'posts/index');
  492. Configure::write('Cache.check', false);
  493. $Cache->afterLayout($event, 'posts/index');
  494. Configure::write('Cache.check', true);
  495. $View->cacheAction = false;
  496. $Cache->afterLayout($event, 'posts/index');
  497. }
  498. /**
  499. * testCacheEmptySections method
  500. *
  501. * This test must be uncommented/fixed in next release (1.2+)
  502. *
  503. * @return void
  504. */
  505. public function testCacheEmptySections() {
  506. Configure::write('Cache.check', true);
  507. $this->Controller->cache_parsing();
  508. $this->Controller->request->addParams([
  509. 'controller' => 'cacheTest',
  510. 'action' => 'cache_empty_sections',
  511. 'pass' => [],
  512. ]);
  513. $this->Controller->request->here = '/cacheTest/cache_empty_sections';
  514. $this->Controller->cacheAction = ['cache_empty_sections' => 21600];
  515. $this->Controller->layout = 'cache_empty_sections';
  516. $this->Controller->viewPath = 'Posts';
  517. $View = $this->Controller->createView();
  518. $result = $View->render('cache_empty_sections');
  519. $this->assertNotContains('nocache', $result);
  520. $this->assertNotContains('<?php echo', $result);
  521. $this->assertRegExp(
  522. '@</title>\s*</head>\s*' .
  523. '<body>\s*' .
  524. 'View Content\s*' .
  525. 'cached count is: 3\s*' .
  526. '</body>@', $result);
  527. $filename = CACHE . 'views/cachetest_cache_empty_sections.php';
  528. $this->assertTrue(file_exists($filename));
  529. $contents = file_get_contents($filename);
  530. $this->assertNotContains('nocache', $contents);
  531. $this->assertRegExp(
  532. '@<head>\s*<title>Posts</title>\s*' .
  533. '<\?php \$x \= 1; \?>\s*' .
  534. '</head>\s*' .
  535. '<body>\s*' .
  536. '<\?php \$x\+\+; \?>\s*' .
  537. '<\?php \$x\+\+; \?>\s*' .
  538. 'View Content\s*' .
  539. '<\?php \$y = 1; \?>\s*' .
  540. '<\?= \'cached count is: \' . \$x; \?>\s*' .
  541. '@', $contents);
  542. unlink($filename);
  543. }
  544. }