RouterTest.php 80 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859
  1. <?php
  2. /**
  3. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  12. * @since 1.2.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Routing;
  16. use Cake\Core\App;
  17. use Cake\Core\Configure;
  18. use Cake\Core\Plugin;
  19. use Cake\Network\Request;
  20. use Cake\Routing\RouteCollection;
  21. use Cake\Routing\Router;
  22. use Cake\Routing\Route\Route;
  23. use Cake\TestSuite\TestCase;
  24. use TestPlugin\Routing\Route\TestRoute;
  25. /**
  26. * RouterTest class
  27. *
  28. */
  29. class RouterTest extends TestCase {
  30. /**
  31. * setUp method
  32. *
  33. * @return void
  34. */
  35. public function setUp() {
  36. parent::setUp();
  37. Configure::write('Routing', array('admin' => null, 'prefixes' => []));
  38. Router::fullbaseUrl('');
  39. Configure::write('App.fullBaseUrl', 'http://localhost');
  40. }
  41. /**
  42. * tearDown method
  43. *
  44. * @return void
  45. */
  46. public function tearDown() {
  47. parent::tearDown();
  48. Plugin::unload();
  49. Router::fullBaseUrl('');
  50. Configure::write('App.fullBaseUrl', 'http://localhost');
  51. Router::reload();
  52. }
  53. /**
  54. * testFullBaseUrl method
  55. *
  56. * @return void
  57. */
  58. public function testbaseUrl() {
  59. $this->assertRegExp('/^http(s)?:\/\//', Router::url('/', true));
  60. $this->assertRegExp('/^http(s)?:\/\//', Router::url(null, true));
  61. $this->assertRegExp('/^http(s)?:\/\//', Router::url(array('_full' => true)));
  62. }
  63. /**
  64. * Tests that the base URL can be changed at runtime.
  65. *
  66. * @return void
  67. */
  68. public function testfullBaseURL() {
  69. Router::fullbaseUrl('http://example.com');
  70. $this->assertEquals('http://example.com/', Router::url('/', true));
  71. $this->assertEquals('http://example.com', Configure::read('App.fullBaseUrl'));
  72. Router::fullBaseUrl('https://example.com');
  73. $this->assertEquals('https://example.com/', Router::url('/', true));
  74. $this->assertEquals('https://example.com', Configure::read('App.fullBaseUrl'));
  75. }
  76. /**
  77. * Test that Router uses App.base to build URL's when there are no stored
  78. * request objects.
  79. *
  80. * @return void
  81. */
  82. public function testBaseUrlWithBasePath() {
  83. Configure::write('App.base', '/cakephp');
  84. Router::fullBaseUrl('http://example.com');
  85. $this->assertEquals('http://example.com/cakephp/tasks', Router::url('/tasks', true));
  86. }
  87. /**
  88. * testRouteDefaultParams method
  89. *
  90. * @return void
  91. */
  92. public function testRouteDefaultParams() {
  93. Router::connect('/:controller', array('controller' => 'posts'));
  94. $this->assertEquals(Router::url(array('action' => 'index')), '/');
  95. }
  96. /**
  97. * testMapResources method
  98. *
  99. * @return void
  100. */
  101. public function testMapResources() {
  102. $resources = Router::mapResources('Posts');
  103. $_SERVER['REQUEST_METHOD'] = 'GET';
  104. $expected = [
  105. 'pass' => [],
  106. 'plugin' => null,
  107. 'controller' => 'Posts',
  108. 'action' => 'index',
  109. '[method]' => 'GET',
  110. '_ext' => null
  111. ];
  112. $result = Router::parse('/posts');
  113. $this->assertEquals($expected, $result);
  114. $this->assertEquals($resources, ['posts']);
  115. $_SERVER['REQUEST_METHOD'] = 'GET';
  116. $expected = [
  117. 'pass' => ['13'],
  118. 'plugin' => null,
  119. 'controller' => 'Posts',
  120. 'action' => 'view',
  121. 'id' => '13',
  122. '[method]' => 'GET',
  123. '_ext' => null
  124. ];
  125. $result = Router::parse('/posts/13');
  126. $this->assertEquals($expected, $result);
  127. $_SERVER['REQUEST_METHOD'] = 'POST';
  128. $expected = [
  129. 'pass' => [],
  130. 'plugin' => null,
  131. 'controller' => 'Posts',
  132. 'action' => 'add',
  133. '[method]' => 'POST',
  134. '_ext' => null
  135. ];
  136. $result = Router::parse('/posts');
  137. $this->assertEquals($expected, $result);
  138. $_SERVER['REQUEST_METHOD'] = 'PUT';
  139. $expected = [
  140. 'pass' => ['13'],
  141. 'plugin' => null,
  142. 'controller' => 'Posts',
  143. 'action' => 'edit',
  144. 'id' => '13',
  145. '[method]' => 'PUT',
  146. '_ext' => null
  147. ];
  148. $result = Router::parse('/posts/13');
  149. $this->assertEquals($expected, $result);
  150. $expected = [
  151. 'pass' => ['475acc39-a328-44d3-95fb-015000000000'],
  152. 'plugin' => null,
  153. 'controller' => 'Posts',
  154. 'action' => 'edit',
  155. 'id' => '475acc39-a328-44d3-95fb-015000000000',
  156. '[method]' => 'PUT',
  157. '_ext' => null
  158. ];
  159. $result = Router::parse('/posts/475acc39-a328-44d3-95fb-015000000000');
  160. $this->assertEquals($expected, $result);
  161. $_SERVER['REQUEST_METHOD'] = 'DELETE';
  162. $expected = [
  163. 'pass' => ['13'],
  164. 'plugin' => null,
  165. 'controller' => 'Posts',
  166. 'action' => 'delete',
  167. 'id' => '13',
  168. '[method]' => 'DELETE',
  169. '_ext' => null
  170. ];
  171. $result = Router::parse('/posts/13');
  172. $this->assertEquals($expected, $result);
  173. $_SERVER['REQUEST_METHOD'] = 'GET';
  174. $result = Router::parse('/posts/add');
  175. $this->assertSame([], $result);
  176. Router::reload();
  177. $result = Router::mapResources('Posts', ['id' => '[a-z0-9_]+']);
  178. $this->assertEquals(['posts'], $result);
  179. $_SERVER['REQUEST_METHOD'] = 'GET';
  180. $expected = [
  181. 'pass' => ['add'],
  182. 'plugin' => null,
  183. 'controller' => 'Posts',
  184. 'action' => 'view',
  185. 'id' => 'add',
  186. '[method]' => 'GET',
  187. '_ext' => null
  188. ];
  189. $result = Router::parse('/posts/add');
  190. $this->assertEquals($expected, $result);
  191. $_SERVER['REQUEST_METHOD'] = 'PUT';
  192. $expected = [
  193. 'pass' => ['name'],
  194. 'plugin' => null,
  195. 'controller' => 'Posts',
  196. 'action' => 'edit',
  197. 'id' => 'name',
  198. '[method]' => 'PUT',
  199. '_ext' => null
  200. ];
  201. $result = Router::parse('/posts/name');
  202. $this->assertEquals($expected, $result);
  203. }
  204. /**
  205. * testMapResources with plugin controllers.
  206. *
  207. * @return void
  208. */
  209. public function testPluginMapResources() {
  210. $resources = Router::mapResources('TestPlugin.TestPlugin');
  211. $_SERVER['REQUEST_METHOD'] = 'GET';
  212. $result = Router::parse('/test_plugin/test_plugin');
  213. $expected = array(
  214. 'pass' => [],
  215. 'plugin' => 'TestPlugin',
  216. 'controller' => 'TestPlugin',
  217. 'action' => 'index',
  218. '[method]' => 'GET',
  219. '_ext' => null
  220. );
  221. $this->assertEquals($expected, $result);
  222. $this->assertEquals(array('test_plugin'), $resources);
  223. $_SERVER['REQUEST_METHOD'] = 'GET';
  224. $result = Router::parse('/test_plugin/test_plugin/13');
  225. $expected = array(
  226. 'pass' => array('13'),
  227. 'plugin' => 'TestPlugin',
  228. 'controller' => 'TestPlugin',
  229. 'action' => 'view',
  230. 'id' => '13',
  231. '[method]' => 'GET',
  232. '_ext' => null
  233. );
  234. $this->assertEquals($expected, $result);
  235. }
  236. /**
  237. * Test mapResources with a prefix.
  238. *
  239. * @return void
  240. */
  241. public function testMapResourcesWithPrefix() {
  242. $resources = Router::mapResources('Posts', array('prefix' => 'api'));
  243. $this->assertEquals(array('posts'), $resources);
  244. $_SERVER['REQUEST_METHOD'] = 'GET';
  245. $result = Router::parse('/api/posts');
  246. $expected = array(
  247. 'plugin' => null,
  248. 'controller' => 'Posts',
  249. 'action' => 'index',
  250. 'pass' => [],
  251. 'prefix' => 'api',
  252. '[method]' => 'GET',
  253. '_ext' => null
  254. );
  255. $this->assertEquals($expected, $result);
  256. }
  257. /**
  258. * Test mapResources with a default extension.
  259. *
  260. * @return void
  261. */
  262. public function testMapResourcesWithExtension() {
  263. $resources = Router::mapResources('Posts', ['_ext' => 'json']);
  264. $this->assertEquals(['posts'], $resources);
  265. $_SERVER['REQUEST_METHOD'] = 'GET';
  266. Router::parseExtensions(['json', 'xml'], false);
  267. $expected = array(
  268. 'plugin' => null,
  269. 'controller' => 'Posts',
  270. 'action' => 'index',
  271. 'pass' => [],
  272. '[method]' => 'GET',
  273. '_ext' => 'json',
  274. );
  275. $result = Router::parse('/posts');
  276. $this->assertEquals($expected, $result);
  277. $result = Router::parse('/posts.json');
  278. $this->assertEquals($expected, $result);
  279. $expected['_ext'] = 'xml';
  280. $result = Router::parse('/posts.xml');
  281. $this->assertEquals($expected, $result);
  282. }
  283. /**
  284. * testMapResources with custom connectOptions
  285. */
  286. public function testMapResourcesConnectOptions() {
  287. Plugin::load('TestPlugin');
  288. $collection = new RouteCollection();
  289. Router::setRouteCollection($collection);
  290. Router::mapResources('Posts', array(
  291. 'connectOptions' => array(
  292. 'routeClass' => 'TestPlugin.TestRoute',
  293. 'foo' => '^(bar)$',
  294. ),
  295. ));
  296. $route = $collection->get(0);
  297. $this->assertInstanceOf('TestPlugin\Routing\Route\TestRoute', $route);
  298. $this->assertEquals('^(bar)$', $route->options['foo']);
  299. }
  300. /**
  301. * Test that RouterCollection::all() gets the list of all connected routes.
  302. *
  303. * @return void
  304. */
  305. public function testRouteCollectionRoutes() {
  306. $collection = new RouteCollection();
  307. Router::setRouteCollection($collection);
  308. Router::mapResources('Posts');
  309. $routes = $collection->all();
  310. $this->assertEquals(count($routes), 6);
  311. $this->assertInstanceOf('Cake\Routing\Route\Route', $routes[0]);
  312. $this->assertEquals($collection->get(0), $routes[0]);
  313. $this->assertInstanceOf('Cake\Routing\Route\Route', $routes[5]);
  314. $this->assertEquals($collection->get(5), $routes[5]);
  315. }
  316. /**
  317. * Test mapResources with a plugin and prefix.
  318. *
  319. * @return void
  320. */
  321. public function testPluginMapResourcesWithPrefix() {
  322. $resources = Router::mapResources('TestPlugin.TestPlugin', array('prefix' => 'api'));
  323. $_SERVER['REQUEST_METHOD'] = 'GET';
  324. $result = Router::parse('/api/test_plugin/test_plugin');
  325. $expected = array(
  326. 'pass' => [],
  327. 'plugin' => 'TestPlugin',
  328. 'controller' => 'TestPlugin',
  329. 'prefix' => 'api',
  330. 'action' => 'index',
  331. '[method]' => 'GET',
  332. '_ext' => null
  333. );
  334. $this->assertEquals($expected, $result);
  335. $this->assertEquals(array('test_plugin'), $resources);
  336. $resources = Router::mapResources('Posts', array('prefix' => 'api'));
  337. $_SERVER['REQUEST_METHOD'] = 'GET';
  338. $result = Router::parse('/api/posts');
  339. $expected = array(
  340. 'pass' => [],
  341. 'plugin' => null,
  342. 'controller' => 'Posts',
  343. 'action' => 'index',
  344. '[method]' => 'GET',
  345. 'prefix' => 'api',
  346. '_ext' => null
  347. );
  348. $this->assertEquals($expected, $result);
  349. }
  350. /**
  351. * testMultipleResourceRoute method
  352. *
  353. * @return void
  354. */
  355. public function testMultipleResourceRoute() {
  356. Router::connect('/:controller', array('action' => 'index', '[method]' => array('GET', 'POST')));
  357. $_SERVER['REQUEST_METHOD'] = 'GET';
  358. $result = Router::parse('/posts');
  359. $expected = array(
  360. 'pass' => [],
  361. 'plugin' => null,
  362. 'controller' => 'posts',
  363. 'action' => 'index',
  364. '[method]' => array('GET', 'POST')
  365. );
  366. $this->assertEquals($expected, $result);
  367. $_SERVER['REQUEST_METHOD'] = 'POST';
  368. $result = Router::parse('/posts');
  369. $expected = array(
  370. 'pass' => [],
  371. 'plugin' => null,
  372. 'controller' => 'posts',
  373. 'action' => 'index',
  374. '[method]' => array('GET', 'POST')
  375. );
  376. $this->assertEquals($expected, $result);
  377. }
  378. /**
  379. * testGenerateUrlResourceRoute method
  380. *
  381. * @return void
  382. */
  383. public function testGenerateUrlResourceRoute() {
  384. Router::mapResources('Posts');
  385. $result = Router::url([
  386. 'controller' => 'Posts',
  387. 'action' => 'index',
  388. '[method]' => 'GET'
  389. ]);
  390. $expected = '/posts';
  391. $this->assertEquals($expected, $result);
  392. $result = Router::url([
  393. 'controller' => 'Posts',
  394. 'action' => 'view',
  395. '[method]' => 'GET',
  396. 'id' => 10
  397. ]);
  398. $expected = '/posts/10';
  399. $this->assertEquals($expected, $result);
  400. $result = Router::url(['controller' => 'Posts', 'action' => 'add', '[method]' => 'POST']);
  401. $expected = '/posts';
  402. $this->assertEquals($expected, $result);
  403. $result = Router::url(['controller' => 'Posts', 'action' => 'edit', '[method]' => 'PUT', 'id' => 10]);
  404. $expected = '/posts/10';
  405. $this->assertEquals($expected, $result);
  406. $result = Router::url(['controller' => 'Posts', 'action' => 'delete', '[method]' => 'DELETE', 'id' => 10]);
  407. $expected = '/posts/10';
  408. $this->assertEquals($expected, $result);
  409. $result = Router::url(['controller' => 'Posts', 'action' => 'edit', '[method]' => 'POST', 'id' => 10]);
  410. $expected = '/posts/10';
  411. $this->assertEquals($expected, $result);
  412. }
  413. /**
  414. * testUrlNormalization method
  415. *
  416. * @return void
  417. */
  418. public function testUrlNormalization() {
  419. Router::connect('/:controller/:action');
  420. $expected = '/users/logout';
  421. $result = Router::normalize('/users/logout/');
  422. $this->assertEquals($expected, $result);
  423. $result = Router::normalize('//users//logout//');
  424. $this->assertEquals($expected, $result);
  425. $result = Router::normalize('users/logout');
  426. $this->assertEquals($expected, $result);
  427. $result = Router::normalize(array('controller' => 'users', 'action' => 'logout'));
  428. $this->assertEquals($expected, $result);
  429. $result = Router::normalize('/');
  430. $this->assertEquals('/', $result);
  431. $result = Router::normalize('http://google.com/');
  432. $this->assertEquals('http://google.com/', $result);
  433. $result = Router::normalize('http://google.com//');
  434. $this->assertEquals('http://google.com//', $result);
  435. $result = Router::normalize('/users/login/scope://foo');
  436. $this->assertEquals('/users/login/scope:/foo', $result);
  437. $result = Router::normalize('/recipe/recipes/add');
  438. $this->assertEquals('/recipe/recipes/add', $result);
  439. $request = new Request();
  440. $request->base = '/us';
  441. Router::setRequestInfo($request);
  442. $result = Router::normalize('/us/users/logout/');
  443. $this->assertEquals('/users/logout', $result);
  444. Router::reload();
  445. $request = new Request();
  446. $request->base = '/cake_12';
  447. Router::setRequestInfo($request);
  448. $result = Router::normalize('/cake_12/users/logout/');
  449. $this->assertEquals('/users/logout', $result);
  450. Router::reload();
  451. $_back = Configure::read('App.fullBaseUrl');
  452. Configure::write('App.fullBaseUrl', '/');
  453. $request = new Request();
  454. $request->base = '/';
  455. Router::setRequestInfo($request);
  456. $result = Router::normalize('users/login');
  457. $this->assertEquals('/users/login', $result);
  458. Configure::write('App.fullBaseUrl', $_back);
  459. Router::reload();
  460. $request = new Request();
  461. $request->base = 'beer';
  462. Router::setRequestInfo($request);
  463. $result = Router::normalize('beer/admin/beers_tags/add');
  464. $this->assertEquals('/admin/beers_tags/add', $result);
  465. $result = Router::normalize('/admin/beers_tags/add');
  466. $this->assertEquals('/admin/beers_tags/add', $result);
  467. }
  468. /**
  469. * Test generating urls with base paths.
  470. *
  471. * @return void
  472. */
  473. public function testUrlGenerationWithBasePath() {
  474. Router::connect('/:controller/:action/*');
  475. $request = new Request();
  476. $request->addParams([
  477. 'action' => 'index',
  478. 'plugin' => null,
  479. 'controller' => 'subscribe',
  480. ]);
  481. $request->base = '/magazine';
  482. $request->here = '/magazine/';
  483. $request->webroot = '/magazine/';
  484. Router::pushRequest($request);
  485. $result = Router::url();
  486. $this->assertEquals('/magazine/', $result);
  487. $result = Router::url('/');
  488. $this->assertEquals('/magazine/', $result);
  489. $result = Router::url('/articles/');
  490. $this->assertEquals('/magazine/articles/', $result);
  491. $result = Router::url('/articles/view');
  492. $this->assertEquals('/magazine/articles/view', $result);
  493. $result = Router::url(['controller' => 'articles', 'action' => 'view', 1]);
  494. $this->assertEquals('/magazine/articles/view/1', $result);
  495. }
  496. /**
  497. * Test that catch all routes work with a variety of falsey inputs.
  498. *
  499. * @return void
  500. */
  501. public function testUrlCatchAllRoute() {
  502. Router::connect('/*', array('controller' => 'categories', 'action' => 'index'));
  503. $result = Router::url(array('controller' => 'categories', 'action' => 'index', '0'));
  504. $this->assertEquals('/0', $result);
  505. $expected = [
  506. 'plugin' => null,
  507. 'controller' => 'categories',
  508. 'action' => 'index',
  509. 'pass' => ['0'],
  510. ];
  511. $result = Router::parse('/0');
  512. $this->assertEquals($expected, $result);
  513. $result = Router::parse('0');
  514. $this->assertEquals($expected, $result);
  515. }
  516. /**
  517. * test generation of basic urls.
  518. *
  519. * @return void
  520. */
  521. public function testUrlGenerationBasic() {
  522. extract(Router::getNamedExpressions());
  523. Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
  524. $out = Router::url(array('controller' => 'pages', 'action' => 'display', 'home'));
  525. $this->assertEquals('/', $out);
  526. Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
  527. $result = Router::url(array('controller' => 'pages', 'action' => 'display', 'about'));
  528. $expected = '/pages/about';
  529. $this->assertEquals($expected, $result);
  530. Router::reload();
  531. Router::connect('/:plugin/:id/*', array('controller' => 'posts', 'action' => 'view'), array('id' => $ID));
  532. Router::parse('/');
  533. $result = Router::url(array(
  534. 'plugin' => 'cake_plugin',
  535. 'controller' => 'posts',
  536. 'action' => 'view',
  537. 'id' => '1'
  538. ));
  539. $expected = '/cake_plugin/1';
  540. $this->assertEquals($expected, $result);
  541. $result = Router::url(array(
  542. 'plugin' => 'cake_plugin',
  543. 'controller' => 'posts',
  544. 'action' => 'view',
  545. 'id' => '1',
  546. '0'
  547. ));
  548. $expected = '/cake_plugin/1/0';
  549. $this->assertEquals($expected, $result);
  550. Router::reload();
  551. Router::connect('/:controller/:action/:id', [], array('id' => $ID));
  552. Router::parse('/');
  553. $result = Router::url(array('controller' => 'posts', 'action' => 'view', 'id' => '1'));
  554. $expected = '/posts/view/1';
  555. $this->assertEquals($expected, $result);
  556. Router::reload();
  557. Router::connect('/:controller/:id', array('action' => 'view'));
  558. Router::parse('/');
  559. $result = Router::url(array('controller' => 'posts', 'action' => 'view', 'id' => '1'));
  560. $expected = '/posts/1';
  561. $this->assertEquals($expected, $result);
  562. Router::connect('/view/*', array('controller' => 'posts', 'action' => 'view'));
  563. Router::promote();
  564. $result = Router::url(array('controller' => 'posts', 'action' => 'view', '1'));
  565. $expected = '/view/1';
  566. $this->assertEquals($expected, $result);
  567. Router::reload();
  568. Router::connect('/:controller/:action');
  569. Router::parse('/');
  570. $request = new Request();
  571. $request->addParams(array(
  572. 'action' => 'index',
  573. 'plugin' => null,
  574. 'controller' => 'users',
  575. ));
  576. $request->base = '/';
  577. $request->here = '/';
  578. $request->webroot = '/';
  579. Router::setRequestInfo($request);
  580. $result = Router::url(array('action' => 'login'));
  581. $expected = '/users/login';
  582. $this->assertEquals($expected, $result);
  583. Router::reload();
  584. Router::connect('/contact/:action', array('plugin' => 'contact', 'controller' => 'contact'));
  585. Router::parse('/');
  586. $result = Router::url(array(
  587. 'plugin' => 'contact',
  588. 'controller' => 'contact',
  589. 'action' => 'me'
  590. ));
  591. $expected = '/contact/me';
  592. $this->assertEquals($expected, $result);
  593. Router::reload();
  594. Router::connect('/:controller', array('action' => 'index'));
  595. $request = new Request();
  596. $request->addParams(array(
  597. 'action' => 'index',
  598. 'plugin' => 'myplugin',
  599. 'controller' => 'mycontroller',
  600. ));
  601. $request->base = '/';
  602. $request->here = '/';
  603. $request->webroot = '/';
  604. Router::setRequestInfo($request);
  605. $result = Router::url(array('plugin' => null, 'controller' => 'myothercontroller'));
  606. $expected = '/myothercontroller';
  607. $this->assertEquals($expected, $result);
  608. }
  609. /**
  610. * Test that generated names for routes are case-insensitive.
  611. *
  612. * @return void
  613. */
  614. public function testRouteNameCasing() {
  615. Router::connect('/articles/:id', ['controller' => 'Articles', 'action' => 'view']);
  616. Router::connect('/:controller/:action/*', [], ['routeClass' => 'InflectedRoute']);
  617. $result = Router::url(['controller' => 'Articles', 'action' => 'view', 'id' => 10]);
  618. $expected = '/articles/10';
  619. $this->assertEquals($expected, $result);
  620. }
  621. /**
  622. * Test generation of routes with query string parameters.
  623. *
  624. * @return void
  625. */
  626. public function testUrlGenerationWithQueryStrings() {
  627. Router::connect('/:controller/:action/*');
  628. $result = Router::url(array(
  629. 'controller' => 'posts',
  630. '0',
  631. '?' => array('var' => 'test', 'var2' => 'test2')
  632. ));
  633. $expected = '/posts/index/0?var=test&var2=test2';
  634. $this->assertEquals($expected, $result);
  635. $result = Router::url(array('controller' => 'posts', '0', '?' => array('var' => null)));
  636. $this->assertEquals('/posts/index/0', $result);
  637. $result = Router::url(array(
  638. 'controller' => 'posts',
  639. '0',
  640. '?' => array(
  641. 'var' => 'test',
  642. 'var2' => 'test2'
  643. ),
  644. '#' => 'unencoded string %'
  645. ));
  646. $expected = '/posts/index/0?var=test&var2=test2#unencoded string %';
  647. $this->assertEquals($expected, $result);
  648. }
  649. /**
  650. * test that regex validation of keyed route params is working.
  651. *
  652. * @return void
  653. */
  654. public function testUrlGenerationWithRegexQualifiedParams() {
  655. Router::connect(
  656. ':language/galleries',
  657. array('controller' => 'galleries', 'action' => 'index'),
  658. array('language' => '[a-z]{3}')
  659. );
  660. Router::connect(
  661. '/:language/:admin/:controller/:action/*',
  662. array('admin' => 'admin'),
  663. array('language' => '[a-z]{3}', 'admin' => 'admin')
  664. );
  665. Router::connect('/:language/:controller/:action/*',
  666. [],
  667. array('language' => '[a-z]{3}')
  668. );
  669. $result = Router::url(array('admin' => false, 'language' => 'dan', 'action' => 'index', 'controller' => 'galleries'));
  670. $expected = '/dan/galleries';
  671. $this->assertEquals($expected, $result);
  672. $result = Router::url(array('admin' => false, 'language' => 'eng', 'action' => 'index', 'controller' => 'galleries'));
  673. $expected = '/eng/galleries';
  674. $this->assertEquals($expected, $result);
  675. Router::reload();
  676. Router::connect('/:language/pages',
  677. array('controller' => 'pages', 'action' => 'index'),
  678. array('language' => '[a-z]{3}')
  679. );
  680. Router::connect('/:language/:controller/:action/*', [], array('language' => '[a-z]{3}'));
  681. $result = Router::url(array('language' => 'eng', 'action' => 'index', 'controller' => 'pages'));
  682. $expected = '/eng/pages';
  683. $this->assertEquals($expected, $result);
  684. $result = Router::url(array('language' => 'eng', 'controller' => 'pages'));
  685. $this->assertEquals($expected, $result);
  686. $result = Router::url(array('language' => 'eng', 'controller' => 'pages', 'action' => 'add'));
  687. $expected = '/eng/pages/add';
  688. $this->assertEquals($expected, $result);
  689. Router::reload();
  690. Router::connect('/forestillinger/:month/:year/*',
  691. array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar'),
  692. array('month' => '0[1-9]|1[012]', 'year' => '[12][0-9]{3}')
  693. );
  694. Router::parse('/');
  695. $result = Router::url(array(
  696. 'plugin' => 'shows',
  697. 'controller' => 'shows',
  698. 'action' => 'calendar',
  699. 'month' => 10,
  700. 'year' => 2007,
  701. 'min-forestilling'
  702. ));
  703. $expected = '/forestillinger/10/2007/min-forestilling';
  704. $this->assertEquals($expected, $result);
  705. Router::reload();
  706. Router::connect('/kalender/:month/:year/*',
  707. array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar'),
  708. array('month' => '0[1-9]|1[012]', 'year' => '[12][0-9]{3}')
  709. );
  710. Router::connect('/kalender/*', array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar'));
  711. Router::parse('/');
  712. $result = Router::url(array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar', 'min-forestilling'));
  713. $expected = '/kalender/min-forestilling';
  714. $this->assertEquals($expected, $result);
  715. $result = Router::url(array(
  716. 'plugin' => 'shows',
  717. 'controller' => 'shows',
  718. 'action' => 'calendar',
  719. 'year' => 2007,
  720. 'month' => 10,
  721. 'min-forestilling'
  722. ));
  723. $expected = '/kalender/10/2007/min-forestilling';
  724. $this->assertEquals($expected, $result);
  725. }
  726. /**
  727. * Test URL generation with an admin prefix
  728. *
  729. * @return void
  730. */
  731. public function testUrlGenerationWithPrefix() {
  732. Configure::write('Routing.prefixes', array('admin'));
  733. Router::reload();
  734. Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
  735. Router::connect('/reset/*', array('admin' => true, 'controller' => 'users', 'action' => 'reset'));
  736. Router::connect('/tests', array('controller' => 'tests', 'action' => 'index'));
  737. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  738. Router::parseExtensions('rss', false);
  739. $request = new Request();
  740. $request->addParams(array(
  741. 'controller' => 'registrations',
  742. 'action' => 'admin_index',
  743. 'plugin' => null,
  744. 'prefix' => 'admin',
  745. '_ext' => 'html'
  746. ));
  747. $request->base = '';
  748. $request->here = '/admin/registrations/index';
  749. $request->webroot = '/';
  750. Router::setRequestInfo($request);
  751. $result = Router::url([]);
  752. $expected = '/admin/registrations/index';
  753. $this->assertEquals($expected, $result);
  754. Router::reload();
  755. Router::connect('/admin/subscriptions/:action/*', array('controller' => 'subscribe', 'prefix' => 'admin'));
  756. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  757. Router::parse('/');
  758. $request = new Request();
  759. $request->addParams(array(
  760. 'action' => 'index',
  761. 'plugin' => null,
  762. 'controller' => 'subscribe',
  763. 'prefix' => 'admin',
  764. ));
  765. $request->base = '/magazine';
  766. $request->here = '/magazine/admin/subscriptions/edit/1';
  767. $request->webroot = '/magazine/';
  768. Router::setRequestInfo($request);
  769. $result = Router::url(array('action' => 'edit', 1));
  770. $expected = '/magazine/admin/subscriptions/edit/1';
  771. $this->assertEquals($expected, $result);
  772. $result = Router::url(array('prefix' => 'admin', 'controller' => 'users', 'action' => 'login'));
  773. $expected = '/magazine/admin/users/login';
  774. $this->assertEquals($expected, $result);
  775. Router::reload();
  776. $request = new Request();
  777. $request->addParams(array(
  778. 'prefix' => 'admin',
  779. 'action' => 'index',
  780. 'plugin' => null,
  781. 'controller' => 'users',
  782. ));
  783. $request->base = '/';
  784. $request->here = '/';
  785. $request->webroot = '/';
  786. Router::setRequestInfo($request);
  787. Router::connect('/page/*', array('controller' => 'pages', 'action' => 'view', 'prefix' => 'admin'));
  788. Router::parse('/');
  789. $result = Router::url(array('prefix' => 'admin', 'controller' => 'pages', 'action' => 'view', 'my-page'));
  790. $expected = '/page/my-page';
  791. $this->assertEquals($expected, $result);
  792. Router::reload();
  793. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  794. $request = new Request();
  795. $request->addParams(array(
  796. 'plugin' => null,
  797. 'controller' => 'pages',
  798. 'action' => 'add',
  799. 'prefix' => 'admin'
  800. ));
  801. $request->base = '';
  802. $request->here = '/admin/pages/add';
  803. $request->webroot = '/';
  804. Router::setRequestInfo($request);
  805. Router::parse('/');
  806. $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'add', 'id' => false));
  807. $expected = '/admin/pages/add';
  808. $this->assertEquals($expected, $result);
  809. Router::reload();
  810. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  811. Router::parse('/');
  812. $request = new Request();
  813. $request->addParams(array(
  814. 'plugin' => null,
  815. 'controller' => 'pages',
  816. 'action' => 'add',
  817. 'prefix' => 'admin'
  818. ));
  819. $request->base = '';
  820. $request->here = '/admin/pages/add';
  821. $request->webroot = '/';
  822. Router::setRequestInfo($request);
  823. $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'add', 'id' => false));
  824. $expected = '/admin/pages/add';
  825. $this->assertEquals($expected, $result);
  826. Router::reload();
  827. Router::connect('/admin/:controller/:action/:id', array('prefix' => 'admin'), array('id' => '[0-9]+'));
  828. Router::parse('/');
  829. $request = new Request();
  830. Router::setRequestInfo(
  831. $request->addParams(array(
  832. 'plugin' => null,
  833. 'controller' => 'pages',
  834. 'action' => 'edit',
  835. 'pass' => array('284'),
  836. 'prefix' => 'admin'
  837. ))->addPaths(array(
  838. 'base' => '',
  839. 'here' => '/admin/pages/edit/284',
  840. 'webroot' => '/'
  841. ))
  842. );
  843. $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'edit', 'id' => '284'));
  844. $expected = '/admin/pages/edit/284';
  845. $this->assertEquals($expected, $result);
  846. Router::reload();
  847. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  848. Router::parse('/');
  849. $request = new Request();
  850. Router::setRequestInfo(
  851. $request->addParams(array(
  852. 'plugin' => null, 'controller' => 'pages', 'action' => 'add', 'prefix' => 'admin',
  853. ))->addPaths(array(
  854. 'base' => '', 'here' => '/admin/pages/add', 'webroot' => '/'
  855. ))
  856. );
  857. $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'add', 'id' => false));
  858. $expected = '/admin/pages/add';
  859. $this->assertEquals($expected, $result);
  860. Router::reload();
  861. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  862. Router::parse('/');
  863. $request = new Request();
  864. Router::setRequestInfo(
  865. $request->addParams(array(
  866. 'plugin' => null, 'controller' => 'pages', 'action' => 'edit', 'prefix' => 'admin',
  867. 'pass' => array('284')
  868. ))->addPaths(array(
  869. 'base' => '', 'here' => '/admin/pages/edit/284', 'webroot' => '/'
  870. ))
  871. );
  872. $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'edit', 284));
  873. $expected = '/admin/pages/edit/284';
  874. $this->assertEquals($expected, $result);
  875. Router::reload();
  876. Router::connect('/admin/posts/*', array('controller' => 'posts', 'action' => 'index', 'prefix' => 'admin'));
  877. Router::parse('/');
  878. Router::setRequestInfo(
  879. $request->addParams(array(
  880. 'plugin' => null, 'controller' => 'posts', 'action' => 'index', 'prefix' => 'admin',
  881. 'pass' => array('284')
  882. ))->addPaths(array(
  883. 'base' => '', 'here' => '/admin/posts', 'webroot' => '/'
  884. ))
  885. );
  886. $result = Router::url(array('all'));
  887. $expected = '/admin/posts/all';
  888. $this->assertEquals($expected, $result);
  889. }
  890. /**
  891. * testUrlGenerationWithExtensions method
  892. *
  893. * @return void
  894. */
  895. public function testUrlGenerationWithExtensions() {
  896. Router::connect('/:controller', array('action' => 'index'));
  897. Router::connect('/:controller/:action');
  898. Router::parse('/');
  899. $result = Router::url(array(
  900. 'plugin' => null,
  901. 'controller' => 'articles',
  902. 'action' => 'add',
  903. 'id' => null,
  904. '_ext' => 'json'
  905. ));
  906. $expected = '/articles/add.json';
  907. $this->assertEquals($expected, $result);
  908. $result = Router::url(array(
  909. 'plugin' => null,
  910. 'controller' => 'articles',
  911. 'action' => 'add',
  912. '_ext' => 'json'
  913. ));
  914. $expected = '/articles/add.json';
  915. $this->assertEquals($expected, $result);
  916. $result = Router::url(array(
  917. 'plugin' => null,
  918. 'controller' => 'articles',
  919. 'action' => 'index',
  920. 'id' => null,
  921. '_ext' => 'json'
  922. ));
  923. $expected = '/articles.json';
  924. $this->assertEquals($expected, $result);
  925. $result = Router::url(array(
  926. 'plugin' => null,
  927. 'controller' => 'articles',
  928. 'action' => 'index',
  929. 'ext' => 'json'
  930. ));
  931. $expected = '/articles.json';
  932. $this->assertEquals($expected, $result);
  933. }
  934. /**
  935. * Test url generation with named routes.
  936. */
  937. public function testUrlGenerationNamedRoute() {
  938. Router::connect(
  939. '/users',
  940. array('controller' => 'users', 'action' => 'index'),
  941. array('_name' => 'users-index')
  942. );
  943. Router::connect(
  944. '/users/:name',
  945. array('controller' => 'users', 'action' => 'view'),
  946. array('_name' => 'test')
  947. );
  948. $url = Router::url('test', array('name' => 'mark'));
  949. $this->assertEquals('/users/mark', $url);
  950. $url = Router::url('test', array('name' => 'mark', 'page' => 1, 'sort' => 'title', 'dir' => 'desc'));
  951. $this->assertEquals('/users/mark?page=1&sort=title&dir=desc', $url);
  952. $url = Router::url('users-index');
  953. $this->assertEquals('/users', $url);
  954. }
  955. /**
  956. * Test that using invalid names causes exceptions.
  957. *
  958. * @expectedException \Cake\Error\Exception
  959. * @return void
  960. */
  961. public function testNamedRouteException() {
  962. Router::connect(
  963. '/users/:name',
  964. array('controller' => 'users', 'action' => 'view'),
  965. array('_name' => 'test')
  966. );
  967. $url = Router::url('junk', array('name' => 'mark'));
  968. }
  969. /**
  970. * Test that url filters are applied to url params.
  971. *
  972. * @return void
  973. */
  974. public function testUrlGenerationWithUrlFilter() {
  975. Router::connect('/:lang/:controller/:action/*');
  976. $request = new Request();
  977. $request->addParams(array(
  978. 'lang' => 'en',
  979. 'controller' => 'posts',
  980. 'action' => 'index'
  981. ))->addPaths(array(
  982. 'base' => '',
  983. 'here' => '/'
  984. ));
  985. Router::pushRequest($request);
  986. $calledCount = 0;
  987. Router::addUrlFilter(function ($url, $request) use (&$calledCount) {
  988. $calledCount++;
  989. $url['lang'] = $request->lang;
  990. return $url;
  991. });
  992. Router::addUrlFilter(function ($url, $request) use (&$calledCount) {
  993. $calledCount++;
  994. $url[] = '1234';
  995. return $url;
  996. });
  997. $result = Router::url(array('controller' => 'tasks', 'action' => 'edit'));
  998. $this->assertEquals('/en/tasks/edit/1234', $result);
  999. $this->assertEquals(2, $calledCount);
  1000. }
  1001. /**
  1002. * Test that plain strings urls work
  1003. *
  1004. * @return void
  1005. */
  1006. public function testUrlGenerationPlainString() {
  1007. $mailto = 'mailto:mark@example.com';
  1008. $result = Router::url($mailto);
  1009. $this->assertEquals($mailto, $result);
  1010. $js = 'javascript:alert("hi")';
  1011. $result = Router::url($js);
  1012. $this->assertEquals($js, $result);
  1013. $hash = '#first';
  1014. $result = Router::url($hash);
  1015. $this->assertEquals($hash, $result);
  1016. }
  1017. /**
  1018. * test that you can leave active plugin routes with plugin = null
  1019. *
  1020. * @return void
  1021. */
  1022. public function testCanLeavePlugin() {
  1023. Router::connect('/admin/:controller', array('action' => 'index', 'prefix' => 'admin'));
  1024. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  1025. $request = new Request();
  1026. Router::setRequestInfo(
  1027. $request->addParams(array(
  1028. 'pass' => [],
  1029. 'prefix' => 'admin',
  1030. 'plugin' => 'this',
  1031. 'action' => 'index',
  1032. 'controller' => 'interesting',
  1033. ))->addPaths(array(
  1034. 'base' => '',
  1035. 'here' => '/admin/this/interesting/index',
  1036. 'webroot' => '/',
  1037. ))
  1038. );
  1039. $result = Router::url(array('plugin' => null, 'controller' => 'posts', 'action' => 'index'));
  1040. $this->assertEquals('/admin/posts', $result);
  1041. }
  1042. /**
  1043. * testUrlParsing method
  1044. *
  1045. * @return void
  1046. */
  1047. public function testUrlParsing() {
  1048. extract(Router::getNamedExpressions());
  1049. Router::connect(
  1050. '/posts/:value/:somevalue/:othervalue/*',
  1051. array('controller' => 'Posts', 'action' => 'view'),
  1052. array('value', 'somevalue', 'othervalue')
  1053. );
  1054. $result = Router::parse('/posts/2007/08/01/title-of-post-here');
  1055. $expected = array(
  1056. 'value' => '2007',
  1057. 'somevalue' => '08',
  1058. 'othervalue' => '01',
  1059. 'controller' => 'Posts',
  1060. 'action' => 'view',
  1061. 'plugin' => null,
  1062. 'pass' => array('0' => 'title-of-post-here')
  1063. );
  1064. $this->assertEquals($expected, $result);
  1065. Router::reload();
  1066. Router::connect(
  1067. '/posts/:year/:month/:day/*',
  1068. array('controller' => 'posts', 'action' => 'view'),
  1069. array('year' => $Year, 'month' => $Month, 'day' => $Day)
  1070. );
  1071. $result = Router::parse('/posts/2007/08/01/title-of-post-here');
  1072. $expected = array(
  1073. 'year' => '2007',
  1074. 'month' => '08',
  1075. 'day' => '01',
  1076. 'controller' => 'posts',
  1077. 'action' => 'view',
  1078. 'plugin' => null,
  1079. 'pass' => array('0' => 'title-of-post-here')
  1080. );
  1081. $this->assertEquals($expected, $result);
  1082. Router::reload();
  1083. Router::connect(
  1084. '/posts/:day/:year/:month/*',
  1085. array('controller' => 'posts', 'action' => 'view'),
  1086. array('year' => $Year, 'month' => $Month, 'day' => $Day)
  1087. );
  1088. $result = Router::parse('/posts/01/2007/08/title-of-post-here');
  1089. $expected = array(
  1090. 'day' => '01',
  1091. 'year' => '2007',
  1092. 'month' => '08',
  1093. 'controller' => 'posts',
  1094. 'action' => 'view',
  1095. 'plugin' => null,
  1096. 'pass' => array('0' => 'title-of-post-here')
  1097. );
  1098. $this->assertEquals($expected, $result);
  1099. Router::reload();
  1100. Router::connect(
  1101. '/posts/:month/:day/:year/*',
  1102. array('controller' => 'posts', 'action' => 'view'),
  1103. array('year' => $Year, 'month' => $Month, 'day' => $Day)
  1104. );
  1105. $result = Router::parse('/posts/08/01/2007/title-of-post-here');
  1106. $expected = array(
  1107. 'month' => '08',
  1108. 'day' => '01',
  1109. 'year' => '2007',
  1110. 'controller' => 'posts',
  1111. 'action' => 'view',
  1112. 'plugin' => null,
  1113. 'pass' => array('0' => 'title-of-post-here')
  1114. );
  1115. $this->assertEquals($expected, $result);
  1116. Router::reload();
  1117. Router::connect(
  1118. '/posts/:year/:month/:day/*',
  1119. array('controller' => 'posts', 'action' => 'view')
  1120. );
  1121. $result = Router::parse('/posts/2007/08/01/title-of-post-here');
  1122. $expected = array(
  1123. 'year' => '2007',
  1124. 'month' => '08',
  1125. 'day' => '01',
  1126. 'controller' => 'posts',
  1127. 'action' => 'view',
  1128. 'plugin' => null,
  1129. 'pass' => array('0' => 'title-of-post-here')
  1130. );
  1131. $this->assertEquals($expected, $result);
  1132. Router::reload();
  1133. require CAKE . 'Config/routes.php';
  1134. $result = Router::parse('/pages/display/home');
  1135. $expected = array(
  1136. 'plugin' => null,
  1137. 'pass' => array('home'),
  1138. 'controller' => 'Pages',
  1139. 'action' => 'display'
  1140. );
  1141. $this->assertEquals($expected, $result);
  1142. $result = Router::parse('pages/display/home/');
  1143. $this->assertEquals($expected, $result);
  1144. $result = Router::parse('pages/display/home');
  1145. $this->assertEquals($expected, $result);
  1146. Router::reload();
  1147. Router::connect('/page/*', array('controller' => 'test'));
  1148. $result = Router::parse('/page/my-page');
  1149. $expected = array('pass' => array('my-page'), 'plugin' => null, 'controller' => 'test', 'action' => 'index');
  1150. $this->assertEquals($expected, $result);
  1151. Router::reload();
  1152. Router::connect(
  1153. '/:language/contact',
  1154. array('language' => 'eng', 'plugin' => 'contact', 'controller' => 'contact', 'action' => 'index'),
  1155. array('language' => '[a-z]{3}')
  1156. );
  1157. $result = Router::parse('/eng/contact');
  1158. $expected = array(
  1159. 'pass' => [],
  1160. 'language' => 'eng',
  1161. 'plugin' => 'contact',
  1162. 'controller' => 'contact',
  1163. 'action' => 'index'
  1164. );
  1165. $this->assertEquals($expected, $result);
  1166. Router::reload();
  1167. Router::connect('/forestillinger/:month/:year/*',
  1168. array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar'),
  1169. array('month' => '0[1-9]|1[012]', 'year' => '[12][0-9]{3}')
  1170. );
  1171. $result = Router::parse('/forestillinger/10/2007/min-forestilling');
  1172. $expected = array(
  1173. 'pass' => array('min-forestilling'),
  1174. 'plugin' => 'shows',
  1175. 'controller' => 'shows',
  1176. 'action' => 'calendar',
  1177. 'year' => 2007,
  1178. 'month' => 10
  1179. );
  1180. $this->assertEquals($expected, $result);
  1181. Router::reload();
  1182. Router::connect('/:controller/:action/*');
  1183. Router::connect('/', array('plugin' => 'pages', 'controller' => 'pages', 'action' => 'display'));
  1184. $result = Router::parse('/');
  1185. $expected = array('pass' => [], 'controller' => 'pages', 'action' => 'display', 'plugin' => 'pages');
  1186. $this->assertEquals($expected, $result);
  1187. $result = Router::parse('/posts/edit/0');
  1188. $expected = array('pass' => array(0), 'controller' => 'posts', 'action' => 'edit', 'plugin' => null);
  1189. $this->assertEquals($expected, $result);
  1190. Router::reload();
  1191. Router::connect(
  1192. '/posts/:id::url_title',
  1193. array('controller' => 'posts', 'action' => 'view'),
  1194. array('pass' => array('id', 'url_title'), 'id' => '[\d]+')
  1195. );
  1196. $result = Router::parse('/posts/5:sample-post-title');
  1197. $expected = array(
  1198. 'pass' => array('5', 'sample-post-title'),
  1199. 'id' => 5,
  1200. 'url_title' => 'sample-post-title',
  1201. 'plugin' => null,
  1202. 'controller' => 'posts',
  1203. 'action' => 'view'
  1204. );
  1205. $this->assertEquals($expected, $result);
  1206. Router::reload();
  1207. Router::connect(
  1208. '/posts/:id::url_title/*',
  1209. array('controller' => 'posts', 'action' => 'view'),
  1210. array('pass' => array('id', 'url_title'), 'id' => '[\d]+')
  1211. );
  1212. $result = Router::parse('/posts/5:sample-post-title/other/params/4');
  1213. $expected = array(
  1214. 'pass' => array('5', 'sample-post-title', 'other', 'params', '4'),
  1215. 'id' => 5,
  1216. 'url_title' => 'sample-post-title',
  1217. 'plugin' => null,
  1218. 'controller' => 'posts',
  1219. 'action' => 'view'
  1220. );
  1221. $this->assertEquals($expected, $result);
  1222. Router::reload();
  1223. Router::connect('/posts/view/*', array('controller' => 'posts', 'action' => 'view'));
  1224. $result = Router::parse('/posts/view/10?id=123&tab=abc');
  1225. $expected = array('pass' => array(10), 'plugin' => null, 'controller' => 'posts', 'action' => 'view', '?' => array('id' => '123', 'tab' => 'abc'));
  1226. $this->assertEquals($expected, $result);
  1227. Router::reload();
  1228. Router::connect(
  1229. '/posts/:url_title-(uuid::id)',
  1230. array('controller' => 'posts', 'action' => 'view'),
  1231. array('pass' => array('id', 'url_title'), 'id' => $UUID)
  1232. );
  1233. $result = Router::parse('/posts/sample-post-title-(uuid:47fc97a9-019c-41d1-a058-1fa3cbdd56cb)');
  1234. $expected = array(
  1235. 'pass' => array('47fc97a9-019c-41d1-a058-1fa3cbdd56cb', 'sample-post-title'),
  1236. 'id' => '47fc97a9-019c-41d1-a058-1fa3cbdd56cb',
  1237. 'url_title' => 'sample-post-title',
  1238. 'plugin' => null,
  1239. 'controller' => 'posts',
  1240. 'action' => 'view'
  1241. );
  1242. $this->assertEquals($expected, $result);
  1243. Router::reload();
  1244. Router::connect('/posts/view/*', array('controller' => 'posts', 'action' => 'view'));
  1245. $result = Router::parse('/posts/view/foo:bar/routing:fun');
  1246. $expected = array(
  1247. 'pass' => array('foo:bar', 'routing:fun'),
  1248. 'plugin' => null,
  1249. 'controller' => 'posts',
  1250. 'action' => 'view'
  1251. );
  1252. $this->assertEquals($expected, $result);
  1253. }
  1254. /**
  1255. * testUuidRoutes method
  1256. *
  1257. * @return void
  1258. */
  1259. public function testUuidRoutes() {
  1260. Router::connect(
  1261. '/subjects/add/:category_id',
  1262. array('controller' => 'subjects', 'action' => 'add'),
  1263. array('category_id' => '\w{8}-\w{4}-\w{4}-\w{4}-\w{12}')
  1264. );
  1265. $result = Router::parse('/subjects/add/4795d601-19c8-49a6-930e-06a8b01d17b7');
  1266. $expected = array(
  1267. 'pass' => [],
  1268. 'category_id' => '4795d601-19c8-49a6-930e-06a8b01d17b7',
  1269. 'plugin' => null,
  1270. 'controller' => 'subjects',
  1271. 'action' => 'add'
  1272. );
  1273. $this->assertEquals($expected, $result);
  1274. }
  1275. /**
  1276. * testRouteSymmetry method
  1277. *
  1278. * @return void
  1279. */
  1280. public function testRouteSymmetry() {
  1281. Router::connect(
  1282. "/:extra/page/:slug/*",
  1283. array('controller' => 'pages', 'action' => 'view', 'extra' => null),
  1284. array("extra" => '[a-z1-9_]*', "slug" => '[a-z1-9_]+', "action" => 'view')
  1285. );
  1286. $result = Router::parse('/some_extra/page/this_is_the_slug');
  1287. $expected = array(
  1288. 'pass' => [],
  1289. 'plugin' => null,
  1290. 'controller' => 'pages',
  1291. 'action' => 'view',
  1292. 'slug' => 'this_is_the_slug',
  1293. 'extra' => 'some_extra'
  1294. );
  1295. $this->assertEquals($expected, $result);
  1296. $result = Router::parse('/page/this_is_the_slug');
  1297. $expected = array(
  1298. 'pass' => [],
  1299. 'plugin' => null,
  1300. 'controller' => 'pages',
  1301. 'action' => 'view',
  1302. 'slug' => 'this_is_the_slug',
  1303. 'extra' => null
  1304. );
  1305. $this->assertEquals($expected, $result);
  1306. Router::reload();
  1307. Router::connect(
  1308. "/:extra/page/:slug/*",
  1309. array('controller' => 'pages', 'action' => 'view', 'extra' => null),
  1310. array("extra" => '[a-z1-9_]*', "slug" => '[a-z1-9_]+')
  1311. );
  1312. Router::parse('/');
  1313. $result = Router::url(array(
  1314. 'admin' => null,
  1315. 'plugin' => null,
  1316. 'controller' => 'pages',
  1317. 'action' => 'view',
  1318. 'slug' => 'this_is_the_slug',
  1319. 'extra' => null
  1320. ));
  1321. $expected = '/page/this_is_the_slug';
  1322. $this->assertEquals($expected, $result);
  1323. $result = Router::url(array(
  1324. 'admin' => null,
  1325. 'plugin' => null,
  1326. 'controller' => 'pages',
  1327. 'action' => 'view',
  1328. 'slug' => 'this_is_the_slug',
  1329. 'extra' => 'some_extra'
  1330. ));
  1331. $expected = '/some_extra/page/this_is_the_slug';
  1332. $this->assertEquals($expected, $result);
  1333. }
  1334. /**
  1335. * Test parse and reverse symmetry
  1336. *
  1337. * @return void
  1338. * @dataProvider parseReverseSymmetryData
  1339. */
  1340. public function testParseReverseSymmetry($url) {
  1341. require CAKE . 'Config/routes.php';
  1342. $this->assertSame($url, Router::reverse(Router::parse($url) + array('url' => [])));
  1343. }
  1344. /**
  1345. * Data for parse and reverse test
  1346. *
  1347. * @return array
  1348. */
  1349. public function parseReverseSymmetryData() {
  1350. return array(
  1351. array('/'),
  1352. array('/controller/action'),
  1353. array('/controller/action/param'),
  1354. array('/controller/action?param1=value1&param2=value2'),
  1355. array('/controller/action/param?param1=value1'),
  1356. );
  1357. }
  1358. /**
  1359. * Test that Routing.prefixes are used when a Router instance is created
  1360. * or reset
  1361. *
  1362. * @return void
  1363. */
  1364. public function testRoutingPrefixesSetting() {
  1365. $restore = Configure::read('Routing');
  1366. Configure::write('Routing.prefixes', array('admin', 'member', 'super_user'));
  1367. Router::reload();
  1368. $result = Router::prefixes();
  1369. $expected = array('admin', 'member', 'super_user');
  1370. $this->assertEquals($expected, $result);
  1371. Configure::write('Routing.prefixes', array('admin', 'member'));
  1372. Router::reload();
  1373. $result = Router::prefixes();
  1374. $expected = array('admin', 'member');
  1375. $this->assertEquals($expected, $result);
  1376. Configure::write('Routing', $restore);
  1377. }
  1378. /**
  1379. * Test prefix routing and plugin combinations
  1380. *
  1381. * @return void
  1382. */
  1383. public function testPrefixRoutingAndPlugins() {
  1384. Configure::write('Routing.prefixes', array('admin'));
  1385. $paths = App::path('Plugin');
  1386. Plugin::load(array('TestPlugin'));
  1387. Router::reload();
  1388. require CAKE . 'Config/routes.php';
  1389. $request = new Request();
  1390. Router::setRequestInfo(
  1391. $request->addParams(array(
  1392. 'controller' => 'controller',
  1393. 'action' => 'action',
  1394. 'plugin' => null,
  1395. 'prefix' => 'admin'
  1396. ))->addPaths(array(
  1397. 'base' => '/',
  1398. 'here' => '/',
  1399. 'webroot' => '/base/',
  1400. ))
  1401. );
  1402. Router::parse('/');
  1403. $result = Router::url(array(
  1404. 'plugin' => 'test_plugin',
  1405. 'controller' => 'test_plugin',
  1406. 'action' => 'index'
  1407. ));
  1408. $expected = '/admin/test_plugin';
  1409. $this->assertEquals($expected, $result);
  1410. Router::reload();
  1411. require CAKE . 'Config/routes.php';
  1412. $request = new Request();
  1413. Router::setRequestInfo(
  1414. $request->addParams(array(
  1415. 'plugin' => 'test_plugin',
  1416. 'controller' => 'show_tickets',
  1417. 'action' => 'edit',
  1418. 'pass' => array('6'),
  1419. 'prefix' => 'admin',
  1420. ))->addPaths(array(
  1421. 'base' => '/',
  1422. 'here' => '/admin/shows/show_tickets/edit/6',
  1423. 'webroot' => '/',
  1424. ))
  1425. );
  1426. $result = Router::url(array(
  1427. 'plugin' => 'test_plugin',
  1428. 'controller' => 'show_tickets',
  1429. 'action' => 'edit',
  1430. 6,
  1431. 'prefix' => 'admin'
  1432. ));
  1433. $expected = '/admin/test_plugin/show_tickets/edit/6';
  1434. $this->assertEquals($expected, $result);
  1435. $result = Router::url(array(
  1436. 'plugin' => 'test_plugin',
  1437. 'controller' => 'show_tickets',
  1438. 'action' => 'index',
  1439. 'prefix' => 'admin'
  1440. ));
  1441. $expected = '/admin/test_plugin/show_tickets';
  1442. $this->assertEquals($expected, $result);
  1443. }
  1444. /**
  1445. * testParseExtensions method
  1446. *
  1447. * @return void
  1448. */
  1449. public function testParseExtensions() {
  1450. Router::extensions();
  1451. Router::parseExtensions('rss', false);
  1452. $this->assertContains('rss', Router::extensions());
  1453. }
  1454. /**
  1455. * testSetExtensions method
  1456. *
  1457. * @return void
  1458. */
  1459. public function testSetExtensions() {
  1460. Router::extensions();
  1461. Router::parseExtensions('rss', false);
  1462. $this->assertContains('rss', Router::extensions());
  1463. require CAKE . 'Config/routes.php';
  1464. $result = Router::parse('/posts.rss');
  1465. $this->assertEquals('rss', $result['_ext']);
  1466. $result = Router::parse('/posts.xml');
  1467. $this->assertFalse(isset($result['_ext']));
  1468. Router::parseExtensions(array('xml'));
  1469. $result = Router::extensions();
  1470. $this->assertContains('rss', $result);
  1471. $this->assertContains('xml', $result);
  1472. $result = Router::parse('/posts.xml');
  1473. $this->assertEquals('xml', $result['_ext']);
  1474. $result = Router::parseExtensions(array('pdf'), false);
  1475. $this->assertEquals(array('pdf'), $result);
  1476. }
  1477. /**
  1478. * testExtensionParsing method
  1479. *
  1480. * @return void
  1481. */
  1482. public function testExtensionParsing() {
  1483. Router::parseExtensions('rss', false);
  1484. require CAKE . 'Config/routes.php';
  1485. $result = Router::parse('/posts.rss');
  1486. $expected = array(
  1487. 'plugin' => null,
  1488. 'controller' => 'Posts',
  1489. 'action' => 'index',
  1490. '_ext' => 'rss',
  1491. 'pass' => []
  1492. );
  1493. $this->assertEquals($expected, $result);
  1494. $result = Router::parse('/posts/view/1.rss');
  1495. $expected = array(
  1496. 'plugin' => null,
  1497. 'controller' => 'Posts',
  1498. 'action' => 'view',
  1499. 'pass' => array('1'),
  1500. '_ext' => 'rss'
  1501. );
  1502. $this->assertEquals($expected, $result);
  1503. $result = Router::parse('/posts/view/1.rss?query=test');
  1504. $expected['?'] = array('query' => 'test');
  1505. $this->assertEquals($expected, $result);
  1506. Router::reload();
  1507. Router::parseExtensions(['rss', 'xml'], false);
  1508. require CAKE . 'Config/routes.php';
  1509. $result = Router::parse('/posts.xml');
  1510. $expected = array(
  1511. 'plugin' => null,
  1512. 'controller' => 'Posts',
  1513. 'action' => 'index',
  1514. '_ext' => 'xml',
  1515. 'pass' => []
  1516. );
  1517. $this->assertEquals($expected, $result);
  1518. $result = Router::parse('/posts.atom?hello=goodbye');
  1519. $expected = array(
  1520. 'plugin' => null,
  1521. 'controller' => 'Posts.atom',
  1522. 'action' => 'index',
  1523. 'pass' => [],
  1524. '?' => array('hello' => 'goodbye')
  1525. );
  1526. $this->assertEquals($expected, $result);
  1527. Router::reload();
  1528. Router::connect('/controller/action', array('controller' => 'controller', 'action' => 'action', '_ext' => 'rss'));
  1529. $result = Router::parse('/controller/action');
  1530. $expected = array('controller' => 'controller', 'action' => 'action', 'plugin' => null, '_ext' => 'rss', 'pass' => []);
  1531. $this->assertEquals($expected, $result);
  1532. Router::reload();
  1533. Router::connect('/controller/action', array('controller' => 'controller', 'action' => 'action', '_ext' => 'rss'));
  1534. $result = Router::parse('/controller/action');
  1535. $expected = array(
  1536. 'controller' => 'controller',
  1537. 'action' => 'action',
  1538. 'plugin' => null,
  1539. '_ext' => 'rss',
  1540. 'pass' => []
  1541. );
  1542. $this->assertEquals($expected, $result);
  1543. Router::reload();
  1544. Router::parseExtensions('rss', false);
  1545. Router::connect('/controller/action', array('controller' => 'controller', 'action' => 'action', '_ext' => 'rss'));
  1546. $result = Router::parse('/controller/action');
  1547. $expected = array(
  1548. 'controller' => 'controller',
  1549. 'action' => 'action',
  1550. 'plugin' => null,
  1551. '_ext' => 'rss',
  1552. 'pass' => []
  1553. );
  1554. $this->assertEquals($expected, $result);
  1555. }
  1556. /**
  1557. * Test newer style automatically generated prefix routes.
  1558. *
  1559. * @return void
  1560. * @see testUrlGenerationWithAutoPrefixes
  1561. */
  1562. public function testUrlGenerationWithAutoPrefixes() {
  1563. Router::reload();
  1564. Router::connect('/protected/:controller/:action/*', array('prefix' => 'protected'));
  1565. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  1566. Router::connect('/:controller/:action/*');
  1567. Router::parse('/');
  1568. $request = new Request();
  1569. Router::setRequestInfo(
  1570. $request->addParams(array(
  1571. 'plugin' => null, 'controller' => 'images', 'action' => 'index',
  1572. 'prefix' => null, 'protected' => false, 'url' => array('url' => 'images/index')
  1573. ))->addPaths(array(
  1574. 'base' => '',
  1575. 'here' => '/images/index',
  1576. 'webroot' => '/',
  1577. ))
  1578. );
  1579. $result = Router::url(array('controller' => 'images', 'action' => 'add'));
  1580. $expected = '/images/add';
  1581. $this->assertEquals($expected, $result);
  1582. $result = Router::url(array('controller' => 'images', 'action' => 'add', 'prefix' => 'protected'));
  1583. $expected = '/protected/images/add';
  1584. $this->assertEquals($expected, $result);
  1585. $result = Router::url(array('controller' => 'images', 'action' => 'add_protected_test', 'prefix' => 'protected'));
  1586. $expected = '/protected/images/add_protected_test';
  1587. $this->assertEquals($expected, $result);
  1588. $result = Router::url(array('action' => 'edit', 1));
  1589. $expected = '/images/edit/1';
  1590. $this->assertEquals($expected, $result);
  1591. $result = Router::url(array('action' => 'edit', 1, 'prefix' => 'protected'));
  1592. $expected = '/protected/images/edit/1';
  1593. $this->assertEquals($expected, $result);
  1594. $result = Router::url(array('action' => 'protectededit', 1, 'prefix' => 'protected'));
  1595. $expected = '/protected/images/protectededit/1';
  1596. $this->assertEquals($expected, $result);
  1597. $result = Router::url(array('action' => 'edit', 1, 'prefix' => 'protected'));
  1598. $expected = '/protected/images/edit/1';
  1599. $this->assertEquals($expected, $result);
  1600. $result = Router::url(array('controller' => 'others', 'action' => 'edit', 1));
  1601. $expected = '/others/edit/1';
  1602. $this->assertEquals($expected, $result);
  1603. $result = Router::url(array('controller' => 'others', 'action' => 'edit', 1, 'prefix' => 'protected'));
  1604. $expected = '/protected/others/edit/1';
  1605. $this->assertEquals($expected, $result);
  1606. }
  1607. /**
  1608. * Test that the ssl option works.
  1609. *
  1610. * @return void
  1611. */
  1612. public function testGenerationWithSslOption() {
  1613. Router::connect('/:controller/:action/*');
  1614. $_SERVER['HTTP_HOST'] = 'localhost';
  1615. $request = new Request();
  1616. Router::pushRequest(
  1617. $request->addParams(array(
  1618. 'plugin' => null, 'controller' => 'images', 'action' => 'index'
  1619. ))->addPaths(array(
  1620. 'base' => '',
  1621. 'here' => '/images/index',
  1622. 'webroot' => '/',
  1623. ))
  1624. );
  1625. $result = Router::url(array(
  1626. 'ssl' => true
  1627. ));
  1628. $this->assertEquals('https://localhost/images/index', $result);
  1629. $result = Router::url(array(
  1630. 'ssl' => false
  1631. ));
  1632. $this->assertEquals('http://localhost/images/index', $result);
  1633. }
  1634. /**
  1635. * Test ssl option when the current request is ssl.
  1636. *
  1637. * @return void
  1638. */
  1639. public function testGenerateWithSslInSsl() {
  1640. Router::connect('/:controller/:action/*');
  1641. $_SERVER['HTTP_HOST'] = 'localhost';
  1642. $_SERVER['HTTPS'] = 'on';
  1643. $request = new Request();
  1644. Router::pushRequest(
  1645. $request->addParams(array(
  1646. 'plugin' => null,
  1647. 'controller' => 'images',
  1648. 'action' => 'index'
  1649. ))->addPaths(array(
  1650. 'base' => '',
  1651. 'here' => '/images/index',
  1652. 'webroot' => '/',
  1653. ))
  1654. );
  1655. $result = Router::url(array(
  1656. 'ssl' => false
  1657. ));
  1658. $this->assertEquals('http://localhost/images/index', $result);
  1659. $result = Router::url(array(
  1660. 'ssl' => true
  1661. ));
  1662. $this->assertEquals('https://localhost/images/index', $result);
  1663. }
  1664. /**
  1665. * test that prefix routes persist when they are in the current request.
  1666. *
  1667. * @return void
  1668. */
  1669. public function testPrefixRoutePersistence() {
  1670. Router::reload();
  1671. Router::connect('/protected/:controller/:action', array('prefix' => 'protected'));
  1672. Router::connect('/:controller/:action');
  1673. Router::parse('/');
  1674. $request = new Request();
  1675. Router::setRequestInfo(
  1676. $request->addParams(array(
  1677. 'plugin' => null,
  1678. 'controller' => 'images',
  1679. 'action' => 'index',
  1680. 'prefix' => 'protected',
  1681. ))->addPaths(array(
  1682. 'base' => '',
  1683. 'here' => '/protected/images/index',
  1684. 'webroot' => '/',
  1685. ))
  1686. );
  1687. $result = Router::url(array('prefix' => 'protected', 'controller' => 'images', 'action' => 'add'));
  1688. $expected = '/protected/images/add';
  1689. $this->assertEquals($expected, $result);
  1690. $result = Router::url(array('controller' => 'images', 'action' => 'add'));
  1691. $expected = '/protected/images/add';
  1692. $this->assertEquals($expected, $result);
  1693. $result = Router::url(array('controller' => 'images', 'action' => 'add', 'prefix' => false));
  1694. $expected = '/images/add';
  1695. $this->assertEquals($expected, $result);
  1696. }
  1697. /**
  1698. * test that setting a prefix override the current one
  1699. *
  1700. * @return void
  1701. */
  1702. public function testPrefixOverride() {
  1703. Router::connect('/admin/:controller/:action', array('prefix' => 'admin'));
  1704. Router::connect('/protected/:controller/:action', array('prefix' => 'protected'));
  1705. $request = new Request();
  1706. Router::setRequestInfo(
  1707. $request->addParams(array(
  1708. 'plugin' => null, 'controller' => 'images', 'action' => 'index', 'prefix' => 'protected',
  1709. ))->addPaths(array(
  1710. 'base' => '',
  1711. 'here' => '/protected/images/index',
  1712. 'webroot' => '/',
  1713. ))
  1714. );
  1715. $result = Router::url(array('controller' => 'images', 'action' => 'add', 'prefix' => 'admin'));
  1716. $expected = '/admin/images/add';
  1717. $this->assertEquals($expected, $result);
  1718. $request = new Request();
  1719. Router::setRequestInfo(
  1720. $request->addParams(array(
  1721. 'plugin' => null,
  1722. 'controller' => 'images',
  1723. 'action' => 'index',
  1724. 'prefix' => 'admin',
  1725. ))->addPaths(array(
  1726. 'base' => '',
  1727. 'here' => '/admin/images/index',
  1728. 'webroot' => '/',
  1729. ))
  1730. );
  1731. $result = Router::url(array('controller' => 'images', 'action' => 'add', 'prefix' => 'protected'));
  1732. $expected = '/protected/images/add';
  1733. $this->assertEquals($expected, $result);
  1734. }
  1735. /**
  1736. * Test that well known route parameters are passed through.
  1737. *
  1738. * @return void
  1739. */
  1740. public function testRouteParamDefaults() {
  1741. Configure::write('Routing.prefixes', array('admin'));
  1742. Router::reload();
  1743. Router::connect('/cache/*', array('prefix' => false, 'plugin' => true, 'controller' => 0, 'action' => 1));
  1744. $url = Router::url(array('controller' => 0, 'action' => 1, 'test'));
  1745. $expected = '/';
  1746. $this->assertEquals($expected, $url);
  1747. $url = Router::url(array('prefix' => 1, 'controller' => 0, 'action' => 1, 'test'));
  1748. $expected = '/';
  1749. $this->assertEquals($expected, $url);
  1750. $url = Router::url(array('prefix' => 0, 'plugin' => 1, 'controller' => 0, 'action' => 1, 'test'));
  1751. $expected = '/cache/test';
  1752. $this->assertEquals($expected, $url);
  1753. }
  1754. /**
  1755. * testRemoveBase method
  1756. *
  1757. * @return void
  1758. */
  1759. public function testRemoveBase() {
  1760. Router::connect('/:controller/:action');
  1761. $request = new Request();
  1762. Router::setRequestInfo(
  1763. $request->addParams(array(
  1764. 'plugin' => null, 'controller' => 'controller', 'action' => 'index',
  1765. ))->addPaths(array(
  1766. 'base' => '/base',
  1767. 'here' => '/',
  1768. 'webroot' => '/base/',
  1769. ))
  1770. );
  1771. $result = Router::url(array('controller' => 'my_controller', 'action' => 'my_action'));
  1772. $expected = '/base/my_controller/my_action';
  1773. $this->assertEquals($expected, $result);
  1774. $result = Router::url(array('controller' => 'my_controller', 'action' => 'my_action', '_base' => false));
  1775. $expected = '/my_controller/my_action';
  1776. $this->assertEquals($expected, $result);
  1777. }
  1778. /**
  1779. * testPagesUrlParsing method
  1780. *
  1781. * @return void
  1782. */
  1783. public function testPagesUrlParsing() {
  1784. Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
  1785. Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
  1786. $result = Router::parse('/');
  1787. $expected = array('pass' => array('home'), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
  1788. $this->assertEquals($expected, $result);
  1789. $result = Router::parse('/pages/home/');
  1790. $expected = array('pass' => array('home'), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
  1791. $this->assertEquals($expected, $result);
  1792. Router::reload();
  1793. require CAKE . 'Config/routes.php';
  1794. Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
  1795. $result = Router::parse('/');
  1796. $expected = array('pass' => array('home'), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
  1797. $this->assertEquals($expected, $result);
  1798. Router::reload();
  1799. Router::connect('/', array('controller' => 'posts', 'action' => 'index'));
  1800. Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
  1801. $result = Router::parse('/pages/contact/');
  1802. $expected = array('pass' => array('contact'), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
  1803. $this->assertEquals($expected, $result);
  1804. }
  1805. /**
  1806. * test that requests with a trailing dot don't loose the do.
  1807. *
  1808. * @return void
  1809. */
  1810. public function testParsingWithTrailingPeriod() {
  1811. Router::reload();
  1812. Router::connect('/:controller/:action/*');
  1813. $result = Router::parse('/posts/view/something.');
  1814. $this->assertEquals('something.', $result['pass'][0], 'Period was chopped off %s');
  1815. $result = Router::parse('/posts/view/something. . .');
  1816. $this->assertEquals('something. . .', $result['pass'][0], 'Period was chopped off %s');
  1817. }
  1818. /**
  1819. * test that requests with a trailing dot don't loose the do.
  1820. *
  1821. * @return void
  1822. */
  1823. public function testParsingWithTrailingPeriodAndParseExtensions() {
  1824. Router::reload();
  1825. Router::connect('/:controller/:action/*');
  1826. Router::parseExtensions('json', false);
  1827. $result = Router::parse('/posts/view/something.');
  1828. $this->assertEquals('something.', $result['pass'][0], 'Period was chopped off %s');
  1829. $result = Router::parse('/posts/view/something. . .');
  1830. $this->assertEquals('something. . .', $result['pass'][0], 'Period was chopped off %s');
  1831. }
  1832. /**
  1833. * test that patterns work for :action
  1834. *
  1835. * @return void
  1836. */
  1837. public function testParsingWithPatternOnAction() {
  1838. Router::reload();
  1839. Router::connect(
  1840. '/blog/:action/*',
  1841. array('controller' => 'blog_posts'),
  1842. array('action' => 'other|actions')
  1843. );
  1844. $result = Router::parse('/blog/other');
  1845. $expected = array(
  1846. 'plugin' => null,
  1847. 'controller' => 'blog_posts',
  1848. 'action' => 'other',
  1849. 'pass' => [],
  1850. );
  1851. $this->assertEquals($expected, $result);
  1852. $result = Router::parse('/blog/foobar');
  1853. $this->assertSame([], $result);
  1854. $result = Router::url(array('controller' => 'blog_posts', 'action' => 'foo'));
  1855. $this->assertEquals('/', $result);
  1856. $result = Router::url(array('controller' => 'blog_posts', 'action' => 'actions'));
  1857. $this->assertEquals('/blog/actions', $result);
  1858. }
  1859. /**
  1860. * testParsingWithLiteralPrefixes method
  1861. *
  1862. * @return void
  1863. */
  1864. public function testParsingWithLiteralPrefixes() {
  1865. Configure::write('Routing.prefixes', []);
  1866. Router::reload();
  1867. $adminParams = array('prefix' => 'admin');
  1868. Router::connect('/admin/:controller', $adminParams);
  1869. Router::connect('/admin/:controller/:action', $adminParams);
  1870. Router::connect('/admin/:controller/:action/*', $adminParams);
  1871. $request = new Request();
  1872. Router::setRequestInfo(
  1873. $request->addParams(array(
  1874. 'plugin' => null, 'controller' => 'controller', 'action' => 'index'
  1875. ))->addPaths(array(
  1876. 'base' => '/base',
  1877. 'here' => '/',
  1878. 'webroot' => '/base/',
  1879. ))
  1880. );
  1881. $result = Router::parse('/admin/posts/');
  1882. $expected = array('pass' => [], 'prefix' => 'admin', 'plugin' => null, 'controller' => 'posts', 'action' => 'index');
  1883. $this->assertEquals($expected, $result);
  1884. $result = Router::parse('/admin/posts');
  1885. $this->assertEquals($expected, $result);
  1886. $result = Router::url(array('prefix' => 'admin', 'controller' => 'posts'));
  1887. $expected = '/base/admin/posts';
  1888. $this->assertEquals($expected, $result);
  1889. $result = Router::prefixes();
  1890. $expected = [];
  1891. $this->assertEquals($expected, $result);
  1892. Router::reload();
  1893. $prefixParams = array('prefix' => 'members');
  1894. Router::connect('/members/:controller', $prefixParams);
  1895. Router::connect('/members/:controller/:action', $prefixParams);
  1896. Router::connect('/members/:controller/:action/*', $prefixParams);
  1897. $request = new Request();
  1898. Router::setRequestInfo(
  1899. $request->addParams(array(
  1900. 'plugin' => null, 'controller' => 'controller', 'action' => 'index',
  1901. ))->addPaths(array(
  1902. 'base' => '/base',
  1903. 'here' => '/',
  1904. 'webroot' => '/',
  1905. ))
  1906. );
  1907. $result = Router::parse('/members/posts/index');
  1908. $expected = array('pass' => [], 'prefix' => 'members', 'plugin' => null, 'controller' => 'posts', 'action' => 'index');
  1909. $this->assertEquals($expected, $result);
  1910. $result = Router::url(array('prefix' => 'members', 'controller' => 'users', 'action' => 'add'));
  1911. $expected = '/base/members/users/add';
  1912. $this->assertEquals($expected, $result);
  1913. }
  1914. /**
  1915. * Tests URL generation with flags and prefixes in and out of context
  1916. *
  1917. * @return void
  1918. */
  1919. public function testUrlWritingWithPrefixes() {
  1920. Router::connect('/company/:controller/:action/*', array('prefix' => 'company'));
  1921. Router::connect('/:action', array('controller' => 'users'));
  1922. /*
  1923. $result = Router::url(array('controller' => 'users', 'action' => 'login', 'prefix' => 'company'));
  1924. $expected = '/company/users/login';
  1925. $this->assertEquals($expected, $result);
  1926. $result = Router::url(array('controller' => 'users', 'action' => 'login', 'prefix' => 'company'));
  1927. $expected = '/company/users/login';
  1928. $this->assertEquals($expected, $result);
  1929. */
  1930. $request = new Request();
  1931. Router::setRequestInfo(
  1932. $request->addParams(array(
  1933. 'plugin' => null,
  1934. 'controller' => 'users',
  1935. 'action' => 'login',
  1936. 'prefix' => 'company'
  1937. ))->addPaths(array(
  1938. 'base' => '/',
  1939. 'here' => '/',
  1940. 'webroot' => '/base/',
  1941. ))
  1942. );
  1943. $result = Router::url(array('controller' => 'users', 'action' => 'login', 'prefix' => false));
  1944. $expected = '/login';
  1945. $this->assertEquals($expected, $result);
  1946. }
  1947. /**
  1948. * test url generation with prefixes and custom routes
  1949. *
  1950. * @return void
  1951. */
  1952. public function testUrlWritingWithPrefixesAndCustomRoutes() {
  1953. Router::connect(
  1954. '/admin/login',
  1955. array('controller' => 'users', 'action' => 'login', 'prefix' => 'admin')
  1956. );
  1957. $request = new Request();
  1958. Router::setRequestInfo(
  1959. $request->addParams(array(
  1960. 'plugin' => null, 'controller' => 'posts', 'action' => 'index',
  1961. 'prefix' => 'admin'
  1962. ))->addPaths(array(
  1963. 'base' => '/',
  1964. 'here' => '/',
  1965. 'webroot' => '/',
  1966. ))
  1967. );
  1968. $result = Router::url(array('controller' => 'users', 'action' => 'login'));
  1969. $this->assertEquals('/admin/login', $result);
  1970. $result = Router::url(array('controller' => 'users', 'action' => 'login'));
  1971. $this->assertEquals('/admin/login', $result);
  1972. }
  1973. /**
  1974. * testPassedArgsOrder method
  1975. *
  1976. * @return void
  1977. */
  1978. public function testPassedArgsOrder() {
  1979. Router::connect('/test-passed/*', array('controller' => 'pages', 'action' => 'display', 'home'));
  1980. Router::connect('/test2/*', array('controller' => 'pages', 'action' => 'display', 2));
  1981. Router::connect('/test/*', array('controller' => 'pages', 'action' => 'display', 1));
  1982. Router::parse('/');
  1983. $result = Router::url(array('controller' => 'pages', 'action' => 'display', 1, 'whatever'));
  1984. $expected = '/test/whatever';
  1985. $this->assertEquals($expected, $result);
  1986. $result = Router::url(array('controller' => 'pages', 'action' => 'display', 2, 'whatever'));
  1987. $expected = '/test2/whatever';
  1988. $this->assertEquals($expected, $result);
  1989. $result = Router::url(array('controller' => 'pages', 'action' => 'display', 'home', 'whatever'));
  1990. $expected = '/test-passed/whatever';
  1991. $this->assertEquals($expected, $result);
  1992. }
  1993. /**
  1994. * testRegexRouteMatching method
  1995. *
  1996. * @return void
  1997. */
  1998. public function testRegexRouteMatching() {
  1999. Router::connect('/:locale/:controller/:action/*', [], array('locale' => 'dan|eng'));
  2000. $result = Router::parse('/eng/test/test_action');
  2001. $expected = array('pass' => [], 'locale' => 'eng', 'controller' => 'test', 'action' => 'test_action', 'plugin' => null);
  2002. $this->assertEquals($expected, $result);
  2003. $result = Router::parse('/badness/test/test_action');
  2004. $this->assertSame([], $result);
  2005. Router::reload();
  2006. Router::connect('/:locale/:controller/:action/*', [], array('locale' => 'dan|eng'));
  2007. $request = new Request();
  2008. Router::setRequestInfo(
  2009. $request->addParams(array(
  2010. 'plugin' => null,
  2011. 'controller' => 'test',
  2012. 'action' => 'index',
  2013. 'url' => array('url' => 'test/test_action')
  2014. ))->addPaths(array(
  2015. 'base' => '',
  2016. 'here' => '/test/test_action',
  2017. 'webroot' => '/',
  2018. ))
  2019. );
  2020. $result = Router::url(array('action' => 'test_another_action'));
  2021. $expected = '/';
  2022. $this->assertEquals($expected, $result);
  2023. $result = Router::url(array('action' => 'test_another_action', 'locale' => 'eng'));
  2024. $expected = '/eng/test/test_another_action';
  2025. $this->assertEquals($expected, $result);
  2026. }
  2027. /**
  2028. * test that connectDefaults() can disable default route connection
  2029. *
  2030. * @return void
  2031. */
  2032. public function testDefaultsMethod() {
  2033. Router::connect('/test/*', array('controller' => 'pages', 'action' => 'display', 2));
  2034. $result = Router::parse('/posts/edit/5');
  2035. $this->assertFalse(isset($result['controller']));
  2036. $this->assertFalse(isset($result['action']));
  2037. }
  2038. /**
  2039. * test that the required default routes are connected.
  2040. *
  2041. * @return void
  2042. */
  2043. public function testConnectDefaultRoutes() {
  2044. Plugin::load(array('TestPlugin', 'PluginJs'));
  2045. Router::reload();
  2046. require CAKE . 'Config/routes.php';
  2047. $result = Router::url(array('plugin' => 'PluginJs', 'controller' => 'JsFile', 'action' => 'index'));
  2048. $this->assertEquals('/plugin_js/js_file', $result);
  2049. $result = Router::parse('/plugin_js/js_file');
  2050. $expected = array(
  2051. 'plugin' => 'PluginJs', 'controller' => 'JsFile', 'action' => 'index',
  2052. 'pass' => []
  2053. );
  2054. $this->assertEquals($expected, $result);
  2055. $result = Router::url(array('plugin' => 'test_plugin', 'controller' => 'test_plugin', 'action' => 'index'));
  2056. $this->assertEquals('/test_plugin', $result, 'Plugin shortcut route generation failed.');
  2057. $result = Router::parse('/test_plugin');
  2058. $expected = array(
  2059. 'plugin' => 'TestPlugin',
  2060. 'controller' => 'TestPlugin',
  2061. 'action' => 'index',
  2062. 'pass' => []
  2063. );
  2064. $this->assertEquals($expected, $result, 'Plugin shortcut route broken.');
  2065. }
  2066. /**
  2067. * test using a custom route class for route connection
  2068. *
  2069. * @return void
  2070. */
  2071. public function testUsingCustomRouteClass() {
  2072. $routes = $this->getMock('Cake\Routing\RouteCollection');
  2073. $this->getMock('Cake\Routing\Route\Route', [], [], 'MockConnectedRoute', false);
  2074. Router::setRouteCollection($routes);
  2075. $routes->expects($this->once())
  2076. ->method('add')
  2077. ->with($this->isInstanceOf('\MockConnectedRoute'));
  2078. Router::connect(
  2079. '/:slug',
  2080. array('controller' => 'posts', 'action' => 'view'),
  2081. array('routeClass' => '\MockConnectedRoute', 'slug' => '[a-z_-]+')
  2082. );
  2083. }
  2084. /**
  2085. * test using custom route class in PluginDot notation
  2086. *
  2087. * @return void
  2088. */
  2089. public function testUsingCustomRouteClassPluginDotSyntax() {
  2090. Plugin::load('TestPlugin');
  2091. Router::connect(
  2092. '/:slug',
  2093. array('controller' => 'posts', 'action' => 'view'),
  2094. array('routeClass' => 'TestPlugin.TestRoute', 'slug' => '[a-z_-]+')
  2095. );
  2096. $this->assertTrue(true); // Just to make sure the connect do not throw exception
  2097. Plugin::unload('TestPlugin');
  2098. }
  2099. /**
  2100. * test that route classes must extend \Cake\Routing\Route\Route
  2101. *
  2102. * @expectedException \Cake\Error\Exception
  2103. * @return void
  2104. */
  2105. public function testCustomRouteException() {
  2106. Router::connect('/:controller', [], array('routeClass' => 'Object'));
  2107. }
  2108. /**
  2109. * test reversing parameter arrays back into strings.
  2110. *
  2111. * Mark the router as initialized so it doesn't auto-load routes
  2112. *
  2113. * @return void
  2114. */
  2115. public function testReverse() {
  2116. Router::connect('/:controller/:action/*');
  2117. $params = array(
  2118. 'controller' => 'posts',
  2119. 'action' => 'view',
  2120. 'pass' => array(1),
  2121. 'url' => [],
  2122. 'autoRender' => 1,
  2123. 'bare' => 1,
  2124. 'return' => 1,
  2125. 'requested' => 1,
  2126. '_Token' => array('key' => 'sekret')
  2127. );
  2128. $result = Router::reverse($params);
  2129. $this->assertEquals('/posts/view/1', $result);
  2130. Router::reload();
  2131. Router::connect('/:lang/:controller/:action/*', [], array('lang' => '[a-z]{3}'));
  2132. $params = array(
  2133. 'lang' => 'eng',
  2134. 'controller' => 'posts',
  2135. 'action' => 'view',
  2136. 'pass' => array(1),
  2137. 'url' => array('url' => 'eng/posts/view/1')
  2138. );
  2139. $result = Router::reverse($params);
  2140. $this->assertEquals('/eng/posts/view/1', $result);
  2141. $params = array(
  2142. 'lang' => 'eng',
  2143. 'controller' => 'posts',
  2144. 'action' => 'view',
  2145. 1,
  2146. '?' => ['foo' => 'bar']
  2147. );
  2148. $result = Router::reverse($params);
  2149. $this->assertEquals('/eng/posts/view/1?foo=bar', $result);
  2150. $params = array(
  2151. 'lang' => 'eng',
  2152. 'controller' => 'posts',
  2153. 'action' => 'view',
  2154. 'pass' => array(1),
  2155. 'url' => array('url' => 'eng/posts/view/1', 'foo' => 'bar', 'baz' => 'quu'),
  2156. 'paging' => [],
  2157. 'models' => []
  2158. );
  2159. $result = Router::reverse($params);
  2160. $this->assertEquals('/eng/posts/view/1?foo=bar&baz=quu', $result);
  2161. $request = new Request('/eng/posts/view/1');
  2162. $request->addParams(array(
  2163. 'lang' => 'eng',
  2164. 'controller' => 'posts',
  2165. 'action' => 'view',
  2166. 'pass' => array(1),
  2167. ));
  2168. $request->query = array('url' => 'eng/posts/view/1', 'test' => 'value');
  2169. $result = Router::reverse($request);
  2170. $expected = '/eng/posts/view/1?test=value';
  2171. $this->assertEquals($expected, $result);
  2172. $params = array(
  2173. 'lang' => 'eng',
  2174. 'controller' => 'posts',
  2175. 'action' => 'view',
  2176. 'pass' => array(1),
  2177. 'url' => array('url' => 'eng/posts/view/1')
  2178. );
  2179. $result = Router::reverse($params, true);
  2180. $this->assertRegExp('/^http(s)?:\/\//', $result);
  2181. }
  2182. /**
  2183. * Test that extensions work with Router::reverse()
  2184. *
  2185. * @return void
  2186. */
  2187. public function testReverseWithExtension() {
  2188. Router::connect('/:controller/:action/*');
  2189. Router::parseExtensions('json', false);
  2190. $request = new Request('/posts/view/1.json');
  2191. $request->addParams(array(
  2192. 'controller' => 'posts',
  2193. 'action' => 'view',
  2194. 'pass' => array(1),
  2195. 'ext' => 'json',
  2196. ));
  2197. $request->query = [];
  2198. $result = Router::reverse($request);
  2199. $expected = '/posts/view/1.json';
  2200. $this->assertEquals($expected, $result);
  2201. }
  2202. /**
  2203. * test that setRequestInfo can accept arrays and turn that into a Request object.
  2204. *
  2205. * @return void
  2206. */
  2207. public function testSetRequestInfoLegacy() {
  2208. Router::setRequestInfo(array(
  2209. array(
  2210. 'plugin' => null, 'controller' => 'images', 'action' => 'index',
  2211. 'url' => array('url' => 'protected/images/index')
  2212. ),
  2213. array(
  2214. 'base' => '',
  2215. 'here' => '/protected/images/index',
  2216. 'webroot' => '/',
  2217. )
  2218. ));
  2219. $result = Router::getRequest();
  2220. $this->assertEquals('images', $result->controller);
  2221. $this->assertEquals('index', $result->action);
  2222. $this->assertEquals('', $result->base);
  2223. $this->assertEquals('/protected/images/index', $result->here);
  2224. $this->assertEquals('/', $result->webroot);
  2225. }
  2226. /**
  2227. * test get request.
  2228. *
  2229. * @return void
  2230. */
  2231. public function testGetRequest() {
  2232. $requestA = new Request('/');
  2233. $requestB = new Request('/posts');
  2234. Router::pushRequest($requestA);
  2235. Router::pushRequest($requestB);
  2236. $this->assertSame($requestA, Router::getRequest(false));
  2237. $this->assertSame($requestB, Router::getRequest(true));
  2238. }
  2239. /**
  2240. * Test that Router::url() uses the first request
  2241. */
  2242. public function testUrlWithRequestAction() {
  2243. Router::connect('/:controller', array('action' => 'index'));
  2244. Router::connect('/:controller/:action');
  2245. $firstRequest = new Request('/posts/index');
  2246. $firstRequest->addParams(array(
  2247. 'plugin' => null,
  2248. 'controller' => 'posts',
  2249. 'action' => 'index'
  2250. ))->addPaths(array('base' => ''));
  2251. $secondRequest = new Request('/posts/index');
  2252. $secondRequest->addParams(array(
  2253. 'requested' => 1,
  2254. 'plugin' => null,
  2255. 'controller' => 'comments',
  2256. 'action' => 'listing'
  2257. ))->addPaths(array('base' => ''));
  2258. Router::setRequestInfo($firstRequest);
  2259. Router::setRequestInfo($secondRequest);
  2260. $result = Router::url(array('_base' => false));
  2261. $this->assertEquals('/comments/listing', $result, 'with second requests, the last should win.');
  2262. Router::popRequest();
  2263. $result = Router::url(array('_base' => false));
  2264. $this->assertEquals('/posts', $result, 'with second requests, the last should win.');
  2265. // Make sure that popping an empty request doesn't fail.
  2266. Router::popRequest();
  2267. }
  2268. /**
  2269. * test that a route object returning a full URL is not modified.
  2270. *
  2271. * @return void
  2272. */
  2273. public function testUrlFullUrlReturnFromRoute() {
  2274. $url = 'http://example.com/posts/view/1';
  2275. $routes = $this->getMock('Cake\Routing\RouteCollection');
  2276. Router::setRouteCollection($routes);
  2277. $routes->expects($this->any())->method('match')
  2278. ->will($this->returnValue($url));
  2279. $result = Router::url(array('controller' => 'posts', 'action' => 'view', 1));
  2280. $this->assertEquals($url, $result);
  2281. }
  2282. /**
  2283. * test protocol in url
  2284. *
  2285. * @return void
  2286. */
  2287. public function testUrlProtocol() {
  2288. $url = 'http://example.com';
  2289. $this->assertEquals($url, Router::url($url));
  2290. $url = 'ed2k://example.com';
  2291. $this->assertEquals($url, Router::url($url));
  2292. $url = 'svn+ssh://example.com';
  2293. $this->assertEquals($url, Router::url($url));
  2294. $url = '://example.com';
  2295. $this->assertEquals($url, Router::url($url));
  2296. $url = '//example.com';
  2297. $this->assertEquals($url, Router::url($url));
  2298. $url = 'javascript:void(0)';
  2299. $this->assertEquals($url, Router::url($url));
  2300. $url = 'tel:012345-678';
  2301. $this->assertEquals($url, Router::url($url));
  2302. $url = 'sms:012345-678';
  2303. $this->assertEquals($url, Router::url($url));
  2304. $url = '#here';
  2305. $this->assertEquals($url, Router::url($url));
  2306. $url = '?param=0';
  2307. $this->assertEquals($url, Router::url($url));
  2308. $url = '/posts/index#here';
  2309. $expected = Configure::read('App.fullBaseUrl') . '/posts/index#here';
  2310. $this->assertEquals($expected, Router::url($url, true));
  2311. }
  2312. /**
  2313. * Testing that patterns on the :action param work properly.
  2314. *
  2315. * @return void
  2316. */
  2317. public function testPatternOnAction() {
  2318. $route = new Route(
  2319. '/blog/:action/*',
  2320. array('controller' => 'blog_posts'),
  2321. array('action' => 'other|actions')
  2322. );
  2323. $result = $route->match(array('controller' => 'blog_posts', 'action' => 'foo'));
  2324. $this->assertFalse($result);
  2325. $result = $route->match(array('controller' => 'blog_posts', 'action' => 'actions'));
  2326. $this->assertEquals('/blog/actions/', $result);
  2327. $result = $route->parse('/blog/other');
  2328. $expected = array('controller' => 'blog_posts', 'action' => 'other', 'pass' => []);
  2329. $this->assertEquals($expected, $result);
  2330. $result = $route->parse('/blog/foobar');
  2331. $this->assertFalse($result);
  2332. }
  2333. /**
  2334. * Tests resourceMap as getter and setter.
  2335. *
  2336. * @return void
  2337. */
  2338. public function testResourceMap() {
  2339. $default = Router::resourceMap();
  2340. $expected = array(
  2341. array('action' => 'index', 'method' => 'GET', 'id' => false),
  2342. array('action' => 'view', 'method' => 'GET', 'id' => true),
  2343. array('action' => 'add', 'method' => 'POST', 'id' => false),
  2344. array('action' => 'edit', 'method' => 'PUT', 'id' => true),
  2345. array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
  2346. array('action' => 'edit', 'method' => 'POST', 'id' => true)
  2347. );
  2348. $this->assertEquals($expected, $default);
  2349. $custom = array(
  2350. array('action' => 'index', 'method' => 'GET', 'id' => false),
  2351. array('action' => 'view', 'method' => 'GET', 'id' => true),
  2352. array('action' => 'add', 'method' => 'POST', 'id' => false),
  2353. array('action' => 'edit', 'method' => 'PUT', 'id' => true),
  2354. array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
  2355. array('action' => 'update', 'method' => 'POST', 'id' => true)
  2356. );
  2357. Router::resourceMap($custom);
  2358. $this->assertEquals(Router::resourceMap(), $custom);
  2359. Router::resourceMap($default);
  2360. }
  2361. /**
  2362. * test setting redirect routes
  2363. *
  2364. * @return void
  2365. */
  2366. public function testRouteRedirection() {
  2367. $routes = new RouteCollection();
  2368. Router::setRouteCollection($routes);
  2369. Router::redirect('/blog', array('controller' => 'posts'), array('status' => 302));
  2370. Router::connect('/:controller', array('action' => 'index'));
  2371. $this->assertEquals(2, count($routes));
  2372. $routes->get(0)->response = $this->getMock(
  2373. 'Cake\Network\Response',
  2374. array('_sendHeader', 'stop')
  2375. );
  2376. $this->assertEquals(302, $routes->get(0)->options['status']);
  2377. Router::parse('/blog');
  2378. $header = $routes->get(0)->response->header();
  2379. $this->assertEquals(Router::url('/posts', true), $header['Location']);
  2380. $this->assertEquals(302, $routes->get(0)->response->statusCode());
  2381. $routes->get(0)->response = $this->getMock(
  2382. 'Cake\Network\Response',
  2383. array('_sendHeader')
  2384. );
  2385. Router::parse('/not-a-match');
  2386. $this->assertSame([], $routes->get(0)->response->header());
  2387. }
  2388. /**
  2389. * Test setting the default route class
  2390. *
  2391. * @return void
  2392. */
  2393. public function testDefaultRouteClass() {
  2394. $routes = $this->getMock('Cake\Routing\RouteCollection');
  2395. $this->getMock('Cake\Routing\Route\Route', [], array('/test'), 'TestDefaultRouteClass');
  2396. $routes->expects($this->once())
  2397. ->method('add')
  2398. ->with($this->isInstanceOf('\TestDefaultRouteClass'));
  2399. Router::setRouteCollection($routes);
  2400. Router::defaultRouteClass('\TestDefaultRouteClass');
  2401. Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
  2402. }
  2403. /**
  2404. * Test getting the default route class
  2405. *
  2406. * @return void
  2407. */
  2408. public function testDefaultRouteClassGetter() {
  2409. $routeClass = '\TestDefaultRouteClass';
  2410. Router::defaultRouteClass($routeClass);
  2411. $this->assertEquals($routeClass, Router::defaultRouteClass());
  2412. $this->assertEquals($routeClass, Router::defaultRouteClass(null));
  2413. }
  2414. /**
  2415. * Test that route classes must extend Cake\Routing\Route\Route
  2416. *
  2417. * @expectedException \Cake\Error\Exception
  2418. * @return void
  2419. */
  2420. public function testDefaultRouteException() {
  2421. Router::defaultRouteClass('');
  2422. Router::connect('/:controller', []);
  2423. }
  2424. /**
  2425. * Test that route classes must extend Cake\Routing\Route\Route
  2426. *
  2427. * @expectedException \Cake\Error\Exception
  2428. * @return void
  2429. */
  2430. public function testSettingInvalidDefaultRouteException() {
  2431. Router::defaultRouteClass('Object');
  2432. }
  2433. /**
  2434. * Test that class must exist
  2435. *
  2436. * @expectedException \Cake\Error\Exception
  2437. * @return void
  2438. */
  2439. public function testSettingNonExistentDefaultRouteException() {
  2440. Router::defaultRouteClass('NonExistentClass');
  2441. }
  2442. /**
  2443. * Test that the compatibility method for incoming urls works.
  2444. *
  2445. * @return void
  2446. */
  2447. public function testParseNamedParameters() {
  2448. $request = new Request();
  2449. $request->addParams(array(
  2450. 'controller' => 'posts',
  2451. 'action' => 'index',
  2452. ));
  2453. $result = Router::parseNamedParams($request);
  2454. $this->assertSame([], $result->params['named']);
  2455. $request = new Request();
  2456. $request->addParams(array(
  2457. 'controller' => 'posts',
  2458. 'action' => 'index',
  2459. 'pass' => array('home', 'one:two', 'three:four', 'five[nested][0]:six', 'five[nested][1]:seven')
  2460. ));
  2461. Router::parseNamedParams($request);
  2462. $expected = array(
  2463. 'plugin' => null,
  2464. 'controller' => 'posts',
  2465. 'action' => 'index',
  2466. '_ext' => null,
  2467. 'pass' => array('home'),
  2468. 'named' => array(
  2469. 'one' => 'two',
  2470. 'three' => 'four',
  2471. 'five' => array(
  2472. 'nested' => array('six', 'seven')
  2473. )
  2474. )
  2475. );
  2476. $this->assertEquals($expected, $request->params);
  2477. }
  2478. /**
  2479. * Test promote()
  2480. *
  2481. * @return void
  2482. */
  2483. public function testPromote() {
  2484. Router::connect('/:controller/:action/*');
  2485. Router::connect('/:lang/:controller/:action/*');
  2486. $result = Router::url(['controller' => 'posts', 'action' => 'index', 'lang' => 'en']);
  2487. $this->assertEquals('/posts/index?lang=en', $result, 'First route should match');
  2488. Router::promote();
  2489. $result = Router::url(['controller' => 'posts', 'action' => 'index', 'lang' => 'en']);
  2490. $this->assertEquals('/en/posts/index', $result, 'promote() should move 2nd route ahead.');
  2491. }
  2492. }