RouterTest.php 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845
  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::reload();
  39. Router::fullbaseUrl('');
  40. Configure::write('App.fullBaseUrl', 'http://localhost');
  41. }
  42. /**
  43. * tearDown method
  44. *
  45. * @return void
  46. */
  47. public function tearDown() {
  48. parent::tearDown();
  49. Plugin::unload();
  50. Router::fullBaseUrl('');
  51. Configure::write('App.fullBaseUrl', 'http://localhost');
  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 generation of routes with query string parameters.
  611. *
  612. * @return void
  613. */
  614. public function testUrlGenerationWithQueryStrings() {
  615. Router::connect('/:controller/:action/*');
  616. $result = Router::url(array(
  617. 'controller' => 'posts',
  618. '0',
  619. '?' => array('var' => 'test', 'var2' => 'test2')
  620. ));
  621. $expected = '/posts/index/0?var=test&var2=test2';
  622. $this->assertEquals($expected, $result);
  623. $result = Router::url(array('controller' => 'posts', '0', '?' => array('var' => null)));
  624. $this->assertEquals('/posts/index/0', $result);
  625. $result = Router::url(array(
  626. 'controller' => 'posts',
  627. '0',
  628. '?' => array(
  629. 'var' => 'test',
  630. 'var2' => 'test2'
  631. ),
  632. '#' => 'unencoded string %'
  633. ));
  634. $expected = '/posts/index/0?var=test&var2=test2#unencoded string %';
  635. $this->assertEquals($expected, $result);
  636. }
  637. /**
  638. * test that regex validation of keyed route params is working.
  639. *
  640. * @return void
  641. */
  642. public function testUrlGenerationWithRegexQualifiedParams() {
  643. Router::connect(
  644. ':language/galleries',
  645. array('controller' => 'galleries', 'action' => 'index'),
  646. array('language' => '[a-z]{3}')
  647. );
  648. Router::connect(
  649. '/:language/:admin/:controller/:action/*',
  650. array('admin' => 'admin'),
  651. array('language' => '[a-z]{3}', 'admin' => 'admin')
  652. );
  653. Router::connect('/:language/:controller/:action/*',
  654. [],
  655. array('language' => '[a-z]{3}')
  656. );
  657. $result = Router::url(array('admin' => false, 'language' => 'dan', 'action' => 'index', 'controller' => 'galleries'));
  658. $expected = '/dan/galleries';
  659. $this->assertEquals($expected, $result);
  660. $result = Router::url(array('admin' => false, 'language' => 'eng', 'action' => 'index', 'controller' => 'galleries'));
  661. $expected = '/eng/galleries';
  662. $this->assertEquals($expected, $result);
  663. Router::reload();
  664. Router::connect('/:language/pages',
  665. array('controller' => 'pages', 'action' => 'index'),
  666. array('language' => '[a-z]{3}')
  667. );
  668. Router::connect('/:language/:controller/:action/*', [], array('language' => '[a-z]{3}'));
  669. $result = Router::url(array('language' => 'eng', 'action' => 'index', 'controller' => 'pages'));
  670. $expected = '/eng/pages';
  671. $this->assertEquals($expected, $result);
  672. $result = Router::url(array('language' => 'eng', 'controller' => 'pages'));
  673. $this->assertEquals($expected, $result);
  674. $result = Router::url(array('language' => 'eng', 'controller' => 'pages', 'action' => 'add'));
  675. $expected = '/eng/pages/add';
  676. $this->assertEquals($expected, $result);
  677. Router::reload();
  678. Router::connect('/forestillinger/:month/:year/*',
  679. array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar'),
  680. array('month' => '0[1-9]|1[012]', 'year' => '[12][0-9]{3}')
  681. );
  682. Router::parse('/');
  683. $result = Router::url(array(
  684. 'plugin' => 'shows',
  685. 'controller' => 'shows',
  686. 'action' => 'calendar',
  687. 'month' => 10,
  688. 'year' => 2007,
  689. 'min-forestilling'
  690. ));
  691. $expected = '/forestillinger/10/2007/min-forestilling';
  692. $this->assertEquals($expected, $result);
  693. Router::reload();
  694. Router::connect('/kalender/:month/:year/*',
  695. array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar'),
  696. array('month' => '0[1-9]|1[012]', 'year' => '[12][0-9]{3}')
  697. );
  698. Router::connect('/kalender/*', array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar'));
  699. Router::parse('/');
  700. $result = Router::url(array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar', 'min-forestilling'));
  701. $expected = '/kalender/min-forestilling';
  702. $this->assertEquals($expected, $result);
  703. $result = Router::url(array(
  704. 'plugin' => 'shows',
  705. 'controller' => 'shows',
  706. 'action' => 'calendar',
  707. 'year' => 2007,
  708. 'month' => 10,
  709. 'min-forestilling'
  710. ));
  711. $expected = '/kalender/10/2007/min-forestilling';
  712. $this->assertEquals($expected, $result);
  713. }
  714. /**
  715. * Test URL generation with an admin prefix
  716. *
  717. * @return void
  718. */
  719. public function testUrlGenerationWithPrefix() {
  720. Configure::write('Routing.prefixes', array('admin'));
  721. Router::reload();
  722. Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
  723. Router::connect('/reset/*', array('admin' => true, 'controller' => 'users', 'action' => 'reset'));
  724. Router::connect('/tests', array('controller' => 'tests', 'action' => 'index'));
  725. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  726. Router::parseExtensions('rss', false);
  727. $request = new Request();
  728. $request->addParams(array(
  729. 'controller' => 'registrations',
  730. 'action' => 'admin_index',
  731. 'plugin' => null,
  732. 'prefix' => 'admin',
  733. '_ext' => 'html'
  734. ));
  735. $request->base = '';
  736. $request->here = '/admin/registrations/index';
  737. $request->webroot = '/';
  738. Router::setRequestInfo($request);
  739. $result = Router::url([]);
  740. $expected = '/admin/registrations/index';
  741. $this->assertEquals($expected, $result);
  742. Router::reload();
  743. Router::connect('/admin/subscriptions/:action/*', array('controller' => 'subscribe', 'prefix' => 'admin'));
  744. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  745. Router::parse('/');
  746. $request = new Request();
  747. $request->addParams(array(
  748. 'action' => 'index',
  749. 'plugin' => null,
  750. 'controller' => 'subscribe',
  751. 'prefix' => 'admin',
  752. ));
  753. $request->base = '/magazine';
  754. $request->here = '/magazine/admin/subscriptions/edit/1';
  755. $request->webroot = '/magazine/';
  756. Router::setRequestInfo($request);
  757. $result = Router::url(array('action' => 'edit', 1));
  758. $expected = '/magazine/admin/subscriptions/edit/1';
  759. $this->assertEquals($expected, $result);
  760. $result = Router::url(array('prefix' => 'admin', 'controller' => 'users', 'action' => 'login'));
  761. $expected = '/magazine/admin/users/login';
  762. $this->assertEquals($expected, $result);
  763. Router::reload();
  764. $request = new Request();
  765. $request->addParams(array(
  766. 'prefix' => 'admin',
  767. 'action' => 'index',
  768. 'plugin' => null,
  769. 'controller' => 'users',
  770. ));
  771. $request->base = '/';
  772. $request->here = '/';
  773. $request->webroot = '/';
  774. Router::setRequestInfo($request);
  775. Router::connect('/page/*', array('controller' => 'pages', 'action' => 'view', 'prefix' => 'admin'));
  776. Router::parse('/');
  777. $result = Router::url(array('prefix' => 'admin', 'controller' => 'pages', 'action' => 'view', 'my-page'));
  778. $expected = '/page/my-page';
  779. $this->assertEquals($expected, $result);
  780. Router::reload();
  781. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  782. $request = new Request();
  783. $request->addParams(array(
  784. 'plugin' => null,
  785. 'controller' => 'pages',
  786. 'action' => 'add',
  787. 'prefix' => 'admin'
  788. ));
  789. $request->base = '';
  790. $request->here = '/admin/pages/add';
  791. $request->webroot = '/';
  792. Router::setRequestInfo($request);
  793. Router::parse('/');
  794. $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'add', 'id' => false));
  795. $expected = '/admin/pages/add';
  796. $this->assertEquals($expected, $result);
  797. Router::reload();
  798. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  799. Router::parse('/');
  800. $request = new Request();
  801. $request->addParams(array(
  802. 'plugin' => null,
  803. 'controller' => 'pages',
  804. 'action' => 'add',
  805. 'prefix' => 'admin'
  806. ));
  807. $request->base = '';
  808. $request->here = '/admin/pages/add';
  809. $request->webroot = '/';
  810. Router::setRequestInfo($request);
  811. $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'add', 'id' => false));
  812. $expected = '/admin/pages/add';
  813. $this->assertEquals($expected, $result);
  814. Router::reload();
  815. Router::connect('/admin/:controller/:action/:id', array('prefix' => 'admin'), array('id' => '[0-9]+'));
  816. Router::parse('/');
  817. $request = new Request();
  818. Router::setRequestInfo(
  819. $request->addParams(array(
  820. 'plugin' => null,
  821. 'controller' => 'pages',
  822. 'action' => 'edit',
  823. 'pass' => array('284'),
  824. 'prefix' => 'admin'
  825. ))->addPaths(array(
  826. 'base' => '',
  827. 'here' => '/admin/pages/edit/284',
  828. 'webroot' => '/'
  829. ))
  830. );
  831. $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'edit', 'id' => '284'));
  832. $expected = '/admin/pages/edit/284';
  833. $this->assertEquals($expected, $result);
  834. Router::reload();
  835. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  836. Router::parse('/');
  837. $request = new Request();
  838. Router::setRequestInfo(
  839. $request->addParams(array(
  840. 'plugin' => null, 'controller' => 'pages', 'action' => 'add', 'prefix' => 'admin',
  841. ))->addPaths(array(
  842. 'base' => '', 'here' => '/admin/pages/add', 'webroot' => '/'
  843. ))
  844. );
  845. $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'add', 'id' => false));
  846. $expected = '/admin/pages/add';
  847. $this->assertEquals($expected, $result);
  848. Router::reload();
  849. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  850. Router::parse('/');
  851. $request = new Request();
  852. Router::setRequestInfo(
  853. $request->addParams(array(
  854. 'plugin' => null, 'controller' => 'pages', 'action' => 'edit', 'prefix' => 'admin',
  855. 'pass' => array('284')
  856. ))->addPaths(array(
  857. 'base' => '', 'here' => '/admin/pages/edit/284', 'webroot' => '/'
  858. ))
  859. );
  860. $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'edit', 284));
  861. $expected = '/admin/pages/edit/284';
  862. $this->assertEquals($expected, $result);
  863. Router::reload();
  864. Router::connect('/admin/posts/*', array('controller' => 'posts', 'action' => 'index', 'prefix' => 'admin'));
  865. Router::parse('/');
  866. Router::setRequestInfo(
  867. $request->addParams(array(
  868. 'plugin' => null, 'controller' => 'posts', 'action' => 'index', 'prefix' => 'admin',
  869. 'pass' => array('284')
  870. ))->addPaths(array(
  871. 'base' => '', 'here' => '/admin/posts', 'webroot' => '/'
  872. ))
  873. );
  874. $result = Router::url(array('all'));
  875. $expected = '/admin/posts/all';
  876. $this->assertEquals($expected, $result);
  877. }
  878. /**
  879. * testUrlGenerationWithExtensions method
  880. *
  881. * @return void
  882. */
  883. public function testUrlGenerationWithExtensions() {
  884. Router::connect('/:controller', array('action' => 'index'));
  885. Router::connect('/:controller/:action');
  886. Router::parse('/');
  887. $result = Router::url(array(
  888. 'plugin' => null,
  889. 'controller' => 'articles',
  890. 'action' => 'add',
  891. 'id' => null,
  892. '_ext' => 'json'
  893. ));
  894. $expected = '/articles/add.json';
  895. $this->assertEquals($expected, $result);
  896. $result = Router::url(array(
  897. 'plugin' => null,
  898. 'controller' => 'articles',
  899. 'action' => 'add',
  900. '_ext' => 'json'
  901. ));
  902. $expected = '/articles/add.json';
  903. $this->assertEquals($expected, $result);
  904. $result = Router::url(array(
  905. 'plugin' => null,
  906. 'controller' => 'articles',
  907. 'action' => 'index',
  908. 'id' => null,
  909. '_ext' => 'json'
  910. ));
  911. $expected = '/articles.json';
  912. $this->assertEquals($expected, $result);
  913. $result = Router::url(array(
  914. 'plugin' => null,
  915. 'controller' => 'articles',
  916. 'action' => 'index',
  917. 'ext' => 'json'
  918. ));
  919. $expected = '/articles.json';
  920. $this->assertEquals($expected, $result);
  921. }
  922. /**
  923. * Test url generation with named routes.
  924. */
  925. public function testUrlGenerationNamedRoute() {
  926. Router::connect(
  927. '/users',
  928. array('controller' => 'users', 'action' => 'index'),
  929. array('_name' => 'users-index')
  930. );
  931. Router::connect(
  932. '/users/:name',
  933. array('controller' => 'users', 'action' => 'view'),
  934. array('_name' => 'test')
  935. );
  936. $url = Router::url('test', array('name' => 'mark'));
  937. $this->assertEquals('/users/mark', $url);
  938. $url = Router::url('test', array('name' => 'mark', 'page' => 1, 'sort' => 'title', 'dir' => 'desc'));
  939. $this->assertEquals('/users/mark?page=1&sort=title&dir=desc', $url);
  940. $url = Router::url('users-index');
  941. $this->assertEquals('/users', $url);
  942. }
  943. /**
  944. * Test that using invalid names causes exceptions.
  945. *
  946. * @expectedException \Cake\Error\Exception
  947. * @return void
  948. */
  949. public function testNamedRouteException() {
  950. Router::connect(
  951. '/users/:name',
  952. array('controller' => 'users', 'action' => 'view'),
  953. array('_name' => 'test')
  954. );
  955. $url = Router::url('junk', array('name' => 'mark'));
  956. }
  957. /**
  958. * Test that url filters are applied to url params.
  959. *
  960. * @return void
  961. */
  962. public function testUrlGenerationWithUrlFilter() {
  963. Router::connect('/:lang/:controller/:action/*');
  964. $request = new Request();
  965. $request->addParams(array(
  966. 'lang' => 'en',
  967. 'controller' => 'posts',
  968. 'action' => 'index'
  969. ))->addPaths(array(
  970. 'base' => '',
  971. 'here' => '/'
  972. ));
  973. Router::pushRequest($request);
  974. $calledCount = 0;
  975. Router::addUrlFilter(function ($url, $request) use (&$calledCount) {
  976. $calledCount++;
  977. $url['lang'] = $request->lang;
  978. return $url;
  979. });
  980. Router::addUrlFilter(function ($url, $request) use (&$calledCount) {
  981. $calledCount++;
  982. $url[] = '1234';
  983. return $url;
  984. });
  985. $result = Router::url(array('controller' => 'tasks', 'action' => 'edit'));
  986. $this->assertEquals('/en/tasks/edit/1234', $result);
  987. $this->assertEquals(2, $calledCount);
  988. }
  989. /**
  990. * Test that plain strings urls work
  991. *
  992. * @return void
  993. */
  994. public function testUrlGenerationPlainString() {
  995. $mailto = 'mailto:mark@example.com';
  996. $result = Router::url($mailto);
  997. $this->assertEquals($mailto, $result);
  998. $js = 'javascript:alert("hi")';
  999. $result = Router::url($js);
  1000. $this->assertEquals($js, $result);
  1001. $hash = '#first';
  1002. $result = Router::url($hash);
  1003. $this->assertEquals($hash, $result);
  1004. }
  1005. /**
  1006. * test that you can leave active plugin routes with plugin = null
  1007. *
  1008. * @return void
  1009. */
  1010. public function testCanLeavePlugin() {
  1011. Router::connect('/admin/:controller', array('action' => 'index', 'prefix' => 'admin'));
  1012. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  1013. $request = new Request();
  1014. Router::setRequestInfo(
  1015. $request->addParams(array(
  1016. 'pass' => [],
  1017. 'prefix' => 'admin',
  1018. 'plugin' => 'this',
  1019. 'action' => 'index',
  1020. 'controller' => 'interesting',
  1021. ))->addPaths(array(
  1022. 'base' => '',
  1023. 'here' => '/admin/this/interesting/index',
  1024. 'webroot' => '/',
  1025. ))
  1026. );
  1027. $result = Router::url(array('plugin' => null, 'controller' => 'posts', 'action' => 'index'));
  1028. $this->assertEquals('/admin/posts', $result);
  1029. }
  1030. /**
  1031. * testUrlParsing method
  1032. *
  1033. * @return void
  1034. */
  1035. public function testUrlParsing() {
  1036. extract(Router::getNamedExpressions());
  1037. Router::connect(
  1038. '/posts/:value/:somevalue/:othervalue/*',
  1039. array('controller' => 'posts', 'action' => 'view'),
  1040. array('value', 'somevalue', 'othervalue')
  1041. );
  1042. $result = Router::parse('/posts/2007/08/01/title-of-post-here');
  1043. $expected = array(
  1044. 'value' => '2007',
  1045. 'somevalue' => '08',
  1046. 'othervalue' => '01',
  1047. 'controller' => 'posts',
  1048. 'action' => 'view',
  1049. 'plugin' => null,
  1050. 'pass' => array('0' => 'title-of-post-here')
  1051. );
  1052. $this->assertEquals($expected, $result);
  1053. Router::reload();
  1054. Router::connect(
  1055. '/posts/:year/:month/:day/*',
  1056. array('controller' => 'posts', 'action' => 'view'),
  1057. array('year' => $Year, 'month' => $Month, 'day' => $Day)
  1058. );
  1059. $result = Router::parse('/posts/2007/08/01/title-of-post-here');
  1060. $expected = array(
  1061. 'year' => '2007',
  1062. 'month' => '08',
  1063. 'day' => '01',
  1064. 'controller' => 'posts',
  1065. 'action' => 'view',
  1066. 'plugin' => null,
  1067. 'pass' => array('0' => 'title-of-post-here')
  1068. );
  1069. $this->assertEquals($expected, $result);
  1070. Router::reload();
  1071. Router::connect(
  1072. '/posts/:day/:year/:month/*',
  1073. array('controller' => 'posts', 'action' => 'view'),
  1074. array('year' => $Year, 'month' => $Month, 'day' => $Day)
  1075. );
  1076. $result = Router::parse('/posts/01/2007/08/title-of-post-here');
  1077. $expected = array(
  1078. 'day' => '01',
  1079. 'year' => '2007',
  1080. 'month' => '08',
  1081. 'controller' => 'posts',
  1082. 'action' => 'view',
  1083. 'plugin' => null,
  1084. 'pass' => array('0' => 'title-of-post-here')
  1085. );
  1086. $this->assertEquals($expected, $result);
  1087. Router::reload();
  1088. Router::connect(
  1089. '/posts/:month/:day/:year/*',
  1090. array('controller' => 'posts', 'action' => 'view'),
  1091. array('year' => $Year, 'month' => $Month, 'day' => $Day)
  1092. );
  1093. $result = Router::parse('/posts/08/01/2007/title-of-post-here');
  1094. $expected = array(
  1095. 'month' => '08',
  1096. 'day' => '01',
  1097. 'year' => '2007',
  1098. 'controller' => 'posts',
  1099. 'action' => 'view',
  1100. 'plugin' => null,
  1101. 'pass' => array('0' => 'title-of-post-here')
  1102. );
  1103. $this->assertEquals($expected, $result);
  1104. Router::reload();
  1105. Router::connect(
  1106. '/posts/:year/:month/:day/*',
  1107. array('controller' => 'posts', 'action' => 'view')
  1108. );
  1109. $result = Router::parse('/posts/2007/08/01/title-of-post-here');
  1110. $expected = array(
  1111. 'year' => '2007',
  1112. 'month' => '08',
  1113. 'day' => '01',
  1114. 'controller' => 'posts',
  1115. 'action' => 'view',
  1116. 'plugin' => null,
  1117. 'pass' => array('0' => 'title-of-post-here')
  1118. );
  1119. $this->assertEquals($expected, $result);
  1120. Router::reload();
  1121. require CAKE . 'Config/routes.php';
  1122. $result = Router::parse('/pages/display/home');
  1123. $expected = array(
  1124. 'plugin' => null,
  1125. 'pass' => array('home'),
  1126. 'controller' => 'pages',
  1127. 'action' => 'display'
  1128. );
  1129. $this->assertEquals($expected, $result);
  1130. $result = Router::parse('pages/display/home/');
  1131. $this->assertEquals($expected, $result);
  1132. $result = Router::parse('pages/display/home');
  1133. $this->assertEquals($expected, $result);
  1134. Router::reload();
  1135. Router::connect('/page/*', array('controller' => 'test'));
  1136. $result = Router::parse('/page/my-page');
  1137. $expected = array('pass' => array('my-page'), 'plugin' => null, 'controller' => 'test', 'action' => 'index');
  1138. $this->assertEquals($expected, $result);
  1139. Router::reload();
  1140. Router::connect(
  1141. '/:language/contact',
  1142. array('language' => 'eng', 'plugin' => 'contact', 'controller' => 'contact', 'action' => 'index'),
  1143. array('language' => '[a-z]{3}')
  1144. );
  1145. $result = Router::parse('/eng/contact');
  1146. $expected = array(
  1147. 'pass' => [],
  1148. 'language' => 'eng',
  1149. 'plugin' => 'contact',
  1150. 'controller' => 'contact',
  1151. 'action' => 'index'
  1152. );
  1153. $this->assertEquals($expected, $result);
  1154. Router::reload();
  1155. Router::connect('/forestillinger/:month/:year/*',
  1156. array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar'),
  1157. array('month' => '0[1-9]|1[012]', 'year' => '[12][0-9]{3}')
  1158. );
  1159. $result = Router::parse('/forestillinger/10/2007/min-forestilling');
  1160. $expected = array(
  1161. 'pass' => array('min-forestilling'),
  1162. 'plugin' => 'shows',
  1163. 'controller' => 'shows',
  1164. 'action' => 'calendar',
  1165. 'year' => 2007,
  1166. 'month' => 10
  1167. );
  1168. $this->assertEquals($expected, $result);
  1169. Router::reload();
  1170. Router::connect('/:controller/:action/*');
  1171. Router::connect('/', array('plugin' => 'pages', 'controller' => 'pages', 'action' => 'display'));
  1172. $result = Router::parse('/');
  1173. $expected = array('pass' => [], 'controller' => 'pages', 'action' => 'display', 'plugin' => 'pages');
  1174. $this->assertEquals($expected, $result);
  1175. $result = Router::parse('/posts/edit/0');
  1176. $expected = array('pass' => array(0), 'controller' => 'posts', 'action' => 'edit', 'plugin' => null);
  1177. $this->assertEquals($expected, $result);
  1178. Router::reload();
  1179. Router::connect(
  1180. '/posts/:id::url_title',
  1181. array('controller' => 'posts', 'action' => 'view'),
  1182. array('pass' => array('id', 'url_title'), 'id' => '[\d]+')
  1183. );
  1184. $result = Router::parse('/posts/5:sample-post-title');
  1185. $expected = array(
  1186. 'pass' => array('5', 'sample-post-title'),
  1187. 'id' => 5,
  1188. 'url_title' => 'sample-post-title',
  1189. 'plugin' => null,
  1190. 'controller' => 'posts',
  1191. 'action' => 'view'
  1192. );
  1193. $this->assertEquals($expected, $result);
  1194. Router::reload();
  1195. Router::connect(
  1196. '/posts/:id::url_title/*',
  1197. array('controller' => 'posts', 'action' => 'view'),
  1198. array('pass' => array('id', 'url_title'), 'id' => '[\d]+')
  1199. );
  1200. $result = Router::parse('/posts/5:sample-post-title/other/params/4');
  1201. $expected = array(
  1202. 'pass' => array('5', 'sample-post-title', 'other', 'params', '4'),
  1203. 'id' => 5,
  1204. 'url_title' => 'sample-post-title',
  1205. 'plugin' => null,
  1206. 'controller' => 'posts',
  1207. 'action' => 'view'
  1208. );
  1209. $this->assertEquals($expected, $result);
  1210. Router::reload();
  1211. Router::connect('/posts/view/*', array('controller' => 'posts', 'action' => 'view'));
  1212. $result = Router::parse('/posts/view/10?id=123&tab=abc');
  1213. $expected = array('pass' => array(10), 'plugin' => null, 'controller' => 'posts', 'action' => 'view', '?' => array('id' => '123', 'tab' => 'abc'));
  1214. $this->assertEquals($expected, $result);
  1215. Router::reload();
  1216. Router::connect(
  1217. '/posts/:url_title-(uuid::id)',
  1218. array('controller' => 'posts', 'action' => 'view'),
  1219. array('pass' => array('id', 'url_title'), 'id' => $UUID)
  1220. );
  1221. $result = Router::parse('/posts/sample-post-title-(uuid:47fc97a9-019c-41d1-a058-1fa3cbdd56cb)');
  1222. $expected = array(
  1223. 'pass' => array('47fc97a9-019c-41d1-a058-1fa3cbdd56cb', 'sample-post-title'),
  1224. 'id' => '47fc97a9-019c-41d1-a058-1fa3cbdd56cb',
  1225. 'url_title' => 'sample-post-title',
  1226. 'plugin' => null,
  1227. 'controller' => 'posts',
  1228. 'action' => 'view'
  1229. );
  1230. $this->assertEquals($expected, $result);
  1231. Router::reload();
  1232. Router::connect('/posts/view/*', array('controller' => 'posts', 'action' => 'view'));
  1233. $result = Router::parse('/posts/view/foo:bar/routing:fun');
  1234. $expected = array(
  1235. 'pass' => array('foo:bar', 'routing:fun'),
  1236. 'plugin' => null,
  1237. 'controller' => 'posts',
  1238. 'action' => 'view'
  1239. );
  1240. $this->assertEquals($expected, $result);
  1241. }
  1242. /**
  1243. * testUuidRoutes method
  1244. *
  1245. * @return void
  1246. */
  1247. public function testUuidRoutes() {
  1248. Router::connect(
  1249. '/subjects/add/:category_id',
  1250. array('controller' => 'subjects', 'action' => 'add'),
  1251. array('category_id' => '\w{8}-\w{4}-\w{4}-\w{4}-\w{12}')
  1252. );
  1253. $result = Router::parse('/subjects/add/4795d601-19c8-49a6-930e-06a8b01d17b7');
  1254. $expected = array(
  1255. 'pass' => [],
  1256. 'category_id' => '4795d601-19c8-49a6-930e-06a8b01d17b7',
  1257. 'plugin' => null,
  1258. 'controller' => 'subjects',
  1259. 'action' => 'add'
  1260. );
  1261. $this->assertEquals($expected, $result);
  1262. }
  1263. /**
  1264. * testRouteSymmetry method
  1265. *
  1266. * @return void
  1267. */
  1268. public function testRouteSymmetry() {
  1269. Router::connect(
  1270. "/:extra/page/:slug/*",
  1271. array('controller' => 'pages', 'action' => 'view', 'extra' => null),
  1272. array("extra" => '[a-z1-9_]*', "slug" => '[a-z1-9_]+', "action" => 'view')
  1273. );
  1274. $result = Router::parse('/some_extra/page/this_is_the_slug');
  1275. $expected = array(
  1276. 'pass' => [],
  1277. 'plugin' => null,
  1278. 'controller' => 'pages',
  1279. 'action' => 'view',
  1280. 'slug' => 'this_is_the_slug',
  1281. 'extra' => 'some_extra'
  1282. );
  1283. $this->assertEquals($expected, $result);
  1284. $result = Router::parse('/page/this_is_the_slug');
  1285. $expected = array(
  1286. 'pass' => [],
  1287. 'plugin' => null,
  1288. 'controller' => 'pages',
  1289. 'action' => 'view',
  1290. 'slug' => 'this_is_the_slug',
  1291. 'extra' => null
  1292. );
  1293. $this->assertEquals($expected, $result);
  1294. Router::reload();
  1295. Router::connect(
  1296. "/:extra/page/:slug/*",
  1297. array('controller' => 'pages', 'action' => 'view', 'extra' => null),
  1298. array("extra" => '[a-z1-9_]*', "slug" => '[a-z1-9_]+')
  1299. );
  1300. Router::parse('/');
  1301. $result = Router::url(array(
  1302. 'admin' => null,
  1303. 'plugin' => null,
  1304. 'controller' => 'pages',
  1305. 'action' => 'view',
  1306. 'slug' => 'this_is_the_slug',
  1307. 'extra' => null
  1308. ));
  1309. $expected = '/page/this_is_the_slug';
  1310. $this->assertEquals($expected, $result);
  1311. $result = Router::url(array(
  1312. 'admin' => null,
  1313. 'plugin' => null,
  1314. 'controller' => 'pages',
  1315. 'action' => 'view',
  1316. 'slug' => 'this_is_the_slug',
  1317. 'extra' => 'some_extra'
  1318. ));
  1319. $expected = '/some_extra/page/this_is_the_slug';
  1320. $this->assertEquals($expected, $result);
  1321. }
  1322. /**
  1323. * Test parse and reverse symmetry
  1324. *
  1325. * @return void
  1326. * @dataProvider parseReverseSymmetryData
  1327. */
  1328. public function testParseReverseSymmetry($url) {
  1329. $this->assertSame($url, Router::reverse(Router::parse($url) + array('url' => [])));
  1330. }
  1331. /**
  1332. * Data for parse and reverse test
  1333. *
  1334. * @return array
  1335. */
  1336. public function parseReverseSymmetryData() {
  1337. return array(
  1338. array('/'),
  1339. array('/controller/action'),
  1340. array('/controller/action/param'),
  1341. array('/controller/action?param1=value1&param2=value2'),
  1342. array('/controller/action/param?param1=value1'),
  1343. );
  1344. }
  1345. /**
  1346. * Test that Routing.prefixes are used when a Router instance is created
  1347. * or reset
  1348. *
  1349. * @return void
  1350. */
  1351. public function testRoutingPrefixesSetting() {
  1352. $restore = Configure::read('Routing');
  1353. Configure::write('Routing.prefixes', array('admin', 'member', 'super_user'));
  1354. Router::reload();
  1355. $result = Router::prefixes();
  1356. $expected = array('admin', 'member', 'super_user');
  1357. $this->assertEquals($expected, $result);
  1358. Configure::write('Routing.prefixes', array('admin', 'member'));
  1359. Router::reload();
  1360. $result = Router::prefixes();
  1361. $expected = array('admin', 'member');
  1362. $this->assertEquals($expected, $result);
  1363. Configure::write('Routing', $restore);
  1364. }
  1365. /**
  1366. * Test prefix routing and plugin combinations
  1367. *
  1368. * @return void
  1369. */
  1370. public function testPrefixRoutingAndPlugins() {
  1371. Configure::write('Routing.prefixes', array('admin'));
  1372. $paths = App::path('Plugin');
  1373. Plugin::load(array('TestPlugin'));
  1374. Router::reload();
  1375. require CAKE . 'Config/routes.php';
  1376. $request = new Request();
  1377. Router::setRequestInfo(
  1378. $request->addParams(array(
  1379. 'controller' => 'controller',
  1380. 'action' => 'action',
  1381. 'plugin' => null,
  1382. 'prefix' => 'admin'
  1383. ))->addPaths(array(
  1384. 'base' => '/',
  1385. 'here' => '/',
  1386. 'webroot' => '/base/',
  1387. ))
  1388. );
  1389. Router::parse('/');
  1390. $result = Router::url(array(
  1391. 'plugin' => 'test_plugin',
  1392. 'controller' => 'test_plugin',
  1393. 'action' => 'index'
  1394. ));
  1395. $expected = '/admin/test_plugin';
  1396. $this->assertEquals($expected, $result);
  1397. Router::reload();
  1398. require CAKE . 'Config/routes.php';
  1399. $request = new Request();
  1400. Router::setRequestInfo(
  1401. $request->addParams(array(
  1402. 'plugin' => 'test_plugin',
  1403. 'controller' => 'show_tickets',
  1404. 'action' => 'edit',
  1405. 'pass' => array('6'),
  1406. 'prefix' => 'admin',
  1407. ))->addPaths(array(
  1408. 'base' => '/',
  1409. 'here' => '/admin/shows/show_tickets/edit/6',
  1410. 'webroot' => '/',
  1411. ))
  1412. );
  1413. $result = Router::url(array(
  1414. 'plugin' => 'test_plugin',
  1415. 'controller' => 'show_tickets',
  1416. 'action' => 'edit',
  1417. 6,
  1418. 'prefix' => 'admin'
  1419. ));
  1420. $expected = '/admin/test_plugin/show_tickets/edit/6';
  1421. $this->assertEquals($expected, $result);
  1422. $result = Router::url(array(
  1423. 'plugin' => 'test_plugin',
  1424. 'controller' => 'show_tickets',
  1425. 'action' => 'index',
  1426. 'prefix' => 'admin'
  1427. ));
  1428. $expected = '/admin/test_plugin/show_tickets';
  1429. $this->assertEquals($expected, $result);
  1430. }
  1431. /**
  1432. * testParseExtensions method
  1433. *
  1434. * @return void
  1435. */
  1436. public function testParseExtensions() {
  1437. Router::extensions();
  1438. Router::parseExtensions('rss', false);
  1439. $this->assertContains('rss', Router::extensions());
  1440. }
  1441. /**
  1442. * testSetExtensions method
  1443. *
  1444. * @return void
  1445. */
  1446. public function testSetExtensions() {
  1447. Router::extensions();
  1448. Router::parseExtensions('rss', false);
  1449. $this->assertContains('rss', Router::extensions());
  1450. require CAKE . 'Config/routes.php';
  1451. $result = Router::parse('/posts.rss');
  1452. $this->assertEquals('rss', $result['_ext']);
  1453. $result = Router::parse('/posts.xml');
  1454. $this->assertFalse(isset($result['_ext']));
  1455. Router::parseExtensions(array('xml'));
  1456. $result = Router::extensions();
  1457. $this->assertContains('rss', $result);
  1458. $this->assertContains('xml', $result);
  1459. $result = Router::parse('/posts.xml');
  1460. $this->assertEquals('xml', $result['_ext']);
  1461. $result = Router::parseExtensions(array('pdf'), false);
  1462. $this->assertEquals(array('pdf'), $result);
  1463. }
  1464. /**
  1465. * testExtensionParsing method
  1466. *
  1467. * @return void
  1468. */
  1469. public function testExtensionParsing() {
  1470. Router::parseExtensions('rss', false);
  1471. require CAKE . 'Config/routes.php';
  1472. $result = Router::parse('/posts.rss');
  1473. $expected = array(
  1474. 'plugin' => null,
  1475. 'controller' => 'posts',
  1476. 'action' => 'index',
  1477. '_ext' => 'rss',
  1478. 'pass' => []
  1479. );
  1480. $this->assertEquals($expected, $result);
  1481. $result = Router::parse('/posts/view/1.rss');
  1482. $expected = array(
  1483. 'plugin' => null,
  1484. 'controller' => 'posts',
  1485. 'action' => 'view',
  1486. 'pass' => array('1'),
  1487. '_ext' => 'rss'
  1488. );
  1489. $this->assertEquals($expected, $result);
  1490. $result = Router::parse('/posts/view/1.rss?query=test');
  1491. $expected['?'] = array('query' => 'test');
  1492. $this->assertEquals($expected, $result);
  1493. Router::reload();
  1494. Router::parseExtensions(['rss', 'xml'], false);
  1495. require CAKE . 'Config/routes.php';
  1496. $result = Router::parse('/posts.xml');
  1497. $expected = array(
  1498. 'plugin' => null,
  1499. 'controller' => 'posts',
  1500. 'action' => 'index',
  1501. '_ext' => 'xml',
  1502. 'pass' => []
  1503. );
  1504. $this->assertEquals($expected, $result);
  1505. $result = Router::parse('/posts.atom?hello=goodbye');
  1506. $expected = array(
  1507. 'plugin' => null,
  1508. 'controller' => 'posts.atom',
  1509. 'action' => 'index',
  1510. 'pass' => [],
  1511. '?' => array('hello' => 'goodbye')
  1512. );
  1513. $this->assertEquals($expected, $result);
  1514. Router::reload();
  1515. Router::connect('/controller/action', array('controller' => 'controller', 'action' => 'action', '_ext' => 'rss'));
  1516. $result = Router::parse('/controller/action');
  1517. $expected = array('controller' => 'controller', 'action' => 'action', 'plugin' => null, '_ext' => 'rss', 'pass' => []);
  1518. $this->assertEquals($expected, $result);
  1519. Router::reload();
  1520. Router::connect('/controller/action', array('controller' => 'controller', 'action' => 'action', '_ext' => 'rss'));
  1521. $result = Router::parse('/controller/action');
  1522. $expected = array(
  1523. 'controller' => 'controller',
  1524. 'action' => 'action',
  1525. 'plugin' => null,
  1526. '_ext' => 'rss',
  1527. 'pass' => []
  1528. );
  1529. $this->assertEquals($expected, $result);
  1530. Router::reload();
  1531. Router::parseExtensions('rss', false);
  1532. Router::connect('/controller/action', array('controller' => 'controller', 'action' => 'action', '_ext' => 'rss'));
  1533. $result = Router::parse('/controller/action');
  1534. $expected = array(
  1535. 'controller' => 'controller',
  1536. 'action' => 'action',
  1537. 'plugin' => null,
  1538. '_ext' => 'rss',
  1539. 'pass' => []
  1540. );
  1541. $this->assertEquals($expected, $result);
  1542. }
  1543. /**
  1544. * Test newer style automatically generated prefix routes.
  1545. *
  1546. * @return void
  1547. * @see testUrlGenerationWithAutoPrefixes
  1548. */
  1549. public function testUrlGenerationWithAutoPrefixes() {
  1550. Router::reload();
  1551. Router::connect('/protected/:controller/:action/*', array('prefix' => 'protected'));
  1552. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  1553. Router::connect('/:controller/:action/*');
  1554. Router::parse('/');
  1555. $request = new Request();
  1556. Router::setRequestInfo(
  1557. $request->addParams(array(
  1558. 'plugin' => null, 'controller' => 'images', 'action' => 'index',
  1559. 'prefix' => null, 'protected' => false, 'url' => array('url' => 'images/index')
  1560. ))->addPaths(array(
  1561. 'base' => '',
  1562. 'here' => '/images/index',
  1563. 'webroot' => '/',
  1564. ))
  1565. );
  1566. $result = Router::url(array('controller' => 'images', 'action' => 'add'));
  1567. $expected = '/images/add';
  1568. $this->assertEquals($expected, $result);
  1569. $result = Router::url(array('controller' => 'images', 'action' => 'add', 'prefix' => 'protected'));
  1570. $expected = '/protected/images/add';
  1571. $this->assertEquals($expected, $result);
  1572. $result = Router::url(array('controller' => 'images', 'action' => 'add_protected_test', 'prefix' => 'protected'));
  1573. $expected = '/protected/images/add_protected_test';
  1574. $this->assertEquals($expected, $result);
  1575. $result = Router::url(array('action' => 'edit', 1));
  1576. $expected = '/images/edit/1';
  1577. $this->assertEquals($expected, $result);
  1578. $result = Router::url(array('action' => 'edit', 1, 'prefix' => 'protected'));
  1579. $expected = '/protected/images/edit/1';
  1580. $this->assertEquals($expected, $result);
  1581. $result = Router::url(array('action' => 'protectededit', 1, 'prefix' => 'protected'));
  1582. $expected = '/protected/images/protectededit/1';
  1583. $this->assertEquals($expected, $result);
  1584. $result = Router::url(array('action' => 'edit', 1, 'prefix' => 'protected'));
  1585. $expected = '/protected/images/edit/1';
  1586. $this->assertEquals($expected, $result);
  1587. $result = Router::url(array('controller' => 'others', 'action' => 'edit', 1));
  1588. $expected = '/others/edit/1';
  1589. $this->assertEquals($expected, $result);
  1590. $result = Router::url(array('controller' => 'others', 'action' => 'edit', 1, 'prefix' => 'protected'));
  1591. $expected = '/protected/others/edit/1';
  1592. $this->assertEquals($expected, $result);
  1593. }
  1594. /**
  1595. * Test that the ssl option works.
  1596. *
  1597. * @return void
  1598. */
  1599. public function testGenerationWithSslOption() {
  1600. Router::connect('/:controller/:action/*');
  1601. $_SERVER['HTTP_HOST'] = 'localhost';
  1602. $request = new Request();
  1603. Router::pushRequest(
  1604. $request->addParams(array(
  1605. 'plugin' => null, 'controller' => 'images', 'action' => 'index'
  1606. ))->addPaths(array(
  1607. 'base' => '',
  1608. 'here' => '/images/index',
  1609. 'webroot' => '/',
  1610. ))
  1611. );
  1612. $result = Router::url(array(
  1613. 'ssl' => true
  1614. ));
  1615. $this->assertEquals('https://localhost/images/index', $result);
  1616. $result = Router::url(array(
  1617. 'ssl' => false
  1618. ));
  1619. $this->assertEquals('http://localhost/images/index', $result);
  1620. }
  1621. /**
  1622. * Test ssl option when the current request is ssl.
  1623. *
  1624. * @return void
  1625. */
  1626. public function testGenerateWithSslInSsl() {
  1627. Router::connect('/:controller/:action/*');
  1628. $_SERVER['HTTP_HOST'] = 'localhost';
  1629. $_SERVER['HTTPS'] = 'on';
  1630. $request = new Request();
  1631. Router::pushRequest(
  1632. $request->addParams(array(
  1633. 'plugin' => null,
  1634. 'controller' => 'images',
  1635. 'action' => 'index'
  1636. ))->addPaths(array(
  1637. 'base' => '',
  1638. 'here' => '/images/index',
  1639. 'webroot' => '/',
  1640. ))
  1641. );
  1642. $result = Router::url(array(
  1643. 'ssl' => false
  1644. ));
  1645. $this->assertEquals('http://localhost/images/index', $result);
  1646. $result = Router::url(array(
  1647. 'ssl' => true
  1648. ));
  1649. $this->assertEquals('https://localhost/images/index', $result);
  1650. }
  1651. /**
  1652. * test that prefix routes persist when they are in the current request.
  1653. *
  1654. * @return void
  1655. */
  1656. public function testPrefixRoutePersistence() {
  1657. Router::reload();
  1658. Router::connect('/protected/:controller/:action', array('prefix' => 'protected'));
  1659. Router::connect('/:controller/:action');
  1660. Router::parse('/');
  1661. $request = new Request();
  1662. Router::setRequestInfo(
  1663. $request->addParams(array(
  1664. 'plugin' => null,
  1665. 'controller' => 'images',
  1666. 'action' => 'index',
  1667. 'prefix' => 'protected',
  1668. ))->addPaths(array(
  1669. 'base' => '',
  1670. 'here' => '/protected/images/index',
  1671. 'webroot' => '/',
  1672. ))
  1673. );
  1674. $result = Router::url(array('prefix' => 'protected', 'controller' => 'images', 'action' => 'add'));
  1675. $expected = '/protected/images/add';
  1676. $this->assertEquals($expected, $result);
  1677. $result = Router::url(array('controller' => 'images', 'action' => 'add'));
  1678. $expected = '/protected/images/add';
  1679. $this->assertEquals($expected, $result);
  1680. $result = Router::url(array('controller' => 'images', 'action' => 'add', 'prefix' => false));
  1681. $expected = '/images/add';
  1682. $this->assertEquals($expected, $result);
  1683. }
  1684. /**
  1685. * test that setting a prefix override the current one
  1686. *
  1687. * @return void
  1688. */
  1689. public function testPrefixOverride() {
  1690. Router::connect('/admin/:controller/:action', array('prefix' => 'admin'));
  1691. Router::connect('/protected/:controller/:action', array('prefix' => 'protected'));
  1692. $request = new Request();
  1693. Router::setRequestInfo(
  1694. $request->addParams(array(
  1695. 'plugin' => null, 'controller' => 'images', 'action' => 'index', 'prefix' => 'protected',
  1696. ))->addPaths(array(
  1697. 'base' => '',
  1698. 'here' => '/protected/images/index',
  1699. 'webroot' => '/',
  1700. ))
  1701. );
  1702. $result = Router::url(array('controller' => 'images', 'action' => 'add', 'prefix' => 'admin'));
  1703. $expected = '/admin/images/add';
  1704. $this->assertEquals($expected, $result);
  1705. $request = new Request();
  1706. Router::setRequestInfo(
  1707. $request->addParams(array(
  1708. 'plugin' => null,
  1709. 'controller' => 'images',
  1710. 'action' => 'index',
  1711. 'prefix' => 'admin',
  1712. ))->addPaths(array(
  1713. 'base' => '',
  1714. 'here' => '/admin/images/index',
  1715. 'webroot' => '/',
  1716. ))
  1717. );
  1718. $result = Router::url(array('controller' => 'images', 'action' => 'add', 'prefix' => 'protected'));
  1719. $expected = '/protected/images/add';
  1720. $this->assertEquals($expected, $result);
  1721. }
  1722. /**
  1723. * Test that well known route parameters are passed through.
  1724. *
  1725. * @return void
  1726. */
  1727. public function testRouteParamDefaults() {
  1728. Configure::write('Routing.prefixes', array('admin'));
  1729. Router::reload();
  1730. Router::connect('/cache/*', array('prefix' => false, 'plugin' => true, 'controller' => 0, 'action' => 1));
  1731. $url = Router::url(array('controller' => 0, 'action' => 1, 'test'));
  1732. $expected = '/';
  1733. $this->assertEquals($expected, $url);
  1734. $url = Router::url(array('prefix' => 1, 'controller' => 0, 'action' => 1, 'test'));
  1735. $expected = '/';
  1736. $this->assertEquals($expected, $url);
  1737. $url = Router::url(array('prefix' => 0, 'plugin' => 1, 'controller' => 0, 'action' => 1, 'test'));
  1738. $expected = '/cache/test';
  1739. $this->assertEquals($expected, $url);
  1740. }
  1741. /**
  1742. * testRemoveBase method
  1743. *
  1744. * @return void
  1745. */
  1746. public function testRemoveBase() {
  1747. Router::connect('/:controller/:action');
  1748. $request = new Request();
  1749. Router::setRequestInfo(
  1750. $request->addParams(array(
  1751. 'plugin' => null, 'controller' => 'controller', 'action' => 'index',
  1752. ))->addPaths(array(
  1753. 'base' => '/base',
  1754. 'here' => '/',
  1755. 'webroot' => '/base/',
  1756. ))
  1757. );
  1758. $result = Router::url(array('controller' => 'my_controller', 'action' => 'my_action'));
  1759. $expected = '/base/my_controller/my_action';
  1760. $this->assertEquals($expected, $result);
  1761. $result = Router::url(array('controller' => 'my_controller', 'action' => 'my_action', '_base' => false));
  1762. $expected = '/my_controller/my_action';
  1763. $this->assertEquals($expected, $result);
  1764. }
  1765. /**
  1766. * testPagesUrlParsing method
  1767. *
  1768. * @return void
  1769. */
  1770. public function testPagesUrlParsing() {
  1771. Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
  1772. Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
  1773. $result = Router::parse('/');
  1774. $expected = array('pass' => array('home'), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
  1775. $this->assertEquals($expected, $result);
  1776. $result = Router::parse('/pages/home/');
  1777. $expected = array('pass' => array('home'), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
  1778. $this->assertEquals($expected, $result);
  1779. Router::reload();
  1780. require CAKE . 'Config/routes.php';
  1781. Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
  1782. $result = Router::parse('/');
  1783. $expected = array('pass' => array('home'), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
  1784. $this->assertEquals($expected, $result);
  1785. Router::reload();
  1786. Router::connect('/', array('controller' => 'posts', 'action' => 'index'));
  1787. Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
  1788. $result = Router::parse('/pages/contact/');
  1789. $expected = array('pass' => array('contact'), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
  1790. $this->assertEquals($expected, $result);
  1791. }
  1792. /**
  1793. * test that requests with a trailing dot don't loose the do.
  1794. *
  1795. * @return void
  1796. */
  1797. public function testParsingWithTrailingPeriod() {
  1798. Router::reload();
  1799. Router::connect('/:controller/:action/*');
  1800. $result = Router::parse('/posts/view/something.');
  1801. $this->assertEquals('something.', $result['pass'][0], 'Period was chopped off %s');
  1802. $result = Router::parse('/posts/view/something. . .');
  1803. $this->assertEquals('something. . .', $result['pass'][0], 'Period was chopped off %s');
  1804. }
  1805. /**
  1806. * test that requests with a trailing dot don't loose the do.
  1807. *
  1808. * @return void
  1809. */
  1810. public function testParsingWithTrailingPeriodAndParseExtensions() {
  1811. Router::reload();
  1812. Router::connect('/:controller/:action/*');
  1813. Router::parseExtensions('json', false);
  1814. $result = Router::parse('/posts/view/something.');
  1815. $this->assertEquals('something.', $result['pass'][0], 'Period was chopped off %s');
  1816. $result = Router::parse('/posts/view/something. . .');
  1817. $this->assertEquals('something. . .', $result['pass'][0], 'Period was chopped off %s');
  1818. }
  1819. /**
  1820. * test that patterns work for :action
  1821. *
  1822. * @return void
  1823. */
  1824. public function testParsingWithPatternOnAction() {
  1825. Router::reload();
  1826. Router::connect(
  1827. '/blog/:action/*',
  1828. array('controller' => 'blog_posts'),
  1829. array('action' => 'other|actions')
  1830. );
  1831. $result = Router::parse('/blog/other');
  1832. $expected = array(
  1833. 'plugin' => null,
  1834. 'controller' => 'blog_posts',
  1835. 'action' => 'other',
  1836. 'pass' => [],
  1837. );
  1838. $this->assertEquals($expected, $result);
  1839. $result = Router::parse('/blog/foobar');
  1840. $this->assertSame([], $result);
  1841. $result = Router::url(array('controller' => 'blog_posts', 'action' => 'foo'));
  1842. $this->assertEquals('/', $result);
  1843. $result = Router::url(array('controller' => 'blog_posts', 'action' => 'actions'));
  1844. $this->assertEquals('/blog/actions', $result);
  1845. }
  1846. /**
  1847. * testParsingWithLiteralPrefixes method
  1848. *
  1849. * @return void
  1850. */
  1851. public function testParsingWithLiteralPrefixes() {
  1852. Configure::write('Routing.prefixes', []);
  1853. Router::reload();
  1854. $adminParams = array('prefix' => 'admin');
  1855. Router::connect('/admin/:controller', $adminParams);
  1856. Router::connect('/admin/:controller/:action', $adminParams);
  1857. Router::connect('/admin/:controller/:action/*', $adminParams);
  1858. $request = new Request();
  1859. Router::setRequestInfo(
  1860. $request->addParams(array(
  1861. 'plugin' => null, 'controller' => 'controller', 'action' => 'index'
  1862. ))->addPaths(array(
  1863. 'base' => '/base',
  1864. 'here' => '/',
  1865. 'webroot' => '/base/',
  1866. ))
  1867. );
  1868. $result = Router::parse('/admin/posts/');
  1869. $expected = array('pass' => [], 'prefix' => 'admin', 'plugin' => null, 'controller' => 'posts', 'action' => 'index');
  1870. $this->assertEquals($expected, $result);
  1871. $result = Router::parse('/admin/posts');
  1872. $this->assertEquals($expected, $result);
  1873. $result = Router::url(array('prefix' => 'admin', 'controller' => 'posts'));
  1874. $expected = '/base/admin/posts';
  1875. $this->assertEquals($expected, $result);
  1876. $result = Router::prefixes();
  1877. $expected = [];
  1878. $this->assertEquals($expected, $result);
  1879. Router::reload();
  1880. $prefixParams = array('prefix' => 'members');
  1881. Router::connect('/members/:controller', $prefixParams);
  1882. Router::connect('/members/:controller/:action', $prefixParams);
  1883. Router::connect('/members/:controller/:action/*', $prefixParams);
  1884. $request = new Request();
  1885. Router::setRequestInfo(
  1886. $request->addParams(array(
  1887. 'plugin' => null, 'controller' => 'controller', 'action' => 'index',
  1888. ))->addPaths(array(
  1889. 'base' => '/base',
  1890. 'here' => '/',
  1891. 'webroot' => '/',
  1892. ))
  1893. );
  1894. $result = Router::parse('/members/posts/index');
  1895. $expected = array('pass' => [], 'prefix' => 'members', 'plugin' => null, 'controller' => 'posts', 'action' => 'index');
  1896. $this->assertEquals($expected, $result);
  1897. $result = Router::url(array('prefix' => 'members', 'controller' => 'users', 'action' => 'add'));
  1898. $expected = '/base/members/users/add';
  1899. $this->assertEquals($expected, $result);
  1900. }
  1901. /**
  1902. * Tests URL generation with flags and prefixes in and out of context
  1903. *
  1904. * @return void
  1905. */
  1906. public function testUrlWritingWithPrefixes() {
  1907. Router::connect('/company/:controller/:action/*', array('prefix' => 'company'));
  1908. Router::connect('/:action', array('controller' => 'users'));
  1909. /*
  1910. $result = Router::url(array('controller' => 'users', 'action' => 'login', 'prefix' => 'company'));
  1911. $expected = '/company/users/login';
  1912. $this->assertEquals($expected, $result);
  1913. $result = Router::url(array('controller' => 'users', 'action' => 'login', 'prefix' => 'company'));
  1914. $expected = '/company/users/login';
  1915. $this->assertEquals($expected, $result);
  1916. */
  1917. $request = new Request();
  1918. Router::setRequestInfo(
  1919. $request->addParams(array(
  1920. 'plugin' => null,
  1921. 'controller' => 'users',
  1922. 'action' => 'login',
  1923. 'prefix' => 'company'
  1924. ))->addPaths(array(
  1925. 'base' => '/',
  1926. 'here' => '/',
  1927. 'webroot' => '/base/',
  1928. ))
  1929. );
  1930. $result = Router::url(array('controller' => 'users', 'action' => 'login', 'prefix' => false));
  1931. $expected = '/login';
  1932. $this->assertEquals($expected, $result);
  1933. }
  1934. /**
  1935. * test url generation with prefixes and custom routes
  1936. *
  1937. * @return void
  1938. */
  1939. public function testUrlWritingWithPrefixesAndCustomRoutes() {
  1940. Router::connect(
  1941. '/admin/login',
  1942. array('controller' => 'users', 'action' => 'login', 'prefix' => 'admin')
  1943. );
  1944. $request = new Request();
  1945. Router::setRequestInfo(
  1946. $request->addParams(array(
  1947. 'plugin' => null, 'controller' => 'posts', 'action' => 'index',
  1948. 'prefix' => 'admin'
  1949. ))->addPaths(array(
  1950. 'base' => '/',
  1951. 'here' => '/',
  1952. 'webroot' => '/',
  1953. ))
  1954. );
  1955. $result = Router::url(array('controller' => 'users', 'action' => 'login'));
  1956. $this->assertEquals('/admin/login', $result);
  1957. $result = Router::url(array('controller' => 'users', 'action' => 'login'));
  1958. $this->assertEquals('/admin/login', $result);
  1959. }
  1960. /**
  1961. * testPassedArgsOrder method
  1962. *
  1963. * @return void
  1964. */
  1965. public function testPassedArgsOrder() {
  1966. Router::connect('/test-passed/*', array('controller' => 'pages', 'action' => 'display', 'home'));
  1967. Router::connect('/test2/*', array('controller' => 'pages', 'action' => 'display', 2));
  1968. Router::connect('/test/*', array('controller' => 'pages', 'action' => 'display', 1));
  1969. Router::parse('/');
  1970. $result = Router::url(array('controller' => 'pages', 'action' => 'display', 1, 'whatever'));
  1971. $expected = '/test/whatever';
  1972. $this->assertEquals($expected, $result);
  1973. $result = Router::url(array('controller' => 'pages', 'action' => 'display', 2, 'whatever'));
  1974. $expected = '/test2/whatever';
  1975. $this->assertEquals($expected, $result);
  1976. $result = Router::url(array('controller' => 'pages', 'action' => 'display', 'home', 'whatever'));
  1977. $expected = '/test-passed/whatever';
  1978. $this->assertEquals($expected, $result);
  1979. }
  1980. /**
  1981. * testRegexRouteMatching method
  1982. *
  1983. * @return void
  1984. */
  1985. public function testRegexRouteMatching() {
  1986. Router::connect('/:locale/:controller/:action/*', [], array('locale' => 'dan|eng'));
  1987. $result = Router::parse('/eng/test/test_action');
  1988. $expected = array('pass' => [], 'locale' => 'eng', 'controller' => 'test', 'action' => 'test_action', 'plugin' => null);
  1989. $this->assertEquals($expected, $result);
  1990. $result = Router::parse('/badness/test/test_action');
  1991. $this->assertSame([], $result);
  1992. Router::reload();
  1993. Router::connect('/:locale/:controller/:action/*', [], array('locale' => 'dan|eng'));
  1994. $request = new Request();
  1995. Router::setRequestInfo(
  1996. $request->addParams(array(
  1997. 'plugin' => null,
  1998. 'controller' => 'test',
  1999. 'action' => 'index',
  2000. 'url' => array('url' => 'test/test_action')
  2001. ))->addPaths(array(
  2002. 'base' => '',
  2003. 'here' => '/test/test_action',
  2004. 'webroot' => '/',
  2005. ))
  2006. );
  2007. $result = Router::url(array('action' => 'test_another_action'));
  2008. $expected = '/';
  2009. $this->assertEquals($expected, $result);
  2010. $result = Router::url(array('action' => 'test_another_action', 'locale' => 'eng'));
  2011. $expected = '/eng/test/test_another_action';
  2012. $this->assertEquals($expected, $result);
  2013. }
  2014. /**
  2015. * test that connectDefaults() can disable default route connection
  2016. *
  2017. * @return void
  2018. */
  2019. public function testDefaultsMethod() {
  2020. Router::connect('/test/*', array('controller' => 'pages', 'action' => 'display', 2));
  2021. $result = Router::parse('/posts/edit/5');
  2022. $this->assertFalse(isset($result['controller']));
  2023. $this->assertFalse(isset($result['action']));
  2024. }
  2025. /**
  2026. * test that the required default routes are connected.
  2027. *
  2028. * @return void
  2029. */
  2030. public function testConnectDefaultRoutes() {
  2031. Plugin::load(array('TestPlugin', 'PluginJs'));
  2032. Router::reload();
  2033. require CAKE . 'Config/routes.php';
  2034. $result = Router::url(array('plugin' => 'plugin_js', 'controller' => 'js_file', 'action' => 'index'));
  2035. $this->assertEquals('/plugin_js/js_file', $result);
  2036. $result = Router::parse('/plugin_js/js_file');
  2037. $expected = array(
  2038. 'plugin' => 'plugin_js', 'controller' => 'js_file', 'action' => 'index',
  2039. 'pass' => []
  2040. );
  2041. $this->assertEquals($expected, $result);
  2042. $result = Router::url(array('plugin' => 'test_plugin', 'controller' => 'test_plugin', 'action' => 'index'));
  2043. $this->assertEquals('/test_plugin', $result, 'Plugin shortcut route generation failed.');
  2044. $result = Router::parse('/test_plugin');
  2045. $expected = array(
  2046. 'plugin' => 'test_plugin',
  2047. 'controller' => 'test_plugin',
  2048. 'action' => 'index',
  2049. 'pass' => []
  2050. );
  2051. $this->assertEquals($expected, $result, 'Plugin shortcut route broken.');
  2052. }
  2053. /**
  2054. * test using a custom route class for route connection
  2055. *
  2056. * @return void
  2057. */
  2058. public function testUsingCustomRouteClass() {
  2059. $routes = $this->getMock('Cake\Routing\RouteCollection');
  2060. $this->getMock('Cake\Routing\Route\Route', [], [], 'MockConnectedRoute', false);
  2061. Router::setRouteCollection($routes);
  2062. $routes->expects($this->once())
  2063. ->method('add')
  2064. ->with($this->isInstanceOf('\MockConnectedRoute'));
  2065. Router::connect(
  2066. '/:slug',
  2067. array('controller' => 'posts', 'action' => 'view'),
  2068. array('routeClass' => '\MockConnectedRoute', 'slug' => '[a-z_-]+')
  2069. );
  2070. }
  2071. /**
  2072. * test using custom route class in PluginDot notation
  2073. *
  2074. * @return void
  2075. */
  2076. public function testUsingCustomRouteClassPluginDotSyntax() {
  2077. Plugin::load('TestPlugin');
  2078. Router::connect(
  2079. '/:slug',
  2080. array('controller' => 'posts', 'action' => 'view'),
  2081. array('routeClass' => 'TestPlugin.TestRoute', 'slug' => '[a-z_-]+')
  2082. );
  2083. $this->assertTrue(true); // Just to make sure the connect do not throw exception
  2084. Plugin::unload('TestPlugin');
  2085. }
  2086. /**
  2087. * test that route classes must extend \Cake\Routing\Route\Route
  2088. *
  2089. * @expectedException \Cake\Error\Exception
  2090. * @return void
  2091. */
  2092. public function testCustomRouteException() {
  2093. Router::connect('/:controller', [], array('routeClass' => 'Object'));
  2094. }
  2095. /**
  2096. * test reversing parameter arrays back into strings.
  2097. *
  2098. * Mark the router as initialized so it doesn't auto-load routes
  2099. *
  2100. * @return void
  2101. */
  2102. public function testReverse() {
  2103. Router::connect('/:controller/:action/*');
  2104. $params = array(
  2105. 'controller' => 'posts',
  2106. 'action' => 'view',
  2107. 'pass' => array(1),
  2108. 'url' => [],
  2109. 'autoRender' => 1,
  2110. 'bare' => 1,
  2111. 'return' => 1,
  2112. 'requested' => 1,
  2113. '_Token' => array('key' => 'sekret')
  2114. );
  2115. $result = Router::reverse($params);
  2116. $this->assertEquals('/posts/view/1', $result);
  2117. Router::reload();
  2118. Router::connect('/:lang/:controller/:action/*', [], array('lang' => '[a-z]{3}'));
  2119. $params = array(
  2120. 'lang' => 'eng',
  2121. 'controller' => 'posts',
  2122. 'action' => 'view',
  2123. 'pass' => array(1),
  2124. 'url' => array('url' => 'eng/posts/view/1')
  2125. );
  2126. $result = Router::reverse($params);
  2127. $this->assertEquals('/eng/posts/view/1', $result);
  2128. $params = array(
  2129. 'lang' => 'eng',
  2130. 'controller' => 'posts',
  2131. 'action' => 'view',
  2132. 1,
  2133. '?' => ['foo' => 'bar']
  2134. );
  2135. $result = Router::reverse($params);
  2136. $this->assertEquals('/eng/posts/view/1?foo=bar', $result);
  2137. $params = array(
  2138. 'lang' => 'eng',
  2139. 'controller' => 'posts',
  2140. 'action' => 'view',
  2141. 'pass' => array(1),
  2142. 'url' => array('url' => 'eng/posts/view/1', 'foo' => 'bar', 'baz' => 'quu'),
  2143. 'paging' => [],
  2144. 'models' => []
  2145. );
  2146. $result = Router::reverse($params);
  2147. $this->assertEquals('/eng/posts/view/1?foo=bar&baz=quu', $result);
  2148. $request = new Request('/eng/posts/view/1');
  2149. $request->addParams(array(
  2150. 'lang' => 'eng',
  2151. 'controller' => 'posts',
  2152. 'action' => 'view',
  2153. 'pass' => array(1),
  2154. ));
  2155. $request->query = array('url' => 'eng/posts/view/1', 'test' => 'value');
  2156. $result = Router::reverse($request);
  2157. $expected = '/eng/posts/view/1?test=value';
  2158. $this->assertEquals($expected, $result);
  2159. $params = array(
  2160. 'lang' => 'eng',
  2161. 'controller' => 'posts',
  2162. 'action' => 'view',
  2163. 'pass' => array(1),
  2164. 'url' => array('url' => 'eng/posts/view/1')
  2165. );
  2166. $result = Router::reverse($params, true);
  2167. $this->assertRegExp('/^http(s)?:\/\//', $result);
  2168. }
  2169. /**
  2170. * Test that extensions work with Router::reverse()
  2171. *
  2172. * @return void
  2173. */
  2174. public function testReverseWithExtension() {
  2175. Router::connect('/:controller/:action/*');
  2176. Router::parseExtensions('json', false);
  2177. $request = new Request('/posts/view/1.json');
  2178. $request->addParams(array(
  2179. 'controller' => 'posts',
  2180. 'action' => 'view',
  2181. 'pass' => array(1),
  2182. 'ext' => 'json',
  2183. ));
  2184. $request->query = [];
  2185. $result = Router::reverse($request);
  2186. $expected = '/posts/view/1.json';
  2187. $this->assertEquals($expected, $result);
  2188. }
  2189. /**
  2190. * test that setRequestInfo can accept arrays and turn that into a Request object.
  2191. *
  2192. * @return void
  2193. */
  2194. public function testSetRequestInfoLegacy() {
  2195. Router::setRequestInfo(array(
  2196. array(
  2197. 'plugin' => null, 'controller' => 'images', 'action' => 'index',
  2198. 'url' => array('url' => 'protected/images/index')
  2199. ),
  2200. array(
  2201. 'base' => '',
  2202. 'here' => '/protected/images/index',
  2203. 'webroot' => '/',
  2204. )
  2205. ));
  2206. $result = Router::getRequest();
  2207. $this->assertEquals('images', $result->controller);
  2208. $this->assertEquals('index', $result->action);
  2209. $this->assertEquals('', $result->base);
  2210. $this->assertEquals('/protected/images/index', $result->here);
  2211. $this->assertEquals('/', $result->webroot);
  2212. }
  2213. /**
  2214. * test get request.
  2215. *
  2216. * @return void
  2217. */
  2218. public function testGetRequest() {
  2219. $requestA = new Request('/');
  2220. $requestB = new Request('/posts');
  2221. Router::pushRequest($requestA);
  2222. Router::pushRequest($requestB);
  2223. $this->assertSame($requestA, Router::getRequest(false));
  2224. $this->assertSame($requestB, Router::getRequest(true));
  2225. }
  2226. /**
  2227. * Test that Router::url() uses the first request
  2228. */
  2229. public function testUrlWithRequestAction() {
  2230. Router::connect('/:controller', array('action' => 'index'));
  2231. Router::connect('/:controller/:action');
  2232. $firstRequest = new Request('/posts/index');
  2233. $firstRequest->addParams(array(
  2234. 'plugin' => null,
  2235. 'controller' => 'posts',
  2236. 'action' => 'index'
  2237. ))->addPaths(array('base' => ''));
  2238. $secondRequest = new Request('/posts/index');
  2239. $secondRequest->addParams(array(
  2240. 'requested' => 1,
  2241. 'plugin' => null,
  2242. 'controller' => 'comments',
  2243. 'action' => 'listing'
  2244. ))->addPaths(array('base' => ''));
  2245. Router::setRequestInfo($firstRequest);
  2246. Router::setRequestInfo($secondRequest);
  2247. $result = Router::url(array('_base' => false));
  2248. $this->assertEquals('/comments/listing', $result, 'with second requests, the last should win.');
  2249. Router::popRequest();
  2250. $result = Router::url(array('_base' => false));
  2251. $this->assertEquals('/posts', $result, 'with second requests, the last should win.');
  2252. // Make sure that popping an empty request doesn't fail.
  2253. Router::popRequest();
  2254. }
  2255. /**
  2256. * test that a route object returning a full URL is not modified.
  2257. *
  2258. * @return void
  2259. */
  2260. public function testUrlFullUrlReturnFromRoute() {
  2261. $url = 'http://example.com/posts/view/1';
  2262. $routes = $this->getMock('Cake\Routing\RouteCollection');
  2263. Router::setRouteCollection($routes);
  2264. $routes->expects($this->any())->method('match')
  2265. ->will($this->returnValue($url));
  2266. $result = Router::url(array('controller' => 'posts', 'action' => 'view', 1));
  2267. $this->assertEquals($url, $result);
  2268. }
  2269. /**
  2270. * test protocol in url
  2271. *
  2272. * @return void
  2273. */
  2274. public function testUrlProtocol() {
  2275. $url = 'http://example.com';
  2276. $this->assertEquals($url, Router::url($url));
  2277. $url = 'ed2k://example.com';
  2278. $this->assertEquals($url, Router::url($url));
  2279. $url = 'svn+ssh://example.com';
  2280. $this->assertEquals($url, Router::url($url));
  2281. $url = '://example.com';
  2282. $this->assertEquals($url, Router::url($url));
  2283. $url = '//example.com';
  2284. $this->assertEquals($url, Router::url($url));
  2285. $url = 'javascript:void(0)';
  2286. $this->assertEquals($url, Router::url($url));
  2287. $url = 'tel:012345-678';
  2288. $this->assertEquals($url, Router::url($url));
  2289. $url = 'sms:012345-678';
  2290. $this->assertEquals($url, Router::url($url));
  2291. $url = '#here';
  2292. $this->assertEquals($url, Router::url($url));
  2293. $url = '?param=0';
  2294. $this->assertEquals($url, Router::url($url));
  2295. $url = '/posts/index#here';
  2296. $expected = Configure::read('App.fullBaseUrl') . '/posts/index#here';
  2297. $this->assertEquals($expected, Router::url($url, true));
  2298. }
  2299. /**
  2300. * Testing that patterns on the :action param work properly.
  2301. *
  2302. * @return void
  2303. */
  2304. public function testPatternOnAction() {
  2305. $route = new Route(
  2306. '/blog/:action/*',
  2307. array('controller' => 'blog_posts'),
  2308. array('action' => 'other|actions')
  2309. );
  2310. $result = $route->match(array('controller' => 'blog_posts', 'action' => 'foo'));
  2311. $this->assertFalse($result);
  2312. $result = $route->match(array('controller' => 'blog_posts', 'action' => 'actions'));
  2313. $this->assertEquals('/blog/actions/', $result);
  2314. $result = $route->parse('/blog/other');
  2315. $expected = array('controller' => 'blog_posts', 'action' => 'other', 'pass' => []);
  2316. $this->assertEquals($expected, $result);
  2317. $result = $route->parse('/blog/foobar');
  2318. $this->assertFalse($result);
  2319. }
  2320. /**
  2321. * Tests resourceMap as getter and setter.
  2322. *
  2323. * @return void
  2324. */
  2325. public function testResourceMap() {
  2326. $default = Router::resourceMap();
  2327. $expected = array(
  2328. array('action' => 'index', 'method' => 'GET', 'id' => false),
  2329. array('action' => 'view', 'method' => 'GET', 'id' => true),
  2330. array('action' => 'add', 'method' => 'POST', 'id' => false),
  2331. array('action' => 'edit', 'method' => 'PUT', 'id' => true),
  2332. array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
  2333. array('action' => 'edit', 'method' => 'POST', 'id' => true)
  2334. );
  2335. $this->assertEquals($expected, $default);
  2336. $custom = array(
  2337. array('action' => 'index', 'method' => 'GET', 'id' => false),
  2338. array('action' => 'view', 'method' => 'GET', 'id' => true),
  2339. array('action' => 'add', 'method' => 'POST', 'id' => false),
  2340. array('action' => 'edit', 'method' => 'PUT', 'id' => true),
  2341. array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
  2342. array('action' => 'update', 'method' => 'POST', 'id' => true)
  2343. );
  2344. Router::resourceMap($custom);
  2345. $this->assertEquals(Router::resourceMap(), $custom);
  2346. Router::resourceMap($default);
  2347. }
  2348. /**
  2349. * test setting redirect routes
  2350. *
  2351. * @return void
  2352. */
  2353. public function testRouteRedirection() {
  2354. $routes = new RouteCollection();
  2355. Router::setRouteCollection($routes);
  2356. Router::redirect('/blog', array('controller' => 'posts'), array('status' => 302));
  2357. Router::connect('/:controller', array('action' => 'index'));
  2358. $this->assertEquals(2, count($routes));
  2359. $routes->get(0)->response = $this->getMock(
  2360. 'Cake\Network\Response',
  2361. array('_sendHeader', 'stop')
  2362. );
  2363. $this->assertEquals(302, $routes->get(0)->options['status']);
  2364. Router::parse('/blog');
  2365. $header = $routes->get(0)->response->header();
  2366. $this->assertEquals(Router::url('/posts', true), $header['Location']);
  2367. $this->assertEquals(302, $routes->get(0)->response->statusCode());
  2368. $routes->get(0)->response = $this->getMock(
  2369. 'Cake\Network\Response',
  2370. array('_sendHeader')
  2371. );
  2372. Router::parse('/not-a-match');
  2373. $this->assertSame([], $routes->get(0)->response->header());
  2374. }
  2375. /**
  2376. * Test setting the default route class
  2377. *
  2378. * @return void
  2379. */
  2380. public function testDefaultRouteClass() {
  2381. $routes = $this->getMock('Cake\Routing\RouteCollection');
  2382. $this->getMock('Cake\Routing\Route\Route', [], array('/test'), 'TestDefaultRouteClass');
  2383. $routes->expects($this->once())
  2384. ->method('add')
  2385. ->with($this->isInstanceOf('\TestDefaultRouteClass'));
  2386. Router::setRouteCollection($routes);
  2387. Router::defaultRouteClass('\TestDefaultRouteClass');
  2388. Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
  2389. }
  2390. /**
  2391. * Test getting the default route class
  2392. *
  2393. * @return void
  2394. */
  2395. public function testDefaultRouteClassGetter() {
  2396. $routeClass = '\TestDefaultRouteClass';
  2397. Router::defaultRouteClass($routeClass);
  2398. $this->assertEquals($routeClass, Router::defaultRouteClass());
  2399. $this->assertEquals($routeClass, Router::defaultRouteClass(null));
  2400. }
  2401. /**
  2402. * Test that route classes must extend Cake\Routing\Route\Route
  2403. *
  2404. * @expectedException \Cake\Error\Exception
  2405. * @return void
  2406. */
  2407. public function testDefaultRouteException() {
  2408. Router::defaultRouteClass('');
  2409. Router::connect('/:controller', []);
  2410. }
  2411. /**
  2412. * Test that route classes must extend Cake\Routing\Route\Route
  2413. *
  2414. * @expectedException \Cake\Error\Exception
  2415. * @return void
  2416. */
  2417. public function testSettingInvalidDefaultRouteException() {
  2418. Router::defaultRouteClass('Object');
  2419. }
  2420. /**
  2421. * Test that class must exist
  2422. *
  2423. * @expectedException \Cake\Error\Exception
  2424. * @return void
  2425. */
  2426. public function testSettingNonExistentDefaultRouteException() {
  2427. Router::defaultRouteClass('NonExistentClass');
  2428. }
  2429. /**
  2430. * Test that the compatibility method for incoming urls works.
  2431. *
  2432. * @return void
  2433. */
  2434. public function testParseNamedParameters() {
  2435. $request = new Request();
  2436. $request->addParams(array(
  2437. 'controller' => 'posts',
  2438. 'action' => 'index',
  2439. ));
  2440. $result = Router::parseNamedParams($request);
  2441. $this->assertSame([], $result->params['named']);
  2442. $request = new Request();
  2443. $request->addParams(array(
  2444. 'controller' => 'posts',
  2445. 'action' => 'index',
  2446. 'pass' => array('home', 'one:two', 'three:four', 'five[nested][0]:six', 'five[nested][1]:seven')
  2447. ));
  2448. Router::parseNamedParams($request);
  2449. $expected = array(
  2450. 'plugin' => null,
  2451. 'controller' => 'posts',
  2452. 'action' => 'index',
  2453. '_ext' => null,
  2454. 'pass' => array('home'),
  2455. 'named' => array(
  2456. 'one' => 'two',
  2457. 'three' => 'four',
  2458. 'five' => array(
  2459. 'nested' => array('six', 'seven')
  2460. )
  2461. )
  2462. );
  2463. $this->assertEquals($expected, $request->params);
  2464. }
  2465. /**
  2466. * Test promote()
  2467. *
  2468. * @return void
  2469. */
  2470. public function testPromote() {
  2471. Router::connect('/:controller/:action/*');
  2472. Router::connect('/:lang/:controller/:action/*');
  2473. $result = Router::url(['controller' => 'posts', 'action' => 'index', 'lang' => 'en']);
  2474. $this->assertEquals('/posts/index?lang=en', $result, 'First route should match');
  2475. Router::promote();
  2476. $result = Router::url(['controller' => 'posts', 'action' => 'index', 'lang' => 'en']);
  2477. $this->assertEquals('/en/posts/index', $result, 'promote() should move 2nd route ahead.');
  2478. }
  2479. }