1<?php 2/** 3 * Horde Routes package 4 * 5 * This package is heavily inspired by the Python "Routes" library 6 * by Ben Bangert (http://routes.groovie.org). Routes is based 7 * largely on ideas from Ruby on Rails (http://www.rubyonrails.org). 8 * 9 * @author Maintainable Software, LLC. (http://www.maintainable.com) 10 * @author Mike Naberezny <mike@maintainable.com> 11 * @license http://www.horde.org/licenses/bsd BSD 12 * @package Routes 13 */ 14 15/** 16 * @package Routes 17 */ 18class Horde_Routes_RecognitionTest extends PHPUnit_Framework_TestCase 19{ 20 public function testRegexpCharEscaping() 21 { 22 $m = new Horde_Routes_Mapper(); 23 $m->connect(':controller/:(action).:(id)'); 24 $m->createRegs(array('content')); 25 26 $this->assertNull($m->match('/content/view#2')); 27 28 $matchdata = array('action' => 'view', 'controller' => 'content', 'id' => '2'); 29 $this->assertEquals($matchdata, $m->match('/content/view.2')); 30 31 $m->connect(':controller/:action/:id'); 32 $m->createRegs(array('content', 'find.all')); 33 34 $matchdata = array('action' => 'view#2', 'controller' => 'content', 'id' => null); 35 $this->assertEquals($matchdata, $m->match('/content/view#2')); 36 37 $matchdata = array('action' => 'view', 'controller' => 'find.all', 'id'=> null); 38 $this->assertEquals($matchdata, $m->match('/find.all/view')); 39 40 $this->assertNull($m->match('/findzall/view')); 41 } 42 43 public function testAllStatic() 44 { 45 $m = new Horde_Routes_Mapper(); 46 $m->connect('hello/world/how/are/you', array('controller' => 'content', 'action' => 'index')); 47 $m->createRegs(array()); 48 49 $this->assertNull($m->match('/x')); 50 $this->assertNull($m->match('/hello/world/how')); 51 $this->assertNull($m->match('/hello/world/how/are')); 52 $this->assertNull($m->match('/hello/world/how/are/you/today')); 53 54 $matchdata = array('controller' => 'content', 'action' =>'index'); 55 $this->assertEquals($matchdata, $m->match('/hello/world/how/are/you')); 56 } 57 58 public function testUnicode() 59 { 60 // php version does not handing decoding 61 } 62 63 public function testDisablingUnicode() 64 { 65 // php version does not handing decoding 66 } 67 68 public function testBasicDynamic() 69 { 70 foreach(array('hi/:name', 'hi/:(name)') as $path) { 71 $m = new Horde_Routes_Mapper(); 72 $m->connect($path, array('controller' => 'content')); 73 $m->createRegs(); 74 75 $this->assertNull($m->match('/boo')); 76 $this->assertNull($m->match('/boo/blah')); 77 $this->assertNull($m->match('/hi')); 78 $this->assertNull($m->match('/hi/dude/what')); 79 80 $matchdata = array('controller' => 'content', 'name' => 'dude', 'action' => 'index'); 81 $this->assertEquals($matchdata, $m->match('/hi/dude')); 82 $this->assertEquals($matchdata, $m->match('/hi/dude/')); 83 } 84 } 85 86 public function testBasicDynamicBackwards() 87 { 88 foreach (array(':name/hi', ':(name)/hi') as $path) { 89 $m = new Horde_Routes_Mapper(); 90 $m->connect($path); 91 $m->createRegs(); 92 93 $this->assertNull($m->match('/')); 94 $this->assertNull($m->match('/hi')); 95 $this->assertNull($m->match('/boo')); 96 $this->assertNull($m->match('/boo/blah')); 97 $this->assertNull($m->match('/shop/walmart/hi')); 98 99 $matchdata = array('name' => 'fred', 'action' => 'index', 'controller' => 'content'); 100 $this->assertEquals($matchdata, $m->match('/fred/hi')); 101 102 $matchdata = array('name' => 'index', 'action' => 'index', 'controller' => 'content'); 103 $this->assertEquals($matchdata, $m->match('/index/hi')); 104 } 105 } 106 107 public function testDynamicWithUnderscores() 108 { 109 $m = new Horde_Routes_Mapper(); 110 $m->connect('article/:small_page', array('small_page' => false)); 111 $m->connect(':(controller)/:(action)/:(id)'); 112 $m->createRegs(array('article', 'blog')); 113 114 $matchdata = array('controller' => 'blog', 'action' => 'view', 'id' => '0'); 115 $this->assertEquals($matchdata, $m->match('/blog/view/0')); 116 117 $matchdata = array('controller' => 'blog', 'action' => 'view', 'id' => null); 118 $this->assertEquals($matchdata, $m->match('/blog/view')); 119 } 120 121 public function testDynamicWithDefault() 122 { 123 foreach (array('hi/:action', 'hi/:(action)') as $path) { 124 $m = new Horde_Routes_Mapper(); 125 $m->connect($path, array('controller' => 'content')); 126 $m->createRegs(); 127 128 $this->assertNull($m->match('/boo')); 129 $this->assertNull($m->match('/boo/blah')); 130 $this->assertNull($m->match('/hi/dude/what')); 131 132 $matchdata = array('controller' => 'content', 'action' => 'index'); 133 $this->assertEquals($matchdata, $m->match('/hi')); 134 135 $matchdata = array('controller' => 'content', 'action' => 'index'); 136 $this->assertEquals($matchdata, $m->match('/hi/index')); 137 138 $matchdata = array('controller' => 'content', 'action' => 'dude'); 139 $this->assertEquals($matchdata, $m->match('/hi/dude')); 140 } 141 } 142 143 public function testDynamicWithDefaultBackwards() 144 { 145 foreach (array(':action/hi', ':(action)/hi') as $path) { 146 $m = new Horde_Routes_Mapper(); 147 $m->connect($path, array('controller' => 'content')); 148 $m->createRegs(); 149 150 $this->assertNull($m->match('/')); 151 $this->assertNull($m->match('/boo')); 152 $this->assertNull($m->match('/boo/blah')); 153 $this->assertNull($m->match('/hi')); 154 155 $matchdata = array('controller' => 'content', 'action' => 'index'); 156 $this->assertEquals($matchdata, $m->match('/index/hi')); 157 $this->assertEquals($matchdata, $m->match('/index/hi/')); 158 159 $matchdata = array('controller' => 'content', 'action' => 'dude'); 160 $this->assertEquals($matchdata, $m->match('/dude/hi')); 161 } 162 } 163 164 public function testDynamicWithStringCondition() 165 { 166 foreach (array(':name/hi', ':(name)/hi') as $path) { 167 $m = new Horde_Routes_Mapper(); 168 $m->connect($path, array('controller' => 'content', 169 'requirements' => array('name' => 'index'))); 170 $m->createRegs(); 171 172 $this->assertNull($m->match('/boo')); 173 $this->assertNull($m->match('/boo/blah')); 174 $this->assertNull($m->match('/hi')); 175 $this->assertNull($m->match('/dude/what/hi')); 176 177 $matchdata = array('controller' => 'content', 'name' => 'index', 'action' => 'index'); 178 $this->assertEquals($matchdata, $m->match('/index/hi')); 179 $this->assertNull($m->match('/dude/hi')); 180 } 181 } 182 183 public function testDynamicWithStringConditionBackwards() 184 { 185 foreach (array('hi/:name', 'hi/:(name)') as $path) { 186 $m = new Horde_Routes_Mapper(); 187 $m->connect($path, array('controller' => 'content', 188 'requirements' => array('name' => 'index'))); 189 $m->createRegs(); 190 191 $this->assertNull($m->match('/boo')); 192 $this->assertNull($m->match('/boo/blah')); 193 $this->assertNull($m->match('/hi')); 194 $this->assertNull($m->match('/hi/dude/what')); 195 196 $matchdata = array('controller' => 'content', 'name' => 'index', 'action' => 'index'); 197 $this->assertEquals($matchdata, $m->match('/hi/index')); 198 199 $this->assertEquals($matchdata, $m->match('/hi/index')); 200 201 $this->assertNull($m->match('/dude/hi')); 202 } 203 } 204 205 public function testDynamicWithRegexpCondition() 206 { 207 foreach (array('hi/:name', 'hi/:(name)') as $path) { 208 $m = new Horde_Routes_Mapper(); 209 $m->connect($path, array('controller' => 'content', 210 'requirements' => array('name' => '[a-z]+'))); 211 $m->createRegs(); 212 213 $this->assertNull($m->match('/boo')); 214 $this->assertNull($m->match('/boo/blah')); 215 $this->assertNull($m->match('/hi')); 216 $this->assertNull($m->match('/hi/FOXY')); 217 $this->assertNull($m->match('/hi/138708jkhdf')); 218 $this->assertNull($m->match('/hi/dkjfl8792343dfsf')); 219 $this->assertNull($m->match('/hi/dude/what')); 220 $this->assertNull($m->match('/hi/dude/what/')); 221 222 $matchdata = array('controller' => 'content', 'name' => 'index', 'action' => 'index'); 223 $this->assertEquals($matchdata, $m->match('/hi/index')); 224 225 $matchdata = array('controller' => 'content', 'name' => 'dude', 'action' => 'index'); 226 $this->assertEquals($matchdata, $m->match('/hi/dude')); 227 } 228 } 229 230 public function testDynamicWithRegexpAndDefault() 231 { 232 foreach (array('hi/:action', 'hi/:(action)') as $path) { 233 $m = new Horde_Routes_Mapper(); 234 $m->connect($path, array('controller' => 'content', 235 'requirements' => array('action' => '[a-z]+'))); 236 $m->createRegs(); 237 238 $this->assertNull($m->match('/boo')); 239 $this->assertNull($m->match('/boo/blah')); 240 $this->assertNull($m->match('/hi/FOXY')); 241 $this->assertNull($m->match('/hi/138708jkhdf')); 242 $this->assertNull($m->match('/hi/dkjfl8792343dfsf')); 243 $this->assertNull($m->match('/hi/dude/what/')); 244 245 $matchdata = array('controller' => 'content', 'action' => 'index'); 246 $this->assertEquals($matchdata, $m->match('/hi')); 247 $this->assertEquals($matchdata, $m->match('/hi/index')); 248 249 $matchdata = array('controller' => 'content', 'action' => 'dude'); 250 $this->assertEquals($matchdata, $m->match('/hi/dude')); 251 } 252 } 253 254 public function testDynamicWithDefaultAndStringConditionBackwards() 255 { 256 foreach (array(':action/hi', ':(action)/hi') as $path) { 257 $m = new Horde_Routes_Mapper(); 258 $m->connect($path); 259 $m->createRegs(); 260 261 $this->assertNull($m->match('/')); 262 $this->assertNull($m->match('/boo')); 263 $this->assertNull($m->match('/boo/blah')); 264 $this->assertNull($m->match('/hi')); 265 266 $matchdata = array('action' => 'index', 'controller' => 'content'); 267 $this->assertEquals($matchdata, $m->match('/index/hi')); 268 } 269 } 270 271 public function testDynamicAndControllerWithStringAndDefaultBackwards() 272 { 273 foreach (array(':controller/:action/hi', ':(controller)/:(action)/hi') as $path) { 274 $m = new Horde_Routes_Mapper(); 275 276 $m->connect($path, array('controller' => 'content')); 277 $m->createRegs(array('content', 'admin/user')); 278 279 $this->assertNull($m->match('/')); 280 $this->assertNull($m->match('/fred')); 281 } 282 } 283 284 public function testMultiroute() 285 { 286 $m = new Horde_Routes_Mapper(); 287 $m->connect('archive/:year/:month/:day', array('controller' => 'blog', 'action' => 'view', 288 'month' => null, 'day' => null, 289 'requirements' => array('month' => '\d{1,2}', 290 'day' => '\d{1,2}'))); 291 $m->connect('viewpost/:id', array('controller' => 'post', 'action' => 'view')); 292 $m->connect(':controller/:action/:id'); 293 $m->createRegs(array('post','blog','admin/user')); 294 295 $this->assertNull($m->match('/')); 296 $this->assertNull($m->match('/archive')); 297 $this->assertNull($m->match('/archive/2004/ab')); 298 299 $matchdata = array('controller' => 'blog', 'action' => 'view', 'id' => null); 300 $this->assertEquals($matchdata, $m->match('/blog/view')); 301 302 $matchdata = array('controller' => 'blog', 'action' => 'view', 303 'month' => null, 'day' => null, 'year' => '2004'); 304 $this->assertEquals($matchdata, $m->match('/archive/2004')); 305 306 $matchdata = array('controller' => 'blog', 'action' => 'view', 307 'month' => '4', 'day' => null, 'year' =>'2004'); 308 $this->assertEquals($matchdata, $m->match('/archive/2004/4')); 309 } 310 311 public function testMultirouteWithSplits() 312 { 313 $m = new Horde_Routes_Mapper(); 314 $m->connect('archive/:(year)/:(month)/:(day)', array('controller' => 'blog', 'action' => 'view', 315 'month' => null, 'day' => null, 316 'requirements' => array('month' => '\d{1,2}', 317 'day' => '\d{1,2}'))); 318 $m->connect('viewpost/:(id)', array('controller' => 'post', 'action' => 'view')); 319 $m->connect(':(controller)/:(action)/:(id)'); 320 $m->createRegs(array('post','blog','admin/user')); 321 322 $this->assertNull($m->match('/')); 323 $this->assertNull($m->match('/archive')); 324 $this->assertNull($m->match('/archive/2004/ab')); 325 326 $matchdata = array('controller' => 'blog', 'action' => 'view', 'id' => null); 327 $this->assertEquals($matchdata, $m->match('/blog/view')); 328 329 $matchdata = array('controller' => 'blog', 'action' => 'view', 330 'month' => null, 'day' => null, 'year' => '2004'); 331 $this->assertEquals($matchdata, $m->match('/archive/2004')); 332 333 $matchdata = array('controller' => 'blog', 'action' => 'view', 334 'month' => '4', 'day' => null, 'year' => '2004'); 335 $this->assertEquals($matchdata, $m->match('/archive/2004/4')); 336 } 337 338 public function testDynamicWithRegexpDefaultsAndGaps() 339 { 340 $m = new Horde_Routes_Mapper(); 341 $m->connect('archive/:year/:month/:day', array('controller' => 'blog', 'action' => 'view', 342 'month' => null, 'day' => null, 343 'requirements' => array('month' => '\d{1,2}'))); 344 $m->connect('view/:id/:controller', array('controller' => 'blog', 'action' => 'view', 345 'id' => 2, 'requirements' => array('id' => '\d{1,2}'))); 346 $m->createRegs(array('post','blog','admin/user')); 347 348 $this->assertNull($m->match('/')); 349 $this->assertNull($m->match('/archive')); 350 $this->assertNull($m->match('/archive/2004/haha')); 351 $this->assertNull($m->match('/view/blog')); 352 353 $matchdata = array('controller' => 'blog', 'action' => 'view', 'id' => '2'); 354 $this->assertEquals($matchdata, $m->match('/view')); 355 356 $matchdata = array('controller' => 'blog', 'action' => 'view', 357 'month' => null, 'day' => null, 'year' => '2004'); 358 $this->assertEquals($matchdata, $m->match('/archive/2004')); 359 } 360 361 public function testDynamicWithRegexpDefaultsAndGapsAndSplits() 362 { 363 $m = new Horde_Routes_Mapper(); 364 $m->connect('archive/:(year)/:(month)/:(day)', array('controller' => 'blog', 'action' => 'view', 365 'month' => null, 'day' => null, 366 'requirements' => array('month' => '\d{1,2}'))); 367 $m->connect('view/:(id)/:(controller)', array('controller' => 'blog', 'action' => 'view', 368 'id' => 2, 'requirements' => array('id' => '\d{1,2}'))); 369 $m->createRegs(array('post','blog','admin/user')); 370 371 $this->assertNull($m->match('/')); 372 $this->assertNull($m->match('/archive')); 373 $this->assertNull($m->match('/archive/2004/haha')); 374 $this->assertNull($m->match('/view/blog')); 375 376 $matchdata = array('controller' => 'blog', 'action' => 'view', 'id' => '2'); 377 $this->assertEquals($matchdata, $m->match('/view')); 378 379 $matchdata = array('controller' => 'blog', 'action' => 'view', 380 'month' => null, 'day' => null, 'year' => '2004'); 381 $this->assertEquals($matchdata, $m->match('/archive/2004')); 382 } 383 384 public function testDynamicWithRegexpGapsControllers() 385 { 386 foreach(array('view/:id/:controller', 'view/:(id)/:(controller)') as $path) { 387 $m = new Horde_Routes_Mapper(); 388 $m->connect($path, array('id' => 2, 'action' => 'view', 'requirements' => array('id' => '\d{1,2}'))); 389 $m->createRegs(array('post', 'blog', 'admin/user')); 390 391 $this->assertNull($m->match('/')); 392 $this->assertNull($m->match('/view')); 393 $this->assertNull($m->match('/view/blog')); 394 $this->assertNull($m->match('/view/3')); 395 $this->assertNull($m->match('/view/4/honker')); 396 397 $matchdata = array('controller' => 'blog', 'action' => 'view', 'id' => '2'); 398 $this->assertEquals($matchdata, $m->match('/view/2/blog')); 399 } 400 } 401 402 public function testDynamicWithTrailingStrings() 403 { 404 foreach (array('view/:id/:controller/super', 'view/:(id)/:(controller)/super') as $path) { 405 $m = new Horde_Routes_Mapper(); 406 $m->connect($path, array('controller' => 'blog', 'action' => 'view', 407 'id' => 2, 'requirements' => array('id' => '\d{1,2}'))); 408 $m->createRegs(array('post', 'blog', 'admin/user')); 409 410 $this->assertNull($m->match('/')); 411 $this->assertNull($m->match('/view')); 412 $this->assertNull($m->match('/view/blah/blog/super')); 413 $this->assertNull($m->match('/view/ha/super')); 414 $this->assertNull($m->match('/view/super')); 415 $this->assertNull($m->match('/view/4/super')); 416 417 $matchdata = array('controller' => 'blog', 'action' => 'view', 'id' => '2'); 418 $this->assertEquals($matchdata, $m->match('/view/2/blog/super')); 419 420 $matchdata = array('controller' => 'admin/user', 'action' => 'view', 'id' => '4'); 421 $this->assertEquals($matchdata, $m->match('/view/4/admin/user/super')); 422 } 423 } 424 425 public function testDynamicWithTrailingNonKeywordStrings() 426 { 427 $m = new Horde_Routes_Mapper(); 428 $m->connect('somewhere/:over/rainbow', array('controller' => 'blog')); 429 $m->connect('somewhere/:over', array('controller' => 'post')); 430 $m->createRegs(array('post', 'blog', 'admin/user')); 431 432 $this->assertNull($m->match('/')); 433 $this->assertNull($m->match('/somewhere')); 434 435 $matchdata = array('controller' => 'blog', 'action' => 'index', 'over' => 'near'); 436 $this->assertEquals($matchdata, $m->match('/somewhere/near/rainbow')); 437 438 $matchdata = array('controller' => 'post', 'action' => 'index', 'over' => 'tomorrow'); 439 $this->assertEquals($matchdata, $m->match('/somewhere/tomorrow')); 440 } 441 442 public function testDynamicWithTrailingDynamicDefaults() 443 { 444 foreach (array('archives/:action/:article', 'archives/:(action)/:(article)') as $path) { 445 $m = new Horde_Routes_Mapper(); 446 $m->connect($path, array('controller' => 'blog')); 447 $m->createRegs(array('blog')); 448 449 $this->assertNull($m->match('/')); 450 $this->assertNull($m->match('/archives')); 451 $this->assertNull($m->match('/archives/introduction')); 452 $this->assertNull($m->match('/archives/sample')); 453 $this->assertNull($m->match('/view/super')); 454 $this->assertNull($m->match('/view/4/super')); 455 456 $matchdata = array('controller' => 'blog', 'action' => 'view', 'article' => 'introduction'); 457 $this->assertEquals($matchdata, $m->match('/archives/view/introduction')); 458 459 $matchdata = array('controller' => 'blog', 'action' => 'edit', 'article' => 'recipes'); 460 $this->assertEquals($matchdata, $m->match('/archives/edit/recipes')); 461 } 462 } 463 464 public function testPath() 465 { 466 foreach (array('hi/*file', 'hi/*(file)') as $path) { 467 $m = new Horde_Routes_Mapper(); 468 $m->connect($path, array('controller' => 'content', 'action' => 'download')); 469 $m->createRegs(); 470 471 $this->assertNull($m->match('/boo')); 472 $this->assertNull($m->match('/boo/blah')); 473 $this->assertNull($m->match('/hi')); 474 475 $matchdata = array('controller' => 'content', 'action' => 'download', 476 'file' => 'books/learning_python.pdf'); 477 $this->assertEquals($matchdata, $m->match('/hi/books/learning_python.pdf')); 478 479 $matchdata = array('controller' => 'content', 'action' => 'download', 480 'file' => 'dude'); 481 $this->assertEquals($matchdata, $m->match('/hi/dude')); 482 483 $matchdata = array('controller' => 'content', 'action' => 'download', 484 'file' => 'dude/what'); 485 $this->assertEquals($matchdata, $m->match('/hi/dude/what')); 486 } 487 } 488 489 public function testDynamicWithPath() 490 { 491 foreach (array(':controller/:action/*url', ':(controller)/:(action)/*(url)') as $path) { 492 $m = new Horde_Routes_Mapper(); 493 $m->connect($path); 494 $m->createRegs(array('content', 'admin/user')); 495 496 $this->assertNull($m->match('/')); 497 $this->assertNull($m->match('/blog')); 498 $this->assertNull($m->match('/content')); 499 $this->assertNull($m->match('/content/view')); 500 501 $matchdata = array('controller' => 'content', 'action' => 'view', 'url' => 'blob'); 502 $this->assertEquals($matchdata, $m->match('/content/view/blob')); 503 504 $this->assertNull($m->match('/admin/user')); 505 $this->assertNull($m->match('/admin/user/view')); 506 507 $matchdata = array('controller' => 'admin/user', 'action' => 'view', 508 'url' => 'blob/check'); 509 $this->assertEquals($matchdata, $m->match('/admin/user/view/blob/check')); 510 } 511 } 512 513 public function testPathWithDynamicAndDefault() 514 { 515 foreach (array(':controller/:action/*url', ':(controller)/:(action)/*(url)') as $path) { 516 $m = new Horde_Routes_Mapper(); 517 $m->connect($path, array('controller' => 'content', 'action' => 'view', 'url' => null)); 518 $m->createRegs(array('content', 'admin/user')); 519 520 $this->assertNull($m->match('/goober/view/here')); 521 522 $matchdata = array('controller' => 'content', 'action' => 'view', 'url' => null); 523 $this->assertEquals($matchdata, $m->match('/content')); 524 $this->assertEquals($matchdata, $m->match('/content/')); 525 $this->assertEquals($matchdata, $m->match('/content/view')); 526 527 $matchdata = array('controller' => 'content', 'action' => 'view', 'url' => 'fred'); 528 $this->assertEquals($matchdata, $m->match('/content/view/fred')); 529 530 $matchdata = array('controller' => 'admin/user', 'action' => 'view', 'url' => null); 531 $this->assertEquals($matchdata, $m->match('/admin/user')); 532 $this->assertEquals($matchdata, $m->match('/admin/user/view')); 533 } 534 } 535 536 public function testPathWithDynamicAndDefaultBackwards() 537 { 538 foreach (array('*file/login', '*(file)/login') as $path) { 539 $m = new Horde_Routes_Mapper(); 540 $m->connect($path, array('controller' => 'content', 'action' => 'download', 'file' => null)); 541 $m->createRegs(); 542 543 $this->assertNull($m->match('/boo')); 544 $this->assertNull($m->match('/boo/blah')); 545 546 $matchdata = array('controller' => 'content', 'action' => 'download', 'file' => ''); 547 $this->assertEquals($matchdata, $m->match('//login')); 548 549 $matchdata = array('controller' => 'content', 'action' => 'download', 550 'file' => 'books/learning_python.pdf'); 551 $this->assertEquals($matchdata, $m->match('/books/learning_python.pdf/login')); 552 553 $matchdata = array('controller' => 'content', 'action' => 'download', 'file' => 'dude'); 554 $this->assertEquals($matchdata, $m->match('/dude/login')); 555 556 $matchdata = array('controller' => 'content', 'action' => 'download', 'file' => 'dude/what'); 557 $this->assertEquals($matchdata, $m->match('/dude/what/login')); 558 } 559 } 560 561 public function testPathBackwards() 562 { 563 foreach (array('*file/login', '*(file)/login') as $path) { 564 $m = new Horde_Routes_Mapper(); 565 $m->connect($path, array('controller' => 'content', 'action' => 'download')); 566 $m->createRegs(); 567 568 $this->assertNull($m->match('/boo')); 569 $this->assertNull($m->match('/boo/blah')); 570 $this->assertNull($m->match('/login')); 571 572 $matchdata = array('controller' => 'content', 'action' => 'download', 573 'file' => 'books/learning_python.pdf'); 574 $this->assertEquals($matchdata, $m->match('/books/learning_python.pdf/login')); 575 576 $matchdata = array('controller' => 'content', 'action' => 'download', 'file' => 'dude'); 577 $this->assertEquals($matchdata, $m->match('/dude/login')); 578 579 $matchdata = array('controller' => 'content', 'action' => 'download', 'file' => 'dude/what'); 580 $this->assertEquals($matchdata, $m->match('/dude/what/login')); 581 } 582 } 583 584 public function testPathBackwardsWithController() 585 { 586 $m = new Horde_Routes_Mapper(); 587 $m->connect('*url/login', array('controller' => 'content', 'action' => 'check_access')); 588 $m->connect('*url/:controller', array('action' => 'view')); 589 $m->createRegs(array('content', 'admin/user')); 590 591 $this->assertNull($m->match('/boo')); 592 $this->assertNull($m->match('/boo/blah')); 593 $this->assertNull($m->match('/login')); 594 595 $matchdata = array('controller' => 'content', 'action' => 'check_access', 596 'url' => 'books/learning_python.pdf'); 597 $this->assertEquals($matchdata, $m->match('/books/learning_python.pdf/login')); 598 599 $matchdata = array('controller' => 'content', 'action' => 'check_access', 'url' => 'dude'); 600 $this->assertEquals($matchdata, $m->match('/dude/login')); 601 602 $matchdata = array('controller' => 'content', 'action' => 'check_access', 'url' => 'dude/what'); 603 $this->assertEquals($matchdata, $m->match('/dude/what/login')); 604 605 $this->assertNull($m->match('/admin/user')); 606 607 $matchdata = array('controller' => 'admin/user', 'action' => 'view', 608 'url' => 'books/learning_python.pdf'); 609 $this->assertEquals($matchdata, $m->match('/books/learning_python.pdf/admin/user')); 610 611 $matchdata = array('controller' => 'admin/user', 'action' => 'view', 'url' => 'dude'); 612 $this->assertEquals($matchdata, $m->match('/dude/admin/user')); 613 614 $matchdata = array('controller' => 'admin/user', 'action' => 'view', 'url' => 'dude/what'); 615 $this->assertEquals($matchdata, $m->match('/dude/what/admin/user')); 616 } 617 618 public function testPathBackwardsWithControllerAndSplits() 619 { 620 $m = new Horde_Routes_Mapper(); 621 $m->connect('*(url)/login', array('controller' => 'content', 'action' => 'check_access')); 622 $m->connect('*(url)/:(controller)', array('action' => 'view')); 623 $m->createRegs(array('content', 'admin/user')); 624 625 $this->assertNull($m->match('/boo')); 626 $this->assertNull($m->match('/boo/blah')); 627 $this->assertNull($m->match('/login')); 628 629 $matchdata = array('controller' => 'content', 'action' => 'check_access', 630 'url' => 'books/learning_python.pdf'); 631 $this->assertEquals($matchdata, $m->match('/books/learning_python.pdf/login')); 632 633 $matchdata = array('controller' => 'content', 'action' => 'check_access', 'url' => 'dude'); 634 $this->assertEquals($matchdata, $m->match('/dude/login')); 635 636 $matchdata = array('controller' => 'content', 'action' => 'check_access', 'url' => 'dude/what'); 637 $this->assertEquals($matchdata, $m->match('/dude/what/login')); 638 639 $this->assertNull($m->match('/admin/user')); 640 641 $matchdata = array('controller' => 'admin/user', 'action' => 'view', 642 'url' => 'books/learning_python.pdf'); 643 $this->assertEquals($matchdata, $m->match('/books/learning_python.pdf/admin/user')); 644 645 $matchdata = array('controller' => 'admin/user', 'action' => 'view', 'url' => 'dude'); 646 $this->assertEquals($matchdata, $m->match('/dude/admin/user')); 647 648 $matchdata = array('controller' => 'admin/user', 'action' => 'view', 'url' => 'dude/what'); 649 $this->assertEquals($matchdata, $m->match('/dude/what/admin/user')); 650 } 651 652 public function testController() 653 { 654 $m = new Horde_Routes_Mapper(); 655 $m->connect('hi/:controller', array('action' => 'hi')); 656 $m->createRegs(array('content', 'admin/user')); 657 658 $this->assertNull($m->match('/boo')); 659 $this->assertNull($m->match('/boo/blah')); 660 $this->assertNull($m->match('/hi/13870948')); 661 $this->assertNull($m->match('/hi/content/dog')); 662 $this->assertNull($m->match('/hi/admin/user/foo')); 663 $this->assertNull($m->match('/hi/admin/user/foo/')); 664 665 $matchdata = array('controller' => 'content', 'action' => 'hi'); 666 $this->assertEquals($matchdata, $m->match('/hi/content')); 667 668 $matchdata = array('controller' => 'admin/user', 'action' => 'hi'); 669 $this->assertEquals($matchdata, $m->match('/hi/admin/user')); 670 } 671 672 public function testStandardRoute() 673 { 674 $m = new Horde_Routes_Mapper(); 675 $m->connect(':controller/:action/:id'); 676 $m->createRegs(array('content', 'admin/user')); 677 678 $matchdata = array('controller' => 'content', 'action' => 'index', 'id' => null); 679 $this->assertEquals($matchdata, $m->match('/content')); 680 681 $matchdata = array('controller' => 'content', 'action' => 'list', 'id' => null); 682 $this->assertEquals($matchdata, $m->match('/content/list')); 683 684 $matchdata = array('controller' => 'content', 'action' => 'show', 'id' => '10'); 685 $this->assertEquals($matchdata, $m->match('/content/show/10')); 686 687 $matchdata = array('controller' => 'admin/user', 'action' => 'index', 'id' => null); 688 $this->assertEquals($matchdata, $m->match('/admin/user')); 689 690 $matchdata = array('controller' => 'admin/user', 'action' => 'list', 'id' => null); 691 $this->assertEquals($matchdata, $m->match('/admin/user/list')); 692 693 $matchdata = array('controller' => 'admin/user', 'action' => 'show', 'id' => 'bbangert'); 694 $this->assertEquals($matchdata, $m->match('/admin/user/show/bbangert')); 695 696 $this->assertNull($m->match('/content/show/10/20')); 697 $this->assertNull($m->match('/food')); 698 } 699 700 public function testStandardRouteWithGaps() 701 { 702 $m = new Horde_Routes_Mapper(); 703 $m->connect(':controller/:action/:(id).py'); 704 $m->createRegs(array('content', 'admin/user')); 705 706 $matchdata = array('controller' => 'content', 'action' => 'index', 'id' => 'None'); 707 $this->assertEquals($matchdata, $m->match('/content/index/None.py')); 708 709 $matchdata = array('controller' =>'content', 'action' => 'list', 'id' => 'None'); 710 $this->assertEquals($matchdata, $m->match('/content/list/None.py')); 711 712 $matchdata = array('controller' => 'content', 'action' => 'show', 'id' => '10'); 713 $this->assertEquals($matchdata, $m->match('/content/show/10.py')); 714 } 715 716 public function testStandardRouteWithGapsAndDomains() 717 { 718 $m = new Horde_Routes_Mapper(); 719 $m->connect('manage/:domain.:ext', array('controller' => 'admin/user', 'action' => 'view', 720 'ext' => 'html')); 721 $m->connect(':controller/:action/:id'); 722 $m->createRegs(array('content', 'admin/user')); 723 724 $matchdata = array('controller' => 'content', 'action' => 'index', 'id' => 'None.py'); 725 $this->assertEquals($matchdata, $m->match('/content/index/None.py')); 726 727 $matchdata = array('controller' => 'content', 'action' => 'list', 'id' => 'None.py'); 728 $this->assertEquals($matchdata, $m->match('/content/list/None.py')); 729 730 $matchdata = array('controller' => 'content', 'action' => 'show', 'id' => '10.py'); 731 $this->assertEquals($matchdata, $m->match('/content/show/10.py')); 732 733 $matchdata = array('controller' => 'content', 'action' => 'show.all', 'id' => '10.py'); 734 $this->assertEquals($matchdata, $m->match('/content/show.all/10.py')); 735 736 $matchdata = array('controller' => 'content', 'action' => 'show', 'id' => 'www.groovie.org'); 737 $this->assertEquals($matchdata, $m->match('/content/show/www.groovie.org')); 738 739 $matchdata = array('controller' => 'admin/user', 'action' => 'view', 740 'ext' => 'html', 'domain' => 'groovie'); 741 $this->assertEquals($matchdata, $m->match('/manage/groovie')); 742 743 $matchdata = array('controller' => 'admin/user', 'action' => 'view', 744 'ext' => 'xml', 'domain' => 'groovie'); 745 $this->assertEquals($matchdata, $m->match('/manage/groovie.xml')); 746 } 747 748 public function testStandardWithDomains() 749 { 750 $m = new Horde_Routes_Mapper(); 751 $m->connect('manage/:domain', array('controller' => 'domains', 'action' => 'view')); 752 $m->createRegs(array('domains')); 753 754 $matchdata = array('controller' => 'domains', 'action' => 'view', 'domain' => 'www.groovie.org'); 755 $this->assertEquals($matchdata, $m->match('/manage/www.groovie.org')); 756 } 757 758 public function testDefaultRoute() 759 { 760 $m = new Horde_Routes_Mapper(); 761 $m->connect('', array('controller' => 'content', 'action' => 'index')); 762 $m->createRegs(array('content')); 763 764 $this->assertNull($m->match('/x')); 765 $this->assertNull($m->match('/hello/world')); 766 $this->assertNull($m->match('/hello/world/how/are')); 767 $this->assertNull($m->match('/hello/world/how/are/you/today')); 768 769 $matchdata = array('controller' => 'content', 'action' => 'index'); 770 $this->assertEquals($matchdata, $m->match('/')); 771 } 772 773 public function testDynamicWithPrefix() 774 { 775 $m = new Horde_Routes_Mapper(); 776 $m->prefix = '/blog'; 777 $m->connect(':controller/:action/:id'); 778 $m->connect('', array('controller' => 'content', 'action' => 'index')); 779 $m->createRegs(array('content', 'archive', 'admin/comments')); 780 781 $this->assertNull($m->match('/x')); 782 $this->assertNull($m->match('/admin/comments')); 783 $this->assertNull($m->match('/content/view')); 784 $this->assertNull($m->match('/archive/view/4')); 785 786 $matchdata = array('controller' => 'content', 'action' => 'index'); 787 $this->assertEquals($matchdata, $m->match('/blog')); 788 789 $matchdata = array('controller' => 'content', 'action' => 'index', 'id' => null); 790 $this->assertEquals($matchdata, $m->match('/blog/content')); 791 792 $matchdata = array('controller' => 'admin/comments', 'action' => 'view', 'id' => null); 793 $this->assertEquals($matchdata, $m->match('/blog/admin/comments/view')); 794 795 $matchdata = array('controller' => 'archive', 'action' => 'index', 'id' => null); 796 $this->assertEquals($matchdata, $m->match('/blog/archive')); 797 798 $matchdata = array('controller' => 'archive', 'action' => 'view', 'id' => '4'); 799 $this->assertEquals($matchdata, $m->match('/blog/archive/view/4')); 800 } 801 802 public function testDynamicWithMultipleAndPrefix() 803 { 804 $m = new Horde_Routes_Mapper(); 805 $m->prefix = '/blog'; 806 $m->connect(':controller/:action/:id'); 807 $m->connect('home/:action', array('controller' => 'archive')); 808 $m->connect('', array('controller' => 'content')); 809 $m->createRegs(array('content', 'archive', 'admin/comments')); 810 811 $this->assertNull($m->match('/x')); 812 $this->assertNull($m->match('/admin/comments')); 813 $this->assertNull($m->match('/content/view')); 814 $this->assertNull($m->match('/archive/view/4')); 815 816 $matchdata = array('controller' => 'content', 'action' => 'index'); 817 $this->assertEquals($matchdata, $m->match('/blog/')); 818 819 $matchdata = array('controller' => 'archive', 'action' => 'view'); 820 $this->assertEquals($matchdata, $m->match('/blog/home/view')); 821 822 $matchdata = array('controller' => 'content', 'action' => 'index', 'id' => null); 823 $this->assertEquals($matchdata, $m->match('/blog/content')); 824 825 $matchdata = array('controller' => 'admin/comments', 'action' => 'view', 'id' => null); 826 $this->assertEquals($matchdata, $m->match('/blog/admin/comments/view')); 827 828 $matchdata = array('controller' => 'archive', 'action' => 'index', 'id' => null); 829 $this->assertEquals($matchdata, $m->match('/blog/archive')); 830 831 $matchdata = array('controller' => 'archive', 'action' => 'view', 'id' => '4'); 832 $this->assertEquals($matchdata, $m->match('/blog/archive/view/4')); 833 } 834 835 public function testSplitsWithExtension() 836 { 837 $m = new Horde_Routes_Mapper(); 838 $m->connect('hi/:(action).html', array('controller' => 'content')); 839 $m->createRegs(); 840 841 $this->assertNull($m->match('/boo')); 842 $this->assertNull($m->match('/boo/blah')); 843 $this->assertNull($m->match('/hi/dude/what')); 844 $this->assertNull($m->match('/hi')); 845 846 $matchdata = array('controller' => 'content', 'action' => 'index'); 847 $this->assertEquals($matchdata, $m->match('/hi/index.html')); 848 849 $matchdata = array('controller' => 'content', 'action' => 'dude'); 850 $this->assertEquals($matchdata, $m->match('/hi/dude.html')); 851 } 852 853 public function testSplitsWithDashes() 854 { 855 $m = new Horde_Routes_Mapper(); 856 $m->connect('archives/:(year)-:(month)-:(day).html', 857 array('controller' => 'archives', 'action' => 'view')); 858 $m->createRegs(); 859 860 $this->assertNull($m->match('/boo')); 861 $this->assertNull($m->match('/archives')); 862 863 $matchdata = array('controller' => 'archives', 'action' => 'view', 864 'year' => '2004', 'month' => '12', 'day' => '4'); 865 $this->assertEquals($matchdata, $m->match('/archives/2004-12-4.html')); 866 867 $matchdata = array('controller' => 'archives', 'action' => 'view', 868 'year' => '04', 'month' => '10', 'day' => '4'); 869 $this->assertEquals($matchdata, $m->match('/archives/04-10-4.html')); 870 871 $matchdata = array('controller' => 'archives', 'action' => 'view', 872 'year' => '04', 'month' => '1', 'day' => '1'); 873 $this->assertEquals($matchdata, $m->match('/archives/04-1-1.html')); 874 } 875 876 public function testSplitsPackedWithRegexps() 877 { 878 $m = new Horde_Routes_Mapper(); 879 $m->connect('archives/:(year):(month):(day).html', 880 array('controller' => 'archives', 'action' => 'view', 881 'requirements' => array('year' => '\d{4}', 'month' => '\d{2}', 882 'day' => '\d{2}'))); 883 $m->createRegs(); 884 885 $this->assertNull($m->match('/boo')); 886 $this->assertNull($m->match('/archives')); 887 $this->assertNull($m->match('/archives/2004020.html')); 888 $this->assertNull($m->match('/archives/200502.html')); 889 890 $matchdata = array('controller' => 'archives', 'action' => 'view', 891 'year' => '2004', 'month' => '12', 'day' => '04'); 892 $this->assertEquals($matchdata, $m->match('/archives/20041204.html')); 893 894 $matchdata = array('controller' => 'archives', 'action' => 'view', 895 'year' => '2005', 'month' => '10', 'day' => '04'); 896 $this->assertEquals($matchdata, $m->match('/archives/20051004.html')); 897 898 $matchdata = array('controller' => 'archives', 'action' => 'view', 899 'year' => '2006', 'month' => '01', 'day' => '01'); 900 $this->assertEquals($matchdata, $m->match('/archives/20060101.html')); 901 } 902 903 public function testSplitsWithSlashes() 904 { 905 $m = new Horde_Routes_Mapper(); 906 $m->connect(':name/:(action)-:(day)', array('controller' => 'content')); 907 908 $this->assertNull($m->match('/something')); 909 $this->assertNull($m->match('/something/is-')); 910 911 $matchdata = array('controller' => 'content', 'action' => 'view', 912 'day' => '3', 'name' => 'group'); 913 $this->assertEquals($matchdata, $m->match('/group/view-3')); 914 915 $matchdata = array('controller' => 'content', 'action' => 'view', 916 'day' => '5', 'name' => 'group'); 917 $this->assertEquals($matchdata, $m->match('/group/view-5')); 918 } 919 920 public function testSplitsWithSlashesAndDefault() 921 { 922 $m = new Horde_Routes_Mapper(); 923 $m->connect(':name/:(action)-:(id)', array('controller' => 'content')); 924 $m->createRegs(); 925 926 $this->assertNull($m->match('/something')); 927 $this->assertNull($m->match('/something/is')); 928 929 $matchdata = array('controller' => 'content', 'action' => 'view', 930 'id' => '3', 'name' => 'group'); 931 $this->assertEquals($matchdata, $m->match('/group/view-3')); 932 933 $matchdata = array('controller' => 'content', 'action' => 'view', 934 'id' => null, 'name' => 'group'); 935 $this->assertEquals($matchdata, $m->match('/group/view-')); 936 } 937 938 public function testNoRegMake() 939 { 940 $m = new Horde_Routes_Mapper(); 941 $m->connect(':name/:(action)-:(id)', array('controller' => 'content')); 942 $m->controllerScan = false; 943 try { 944 $m->match('/group/view-3'); 945 $this->fail(); 946 } catch (Horde_Routes_Exception $e) { 947 $this->assertRegExp('/must generate the regular expressions/i', $e->getMessage()); 948 } 949 } 950 951 public function testRoutematch() 952 { 953 $m = new Horde_Routes_Mapper(); 954 $m->connect(':controller/:action/:id'); 955 $m->createRegs(array('content')); 956 $route = $m->matchList[0]; 957 958 list($resultdict, $resultObj) = $m->routematch('/content'); 959 960 $this->assertEquals(array('controller' => 'content', 'action' => 'index', 'id' => null), 961 $resultdict); 962 $this->assertSame($route, $resultObj); 963 $this->assertNull($m->routematch('/nowhere')); 964 } 965 966 public function testRoutematchDebug() 967 { 968 $m = new Horde_Routes_Mapper(); 969 $m->connect(':controller/:action/:id'); 970 $m->debug = true; 971 $m->createRegs(array('content')); 972 $route = $m->matchList[0]; 973 974 list($resultdict, $resultObj, $debug) = $m->routematch('/content'); 975 976 $this->assertEquals(array('controller' => 'content', 'action' => 'index', 'id' => null), 977 $resultdict); 978 $this->assertSame($route, $resultObj); 979 980 list($resultdict, $resultObj, $debug) = $m->routematch('/nowhere'); 981 $this->assertNull($resultdict); 982 $this->assertNull($resultObj); 983 $this->assertEquals(1, count($debug)); 984 } 985 986 public function testMatchDebug() 987 { 988 $m = new Horde_Routes_Mapper(); 989 $m->connect('nowhere', 'http://nowhere.com/', array('_static' => true)); 990 $m->connect(':controller/:action/:id'); 991 $m->debug = true; 992 $m->createRegs(array('content')); 993 $route = $m->matchList[1]; 994 995 list($resultdict, $resultObj, $debug) = $m->match('/content'); 996 $this->assertEquals(array('controller' => 'content', 'action' => 'index', 'id' => null), 997 $resultdict); 998 999 $this->assertSame($route, $resultObj); 1000 1001 list($resultdict, $resultObj, $debug) = $m->match('/nowhere'); 1002 $this->assertNull($resultdict); 1003 $this->assertNull($resultObj); 1004 $this->assertEquals(2, count($debug)); 1005 } 1006 1007 public function testResourceCollection() 1008 { 1009 $m = new Horde_Routes_Mapper(); 1010 $m->resource('message', 'messages'); 1011 $m->createRegs(array('messages')); 1012 1013 $path = '/messages'; 1014 1015 $m->environ = array('REQUEST_METHOD' => 'GET'); 1016 $this->assertEquals(array('controller' => 'messages', 'action' => 'index'), 1017 $m->match($path)); 1018 1019 $m->environ = array('REQUEST_METHOD' => 'POST'); 1020 $this->assertEquals(array('controller' => 'messages', 'action' => 'create'), 1021 $m->match($path)); 1022 } 1023 1024 public function testFormattedResourceCollection() 1025 { 1026 $m = new Horde_Routes_Mapper(); 1027 $m->resource('message', 'messages'); 1028 $m->createRegs(array('messages')); 1029 1030 $path = '/messages.xml'; 1031 1032 $m->environ = array('REQUEST_METHOD' => 'GET'); 1033 $this->assertEquals(array('controller' => 'messages', 'action' => 'index', 1034 'format' => 'xml'), 1035 $m->match($path)); 1036 1037 $m->environ = array('REQUEST_METHOD' => 'POST'); 1038 $this->assertEquals(array('controller' => 'messages', 'action' => 'create', 1039 'format' => 'xml'), 1040 $m->match($path)); 1041 } 1042 1043 public function testResourceMember() 1044 { 1045 $m = new Horde_Routes_Mapper(); 1046 $m->resource('message', 'messages'); 1047 $m->createRegs(array('messages')); 1048 1049 $path = '/messages/42'; 1050 1051 $m->environ = array('REQUEST_METHOD' => 'GET'); 1052 $this->assertEquals(array('controller' => 'messages', 'action' => 'show', 1053 'id' => 42), 1054 $m->match($path)); 1055 1056 $m->environ = array('REQUEST_METHOD' => 'POST'); 1057 $this->assertNull($m->match($path)); 1058 1059 $m->environ = array('REQUEST_METHOD' => 'PUT'); 1060 $this->assertEquals(array('controller' => 'messages', 'action' => 'update', 1061 'id' => 42), 1062 $m->match($path)); 1063 1064 $m->environ = array('REQUEST_METHOD' => 'DELETE'); 1065 $this->assertEquals(array('controller' => 'messages', 'action' => 'delete', 1066 'id' => 42), 1067 $m->match($path)); 1068 } 1069 1070 public function testFormattedResourceMember() 1071 { 1072 $m = new Horde_Routes_Mapper(); 1073 $m->resource('message', 'messages'); 1074 $m->createRegs(array('messages')); 1075 1076 $path = '/messages/42.xml'; 1077 1078 $m->environ = array('REQUEST_METHOD' => 'GET'); 1079 $this->assertEquals(array('controller' => 'messages', 'action' => 'show', 1080 'id' => 42, 'format' => 'xml'), 1081 $m->match($path)); 1082 1083 $m->environ = array('REQUEST_METHOD' => 'POST'); 1084 $this->assertNull($m->match($path)); 1085 1086 $m->environ = array('REQUEST_METHOD' => 'PUT'); 1087 $this->assertEquals(array('controller' => 'messages', 'action' => 'update', 1088 'id' => 42, 'format' => 'xml'), 1089 $m->match($path)); 1090 1091 $m->environ = array('REQUEST_METHOD' => 'DELETE'); 1092 $this->assertEquals(array('controller' => 'messages', 'action' => 'delete', 1093 'id' => 42, 'format' => 'xml'), 1094 $m->match($path)); 1095 } 1096 1097} 1098