Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16591 anikendra 1
<?php
2
/**
3
 * DispatcherTest file
4
 *
5
 * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
14
 * @package       Cake.Test.Case.Routing
15
 * @since         CakePHP(tm) v 1.2.0.4206
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18
 
19
App::uses('Dispatcher', 'Routing');
20
App::uses('DispatcherFilter', 'Routing');
21
 
22
if (!class_exists('AppController', false)) {
23
	require_once CAKE . 'Test' . DS . 'test_app' . DS . 'Controller' . DS . 'AppController.php';
24
} elseif (!defined('APP_CONTROLLER_EXISTS')) {
25
	define('APP_CONTROLLER_EXISTS', true);
26
}
27
 
28
/**
29
 * A testing stub that doesn't send headers.
30
 *
31
 * @package       Cake.Test.Case.Routing
32
 */
33
class DispatcherMockCakeResponse extends CakeResponse {
34
 
35
	protected function _sendHeader($name, $value = null) {
36
		return $name . ' ' . $value;
37
	}
38
 
39
}
40
 
41
/**
42
 * TestDispatcher class
43
 *
44
 * @package       Cake.Test.Case.Routing
45
 */
46
class TestDispatcher extends Dispatcher {
47
 
48
/**
49
 * Controller instance, made publicly available for testing
50
 *
51
 * @var Controller
52
 */
53
	public $controller;
54
 
55
/**
56
 * invoke method
57
 *
58
 * @param Controller $controller
59
 * @param CakeRequest $request
60
 * @return CakeResponse
61
 */
62
	protected function _invoke(Controller $controller, CakeRequest $request) {
63
		$this->controller = $controller;
64
		return parent::_invoke($controller, $request);
65
	}
66
 
67
/**
68
 * Helper function to test single method attaching for dispatcher filters
69
 *
70
 * @param CakeEvent $event
71
 * @return void
72
 */
73
	public function filterTest($event) {
74
		$event->data['request']->params['eventName'] = $event->name();
75
	}
76
 
77
/**
78
 * Helper function to test single method attaching for dispatcher filters
79
 *
80
 * @param CakeEvent
81
 * @return void
82
 */
83
	public function filterTest2($event) {
84
		$event->stopPropagation();
85
		return $event->data['response'];
86
	}
87
 
88
}
89
 
90
/**
91
 * MyPluginAppController class
92
 *
93
 * @package       Cake.Test.Case.Routing
94
 */
95
class MyPluginAppController extends AppController {
96
}
97
 
98
/**
99
 * Abstract Class DispatcherTestAbstractController
100
 */
101
abstract class DispatcherTestAbstractController extends Controller {
102
 
103
	abstract public function index();
104
 
105
}
106
 
107
/**
108
 * Interface DispatcherTestInterfaceController
109
 */
110
interface DispatcherTestInterfaceController {
111
 
112
	public function index();
113
 
114
}
115
 
116
/**
117
 * MyPluginController class
118
 *
119
 * @package       Cake.Test.Case.Routing
120
 */
121
class MyPluginController extends MyPluginAppController {
122
 
123
/**
124
 * uses property
125
 *
126
 * @var array
127
 */
128
	public $uses = array();
129
 
130
/**
131
 * index method
132
 *
133
 * @return void
134
 */
135
	public function index() {
136
		return true;
137
	}
138
 
139
/**
140
 * add method
141
 *
142
 * @return void
143
 */
144
	public function add() {
145
		return true;
146
	}
147
 
148
/**
149
 * admin_add method
150
 *
151
 * @param mixed $id
152
 * @return void
153
 */
154
	public function admin_add($id = null) {
155
		return $id;
156
	}
157
 
158
}
159
 
160
/**
161
 * SomePagesController class
162
 *
163
 * @package       Cake.Test.Case.Routing
164
 */
165
class SomePagesController extends AppController {
166
 
167
/**
168
 * uses property
169
 *
170
 * @var array
171
 */
172
	public $uses = array();
173
 
174
/**
175
 * display method
176
 *
177
 * @param string $page
178
 * @return void
179
 */
180
	public function display($page = null) {
181
		return $page;
182
	}
183
 
184
/**
185
 * index method
186
 *
187
 * @return void
188
 */
189
	public function index() {
190
		return true;
191
	}
192
 
193
/**
194
 * Test method for returning responses.
195
 *
196
 * @return CakeResponse
197
 */
198
	public function responseGenerator() {
199
		return new CakeResponse(array('body' => 'new response'));
200
	}
201
 
202
/**
203
 * Test file sending
204
 *
205
 * @return CakeResponse
206
 */
207
	public function sendfile() {
208
		$this->response->file(CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'css' . DS . 'test_asset.css');
209
		return $this->response;
210
	}
211
 
212
}
213
 
214
/**
215
 * OtherPagesController class
216
 *
217
 * @package       Cake.Test.Case.Routing
218
 */
219
class OtherPagesController extends MyPluginAppController {
220
 
221
/**
222
 * uses property
223
 *
224
 * @var array
225
 */
226
	public $uses = array();
227
 
228
/**
229
 * display method
230
 *
231
 * @param string $page
232
 * @return void
233
 */
234
	public function display($page = null) {
235
		return $page;
236
	}
237
 
238
/**
239
 * index method
240
 *
241
 * @return void
242
 */
243
	public function index() {
244
		return true;
245
	}
246
 
247
}
248
 
249
/**
250
 * TestDispatchPagesController class
251
 *
252
 * @package       Cake.Test.Case.Routing
253
 */
254
class TestDispatchPagesController extends AppController {
255
 
256
/**
257
 * uses property
258
 *
259
 * @var array
260
 */
261
	public $uses = array();
262
 
263
/**
264
 * admin_index method
265
 *
266
 * @return void
267
 */
268
	public function admin_index() {
269
		return true;
270
	}
271
 
272
/**
273
 * camelCased method
274
 *
275
 * @return void
276
 */
277
	public function camelCased() {
278
		return true;
279
	}
280
 
281
}
282
 
283
/**
284
 * ArticlesTestAppController class
285
 *
286
 * @package       Cake.Test.Case.Routing
287
 */
288
class ArticlesTestAppController extends AppController {
289
}
290
 
291
/**
292
 * ArticlesTestController class
293
 *
294
 * @package       Cake.Test.Case.Routing
295
 */
296
class ArticlesTestController extends ArticlesTestAppController {
297
 
298
/**
299
 * uses property
300
 *
301
 * @var array
302
 */
303
	public $uses = array();
304
 
305
/**
306
 * admin_index method
307
 *
308
 * @return void
309
 */
310
	public function admin_index() {
311
		return true;
312
	}
313
 
314
/**
315
 * fake index method.
316
 *
317
 * @return void
318
 */
319
	public function index() {
320
		return true;
321
	}
322
 
323
}
324
 
325
/**
326
 * SomePostsController class
327
 *
328
 * @package       Cake.Test.Case.Routing
329
 */
330
class SomePostsController extends AppController {
331
 
332
/**
333
 * uses property
334
 *
335
 * @var array
336
 */
337
	public $uses = array();
338
 
339
/**
340
 * autoRender property
341
 *
342
 * @var bool
343
 */
344
	public $autoRender = false;
345
 
346
/**
347
 * beforeFilter method
348
 *
349
 * @return void
350
 */
351
	public function beforeFilter() {
352
		if ($this->params['action'] === 'index') {
353
			$this->params['action'] = 'view';
354
		} else {
355
			$this->params['action'] = 'change';
356
		}
357
		$this->params['pass'] = array('changed');
358
	}
359
 
360
/**
361
 * index method
362
 *
363
 * @return void
364
 */
365
	public function index() {
366
		return true;
367
	}
368
 
369
/**
370
 * change method
371
 *
372
 * @return void
373
 */
374
	public function change() {
375
		return true;
376
	}
377
 
378
}
379
 
