RouterTest.php 79 KB

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