RouterTest.php 79 KB

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