380
/**
381
 * TestCachedPagesController class
382
 *
383
 * @package       Cake.Test.Case.Routing
384
 */
385
class TestCachedPagesController extends Controller {
386
 
387
/**
388
 * uses property
389
 *
390
 * @var array
391
 */
392
	public $uses = array();
393
 
394
/**
395
 * helpers property
396
 *
397
 * @var array
398
 */
399
	public $helpers = array('Cache', 'Html');
400
 
401
/**
402
 * cacheAction property
403
 *
404
 * @var array
405
 */
406
	public $cacheAction = array(
407
		'index' => '+2 sec',
408
		'test_nocache_tags' => '+2 sec',
409
		'view' => '+2 sec'
410
	);
411
 
412
/**
413
 * Mock out the response object so it doesn't send headers.
414
 *
415
 * @var string
416
 */
417
	protected $_responseClass = 'DispatcherMockCakeResponse';
418
 
419
/**
420
 * viewPath property
421
 *
422
 * @var string
423
 */
424
	public $viewPath = 'Posts';
425
 
426
/**
427
 * index method
428
 *
429
 * @return void
430
 */
431
	public function index() {
432
		$this->render();
433
	}
434
 
435
/**
436
 * test_nocache_tags method
437
 *
438
 * @return void
439
 */
440
	public function test_nocache_tags() {
441
		$this->render();
442
	}
443
 
444
/**
445
 * view method
446
 *
447
 * @return void
448
 */
449
	public function view($id = null) {
450
		$this->render('index');
451
	}
452
 
453
/**
454
 * test cached forms / tests view object being registered
455
 *
456
 * @return void
457
 */
458
	public function cache_form() {
459
		$this->cacheAction = 10;
460
		$this->helpers[] = 'Form';
461
	}
462
 
463
/**
464
 * Test cached views with themes.
465
 *
466
 * @return void
467
 */
468
	public function themed() {
469
		$this->cacheAction = 10;
470
		$this->viewClass = 'Theme';
471
		$this->theme = 'TestTheme';
472
	}
473
 
474
}
475
 
476
/**
477
 * TimesheetsController class
478
 *
479
 * @package       Cake.Test.Case.Routing
480
 */
481
class TimesheetsController extends Controller {
482
 
483
/**
484
 * uses property
485
 *
486
 * @var array
487
 */
488
	public $uses = array();
489
 
490
/**
491
 * index method
492
 *
493
 * @return void
494
 */
495
	public function index() {
496
		return true;
497
	}
498
 
499
}
500
 
501
/**
502
 * TestFilterDispatcher class
503
 *
504
 * @package       Cake.Test.Case.Routing
505
 */
506
class TestFilterDispatcher extends DispatcherFilter {
507
 
508
	public $priority = 10;
509
 
510
/**
511
 * TestFilterDispatcher::beforeDispatch()
512
 *
513
 * @param mixed $event
514
 * @return CakeResponse|bool
515
 */
516
	public function beforeDispatch(CakeEvent $event) {
517
		$event->stopPropagation();
518
		$response = $event->data['request'];
519
		$response->addParams(array('settings' => $this->settings));
520
		return null;
521
	}
522
 
523
/**
524
 * TestFilterDispatcher::afterDispatch()
525
 *
526
 * @param mixed $event
527
 * @return mixed boolean to stop the event dispatching or null to continue
528
 */
529
	public function afterDispatch(CakeEvent $event) {
530
	}
531
 
532
}
533
 
534
/**
535
 * DispatcherTest class
536
 *
537
 * @package       Cake.Test.Case.Routing
538
 */
539
class DispatcherTest extends CakeTestCase {
540
 
541
/**
542
 * setUp method
543
 *
544
 * @return void
545
 */
546
	public function setUp() {
547
		parent::setUp();
548
		$this->_get = $_GET;
549
		$_GET = array();
550
		$this->_post = $_POST;
551
		$this->_files = $_FILES;
552
		$this->_server = $_SERVER;
553
 
554
		$this->_app = Configure::read('App');
555
		Configure::write('App.base', false);
556
		Configure::write('App.baseUrl', false);
557
		Configure::write('App.dir', 'app');
558
		Configure::write('App.webroot', 'webroot');
559
 
560
		$this->_cache = Configure::read('Cache');
561
		Configure::write('Cache.disable', true);
562
 
563
		$this->_debug = Configure::read('debug');
564
 
565
		App::build();
566
		App::objects('plugin', null, false);
567
	}
568
 
569
/**
570
 * tearDown method
571
 *
572
 * @return void
573
 */
574
	public function tearDown() {
575
		parent::tearDown();
576
		$_GET = $this->_get;
577
		$_POST = $this->_post;
578
		$_FILES = $this->_files;
579
		$_SERVER = $this->_server;
580
		App::build();
581
		CakePlugin::unload();
582
		Configure::write('App', $this->_app);
583
		Configure::write('Cache', $this->_cache);
584
		Configure::write('debug', $this->_debug);
585
		Configure::write('Dispatcher.filters', array());
586
	}
587
 
588
/**
589
 * testParseParamsWithoutZerosAndEmptyPost method
590
 *
591
 * @return void
592
 * @triggers DispatcherTest $Dispatcher, array('request' => $request)
593
 */
594
	public function testParseParamsWithoutZerosAndEmptyPost() {
595
		$Dispatcher = new Dispatcher();
596
		$request = new CakeRequest("/testcontroller/testaction/params1/params2/params3");
597
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
598
		$Dispatcher->parseParams($event);
599
		$this->assertSame($request['controller'], 'testcontroller');
600
		$this->assertSame($request['action'], 'testaction');
601
		$this->assertSame($request['pass'][0], 'params1');
602
		$this->assertSame($request['pass'][1], 'params2');
603
		$this->assertSame($request['pass'][2], 'params3');
604
		$this->assertFalse(!empty($request['form']));
605
	}
606
 
607
/**
608
 * testParseParamsReturnsPostedData method
609
 *
610
 * @return void
611
 * @triggers DispatcherTest $Dispatcher, array('request' => $request)
612
 */
613
	public function testParseParamsReturnsPostedData() {
614
		$_POST['testdata'] = "My Posted Content";
615
		$Dispatcher = new Dispatcher();
616
		$request = new CakeRequest("/");
617
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
618
		$Dispatcher->parseParams($event);
619
		$Dispatcher->parseParams($event);
620
		$this->assertEquals("My Posted Content", $request['data']['testdata']);
621
	}
622
 
623
/**
624
 * testParseParamsWithSingleZero method
625
 *
626
 * @return void
627
 * @triggers DispatcherTest $Dispatcher, array('request' => $test)
628
 */
629
	public function testParseParamsWithSingleZero() {
630
		$Dispatcher = new Dispatcher();
631
		$test = new CakeRequest("/testcontroller/testaction/1/0/23");
632
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
633
		$Dispatcher->parseParams($event);
634
 
635
		$this->assertSame($test['controller'], 'testcontroller');
636
		$this->assertSame($test['action'], 'testaction');
637
		$this->assertSame($test['pass'][0], '1');
638
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][1]);
639
		$this->assertSame($test['pass'][2], '23');
