InflectedRouteTest.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  5. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  6. *
  7. * Licensed under The MIT License
  8. * For full copyright and license information, please see the LICENSE.txt
  9. * Redistributions of files must retain the above copyright notice.
  10. *
  11. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  12. * @link https://cakephp.org CakePHP(tm) Project
  13. * @since 3.2.1
  14. * @license https://opensource.org/licenses/mit-license.php MIT License
  15. */
  16. namespace Cake\Test\TestCase\Routing\Route;
  17. use Cake\Routing\Route\InflectedRoute;
  18. use Cake\Routing\Router;
  19. use Cake\TestSuite\TestCase;
  20. /**
  21. * Test case for InflectedRoute
  22. */
  23. class InflectedRouteTest extends TestCase
  24. {
  25. /**
  26. * test that routes match their pattern.
  27. */
  28. public function testMatchBasic(): void
  29. {
  30. $route = new InflectedRoute('/{controller}/{action}/{id}', ['plugin' => null]);
  31. $result = $route->match(['controller' => 'Posts', 'action' => 'my_view', 'plugin' => null]);
  32. $this->assertNull($result);
  33. $result = $route->match([
  34. 'plugin' => null,
  35. 'controller' => 'Posts',
  36. 'action' => 'my_view',
  37. 0,
  38. ]);
  39. $this->assertNull($result);
  40. $result = $route->match([
  41. 'plugin' => null,
  42. 'controller' => 'MyPosts',
  43. 'action' => 'my_view',
  44. 'id' => 1,
  45. ]);
  46. $this->assertSame('/my_posts/my_view/1', $result);
  47. $route = new InflectedRoute('/', ['controller' => 'Pages', 'action' => 'my_view', 'home']);
  48. $result = $route->match(['controller' => 'Pages', 'action' => 'my_view', 'home']);
  49. $this->assertSame('/', $result);
  50. $result = $route->match(['controller' => 'Pages', 'action' => 'display', 'about']);
  51. $this->assertNull($result);
  52. $route = new InflectedRoute('/blog/{action}', ['controller' => 'Posts']);
  53. $result = $route->match(['controller' => 'Posts', 'action' => 'my_view']);
  54. $this->assertSame('/blog/my_view', $result);
  55. $result = $route->match(['controller' => 'Posts', 'action' => 'my_view', '?' => ['id' => 2]]);
  56. $this->assertSame('/blog/my_view?id=2', $result);
  57. $result = $route->match(['controller' => 'Posts', 'action' => 'my_view', 1]);
  58. $this->assertNull($result);
  59. $route = new InflectedRoute('/foo/{controller}/{action}', ['action' => 'index']);
  60. $result = $route->match(['controller' => 'Posts', 'action' => 'my_view']);
  61. $this->assertSame('/foo/posts/my_view', $result);
  62. $route = new InflectedRoute('/{plugin}/{id}/*', ['controller' => 'Posts', 'action' => 'my_view']);
  63. $result = $route->match([
  64. 'plugin' => 'TestPlugin',
  65. 'controller' => 'Posts',
  66. 'action' => 'my_view',
  67. 'id' => '1',
  68. ]);
  69. $this->assertSame('/test_plugin/1/', $result);
  70. $result = $route->match([
  71. 'plugin' => 'TestPlugin',
  72. 'controller' => 'Posts',
  73. 'action' => 'my_view',
  74. 'id' => '1',
  75. '0',
  76. ]);
  77. $this->assertSame('/test_plugin/1/0', $result);
  78. $result = $route->match([
  79. 'plugin' => 'TestPlugin',
  80. 'controller' => 'Nodes',
  81. 'action' => 'my_view',
  82. 'id' => 1,
  83. ]);
  84. $this->assertNull($result);
  85. $result = $route->match([
  86. 'plugin' => 'TestPlugin',
  87. 'controller' => 'Posts',
  88. 'action' => 'edit',
  89. 'id' => 1,
  90. ]);
  91. $this->assertNull($result);
  92. $route = new InflectedRoute('/admin/subscriptions/{action}/*', [
  93. 'controller' => 'Subscribe', 'prefix' => 'Admin',
  94. ]);
  95. $result = $route->match([
  96. 'controller' => 'Subscribe',
  97. 'prefix' => 'Admin',
  98. 'action' => 'edit_admin_e',
  99. 1,
  100. ]);
  101. $expected = '/admin/subscriptions/edit_admin_e/1';
  102. $this->assertSame($expected, $result);
  103. $route = new InflectedRoute('/{controller}/{action}-{id}');
  104. $result = $route->match([
  105. 'controller' => 'MyPosts',
  106. 'action' => 'my_view',
  107. 'id' => 1,
  108. ]);
  109. $this->assertSame('/my_posts/my_view-1', $result);
  110. $route = new InflectedRoute('/{controller}/{action}/{slug}-{id}', [], ['id' => Router::ID]);
  111. $result = $route->match([
  112. 'controller' => 'MyPosts',
  113. 'action' => 'my_view',
  114. 'id' => '1',
  115. 'slug' => 'the-slug',
  116. ]);
  117. $this->assertSame('/my_posts/my_view/the-slug-1', $result);
  118. }
  119. /**
  120. * test the parse method of InflectedRoute.
  121. */
  122. public function testParse(): void
  123. {
  124. $route = new InflectedRoute('/{controller}/{action}/{id}', [], ['id' => Router::ID]);
  125. $route->compile();
  126. $result = $route->parse('/my_posts/my_view/1', 'GET');
  127. $this->assertSame('MyPosts', $result['controller']);
  128. $this->assertSame('my_view', $result['action']);
  129. $this->assertSame('1', $result['id']);
  130. $route = new InflectedRoute('/{controller}/{action}-{id}');
  131. $route->compile();
  132. $result = $route->parse('/my_posts/my_view-1', 'GET');
  133. $this->assertSame('MyPosts', $result['controller']);
  134. $this->assertSame('my_view', $result['action']);
  135. $this->assertSame('1', $result['id']);
  136. $route = new InflectedRoute('/{controller}/{action}/{slug}-{id}', [], ['id' => Router::ID]);
  137. $route->compile();
  138. $result = $route->parse('/my_posts/my_view/the-slug-1', 'GET');
  139. $this->assertSame('MyPosts', $result['controller']);
  140. $this->assertSame('my_view', $result['action']);
  141. $this->assertSame('1', $result['id']);
  142. $this->assertSame('the-slug', $result['slug']);
  143. $route = new InflectedRoute(
  144. '/admin/{controller}',
  145. ['prefix' => 'Admin', 'action' => 'index']
  146. );
  147. $route->compile();
  148. $result = $route->parse('/admin/', 'GET');
  149. $this->assertNull($result);
  150. $result = $route->parse('/admin/my_posts', 'GET');
  151. $this->assertSame('MyPosts', $result['controller']);
  152. $this->assertSame('index', $result['action']);
  153. $route = new InflectedRoute(
  154. '/media/search/*',
  155. ['controller' => 'Media', 'action' => 'search_it']
  156. );
  157. $result = $route->parse('/media/search', 'GET');
  158. $this->assertSame('Media', $result['controller']);
  159. $this->assertSame('search_it', $result['action']);
  160. $this->assertEquals([], $result['pass']);
  161. $result = $route->parse('/media/search/tv_shows', 'GET');
  162. $this->assertSame('Media', $result['controller']);
  163. $this->assertSame('search_it', $result['action']);
  164. $this->assertEquals(['tv_shows'], $result['pass']);
  165. }
  166. /**
  167. * Test that parse() checks methods.
  168. */
  169. public function testParseMethodMatch(): void
  170. {
  171. $route = new InflectedRoute('/{controller}/{action}', ['_method' => 'POST']);
  172. $this->assertNull($route->parse('/blog_posts/add_new', 'GET'));
  173. $result = $route->parse('/blog_posts/add_new', 'POST');
  174. $this->assertSame('BlogPosts', $result['controller']);
  175. $this->assertSame('add_new', $result['action']);
  176. }
  177. public function testMatchThenParse(): void
  178. {
  179. $route = new InflectedRoute('/plugin/{controller}/{action}', [
  180. 'plugin' => 'Vendor/PluginName',
  181. ]);
  182. $url = $route->match([
  183. 'plugin' => 'Vendor/PluginName',
  184. 'controller' => 'ControllerName',
  185. 'action' => 'action_name',
  186. ]);
  187. $expectedUrl = '/plugin/controller_name/action_name';
  188. $this->assertSame($expectedUrl, $url);
  189. $result = $route->parse($expectedUrl, 'GET');
  190. $this->assertSame('ControllerName', $result['controller']);
  191. $this->assertSame('action_name', $result['action']);
  192. $this->assertSame('Vendor/PluginName', $result['plugin']);
  193. }
  194. public function testMatchDoesNotCorruptDefaults(): void
  195. {
  196. $route = new InflectedRoute('/user_permissions/edit', ['controller' => 'UserPermissions', 'action' => 'edit']);
  197. $route->match(['controller' => 'UserPermissions', 'action' => 'edit'], []);
  198. $this->assertSame('UserPermissions', $route->defaults['controller']);
  199. $this->assertSame('edit', $route->defaults['action']);
  200. // Do the match again to ensure that state doesn't become incorrect.
  201. $route->match(['controller' => 'UserPermissions', 'action' => 'edit'], []);
  202. $this->assertSame('UserPermissions', $route->defaults['controller']);
  203. $this->assertSame('edit', $route->defaults['action']);
  204. }
  205. }