RoutingTest.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <?php
  2. namespace OC\AppFramework\Routing;
  3. use OC\AppFramework\DependencyInjection\DIContainer;
  4. use OC\AppFramework\routing\RouteConfig;
  5. class RoutingTest extends \Test\TestCase
  6. {
  7. public function testSimpleRoute()
  8. {
  9. $routes = array('routes' => array(
  10. array('name' => 'folders#open', 'url' => '/folders/{folderId}/open', 'verb' => 'GET')
  11. ));
  12. $this->assertSimpleRoute($routes, 'folders.open', 'GET', '/folders/{folderId}/open', 'FoldersController', 'open');
  13. }
  14. public function testSimpleRouteWithMissingVerb()
  15. {
  16. $routes = array('routes' => array(
  17. array('name' => 'folders#open', 'url' => '/folders/{folderId}/open')
  18. ));
  19. $this->assertSimpleRoute($routes, 'folders.open', 'GET', '/folders/{folderId}/open', 'FoldersController', 'open');
  20. }
  21. public function testSimpleRouteWithLowercaseVerb()
  22. {
  23. $routes = array('routes' => array(
  24. array('name' => 'folders#open', 'url' => '/folders/{folderId}/open', 'verb' => 'delete')
  25. ));
  26. $this->assertSimpleRoute($routes, 'folders.open', 'DELETE', '/folders/{folderId}/open', 'FoldersController', 'open');
  27. }
  28. public function testSimpleRouteWithRequirements()
  29. {
  30. $routes = array('routes' => array(
  31. array('name' => 'folders#open', 'url' => '/folders/{folderId}/open', 'verb' => 'delete', 'requirements' => array('something'))
  32. ));
  33. $this->assertSimpleRoute($routes, 'folders.open', 'DELETE', '/folders/{folderId}/open', 'FoldersController', 'open', array('something'));
  34. }
  35. public function testSimpleRouteWithDefaults()
  36. {
  37. $routes = array('routes' => array(
  38. array('name' => 'folders#open', 'url' => '/folders/{folderId}/open', 'verb' => 'delete', array(), 'defaults' => array('param' => 'foobar'))
  39. ));
  40. $this->assertSimpleRoute($routes, 'folders.open', 'DELETE', '/folders/{folderId}/open', 'FoldersController', 'open', array(), array('param' => 'foobar'));
  41. }
  42. public function testSimpleRouteWithPostfix()
  43. {
  44. $routes = array('routes' => array(
  45. array('name' => 'folders#open', 'url' => '/folders/{folderId}/open', 'verb' => 'delete', 'postfix' => '_something')
  46. ));
  47. $this->assertSimpleRoute($routes, 'folders.open', 'DELETE', '/folders/{folderId}/open', 'FoldersController', 'open', array(), array(), '_something');
  48. }
  49. /**
  50. * @expectedException \UnexpectedValueException
  51. */
  52. public function testSimpleRouteWithBrokenName()
  53. {
  54. $routes = array('routes' => array(
  55. array('name' => 'folders_open', 'url' => '/folders/{folderId}/open', 'verb' => 'delete')
  56. ));
  57. // router mock
  58. $router = $this->getMock("\OC\Route\Router", array('create'));
  59. // load route configuration
  60. $container = new DIContainer('app1');
  61. $config = new RouteConfig($container, $router, $routes);
  62. $config->register();
  63. }
  64. public function testSimpleRouteWithUnderScoreNames()
  65. {
  66. $routes = array('routes' => array(
  67. array('name' => 'admin_folders#open_current', 'url' => '/folders/{folderId}/open', 'verb' => 'delete')
  68. ));
  69. $this->assertSimpleRoute($routes, 'admin_folders.open_current', 'DELETE', '/folders/{folderId}/open', 'AdminFoldersController', 'openCurrent');
  70. }
  71. public function testResource()
  72. {
  73. $routes = array('resources' => array('account' => array('url' => '/accounts')));
  74. $this->assertResource($routes, 'account', '/accounts', 'AccountController', 'id');
  75. }
  76. public function testResourceWithUnderScoreName()
  77. {
  78. $routes = array('resources' => array('admin_accounts' => array('url' => '/admin/accounts')));
  79. $this->assertResource($routes, 'admin_accounts', '/admin/accounts', 'AdminAccountsController', 'id');
  80. }
  81. /**
  82. * @param string $name
  83. * @param string $verb
  84. * @param string $url
  85. * @param string $controllerName
  86. * @param string $actionName
  87. */
  88. private function assertSimpleRoute($routes, $name, $verb, $url, $controllerName, $actionName, array $requirements=array(), array $defaults=array(), $postfix='')
  89. {
  90. if ($postfix) {
  91. $name .= $postfix;
  92. }
  93. // route mocks
  94. $route = $this->mockRoute($verb, $controllerName, $actionName, $requirements, $defaults);
  95. // router mock
  96. $router = $this->getMock("\OC\Route\Router", array('create'));
  97. // we expect create to be called once:
  98. $router
  99. ->expects($this->once())
  100. ->method('create')
  101. ->with($this->equalTo('app1.' . $name), $this->equalTo($url))
  102. ->will($this->returnValue($route));
  103. // load route configuration
  104. $container = new DIContainer('app1');
  105. $config = new RouteConfig($container, $router, $routes);
  106. $config->register();
  107. }
  108. /**
  109. * @param string $resourceName
  110. * @param string $url
  111. * @param string $controllerName
  112. * @param string $paramName
  113. */
  114. private function assertResource($yaml, $resourceName, $url, $controllerName, $paramName)
  115. {
  116. // router mock
  117. $router = $this->getMock("\OC\Route\Router", array('create'));
  118. // route mocks
  119. $indexRoute = $this->mockRoute('GET', $controllerName, 'index');
  120. $showRoute = $this->mockRoute('GET', $controllerName, 'show');
  121. $createRoute = $this->mockRoute('POST', $controllerName, 'create');
  122. $updateRoute = $this->mockRoute('PUT', $controllerName, 'update');
  123. $destroyRoute = $this->mockRoute('DELETE', $controllerName, 'destroy');
  124. $urlWithParam = $url . '/{' . $paramName . '}';
  125. // we expect create to be called once:
  126. $router
  127. ->expects($this->at(0))
  128. ->method('create')
  129. ->with($this->equalTo('app1.' . $resourceName . '.index'), $this->equalTo($url))
  130. ->will($this->returnValue($indexRoute));
  131. $router
  132. ->expects($this->at(1))
  133. ->method('create')
  134. ->with($this->equalTo('app1.' . $resourceName . '.show'), $this->equalTo($urlWithParam))
  135. ->will($this->returnValue($showRoute));
  136. $router
  137. ->expects($this->at(2))
  138. ->method('create')
  139. ->with($this->equalTo('app1.' . $resourceName . '.create'), $this->equalTo($url))
  140. ->will($this->returnValue($createRoute));
  141. $router
  142. ->expects($this->at(3))
  143. ->method('create')
  144. ->with($this->equalTo('app1.' . $resourceName . '.update'), $this->equalTo($urlWithParam))
  145. ->will($this->returnValue($updateRoute));
  146. $router
  147. ->expects($this->at(4))
  148. ->method('create')
  149. ->with($this->equalTo('app1.' . $resourceName . '.destroy'), $this->equalTo($urlWithParam))
  150. ->will($this->returnValue($destroyRoute));
  151. // load route configuration
  152. $container = new DIContainer('app1');
  153. $config = new RouteConfig($container, $router, $yaml);
  154. $config->register();
  155. }
  156. /**
  157. * @param string $verb
  158. * @param string $controllerName
  159. * @param string $actionName
  160. * @return \PHPUnit_Framework_MockObject_MockObject
  161. */
  162. private function mockRoute($verb, $controllerName, $actionName, array $requirements=array(), array $defaults=array())
  163. {
  164. $container = new DIContainer('app1');
  165. $route = $this->getMock("\OC\Route\Route", array('method', 'action', 'requirements', 'defaults'), array(), '', false);
  166. $route
  167. ->expects($this->exactly(1))
  168. ->method('method')
  169. ->with($this->equalTo($verb))
  170. ->will($this->returnValue($route));
  171. $route
  172. ->expects($this->exactly(1))
  173. ->method('action')
  174. ->with($this->equalTo(new RouteActionHandler($container, $controllerName, $actionName)))
  175. ->will($this->returnValue($route));
  176. if(count($requirements) > 0) {
  177. $route
  178. ->expects($this->exactly(1))
  179. ->method('requirements')
  180. ->with($this->equalTo($requirements))
  181. ->will($this->returnValue($route));
  182. }
  183. if (count($defaults) > 0) {
  184. $route
  185. ->expects($this->exactly(1))
  186. ->method('defaults')
  187. ->with($this->equalTo($defaults))
  188. ->will($this->returnValue($route));
  189. }
  190. return $route;
  191. }
  192. }
  193. /*
  194. #
  195. # sample routes.yaml for ownCloud
  196. #
  197. # the section simple describes one route
  198. routes:
  199. - name: folders#open
  200. url: /folders/{folderId}/open
  201. verb: GET
  202. # controller: name.split()[0]
  203. # action: name.split()[1]
  204. # for a resource following actions will be generated:
  205. # - index
  206. # - create
  207. # - show
  208. # - update
  209. # - destroy
  210. # - new
  211. resources:
  212. accounts:
  213. url: /accounts
  214. folders:
  215. url: /accounts/{accountId}/folders
  216. # actions can be used to define additional actions on the resource
  217. actions:
  218. - name: validate
  219. verb: GET
  220. on-collection: false
  221. * */