640
	}
641
 
642
/**
643
 * testParseParamsWithManySingleZeros method
644
 *
645
 * @return void
646
 * @triggers DispatcherTest $Dispatcher, array('request' => $test)
647
 */
648
	public function testParseParamsWithManySingleZeros() {
649
		$Dispatcher = new Dispatcher();
650
		$test = new CakeRequest("/testcontroller/testaction/0/0/0/0/0/0");
651
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
652
		$Dispatcher->parseParams($event);
653
 
654
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][0]);
655
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][1]);
656
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][2]);
657
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][3]);
658
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][4]);
659
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][5]);
660
	}
661
 
662
/**
663
 * testParseParamsWithManyZerosInEachSectionOfUrl method
664
 *
665
 * @return void
666
 * @triggers DispatcherTest $Dispatcher, array('request' => $test)
667
 */
668
	public function testParseParamsWithManyZerosInEachSectionOfUrl() {
669
		$Dispatcher = new Dispatcher();
670
		$test = new CakeRequest("/testcontroller/testaction/000/0000/00000/000000/000000/0000000");
671
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
672
		$Dispatcher->parseParams($event);
673
 
674
		$this->assertRegExp('/\\A(?:000)\\z/', $test['pass'][0]);
675
		$this->assertRegExp('/\\A(?:0000)\\z/', $test['pass'][1]);
676
		$this->assertRegExp('/\\A(?:00000)\\z/', $test['pass'][2]);
677
		$this->assertRegExp('/\\A(?:000000)\\z/', $test['pass'][3]);
678
		$this->assertRegExp('/\\A(?:000000)\\z/', $test['pass'][4]);
679
		$this->assertRegExp('/\\A(?:0000000)\\z/', $test['pass'][5]);
680
	}
681
 
682
/**
683
 * testParseParamsWithMixedOneToManyZerosInEachSectionOfUrl method
684
 *
685
 * @return void
686
 * @triggers DispatcherTest $Dispatcher, array('request' => $test)
687
 */
688
	public function testParseParamsWithMixedOneToManyZerosInEachSectionOfUrl() {
689
		$Dispatcher = new Dispatcher();
690
		$test = new CakeRequest("/testcontroller/testaction/01/0403/04010/000002/000030/0000400");
691
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
692
		$Dispatcher->parseParams($event);
693
 
694
		$this->assertRegExp('/\\A(?:01)\\z/', $test['pass'][0]);
695
		$this->assertRegExp('/\\A(?:0403)\\z/', $test['pass'][1]);
696
		$this->assertRegExp('/\\A(?:04010)\\z/', $test['pass'][2]);
697
		$this->assertRegExp('/\\A(?:000002)\\z/', $test['pass'][3]);
698
		$this->assertRegExp('/\\A(?:000030)\\z/', $test['pass'][4]);
699
		$this->assertRegExp('/\\A(?:0000400)\\z/', $test['pass'][5]);
700
	}
701
 
702
/**
703
 * testQueryStringOnRoot method
704
 *
705
 * @return void
706
 * @triggers DispatcherTest $Dispatcher, array('request' => $request)
707
 * @triggers DispatcherTest $Dispatcher, array('request' => $request)
708
 */
709
	public function testQueryStringOnRoot() {
710
		Router::reload();
711
		Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
712
		Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
713
		Router::connect('/:controller/:action/*');
714
 
715
		$_GET = array('coffee' => 'life', 'sleep' => 'sissies');
716
		$Dispatcher = new Dispatcher();
717
		$request = new CakeRequest('posts/home/?coffee=life&sleep=sissies');
718
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
719
		$Dispatcher->parseParams($event);
720
 
721
		$this->assertRegExp('/posts/', $request['controller']);
722
		$this->assertRegExp('/home/', $request['action']);
723
		$this->assertTrue(isset($request['url']['sleep']));
724
		$this->assertTrue(isset($request['url']['coffee']));
725
 
726
		$Dispatcher = new Dispatcher();
727
		$request = new CakeRequest('/?coffee=life&sleep=sissy');
728
 
729
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
730
		$Dispatcher->parseParams($event);
731
		$this->assertRegExp('/pages/', $request['controller']);
732
		$this->assertRegExp('/display/', $request['action']);
733
		$this->assertTrue(isset($request['url']['sleep']));
734
		$this->assertTrue(isset($request['url']['coffee']));
735
		$this->assertEquals('life', $request['url']['coffee']);
736
	}
737
 
738
/**
739
 * testMissingController method
740
 *
741
 * @expectedException MissingControllerException
742
 * @expectedExceptionMessage Controller class SomeControllerController could not be found.
743
 * @return void
744
 */
745
	public function testMissingController() {
746
		Router::connect('/:controller/:action/*');
747
 
748
		$Dispatcher = new TestDispatcher();
749
		Configure::write('App.baseUrl', '/index.php');
750
		$url = new CakeRequest('some_controller/home/param:value/param2:value2');
751
		$response = $this->getMock('CakeResponse');
752
 
753
		$Dispatcher->dispatch($url, $response, array('return' => 1));
754
	}
755
 
756
/**
757
 * testMissingControllerInterface method
758
 *
759
 * @expectedException MissingControllerException
760
 * @expectedExceptionMessage Controller class DispatcherTestInterfaceController could not be found.
761
 * @return void
762
 */
763
	public function testMissingControllerInterface() {
764
		Router::connect('/:controller/:action/*');
765
 
766
		$Dispatcher = new TestDispatcher();
767
		Configure::write('App.baseUrl', '/index.php');
768
		$url = new CakeRequest('dispatcher_test_interface/index');
769
		$response = $this->getMock('CakeResponse');
770
 
771
		$Dispatcher->dispatch($url, $response, array('return' => 1));
772
	}
773
 
774
/**
775
 * testMissingControllerInterface method
776
 *
777
 * @expectedException MissingControllerException
778
 * @expectedExceptionMessage Controller class DispatcherTestAbstractController could not be found.
779
 * @return void
780
 */
781
	public function testMissingControllerAbstract() {
782
		Router::connect('/:controller/:action/*');
783
 
784
		$Dispatcher = new TestDispatcher();
785
		Configure::write('App.baseUrl', '/index.php');
786
		$url = new CakeRequest('dispatcher_test_abstract/index');
787
		$response = $this->getMock('CakeResponse');
788
 
789
		$Dispatcher->dispatch($url, $response, array('return' => 1));
790
	}
791
 
792
/**
793
 * testDispatch method
794
 *
795
 * @return void
796
 */
