RoutingTest.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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'), [\OC::$server->getLogger()]);
  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. $container = new DIContainer('app1');
  95. $route = $this->mockRoute($container, $verb, $controllerName, $actionName, $requirements, $defaults);
  96. // router mock
  97. $router = $this->getMock("\OC\Route\Router", array('create'), [\OC::$server->getLogger()]);
  98. // we expect create to be called once:
  99. $router
  100. ->expects($this->once())
  101. ->method('create')
  102. ->with($this->equalTo('app1.' . $name), $this->equalTo($url))
  103. ->will($this->returnValue($route));
  104. // load route configuration
  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'), [\OC::$server->getLogger()]);
  118. // route mocks
  119. $container = new DIContainer('app1');
  120. $indexRoute = $this->mockRoute($container, 'GET', $controllerName, 'index');
  121. $showRoute = $this->mockRoute($container, 'GET', $controllerName, 'show');
  122. $createRoute = $this->mockRoute($container, 'POST', $controllerName, 'create');
  123. $updateRoute = $this->mockRoute($container, 'PUT', $controllerName, 'update');
  124. $destroyRoute = $this->mockRoute($container, 'DELETE', $controllerName, 'destroy');
  125. $urlWithParam = $url . '/{' . $paramName . '}';
  126. // we expect create to be called once:
  127. $router
  128. ->expects($this->at(0))
  129. ->method('create')
  130. ->with($this->equalTo('app1.' . $resourceName . '.index'), $this->equalTo($url))
  131. ->will($this->returnValue($indexRoute));
  132. $router
  133. ->expects($this->at(1))
  134. ->method('create')
  135. ->with($this->equalTo('app1.' . $resourceName . '.show'), $this->equalTo($urlWithParam))
  136. ->will($this->returnValue($showRoute));
  137. $router
  138. ->expects($this->at(2))
  139. ->method('create')
  140. ->with($this->equalTo('app1.' . $resourceName . '.create'), $this->equalTo($url))
  141. ->will($this->returnValue($createRoute));
  142. $router
  143. ->expects($this->at(3))
  144. ->method('create')
  145. ->with($this->equalTo('app1.' . $resourceName . '.update'), $this->equalTo($urlWithParam))
  146. ->will($this->returnValue($updateRoute));
  147. $router
  148. ->expects($this->at(4))
  149. ->method('create')
  150. ->with($this->equalTo('app1.' . $resourceName . '.destroy'), $this->equalTo($urlWithParam))
  151. ->will($this->returnValue($destroyRoute));
  152. // load route configuration
  153. $config = new RouteConfig($container, $router, $yaml);
  154. $config->register();
  155. }
  156. /**
  157. * @param DIContainer $container
  158. * @param string $verb
  159. * @param string $controllerName
  160. * @param string $actionName
  161. * @param array $requirements
  162. * @param array $defaults
  163. * @return \PHPUnit_Framework_MockObject_MockObject
  164. */
  165. private function mockRoute(
  166. DIContainer $container,
  167. $verb,
  168. $controllerName,
  169. $actionName,
  170. array $requirements=array(),
  171. array $defaults=array()
  172. ) {
  173. $route = $this->getMock("\OC\Route\Route", array('method', 'action', 'requirements', 'defaults'), array(), '', false);
  174. $route
  175. ->expects($this->exactly(1))
  176. ->method('method')
  177. ->with($this->equalTo($verb))
  178. ->will($this->returnValue($route));
  179. $route
  180. ->expects($this->exactly(1))
  181. ->method('action')
  182. ->with($this->equalTo(new RouteActionHandler($container, $controllerName, $actionName)))
  183. ->will($this->returnValue($route));
  184. if(count($requirements) > 0) {
  185. $route
  186. ->expects($this->exactly(1))
  187. ->method('requirements')
  188. ->with($this->equalTo($requirements))
  189. ->will($this->returnValue($route));
  190. }
  191. if (count($defaults) > 0) {
  192. $route
  193. ->expects($this->exactly(1))
  194. ->method('defaults')
  195. ->with($this->equalTo($defaults))
  196. ->will($this->returnValue($route));
  197. }
  198. return $route;
  199. }
  200. }
  201. /*
  202. #
  203. # sample routes.yaml for ownCloud
  204. #
  205. # the section simple describes one route
  206. routes:
  207. - name: folders#open
  208. url: /folders/{folderId}/open
  209. verb: GET
  210. # controller: name.split()[0]
  211. # action: name.split()[1]
  212. # for a resource following actions will be generated:
  213. # - index
  214. # - create
  215. # - show
  216. # - update
  217. # - destroy
  218. # - new
  219. resources:
  220. accounts:
  221. url: /accounts
  222. folders:
  223. url: /accounts/{accountId}/folders
  224. # actions can be used to define additional actions on the resource
  225. actions:
  226. - name: validate
  227. verb: GET
  228. on-collection: false
  229. * */