統計
| ブランチ: | リビジョン:

pictcode / lib / Cake / Test / Case / Routing / DispatcherTest.php @ 635eef61

履歴 | 表示 | アノテート | ダウンロード (48.517 KB)

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
}