797
	public function testDispatchBasic() {
798
		App::build(array(
799
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
800
		));
801
		$Dispatcher = new TestDispatcher();
802
		Configure::write('App.baseUrl', '/index.php');
803
		$url = new CakeRequest('pages/home/param:value/param2:value2');
804
		$response = $this->getMock('CakeResponse');
805
 
806
		$Dispatcher->dispatch($url, $response, array('return' => 1));
807
		$expected = 'Pages';
808
		$this->assertEquals($expected, $Dispatcher->controller->name);
809
 
810
		$expected = array('0' => 'home', 'param' => 'value', 'param2' => 'value2');
811
		$this->assertSame($expected, $Dispatcher->controller->passedArgs);
812
 
813
		Configure::write('App.baseUrl', '/pages/index.php');
814
 
815
		$url = new CakeRequest('pages/home');
816
		$Dispatcher->dispatch($url, $response, array('return' => 1));
817
 
818
		$expected = 'Pages';
819
		$this->assertEquals($expected, $Dispatcher->controller->name);
820
 
821
		$url = new CakeRequest('pages/home/');
822
		$Dispatcher->dispatch($url, $response, array('return' => 1));
823
		$this->assertNull($Dispatcher->controller->plugin);
824
 
825
		$expected = 'Pages';
826
		$this->assertEquals($expected, $Dispatcher->controller->name);
827
 
828
		unset($Dispatcher);
829
 
830
		require CAKE . 'Config' . DS . 'routes.php';
831
		$Dispatcher = new TestDispatcher();
832
		Configure::write('App.baseUrl', '/timesheets/index.php');
833
 
834
		$url = new CakeRequest('timesheets');
835
		$Dispatcher->dispatch($url, $response, array('return' => 1));
836
 
837
		$expected = 'Timesheets';
838
		$this->assertEquals($expected, $Dispatcher->controller->name);
839
 
840
		$url = new CakeRequest('timesheets/');
841
		$Dispatcher->dispatch($url, $response, array('return' => 1));
842
 
843
		$this->assertEquals('Timesheets', $Dispatcher->controller->name);
844
		$this->assertEquals('/timesheets/index.php', $url->base);
845
 
846
		$url = new CakeRequest('test_dispatch_pages/camelCased');
847
		$Dispatcher->dispatch($url, $response, array('return' => 1));
848
		$this->assertEquals('TestDispatchPages', $Dispatcher->controller->name);
849
 
850
		$url = new CakeRequest('test_dispatch_pages/camelCased/something. .');
851
		$Dispatcher->dispatch($url, $response, array('return' => 1));
852
		$this->assertEquals('something. .', $Dispatcher->controller->params['pass'][0], 'Period was chopped off. %s');
853
	}
854
 
855
/**
856
 * Test that Dispatcher handles actions that return response objects.
857
 *
858
 * @return void
859
 */
860
	public function testDispatchActionReturnsResponse() {
861
		Router::connect('/:controller/:action');
862
		$Dispatcher = new Dispatcher();
863
		$request = new CakeRequest('some_pages/responseGenerator');
864
		$response = $this->getMock('CakeResponse', array('_sendHeader'));
865
 
866
		ob_start();
867
		$Dispatcher->dispatch($request, $response);
868
		$result = ob_get_clean();
869
 
870
		$this->assertEquals('new response', $result);
871
	}
872
 
873
/**
874
 * testDispatchActionSendsFile
875
 *
876
 * @return void
877
 */
878
	public function testDispatchActionSendsFile() {
879
		Router::connect('/:controller/:action');
880
		$Dispatcher = new Dispatcher();
881
		$request = new CakeRequest('some_pages/sendfile');
882
		$response = $this->getMock('CakeResponse', array(
883
			'header',
884
			'type',
885
			'download',
886
			'_sendHeader',
887
			'_setContentType',
888
			'_isActive',
889
			'_clearBuffer',
890
			'_flushBuffer'
891
		));
892
 
893
		$response->expects($this->never())
894
			->method('body');
895
 
896
		$response->expects($this->exactly(1))
897
			->method('_isActive')
898
			->will($this->returnValue(true));
899
 
900
		ob_start();
901
		$Dispatcher->dispatch($request, $response);
902
		$result = ob_get_clean();
903
 
904
		$this->assertEquals("/* this is the test asset css file */\n", $result);
905
	}
906
 
907
/**
908
 * testAdminDispatch method
909
 *
910
 * @return void
911
 */
912
	public function testAdminDispatch() {
913
		$_POST = array();
914
		$Dispatcher = new TestDispatcher();
915
		Configure::write('Routing.prefixes', array('admin'));
916
		Configure::write('App.baseUrl', '/cake/repo/branches/1.2.x.x/index.php');
917
		$url = new CakeRequest('admin/test_dispatch_pages/index/param:value/param2:value2');
918
		$response = $this->getMock('CakeResponse');
919
 
920
		Router::reload();
921
		$Dispatcher->dispatch($url, $response, array('return' => 1));
922
 
923
		$this->assertEquals('TestDispatchPages', $Dispatcher->controller->name);
924
 
925
		$this->assertSame($Dispatcher->controller->passedArgs, array('param' => 'value', 'param2' => 'value2'));
926
		$this->assertTrue($Dispatcher->controller->params['admin']);
927
 
928
		$expected = '/cake/repo/branches/1.2.x.x/index.php/admin/test_dispatch_pages/index/param:value/param2:value2';
929
		$this->assertSame($expected, $Dispatcher->controller->here);
930
 
931
		$expected = '/cake/repo/branches/1.2.x.x/index.php';
932
		$this->assertSame($expected, $Dispatcher->controller->base);
933
	}
934
 
935
/**
936
 * testPluginDispatch method
937
 *
938
 * @return void
939
 * @triggers DispatcherTest $Dispatcher, array('request' => $url)
940
 */
941
	public function testPluginDispatch() {
942
		$_POST = array();
943
 
944
		Router::reload();
945
		$Dispatcher = new TestDispatcher();
946
		Router::connect(
947
			'/my_plugin/:controller/*',
948
			array('plugin' => 'my_plugin', 'controller' => 'pages', 'action' => 'display')
949
		);
950
 
951
		$url = new CakeRequest('my_plugin/some_pages/home/param:value/param2:value2');
952
		$response = $this->getMock('CakeResponse');
953
		$Dispatcher->dispatch($url, $response, array('return' => 1));
954
 
955
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $url));
956
		$Dispatcher->parseParams($event);
957
		$expected = array(
958
			'pass' => array('home'),
959
			'named' => array('param' => 'value', 'param2' => 'value2'), 'plugin' => 'my_plugin',
960
			'controller' => 'some_pages', 'action' => 'display'
961
		);
962
		foreach ($expected as $key => $value) {
963
			$this->assertEquals($value, $url[$key], 'Value mismatch ' . $key . ' %');
964
		}
965
 
966
		$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
967
		$this->assertSame($Dispatcher->controller->name, 'SomePages');
968
		$this->assertSame($Dispatcher->controller->params['controller'], 'some_pages');
969
		$this->assertSame($Dispatcher->controller->passedArgs, array('0' => 'home', 'param' => 'value', 'param2' => 'value2'));
970
	}
971
 
972
/**
973
 * testAutomaticPluginDispatch method
974
 *
975
 * @return void
976
 */
977
	public function testAutomaticPluginDispatch() {
978
		$_POST = array();
979
		$_SERVER['PHP_SELF'] = '/cake/repo/branches/1.2.x.x/index.php';
980
 
981
		Router::reload();
982
		$Dispatcher = new TestDispatcher();
983
		Router::connect(
984
			'/my_plugin/:controller/:action/*',
985
			array('plugin' => 'my_plugin', 'controller' => 'pages', 'action' => 'display')
986
		);
987
 
988
		$Dispatcher->base = false;
989
 
990
		$url = new CakeRequest('my_plugin/other_pages/index/param:value/param2:value2');
991
		$response = $this->getMock('CakeResponse');
992
		$Dispatcher->dispatch($url, $response, array('return' => 1));
993
 
994
		$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
995
		$this->assertSame($Dispatcher->controller->name, 'OtherPages');
996
		$this->assertSame($Dispatcher->controller->action, 'index');
997
		$this->assertSame($Dispatcher->controller->passedArgs, array('param' => 'value', 'param2' => 'value2'));
998
 
999
		$expected = '/cake/repo/branches/1.2.x.x/my_plugin/other_pages/index/param:value/param2:value2';
1000
		$this->assertSame($expected, $url->here);
1001
 
1002
		$expected = '/cake/repo/branches/1.2.x.x';
1003
		$this->assertSame($expected, $url->base);
1004
	}
