/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php

https://bitbucket.org/vishallogiciel/admin-bootstrap · PHP · 191 lines · 113 code · 29 blank · 49 comment · 0 complexity · 3d4d5292490826d7c90cf82130f04c76 MD5 · raw file

  1. <?php
  2. /**
  3. * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The Open Group Test Suite License
  7. * Redistributions of files must retain the above copyright notice.
  8. *
  9. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  10. * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
  11. * @package Cake.Test.Case.Routing.Filter
  12. * @since CakePHP(tm) v 2.2
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. App::uses('AssetDispatcher', 'Routing/Filter');
  16. App::uses('CakeEvent', 'Event');
  17. App::uses('CakeResponse', 'Network');
  18. /**
  19. * Class AssetDispatcherTest
  20. *
  21. * @package Cake.Test.Case.Routing.Filter
  22. */
  23. class AssetDispatcherTest extends CakeTestCase {
  24. /**
  25. * tearDown method
  26. *
  27. * @return void
  28. */
  29. public function tearDown() {
  30. parent::tearDown();
  31. Configure::write('Dispatcher.filters', array());
  32. }
  33. /**
  34. * test that asset filters work for theme and plugin assets
  35. *
  36. * @return void
  37. */
  38. public function testAssetFilterForThemeAndPlugins() {
  39. $filter = new AssetDispatcher();
  40. $response = $this->getMock('CakeResponse', array('_sendHeader'));
  41. Configure::write('Asset.filter', array(
  42. 'js' => '',
  43. 'css' => ''
  44. ));
  45. App::build(array(
  46. 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
  47. 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
  48. ), APP::RESET);
  49. $request = new CakeRequest('theme/test_theme/ccss/cake.generic.css');
  50. $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
  51. $this->assertSame($response, $filter->beforeDispatch($event));
  52. $this->assertTrue($event->isStopped());
  53. $request = new CakeRequest('theme/test_theme/cjs/debug_kit.js');
  54. $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
  55. $this->assertSame($response, $filter->beforeDispatch($event));
  56. $this->assertTrue($event->isStopped());
  57. $request = new CakeRequest('test_plugin/ccss/cake.generic.css');
  58. $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
  59. $this->assertSame($response, $filter->beforeDispatch($event));
  60. $this->assertTrue($event->isStopped());
  61. $request = new CakeRequest('test_plugin/cjs/debug_kit.js');
  62. $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
  63. $this->assertSame($response, $filter->beforeDispatch($event));
  64. $this->assertTrue($event->isStopped());
  65. $request = new CakeRequest('css/ccss/debug_kit.css');
  66. $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
  67. $this->assertNull($filter->beforeDispatch($event));
  68. $this->assertFalse($event->isStopped());
  69. $request = new CakeRequest('js/cjs/debug_kit.js');
  70. $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
  71. $this->assertNull($filter->beforeDispatch($event));
  72. $this->assertFalse($event->isStopped());
  73. }
  74. /**
  75. * Tests that $response->checkNotModified() is called and bypasses
  76. * file dispatching
  77. *
  78. * @return void
  79. */
  80. public function testNotModified() {
  81. $filter = new AssetDispatcher();
  82. Configure::write('Asset.filter', array(
  83. 'js' => '',
  84. 'css' => ''
  85. ));
  86. App::build(array(
  87. 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
  88. 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
  89. ));
  90. $time = filemtime(App::themePath('TestTheme') . 'webroot' . DS . 'img' . DS . 'cake.power.gif');
  91. $time = new DateTime('@' . $time);
  92. $response = $this->getMock('CakeResponse', array('send', 'checkNotModified'));
  93. $request = new CakeRequest('theme/test_theme/img/cake.power.gif');
  94. $response->expects($this->once())->method('checkNotModified')
  95. ->with($request)
  96. ->will($this->returnValue(true));
  97. $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
  98. ob_start();
  99. $this->assertSame($response, $filter->beforeDispatch($event));
  100. ob_end_clean();
  101. $this->assertEquals(200, $response->statusCode());
  102. $this->assertEquals($time->format('D, j M Y H:i:s') . ' GMT', $response->modified());
  103. $response = $this->getMock('CakeResponse', array('_sendHeader', 'checkNotModified'));
  104. $request = new CakeRequest('theme/test_theme/img/cake.power.gif');
  105. $response->expects($this->once())->method('checkNotModified')
  106. ->with($request)
  107. ->will($this->returnValue(true));
  108. $response->expects($this->never())->method('send');
  109. $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
  110. $this->assertSame($response, $filter->beforeDispatch($event));
  111. $this->assertEquals($time->format('D, j M Y H:i:s') . ' GMT', $response->modified());
  112. }
  113. /**
  114. * Test that no exceptions are thrown for //index.php type urls.
  115. *
  116. * @return void
  117. */
  118. public function test404OnDoubleSlash() {
  119. $filter = new AssetDispatcher();
  120. $response = $this->getMock('CakeResponse', array('_sendHeader'));
  121. $request = new CakeRequest('//index.php');
  122. $event = new CakeEvent('Dispatcher.beforeRequest', $this, compact('request', 'response'));
  123. $this->assertNull($filter->beforeDispatch($event));
  124. $this->assertFalse($event->isStopped());
  125. }
  126. /**
  127. * Test that attempts to traverse directories are prevented.
  128. *
  129. * @return void
  130. */
  131. public function test404OnDoubleDot() {
  132. App::build(array(
  133. 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
  134. 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
  135. ), APP::RESET);
  136. $response = $this->getMock('CakeResponse', array('_sendHeader'));
  137. $request = new CakeRequest('theme/test_theme/../../../../../../VERSION.txt');
  138. $event = new CakeEvent('Dispatcher.beforeRequest', $this, compact('request', 'response'));
  139. $response->expects($this->never())->method('send');
  140. $filter = new AssetDispatcher();
  141. $this->assertNull($filter->beforeDispatch($event));
  142. $this->assertFalse($event->isStopped());
  143. }
  144. /**
  145. * Test that attempts to traverse directories with urlencoded paths fail.
  146. *
  147. * @return void
  148. */
  149. public function test404OnDoubleDotEncoded() {
  150. App::build(array(
  151. 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
  152. 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
  153. ), APP::RESET);
  154. $response = $this->getMock('CakeResponse', array('_sendHeader', 'send'));
  155. $request = new CakeRequest('theme/test_theme/%2e./%2e./%2e./%2e./%2e./%2e./VERSION.txt');
  156. $event = new CakeEvent('Dispatcher.beforeRequest', $this, compact('request', 'response'));
  157. $response->expects($this->never())->method('send');
  158. $filter = new AssetDispatcher();
  159. $this->assertNull($filter->beforeDispatch($event));
  160. $this->assertFalse($event->isStopped());
  161. }
  162. }