1005
 
1006
/**
1007
 * testAutomaticPluginControllerDispatch method
1008
 *
1009
 * @return void
1010
 */
1011
	public function testAutomaticPluginControllerDispatch() {
1012
		$plugins = App::objects('plugin');
1013
		$plugins[] = 'MyPlugin';
1014
		$plugins[] = 'ArticlesTest';
1015
 
1016
		CakePlugin::load('MyPlugin', array('path' => '/fake/path'));
1017
 
1018
		Router::reload();
1019
		$Dispatcher = new TestDispatcher();
1020
		$Dispatcher->base = false;
1021
 
1022
		$url = new CakeRequest('my_plugin/my_plugin/add/param:value/param2:value2');
1023
		$response = $this->getMock('CakeResponse');
1024
 
1025
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1026
 
1027
		$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
1028
		$this->assertSame($Dispatcher->controller->name, 'MyPlugin');
1029
		$this->assertSame($Dispatcher->controller->action, 'add');
1030
		$this->assertEquals(array('param' => 'value', 'param2' => 'value2'), $Dispatcher->controller->params['named']);
1031
 
1032
		Router::reload();
1033
		require CAKE . 'Config' . DS . 'routes.php';
1034
		$Dispatcher = new TestDispatcher();
1035
		$Dispatcher->base = false;
1036
 
1037
		// Simulates the Route for a real plugin, installed in APP/plugins
1038
		Router::connect('/my_plugin/:controller/:action/*', array('plugin' => 'my_plugin'));
1039
 
1040
		$plugin = 'MyPlugin';
1041
		$pluginUrl = Inflector::underscore($plugin);
1042
 
1043
		$url = new CakeRequest($pluginUrl);
1044
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1045
		$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
1046
		$this->assertSame($Dispatcher->controller->name, 'MyPlugin');
1047
		$this->assertSame($Dispatcher->controller->action, 'index');
1048
 
1049
		$expected = $pluginUrl;
1050
		$this->assertEquals($expected, $Dispatcher->controller->params['controller']);
1051
 
1052
		Configure::write('Routing.prefixes', array('admin'));
1053
 
1054
		Router::reload();
1055
		require CAKE . 'Config' . DS . 'routes.php';
1056
		$Dispatcher = new TestDispatcher();
1057
 
1058
		$url = new CakeRequest('admin/my_plugin/my_plugin/add/5/param:value/param2:value2');
1059
		$response = $this->getMock('CakeResponse');
1060
 
1061
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1062
 
1063
		$this->assertEquals('my_plugin', $Dispatcher->controller->params['plugin']);
1064
		$this->assertEquals('my_plugin', $Dispatcher->controller->params['controller']);
1065
		$this->assertEquals('admin_add', $Dispatcher->controller->params['action']);
1066
		$this->assertEquals(array(5), $Dispatcher->controller->params['pass']);
1067
		$this->assertEquals(array('param' => 'value', 'param2' => 'value2'), $Dispatcher->controller->params['named']);
1068
		$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
1069
		$this->assertSame($Dispatcher->controller->name, 'MyPlugin');
1070
		$this->assertSame($Dispatcher->controller->action, 'admin_add');
1071
 
1072
		$expected = array(0 => 5, 'param' => 'value', 'param2' => 'value2');
1073
		$this->assertEquals($expected, $Dispatcher->controller->passedArgs);
1074
 
1075
		Configure::write('Routing.prefixes', array('admin'));
1076
		CakePlugin::load('ArticlesTest', array('path' => '/fake/path'));
1077
		Router::reload();
1078
		require CAKE . 'Config' . DS . 'routes.php';
1079
 
1080
		$Dispatcher = new TestDispatcher();
1081
 
1082
		$Dispatcher->dispatch(new CakeRequest('admin/articles_test'), $response, array('return' => 1));
1083
		$this->assertSame($Dispatcher->controller->plugin, 'ArticlesTest');
1084
		$this->assertSame($Dispatcher->controller->name, 'ArticlesTest');
1085
		$this->assertSame($Dispatcher->controller->action, 'admin_index');
1086
 
1087
		$expected = array(
1088
			'pass' => array(),
1089
			'named' => array(),
1090
			'controller' => 'articles_test',
1091
			'plugin' => 'articles_test',
1092
			'action' => 'admin_index',
1093
			'prefix' => 'admin',
1094
			'admin' => true,
1095
			'return' => 1
1096
		);
1097
		foreach ($expected as $key => $value) {
1098
			$this->assertEquals($expected[$key], $Dispatcher->controller->request[$key], 'Value mismatch ' . $key);
1099
		}
1100
	}
1101
 
1102
/**
1103
 * test Plugin dispatching without controller name and using
1104
 * plugin short form instead.
1105
 *
1106
 * @return void
1107
 */
1108
	public function testAutomaticPluginDispatchWithShortAccess() {
1109
		CakePlugin::load('MyPlugin', array('path' => '/fake/path'));
1110
		Router::reload();
1111
 
1112
		$Dispatcher = new TestDispatcher();
1113
		$Dispatcher->base = false;
1114
 
1115
		$url = new CakeRequest('my_plugin/');
1116
		$response = $this->getMock('CakeResponse');
1117
 
1118
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1119
		$this->assertEquals('my_plugin', $Dispatcher->controller->params['controller']);
1120
		$this->assertEquals('my_plugin', $Dispatcher->controller->params['plugin']);
1121
		$this->assertEquals('index', $Dispatcher->controller->params['action']);
1122
		$this->assertFalse(isset($Dispatcher->controller->params['pass'][0]));
1123
	}
1124
 
1125
/**
1126
 * test plugin shortcut URLs with controllers that need to be loaded,
1127
 * the above test uses a controller that has already been included.
1128
 *
1129
 * @return void
1130
 */
1131
	public function testPluginShortCutUrlsWithControllerThatNeedsToBeLoaded() {
1132
		$loaded = class_exists('TestPluginController', false);
1133
		$this->skipIf($loaded, 'TestPluginController already loaded.');
1134
 
1135
		Router::reload();
1136
		App::build(array(
1137
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
1138
		), App::RESET);
1139
		CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
1140
 
1141
		$Dispatcher = new TestDispatcher();
1142
		$Dispatcher->base = false;
1143
 
1144
		$url = new CakeRequest('test_plugin/');
1145
		$response = $this->getMock('CakeResponse');
1146
 
1147
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1148
		$this->assertEquals('test_plugin', $Dispatcher->controller->params['controller']);
1149
		$this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
1150
		$this->assertEquals('index', $Dispatcher->controller->params['action']);
1151
		$this->assertFalse(isset($Dispatcher->controller->params['pass'][0]));
1152
 
1153
		$url = new CakeRequest('/test_plugin/tests/index');
1154
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1155
		$this->assertEquals('tests', $Dispatcher->controller->params['controller']);
1156
		$this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
1157
		$this->assertEquals('index', $Dispatcher->controller->params['action']);
1158
		$this->assertFalse(isset($Dispatcher->controller->params['pass'][0]));
1159
 
1160
		$url = new CakeRequest('/test_plugin/tests/index/some_param');
1161
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1162
		$this->assertEquals('tests', $Dispatcher->controller->params['controller']);
1163
		$this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
1164
		$this->assertEquals('index', $Dispatcher->controller->params['action']);
1165
		$this->assertEquals('some_param', $Dispatcher->controller->params['pass'][0]);
1166
 
1167
		App::build();
1168
	}
1169
 
1170
/**
1171
 * testAutomaticPluginControllerMissingActionDispatch method
1172
 *
1173
 * @expectedException MissingActionException
1174
 * @expectedExceptionMessage Action MyPluginController::not_here() could not be found.
1175
 * @return void
1176
 */
1177
	public function testAutomaticPluginControllerMissingActionDispatch() {
1178
		Router::reload();
1179
		$Dispatcher = new TestDispatcher();
1180
 
1181
		$url = new CakeRequest('my_plugin/not_here/param:value/param2:value2');
1182
		$response = $this->getMock('CakeResponse');
1183
 
1184
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1185
	}
1186
 
1187
/**
1188
 * testAutomaticPluginControllerMissingActionDispatch method
1189
 *
1190
 * @expectedException MissingActionException
1191
 * @expectedExceptionMessage Action MyPluginController::param:value() could not be found.
1192
 * @return void
1193
 */
1194
 
1195
	public function testAutomaticPluginControllerIndexMissingAction() {
1196
		Router::reload();
1197
		$Dispatcher = new TestDispatcher();
1198
 
1199
		$url = new CakeRequest('my_plugin/param:value/param2:value2');
1200
		$response = $this->getMock('CakeResponse');
1201
 
1202
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1203
	}
1204
 
1205
/**
1206
 * Test dispatching into the TestPlugin in the test_app
1207
 *
1208
 * @return void
1209
 */
1210
	public function testTestPluginDispatch() {
1211
		$Dispatcher = new TestDispatcher();
1212
		App::build(array(
1213
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
1214
		), App::RESET);
1215
		CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
1216
		Router::reload();
1217
		Router::parse('/');
1218
 
1219
		$url = new CakeRequest('/test_plugin/tests/index');
1220
		$response = $this->getMock('CakeResponse');
1221
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1222
		$this->assertTrue(class_exists('TestsController'));
1223
		$this->assertTrue(class_exists('TestPluginAppController'));
1224
		$this->assertTrue(class_exists('PluginsComponent'));
1225
 
1226
		$this->assertEquals('tests', $Dispatcher->controller->params['controller']);
1227
		$this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
1228
		$this->assertEquals('index', $Dispatcher->controller->params['action']);
1229
 
1230
		App::build();
1231
	}
1232
 
1233
/**
1234
 * Tests that it is possible to attach filter classes to the dispatch cycle
1235
 *
1236
 * @return void
1237
 */
1238
	public function testDispatcherFilterSubscriber() {
1239
		App::build(array(
1240
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
1241
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
1242
		), App::RESET);
1243
 
1244
		CakePlugin::load('TestPlugin');
1245
		Configure::write('Dispatcher.filters', array(
1246
			array('callable' => 'TestPlugin.TestDispatcherFilter')
1247
		));
1248
		$dispatcher = new TestDispatcher();
1249
		$request = new CakeRequest('/');
1250
		$request->params['altered'] = false;
1251
		$response = $this->getMock('CakeResponse', array('send'));
1252
 
1253
		$dispatcher->dispatch($request, $response);
1254
		$this->assertTrue($request->params['altered']);
1255
		$this->assertEquals(304, $response->statusCode());
1256
 
1257
		Configure::write('Dispatcher.filters', array(
1258
			'TestPlugin.Test2DispatcherFilter',
1259
			'TestPlugin.TestDispatcherFilter'
1260
		));
1261
		$dispatcher = new TestDispatcher();
1262
		$request = new CakeRequest('/');
1263
		$request->params['altered'] = false;
1264
		$response = $this->getMock('CakeResponse', array('send'));
1265
 
1266
		$dispatcher->dispatch($request, $response);
1267
		$this->assertFalse($request->params['altered']);
1268
		$this->assertEquals(500, $response->statusCode());
1269
		$this->assertNull($dispatcher->controller);
1270
	}
1271
 
1272
/**
1273
 * Tests that it is possible to attach filter with config classes to the dispatch cycle
1274
 *
1275
 * @return void
1276
 */
1277
	public function testDispatcherFilterSettings() {
1278
		Configure::write('Dispatcher.filters', array(
1279
			'TestFilterDispatcher' => array('service' => 'google.com')
1280
		));
1281
		$Dispatcher = new Dispatcher();
1282
		$url = new CakeRequest('some_pages/index');
1283
		$response = $this->getMock('CakeResponse');
1284
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1285
		$settings = $url->param('settings');
1286
		$this->assertEquals($settings, array('service' => 'google.com'));
1287
	}
1288
 
1289
/**
1290
 * Tests that attaching an inexistent class as filter will throw an exception
1291
 *
1292
 * @expectedException MissingDispatcherFilterException
1293
 * @return void
1294
 */
1295
	public function testDispatcherFilterSuscriberMissing() {
1296
		App::build(array(
1297
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
1298
		), App::RESET);
1299
 
1300
		CakePlugin::load('TestPlugin');
1301
		Configure::write('Dispatcher.filters', array(
1302
			array('callable' => 'TestPlugin.NotAFilter')
1303
		));
1304
		$dispatcher = new TestDispatcher();
1305
		$request = new CakeRequest('/');
1306
		$response = $this->getMock('CakeResponse', array('send'));
1307
		$dispatcher->dispatch($request, $response);
1308
	}
1309
 
1310
/**
1311
 * Tests it is possible to attach single callables as filters
1312
 *
1313
 * @return void
1314
 */
1315
	public function testDispatcherFilterCallable() {
1316
		App::build(array(
1317
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
1318
		), App::RESET);
1319
 
1320
		$dispatcher = new TestDispatcher();
1321
		Configure::write('Dispatcher.filters', array(
1322
			array('callable' => array($dispatcher, 'filterTest'), 'on' => 'before')
1323
		));
1324
 
1325
		$request = new CakeRequest('/');
1326
		$response = $this->getMock('CakeResponse', array('send'));
1327
		$dispatcher->dispatch($request, $response);
1328
		$this->assertEquals('Dispatcher.beforeDispatch', $request->params['eventName']);
1329
 
1330
		$dispatcher = new TestDispatcher();
1331
		Configure::write('Dispatcher.filters', array(
1332
			array('callable' => array($dispatcher, 'filterTest'), 'on' => 'after')
1333
		));
1334
 
1335
		$request = new CakeRequest('/');
1336
		$response = $this->getMock('CakeResponse', array('send'));
1337
		$dispatcher->dispatch($request, $response);
1338
		$this->assertEquals('Dispatcher.afterDispatch', $request->params['eventName']);
1339
 
1340
		$dispatcher = new TestDispatcher();
1341
		Configure::write('Dispatcher.filters', array(
1342
			'filterTest' => array('callable' => array($dispatcher, 'filterTest'), 'on' => 'before')
1343
		));
1344
 
1345
		$request = new CakeRequest('/');
1346
		$response = $this->getMock('CakeResponse', array('send'));
1347
		$dispatcher->dispatch($request, $response);
1348
		$this->assertEquals('Dispatcher.beforeDispatch', $request->params['eventName']);
1349
 
1350
		// Test that it is possible to skip the route connection process
1351
		$dispatcher = new TestDispatcher();
1352
		Configure::write('Dispatcher.filters', array(
1353
			array('callable' => array($dispatcher, 'filterTest2'), 'on' => 'before', 'priority' => 1)
1354
		));
1355
 
1356
		$request = new CakeRequest('/');
1357
		$response = $this->getMock('CakeResponse', array('send'));
1358
		$dispatcher->dispatch($request, $response);
1359
		$this->assertEmpty($dispatcher->controller);
1360
		$expected = array('controller' => null, 'action' => null, 'plugin' => null, 'named' => array(), 'pass' => array());
1361
		$this->assertEquals($expected, $request->params);
1362
 
1363
		$dispatcher = new TestDispatcher();
1364
		Configure::write('Dispatcher.filters', array(
1365
			array('callable' => array($dispatcher, 'filterTest2'), 'on' => 'before', 'priority' => 1)
1366
		));
1367
 
1368
		$request = new CakeRequest('/');
1369
		$request->params['return'] = true;
1370
		$response = $this->getMock('CakeResponse', array('send'));
1371
		$response->body('this is a body');
1372
		$result = $dispatcher->dispatch($request, $response);
1373
		$this->assertEquals('this is a body', $result);
1374
 
1375
		$request = new CakeRequest('/');
1376
		$response = $this->getMock('CakeResponse', array('send'));
1377
		$response->expects($this->once())->method('send');
1378
		$response->body('this is a body');
1379
		$result = $dispatcher->dispatch($request, $response);
1380
		$this->assertNull($result);
1381
	}
1382
 
1383
/**
1384
 * testChangingParamsFromBeforeFilter method
1385
 *
1386
 * @return void
1387
 */
1388
	public function testChangingParamsFromBeforeFilter() {
1389
		$Dispatcher = new TestDispatcher();
1390
		$response = $this->getMock('CakeResponse');
1391
		$url = new CakeRequest('some_posts/index/param:value/param2:value2');
1392
 
1393
		try {
1394
			$Dispatcher->dispatch($url, $response, array('return' => 1));
1395
			$this->fail('No exception.');
1396
		} catch (MissingActionException $e) {
1397
			$this->assertEquals('Action SomePostsController::view() could not be found.', $e->getMessage());
1398
		}
1399
 
1400
		$url = new CakeRequest('some_posts/something_else/param:value/param2:value2');
1401
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1402
 
1403
		$expected = 'SomePosts';
1404
		$this->assertEquals($expected, $Dispatcher->controller->name);
1405
 
1406
		$expected = 'change';
1407
		$this->assertEquals($expected, $Dispatcher->controller->action);
1408
 
1409
		$expected = array('changed');
1410
		$this->assertSame($expected, $Dispatcher->controller->params['pass']);
1411
	}
1412
 
1413
/**
1414
 * testStaticAssets method
1415
 *
1416
 * @return void
1417
 */
1418
	public function testAssets() {
1419
		Router::reload();
1420
 
1421
		App::build(array(
1422
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
1423
			'Vendor' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS),
1424
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
1425
		));
1426
		CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
1427
		Configure::write('Dispatcher.filters', array('AssetDispatcher'));
1428
 
1429
		$Dispatcher = new TestDispatcher();
1430
		$response = $this->getMock('CakeResponse', array('_sendHeader'));
1431
 
1432
		try {
1433
			$Dispatcher->dispatch(new CakeRequest('theme/test_theme/../webroot/css/test_asset.css'), $response);
1434
			$this->fail('No exception');
1435
		} catch (MissingControllerException $e) {
1436
			$this->assertEquals('Controller class ThemeController could not be found.', $e->getMessage());
1437
		}
1438
 
1439
		try {
1440
			$Dispatcher->dispatch(new CakeRequest('theme/test_theme/pdfs'), $response);
1441
			$this->fail('No exception');
1442
		} catch (MissingControllerException $e) {
1443
			$this->assertEquals('Controller class ThemeController could not be found.', $e->getMessage());
1444
		}
1445
	}
1446
 
1447
/**
1448
 * Data provider for asset filter
1449
 *
1450
 * - theme assets.
1451
 * - plugin assets.
1452
 * - plugin assets in sub directories.
1453
 * - unknown plugin assets.
1454
 *
1455
 * @return array
1456
 */
1457
	public static function assetProvider() {
1458
		return array(
1459
			array(
1460
				'theme/test_theme/flash/theme_test.swf',
1461
				'View/Themed/TestTheme/webroot/flash/theme_test.swf'
1462
			),
1463
			array(
1464
				'theme/test_theme/pdfs/theme_test.pdf',
1465
				'View/Themed/TestTheme/webroot/pdfs/theme_test.pdf'
1466
			),
1467
			array(
1468
				'theme/test_theme/img/test.jpg',
1469
				'View/Themed/TestTheme/webroot/img/test.jpg'
1470
			),
1471
			array(
1472
				'theme/test_theme/css/test_asset.css',
1473
				'View/Themed/TestTheme/webroot/css/test_asset.css'
1474
			),
1475
			array(
1476
				'theme/test_theme/js/theme.js',
1477
				'View/Themed/TestTheme/webroot/js/theme.js'
1478
			),
1479
			array(
1480
				'theme/test_theme/js/one/theme_one.js',
1481
				'View/Themed/TestTheme/webroot/js/one/theme_one.js'
1482
			),
1483
			array(
1484
				'theme/test_theme/space%20image.text',
1485
				'View/Themed/TestTheme/webroot/space image.text'
1486
			),
1487
			array(
1488
				'test_plugin/root.js',
1489
				'Plugin/TestPlugin/webroot/root.js'
1490
			),
1491
			array(
1492
				'test_plugin/flash/plugin_test.swf',
1493
				'Plugin/TestPlugin/webroot/flash/plugin_test.swf'
1494
			),
1495
			array(
1496
				'test_plugin/pdfs/plugin_test.pdf',
1497
				'Plugin/TestPlugin/webroot/pdfs/plugin_test.pdf'
1498
			),
1499
			array(
1500
				'test_plugin/js/test_plugin/test.js',
1501
				'Plugin/TestPlugin/webroot/js/test_plugin/test.js'
1502
			),
1503
			array(
1504
				'test_plugin/css/test_plugin_asset.css',
1505
				'Plugin/TestPlugin/webroot/css/test_plugin_asset.css'
1506
			),
1507
			array(
1508
				'test_plugin/img/cake.icon.gif',
1509
				'Plugin/TestPlugin/webroot/img/cake.icon.gif'
1510
			),
1511
			array(
1512
				'plugin_js/js/plugin_js.js',
1513
				'Plugin/PluginJs/webroot/js/plugin_js.js'
1514
			),
1515
			array(
1516
				'plugin_js/js/one/plugin_one.js',
1517
				'Plugin/PluginJs/webroot/js/one/plugin_one.js'
1518
			),
1519
			array(
1520
				'test_plugin/css/unknown.extension',
1521
				'Plugin/TestPlugin/webroot/css/unknown.extension'
1522
			),
1523
			array(
1524
				'test_plugin/css/theme_one.htc',
1525
				'Plugin/TestPlugin/webroot/css/theme_one.htc'
1526
			),
1527
		);
1528
	}
1529
 
1530
/**
1531
 * Test assets
1532
 *
1533
 * @dataProvider assetProvider
1534
 * @outputBuffering enabled
1535
 * @return void
1536
 */
1537
	public function testAsset($url, $file) {
1538
		Router::reload();
1539
 
1540
		App::build(array(
1541
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
1542
			'Vendor' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS),
1543
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
1544
		));
1545
		CakePlugin::load(array('TestPlugin', 'PluginJs'));
1546
		Configure::write('Dispatcher.filters', array('AssetDispatcher'));
1547
 
1548
		$Dispatcher = new TestDispatcher();
1549
		$response = $this->getMock('CakeResponse', array('_sendHeader'));
1550
 
1551
		$Dispatcher->dispatch(new CakeRequest($url), $response);
1552
		$result = ob_get_clean();
1553
 
1554
		$path = CAKE . 'Test' . DS . 'test_app' . DS . str_replace('/', DS, $file);
1555
		$file = file_get_contents($path);
1556
		$this->assertEquals($file, $result);
1557
 
1558
		$expected = filesize($path);
1559
		$headers = $response->header();
1560
		$this->assertEquals($expected, $headers['Content-Length']);
1561
	}
1562
 
1563
/**
1564
 * test that missing asset processors trigger a 404 with no response body.
1565
 *
1566
 * @return void
1567
 */
1568
	public function testMissingAssetProcessor404() {
1569
		$response = $this->getMock('CakeResponse', array('send'));
1570
		$Dispatcher = new TestDispatcher();
1571
		Configure::write('Asset.filter', array(
1572
			'js' => '',
1573
			'css' => null
1574
		));
1575
		Configure::write('Dispatcher.filters', array('AssetDispatcher'));
1576
 
1577
		$request = new CakeRequest('ccss/cake.generic.css');
1578
		$Dispatcher->dispatch($request, $response);
1579
		$this->assertEquals('404', $response->statusCode());
1580
	}
1581
 
1582
/**
1583
 * Data provider for cached actions.
1584
 *
1585
 * - Test simple views
1586
 * - Test views with nocache tags
1587
 * - Test requests with named + passed params.
1588
 * - Test requests with query string params
1589
 * - Test themed views.
1590
 *
1591
 * @return array
1592
 */
1593
	public static function cacheActionProvider() {
1594
		return array(
1595
			array('/'),
1596
			array('test_cached_pages/index'),
1597
			array('TestCachedPages/index'),
1598
			array('test_cached_pages/test_nocache_tags'),
1599
			array('TestCachedPages/test_nocache_tags'),
1600
			array('test_cached_pages/view/param/param'),
1601
			array('test_cached_pages/view/foo:bar/value:goo'),
1602
			array('test_cached_pages/view?q=cakephp'),
1603
			array('test_cached_pages/themed'),
1604
		);
1605
	}
1606
 
1607
/**
1608
 * testFullPageCachingDispatch method
1609
 *
1610
 * @dataProvider cacheActionProvider
1611
 * @return void
1612
 */
1613
	public function testFullPageCachingDispatch($url) {
1614
		Configure::write('Cache.disable', false);
1615
		Configure::write('Cache.check', true);
1616
		Configure::write('debug', 2);
1617
 
1618
		Router::reload();
1619
		Router::connect('/', array('controller' => 'test_cached_pages', 'action' => 'index'));
1620
		Router::connect('/:controller/:action/*');
1621
 
1622
		App::build(array(
1623
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
1624
		), App::RESET);
1625
 
1626
		$dispatcher = new TestDispatcher();
1627
		$request = new CakeRequest($url);
1628
		$response = $this->getMock('CakeResponse', array('send'));
1629
 
1630
		$dispatcher->dispatch($request, $response);
1631
		$out = $response->body();
1632
 
1633
		Configure::write('Dispatcher.filters', array('CacheDispatcher'));
1634
		$request = new CakeRequest($url);
1635
		$response = $this->getMock('CakeResponse', array('send'));
1636
		$dispatcher = new TestDispatcher();
1637
		$dispatcher->dispatch($request, $response);
1638
		$cached = $response->body();
1639
 
1640
		$cached = preg_replace('/<!--+[^<>]+-->/', '', $cached);
1641
 
1642
		$this->assertTextEquals($out, $cached);
1643
 
1644
		$filename = $this->_cachePath($request->here());
1645
		unlink($filename);
1646
	}
1647
 
1648
/**
1649
 * testHttpMethodOverrides method
1650
 *
1651
 * @return void
1652
 * @triggers DispatcherTest $dispatcher, array('request' => $request)
1653
 * @triggers DispatcherTest $dispatcher, array('request' => $request)
1654
 * @triggers DispatcherTest $dispatcher, array('request' => $request)
1655
 * @triggers DispatcherTest $dispatcher, array('request' => $request)
1656
 * @triggers DispatcherTest $dispatcher, array('request' => $request)
1657
 */
1658
	public function testHttpMethodOverrides() {
1659
		Router::reload();
1660
		Router::mapResources('Posts');
1661
 
1662
		$_SERVER['REQUEST_METHOD'] = 'POST';
1663
		$dispatcher = new Dispatcher();
1664
 
1665
		$request = new CakeRequest('/posts');
1666
		$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
1667
		$dispatcher->parseParams($event);
1668
		$expected = array('pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add', '[method]' => 'POST');
1669
		foreach ($expected as $key => $value) {
1670
			$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
1671
		}
1672
 
1673
		$_SERVER['REQUEST_METHOD'] = 'GET';
1674
		$_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT';
1675
 
1676
		$request = new CakeRequest('/posts/5');
1677
		$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
1678
		$dispatcher->parseParams($event);
1679
		$expected = array(
1680
			'pass' => array('5'),
1681
			'named' => array(),
1682
			'id' => '5',
1683
			'plugin' => null,
1684
			'controller' => 'posts',
1685
			'action' => 'edit',
1686
			'[method]' => 'PUT'
1687
		);
1688
		foreach ($expected as $key => $value) {
1689
			$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
1690
		}
1691
 
1692
		unset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
1693
		$_SERVER['REQUEST_METHOD'] = 'GET';
1694
 
1695
		$request = new CakeRequest('/posts/5');
1696
		$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
1697
		$dispatcher->parseParams($event);
1698
		$expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'view', '[method]' => 'GET');
1699
		foreach ($expected as $key => $value) {
1700
			$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
1701
		}
1702
 
1703
		$_POST['_method'] = 'PUT';
1704
 
1705
		$request = new CakeRequest('/posts/5');
1706
		$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
1707
		$dispatcher->parseParams($event);
1708
		$expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'edit', '[method]' => 'PUT');
1709
		foreach ($expected as $key => $value) {
1710
			$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
1711
		}
1712
 
1713
		$_POST['_method'] = 'POST';
1714
		$_POST['data'] = array('Post' => array('title' => 'New Post'));
1715
		$_POST['extra'] = 'data';
1716
		$_SERVER = array();
1717
 
1718
		$request = new CakeRequest('/posts');
1719
		$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
1720
		$dispatcher->parseParams($event);
1721
		$expected = array(
1722
			'pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add',
1723
			'[method]' => 'POST', 'data' => array('extra' => 'data', 'Post' => array('title' => 'New Post')),
1724
		);
1725
		foreach ($expected as $key => $value) {
1726
			$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
1727
		}
1728
 
1729
		unset($_POST['_method']);
1730
	}
1731
 
1732
/**
1733
 * cachePath method
1734
 *
1735
 * @param string $here
1736
 * @return string
1737
 */
1738
	protected function _cachePath($here) {
1739
		$path = $here;
1740
		if ($here === '/') {
1741
			$path = 'home';
1742
		}
1743
		$path = strtolower(Inflector::slug($path));
1744
 
1745
		$filename = CACHE . 'views' . DS . $path . '.php';
1746
 
1747
		if (!file_exists($filename)) {
1748
			$filename = CACHE . 'views' . DS . $path . '_index.php';
1749
		}
1750
		return $filename;
1751
	}
1752
}