Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
12345 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
 */
593
	public function testParseParamsWithoutZerosAndEmptyPost() {
594
		$Dispatcher = new Dispatcher();
595
		$request = new CakeRequest("/testcontroller/testaction/params1/params2/params3");
596
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
597
		$Dispatcher->parseParams($event);
598
		$this->assertSame($request['controller'], 'testcontroller');
599
		$this->assertSame($request['action'], 'testaction');
600
		$this->assertSame($request['pass'][0], 'params1');
601
		$this->assertSame($request['pass'][1], 'params2');
602
		$this->assertSame($request['pass'][2], 'params3');
603
		$this->assertFalse(!empty($request['form']));
604
	}
605
 
606
/**
607
 * testParseParamsReturnsPostedData method
608
 *
609
 * @return void
610
 */
611
	public function testParseParamsReturnsPostedData() {
612
		$_POST['testdata'] = "My Posted Content";
613
		$Dispatcher = new Dispatcher();
614
		$request = new CakeRequest("/");
615
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
616
		$Dispatcher->parseParams($event);
617
		$Dispatcher->parseParams($event);
618
		$this->assertEquals("My Posted Content", $request['data']['testdata']);
619
	}
620
 
621
/**
622
 * testParseParamsWithSingleZero method
623
 *
624
 * @return void
625
 */
626
	public function testParseParamsWithSingleZero() {
627
		$Dispatcher = new Dispatcher();
628
		$test = new CakeRequest("/testcontroller/testaction/1/0/23");
629
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
630
		$Dispatcher->parseParams($event);
631
 
632
		$this->assertSame($test['controller'], 'testcontroller');
633
		$this->assertSame($test['action'], 'testaction');
634
		$this->assertSame($test['pass'][0], '1');
635
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][1]);
636
		$this->assertSame($test['pass'][2], '23');
637
	}
638
 
639
/**
640
 * testParseParamsWithManySingleZeros method
641
 *
642
 * @return void
643
 */
644
	public function testParseParamsWithManySingleZeros() {
645
		$Dispatcher = new Dispatcher();
646
		$test = new CakeRequest("/testcontroller/testaction/0/0/0/0/0/0");
647
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
648
		$Dispatcher->parseParams($event);
649
 
650
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][0]);
651
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][1]);
652
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][2]);
653
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][3]);
654
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][4]);
655
		$this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][5]);
656
	}
657
 
658
/**
659
 * testParseParamsWithManyZerosInEachSectionOfUrl method
660
 *
661
 * @return void
662
 */
663
	public function testParseParamsWithManyZerosInEachSectionOfUrl() {
664
		$Dispatcher = new Dispatcher();
665
		$test = new CakeRequest("/testcontroller/testaction/000/0000/00000/000000/000000/0000000");
666
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
667
		$Dispatcher->parseParams($event);
668
 
669
		$this->assertRegExp('/\\A(?:000)\\z/', $test['pass'][0]);
670
		$this->assertRegExp('/\\A(?:0000)\\z/', $test['pass'][1]);
671
		$this->assertRegExp('/\\A(?:00000)\\z/', $test['pass'][2]);
672
		$this->assertRegExp('/\\A(?:000000)\\z/', $test['pass'][3]);
673
		$this->assertRegExp('/\\A(?:000000)\\z/', $test['pass'][4]);
674
		$this->assertRegExp('/\\A(?:0000000)\\z/', $test['pass'][5]);
675
	}
676
 
677
/**
678
 * testParseParamsWithMixedOneToManyZerosInEachSectionOfUrl method
679
 *
680
 * @return void
681
 */
682
	public function testParseParamsWithMixedOneToManyZerosInEachSectionOfUrl() {
683
		$Dispatcher = new Dispatcher();
684
		$test = new CakeRequest("/testcontroller/testaction/01/0403/04010/000002/000030/0000400");
685
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
686
		$Dispatcher->parseParams($event);
687
 
688
		$this->assertRegExp('/\\A(?:01)\\z/', $test['pass'][0]);
689
		$this->assertRegExp('/\\A(?:0403)\\z/', $test['pass'][1]);
690
		$this->assertRegExp('/\\A(?:04010)\\z/', $test['pass'][2]);
691
		$this->assertRegExp('/\\A(?:000002)\\z/', $test['pass'][3]);
692
		$this->assertRegExp('/\\A(?:000030)\\z/', $test['pass'][4]);
693
		$this->assertRegExp('/\\A(?:0000400)\\z/', $test['pass'][5]);
694
	}
695
 
696
/**
697
 * testQueryStringOnRoot method
698
 *
699
 * @return void
700
 */
701
	public function testQueryStringOnRoot() {
702
		Router::reload();
703
		Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
704
		Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
705
		Router::connect('/:controller/:action/*');
706
 
707
		$_GET = array('coffee' => 'life', 'sleep' => 'sissies');
708
		$Dispatcher = new Dispatcher();
709
		$request = new CakeRequest('posts/home/?coffee=life&sleep=sissies');
710
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
711
		$Dispatcher->parseParams($event);
712
 
713
		$this->assertRegExp('/posts/', $request['controller']);
714
		$this->assertRegExp('/home/', $request['action']);
715
		$this->assertTrue(isset($request['url']['sleep']));
716
		$this->assertTrue(isset($request['url']['coffee']));
717
 
718
		$Dispatcher = new Dispatcher();
719
		$request = new CakeRequest('/?coffee=life&sleep=sissy');
720
 
721
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
722
		$Dispatcher->parseParams($event);
723
		$this->assertRegExp('/pages/', $request['controller']);
724
		$this->assertRegExp('/display/', $request['action']);
725
		$this->assertTrue(isset($request['url']['sleep']));
726
		$this->assertTrue(isset($request['url']['coffee']));
727
		$this->assertEquals('life', $request['url']['coffee']);
728
	}
729
 
730
/**
731
 * testMissingController method
732
 *
733
 * @expectedException MissingControllerException
734
 * @expectedExceptionMessage Controller class SomeControllerController could not be found.
735
 * @return void
736
 */
737
	public function testMissingController() {
738
		Router::connect('/:controller/:action/*');
739
 
740
		$Dispatcher = new TestDispatcher();
741
		Configure::write('App.baseUrl', '/index.php');
742
		$url = new CakeRequest('some_controller/home/param:value/param2:value2');
743
		$response = $this->getMock('CakeResponse');
744
 
745
		$Dispatcher->dispatch($url, $response, array('return' => 1));
746
	}
747
 
748
/**
749
 * testMissingControllerInterface method
750
 *
751
 * @expectedException MissingControllerException
752
 * @expectedExceptionMessage Controller class DispatcherTestInterfaceController could not be found.
753
 * @return void
754
 */
755
	public function testMissingControllerInterface() {
756
		Router::connect('/:controller/:action/*');
757
 
758
		$Dispatcher = new TestDispatcher();
759
		Configure::write('App.baseUrl', '/index.php');
760
		$url = new CakeRequest('dispatcher_test_interface/index');
761
		$response = $this->getMock('CakeResponse');
762
 
763
		$Dispatcher->dispatch($url, $response, array('return' => 1));
764
	}
765
 
766
/**
767
 * testMissingControllerInterface method
768
 *
769
 * @expectedException MissingControllerException
770
 * @expectedExceptionMessage Controller class DispatcherTestAbstractController could not be found.
771
 * @return void
772
 */
773
	public function testMissingControllerAbstract() {
774
		Router::connect('/:controller/:action/*');
775
 
776
		$Dispatcher = new TestDispatcher();
777
		Configure::write('App.baseUrl', '/index.php');
778
		$url = new CakeRequest('dispatcher_test_abstract/index');
779
		$response = $this->getMock('CakeResponse');
780
 
781
		$Dispatcher->dispatch($url, $response, array('return' => 1));
782
	}
783
 
784
/**
785
 * testDispatch method
786
 *
787
 * @return void
788
 */
789
	public function testDispatchBasic() {
790
		App::build(array(
791
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
792
		));
793
		$Dispatcher = new TestDispatcher();
794
		Configure::write('App.baseUrl', '/index.php');
795
		$url = new CakeRequest('pages/home/param:value/param2:value2');
796
		$response = $this->getMock('CakeResponse');
797
 
798
		$Dispatcher->dispatch($url, $response, array('return' => 1));
799
		$expected = 'Pages';
800
		$this->assertEquals($expected, $Dispatcher->controller->name);
801
 
802
		$expected = array('0' => 'home', 'param' => 'value', 'param2' => 'value2');
803
		$this->assertSame($expected, $Dispatcher->controller->passedArgs);
804
 
805
		Configure::write('App.baseUrl', '/pages/index.php');
806
 
807
		$url = new CakeRequest('pages/home');
808
		$Dispatcher->dispatch($url, $response, array('return' => 1));
809
 
810
		$expected = 'Pages';
811
		$this->assertEquals($expected, $Dispatcher->controller->name);
812
 
813
		$url = new CakeRequest('pages/home/');
814
		$Dispatcher->dispatch($url, $response, array('return' => 1));
815
		$this->assertNull($Dispatcher->controller->plugin);
816
 
817
		$expected = 'Pages';
818
		$this->assertEquals($expected, $Dispatcher->controller->name);
819
 
820
		unset($Dispatcher);
821
 
822
		require CAKE . 'Config' . DS . 'routes.php';
823
		$Dispatcher = new TestDispatcher();
824
		Configure::write('App.baseUrl', '/timesheets/index.php');
825
 
826
		$url = new CakeRequest('timesheets');
827
		$Dispatcher->dispatch($url, $response, array('return' => 1));
828
 
829
		$expected = 'Timesheets';
830
		$this->assertEquals($expected, $Dispatcher->controller->name);
831
 
832
		$url = new CakeRequest('timesheets/');
833
		$Dispatcher->dispatch($url, $response, array('return' => 1));
834
 
835
		$this->assertEquals('Timesheets', $Dispatcher->controller->name);
836
		$this->assertEquals('/timesheets/index.php', $url->base);
837
 
838
		$url = new CakeRequest('test_dispatch_pages/camelCased');
839
		$Dispatcher->dispatch($url, $response, array('return' => 1));
840
		$this->assertEquals('TestDispatchPages', $Dispatcher->controller->name);
841
 
842
		$url = new CakeRequest('test_dispatch_pages/camelCased/something. .');
843
		$Dispatcher->dispatch($url, $response, array('return' => 1));
844
		$this->assertEquals('something. .', $Dispatcher->controller->params['pass'][0], 'Period was chopped off. %s');
845
	}
846
 
847
/**
848
 * Test that Dispatcher handles actions that return response objects.
849
 *
850
 * @return void
851
 */
852
	public function testDispatchActionReturnsResponse() {
853
		Router::connect('/:controller/:action');
854
		$Dispatcher = new Dispatcher();
855
		$request = new CakeRequest('some_pages/responseGenerator');
856
		$response = $this->getMock('CakeResponse', array('_sendHeader'));
857
 
858
		ob_start();
859
		$Dispatcher->dispatch($request, $response);
860
		$result = ob_get_clean();
861
 
862
		$this->assertEquals('new response', $result);
863
	}
864
 
865
/**
866
 * testDispatchActionSendsFile
867
 *
868
 * @return void
869
 */
870
	public function testDispatchActionSendsFile() {
871
		Router::connect('/:controller/:action');
872
		$Dispatcher = new Dispatcher();
873
		$request = new CakeRequest('some_pages/sendfile');
874
		$response = $this->getMock('CakeResponse', array(
875
			'header',
876
			'type',
877
			'download',
878
			'_sendHeader',
879
			'_setContentType',
880
			'_isActive',
881
			'_clearBuffer',
882
			'_flushBuffer'
883
		));
884
 
885
		$response->expects($this->never())
886
			->method('body');
887
 
888
		$response->expects($this->exactly(1))
889
			->method('_isActive')
890
			->will($this->returnValue(true));
891
 
892
		ob_start();
893
		$Dispatcher->dispatch($request, $response);
894
		$result = ob_get_clean();
895
 
896
		$this->assertEquals("/* this is the test asset css file */\n", $result);
897
	}
898
 
899
/**
900
 * testAdminDispatch method
901
 *
902
 * @return void
903
 */
904
	public function testAdminDispatch() {
905
		$_POST = array();
906
		$Dispatcher = new TestDispatcher();
907
		Configure::write('Routing.prefixes', array('admin'));
908
		Configure::write('App.baseUrl', '/cake/repo/branches/1.2.x.x/index.php');
909
		$url = new CakeRequest('admin/test_dispatch_pages/index/param:value/param2:value2');
910
		$response = $this->getMock('CakeResponse');
911
 
912
		Router::reload();
913
		$Dispatcher->dispatch($url, $response, array('return' => 1));
914
 
915
		$this->assertEquals('TestDispatchPages', $Dispatcher->controller->name);
916
 
917
		$this->assertSame($Dispatcher->controller->passedArgs, array('param' => 'value', 'param2' => 'value2'));
918
		$this->assertTrue($Dispatcher->controller->params['admin']);
919
 
920
		$expected = '/cake/repo/branches/1.2.x.x/index.php/admin/test_dispatch_pages/index/param:value/param2:value2';
921
		$this->assertSame($expected, $Dispatcher->controller->here);
922
 
923
		$expected = '/cake/repo/branches/1.2.x.x/index.php';
924
		$this->assertSame($expected, $Dispatcher->controller->base);
925
	}
926
 
927
/**
928
 * testPluginDispatch method
929
 *
930
 * @return void
931
 */
932
	public function testPluginDispatch() {
933
		$_POST = array();
934
 
935
		Router::reload();
936
		$Dispatcher = new TestDispatcher();
937
		Router::connect(
938
			'/my_plugin/:controller/*',
939
			array('plugin' => 'my_plugin', 'controller' => 'pages', 'action' => 'display')
940
		);
941
 
942
		$url = new CakeRequest('my_plugin/some_pages/home/param:value/param2:value2');
943
		$response = $this->getMock('CakeResponse');
944
		$Dispatcher->dispatch($url, $response, array('return' => 1));
945
 
946
		$event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $url));
947
		$Dispatcher->parseParams($event);
948
		$expected = array(
949
			'pass' => array('home'),
950
			'named' => array('param' => 'value', 'param2' => 'value2'), 'plugin' => 'my_plugin',
951
			'controller' => 'some_pages', 'action' => 'display'
952
		);
953
		foreach ($expected as $key => $value) {
954
			$this->assertEquals($value, $url[$key], 'Value mismatch ' . $key . ' %');
955
		}
956
 
957
		$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
958
		$this->assertSame($Dispatcher->controller->name, 'SomePages');
959
		$this->assertSame($Dispatcher->controller->params['controller'], 'some_pages');
960
		$this->assertSame($Dispatcher->controller->passedArgs, array('0' => 'home', 'param' => 'value', 'param2' => 'value2'));
961
	}
962
 
963
/**
964
 * testAutomaticPluginDispatch method
965
 *
966
 * @return void
967
 */
968
	public function testAutomaticPluginDispatch() {
969
		$_POST = array();
970
		$_SERVER['PHP_SELF'] = '/cake/repo/branches/1.2.x.x/index.php';
971
 
972
		Router::reload();
973
		$Dispatcher = new TestDispatcher();
974
		Router::connect(
975
			'/my_plugin/:controller/:action/*',
976
			array('plugin' => 'my_plugin', 'controller' => 'pages', 'action' => 'display')
977
		);
978
 
979
		$Dispatcher->base = false;
980
 
981
		$url = new CakeRequest('my_plugin/other_pages/index/param:value/param2:value2');
982
		$response = $this->getMock('CakeResponse');
983
		$Dispatcher->dispatch($url, $response, array('return' => 1));
984
 
985
		$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
986
		$this->assertSame($Dispatcher->controller->name, 'OtherPages');
987
		$this->assertSame($Dispatcher->controller->action, 'index');
988
		$this->assertSame($Dispatcher->controller->passedArgs, array('param' => 'value', 'param2' => 'value2'));
989
 
990
		$expected = '/cake/repo/branches/1.2.x.x/my_plugin/other_pages/index/param:value/param2:value2';
991
		$this->assertSame($expected, $url->here);
992
 
993
		$expected = '/cake/repo/branches/1.2.x.x';
994
		$this->assertSame($expected, $url->base);
995
	}
996
 
997
/**
998
 * testAutomaticPluginControllerDispatch method
999
 *
1000
 * @return void
1001
 */
1002
	public function testAutomaticPluginControllerDispatch() {
1003
		$plugins = App::objects('plugin');
1004
		$plugins[] = 'MyPlugin';
1005
		$plugins[] = 'ArticlesTest';
1006
 
1007
		CakePlugin::load('MyPlugin', array('path' => '/fake/path'));
1008
 
1009
		Router::reload();
1010
		$Dispatcher = new TestDispatcher();
1011
		$Dispatcher->base = false;
1012
 
1013
		$url = new CakeRequest('my_plugin/my_plugin/add/param:value/param2:value2');
1014
		$response = $this->getMock('CakeResponse');
1015
 
1016
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1017
 
1018
		$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
1019
		$this->assertSame($Dispatcher->controller->name, 'MyPlugin');
1020
		$this->assertSame($Dispatcher->controller->action, 'add');
1021
		$this->assertEquals(array('param' => 'value', 'param2' => 'value2'), $Dispatcher->controller->params['named']);
1022
 
1023
		Router::reload();
1024
		require CAKE . 'Config' . DS . 'routes.php';
1025
		$Dispatcher = new TestDispatcher();
1026
		$Dispatcher->base = false;
1027
 
1028
		// Simulates the Route for a real plugin, installed in APP/plugins
1029
		Router::connect('/my_plugin/:controller/:action/*', array('plugin' => 'my_plugin'));
1030
 
1031
		$plugin = 'MyPlugin';
1032
		$pluginUrl = Inflector::underscore($plugin);
1033
 
1034
		$url = new CakeRequest($pluginUrl);
1035
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1036
		$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
1037
		$this->assertSame($Dispatcher->controller->name, 'MyPlugin');
1038
		$this->assertSame($Dispatcher->controller->action, 'index');
1039
 
1040
		$expected = $pluginUrl;
1041
		$this->assertEquals($expected, $Dispatcher->controller->params['controller']);
1042
 
1043
		Configure::write('Routing.prefixes', array('admin'));
1044
 
1045
		Router::reload();
1046
		require CAKE . 'Config' . DS . 'routes.php';
1047
		$Dispatcher = new TestDispatcher();
1048
 
1049
		$url = new CakeRequest('admin/my_plugin/my_plugin/add/5/param:value/param2:value2');
1050
		$response = $this->getMock('CakeResponse');
1051
 
1052
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1053
 
1054
		$this->assertEquals('my_plugin', $Dispatcher->controller->params['plugin']);
1055
		$this->assertEquals('my_plugin', $Dispatcher->controller->params['controller']);
1056
		$this->assertEquals('admin_add', $Dispatcher->controller->params['action']);
1057
		$this->assertEquals(array(5), $Dispatcher->controller->params['pass']);
1058
		$this->assertEquals(array('param' => 'value', 'param2' => 'value2'), $Dispatcher->controller->params['named']);
1059
		$this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
1060
		$this->assertSame($Dispatcher->controller->name, 'MyPlugin');
1061
		$this->assertSame($Dispatcher->controller->action, 'admin_add');
1062
 
1063
		$expected = array(0 => 5, 'param' => 'value', 'param2' => 'value2');
1064
		$this->assertEquals($expected, $Dispatcher->controller->passedArgs);
1065
 
1066
		Configure::write('Routing.prefixes', array('admin'));
1067
		CakePlugin::load('ArticlesTest', array('path' => '/fake/path'));
1068
		Router::reload();
1069
		require CAKE . 'Config' . DS . 'routes.php';
1070
 
1071
		$Dispatcher = new TestDispatcher();
1072
 
1073
		$Dispatcher->dispatch(new CakeRequest('admin/articles_test'), $response, array('return' => 1));
1074
		$this->assertSame($Dispatcher->controller->plugin, 'ArticlesTest');
1075
		$this->assertSame($Dispatcher->controller->name, 'ArticlesTest');
1076
		$this->assertSame($Dispatcher->controller->action, 'admin_index');
1077
 
1078
		$expected = array(
1079
			'pass' => array(),
1080
			'named' => array(),
1081
			'controller' => 'articles_test',
1082
			'plugin' => 'articles_test',
1083
			'action' => 'admin_index',
1084
			'prefix' => 'admin',
1085
			'admin' => true,
1086
			'return' => 1
1087
		);
1088
		foreach ($expected as $key => $value) {
1089
			$this->assertEquals($expected[$key], $Dispatcher->controller->request[$key], 'Value mismatch ' . $key);
1090
		}
1091
	}
1092
 
1093
/**
1094
 * test Plugin dispatching without controller name and using
1095
 * plugin short form instead.
1096
 *
1097
 * @return void
1098
 */
1099
	public function testAutomaticPluginDispatchWithShortAccess() {
1100
		CakePlugin::load('MyPlugin', array('path' => '/fake/path'));
1101
		Router::reload();
1102
 
1103
		$Dispatcher = new TestDispatcher();
1104
		$Dispatcher->base = false;
1105
 
1106
		$url = new CakeRequest('my_plugin/');
1107
		$response = $this->getMock('CakeResponse');
1108
 
1109
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1110
		$this->assertEquals('my_plugin', $Dispatcher->controller->params['controller']);
1111
		$this->assertEquals('my_plugin', $Dispatcher->controller->params['plugin']);
1112
		$this->assertEquals('index', $Dispatcher->controller->params['action']);
1113
		$this->assertFalse(isset($Dispatcher->controller->params['pass'][0]));
1114
	}
1115
 
1116
/**
1117
 * test plugin shortcut URLs with controllers that need to be loaded,
1118
 * the above test uses a controller that has already been included.
1119
 *
1120
 * @return void
1121
 */
1122
	public function testPluginShortCutUrlsWithControllerThatNeedsToBeLoaded() {
1123
		$loaded = class_exists('TestPluginController', false);
1124
		$this->skipIf($loaded, 'TestPluginController already loaded.');
1125
 
1126
		Router::reload();
1127
		App::build(array(
1128
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
1129
		), App::RESET);
1130
		CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
1131
 
1132
		$Dispatcher = new TestDispatcher();
1133
		$Dispatcher->base = false;
1134
 
1135
		$url = new CakeRequest('test_plugin/');
1136
		$response = $this->getMock('CakeResponse');
1137
 
1138
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1139
		$this->assertEquals('test_plugin', $Dispatcher->controller->params['controller']);
1140
		$this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
1141
		$this->assertEquals('index', $Dispatcher->controller->params['action']);
1142
		$this->assertFalse(isset($Dispatcher->controller->params['pass'][0]));
1143
 
1144
		$url = new CakeRequest('/test_plugin/tests/index');
1145
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1146
		$this->assertEquals('tests', $Dispatcher->controller->params['controller']);
1147
		$this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
1148
		$this->assertEquals('index', $Dispatcher->controller->params['action']);
1149
		$this->assertFalse(isset($Dispatcher->controller->params['pass'][0]));
1150
 
1151
		$url = new CakeRequest('/test_plugin/tests/index/some_param');
1152
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1153
		$this->assertEquals('tests', $Dispatcher->controller->params['controller']);
1154
		$this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
1155
		$this->assertEquals('index', $Dispatcher->controller->params['action']);
1156
		$this->assertEquals('some_param', $Dispatcher->controller->params['pass'][0]);
1157
 
1158
		App::build();
1159
	}
1160
 
1161
/**
1162
 * testAutomaticPluginControllerMissingActionDispatch method
1163
 *
1164
 * @expectedException MissingActionException
1165
 * @expectedExceptionMessage Action MyPluginController::not_here() could not be found.
1166
 * @return void
1167
 */
1168
	public function testAutomaticPluginControllerMissingActionDispatch() {
1169
		Router::reload();
1170
		$Dispatcher = new TestDispatcher();
1171
 
1172
		$url = new CakeRequest('my_plugin/not_here/param:value/param2:value2');
1173
		$response = $this->getMock('CakeResponse');
1174
 
1175
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1176
	}
1177
 
1178
/**
1179
 * testAutomaticPluginControllerMissingActionDispatch method
1180
 *
1181
 * @expectedException MissingActionException
1182
 * @expectedExceptionMessage Action MyPluginController::param:value() could not be found.
1183
 * @return void
1184
 */
1185
 
1186
	public function testAutomaticPluginControllerIndexMissingAction() {
1187
		Router::reload();
1188
		$Dispatcher = new TestDispatcher();
1189
 
1190
		$url = new CakeRequest('my_plugin/param:value/param2:value2');
1191
		$response = $this->getMock('CakeResponse');
1192
 
1193
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1194
	}
1195
 
1196
/**
1197
 * Test dispatching into the TestPlugin in the test_app
1198
 *
1199
 * @return void
1200
 */
1201
	public function testTestPluginDispatch() {
1202
		$Dispatcher = new TestDispatcher();
1203
		App::build(array(
1204
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
1205
		), App::RESET);
1206
		CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
1207
		Router::reload();
1208
		Router::parse('/');
1209
 
1210
		$url = new CakeRequest('/test_plugin/tests/index');
1211
		$response = $this->getMock('CakeResponse');
1212
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1213
		$this->assertTrue(class_exists('TestsController'));
1214
		$this->assertTrue(class_exists('TestPluginAppController'));
1215
		$this->assertTrue(class_exists('PluginsComponent'));
1216
 
1217
		$this->assertEquals('tests', $Dispatcher->controller->params['controller']);
1218
		$this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
1219
		$this->assertEquals('index', $Dispatcher->controller->params['action']);
1220
 
1221
		App::build();
1222
	}
1223
 
1224
/**
1225
 * Tests that it is possible to attach filter classes to the dispatch cycle
1226
 *
1227
 * @return void
1228
 */
1229
	public function testDispatcherFilterSubscriber() {
1230
		App::build(array(
1231
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
1232
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
1233
		), App::RESET);
1234
 
1235
		CakePlugin::load('TestPlugin');
1236
		Configure::write('Dispatcher.filters', array(
1237
			array('callable' => 'TestPlugin.TestDispatcherFilter')
1238
		));
1239
		$dispatcher = new TestDispatcher();
1240
		$request = new CakeRequest('/');
1241
		$request->params['altered'] = false;
1242
		$response = $this->getMock('CakeResponse', array('send'));
1243
 
1244
		$dispatcher->dispatch($request, $response);
1245
		$this->assertTrue($request->params['altered']);
1246
		$this->assertEquals(304, $response->statusCode());
1247
 
1248
		Configure::write('Dispatcher.filters', array(
1249
			'TestPlugin.Test2DispatcherFilter',
1250
			'TestPlugin.TestDispatcherFilter'
1251
		));
1252
		$dispatcher = new TestDispatcher();
1253
		$request = new CakeRequest('/');
1254
		$request->params['altered'] = false;
1255
		$response = $this->getMock('CakeResponse', array('send'));
1256
 
1257
		$dispatcher->dispatch($request, $response);
1258
		$this->assertFalse($request->params['altered']);
1259
		$this->assertEquals(500, $response->statusCode());
1260
		$this->assertNull($dispatcher->controller);
1261
	}
1262
 
1263
/**
1264
 * Tests that it is possible to attach filter with config classes to the dispatch cycle
1265
 *
1266
 * @return void
1267
 */
1268
	public function testDispatcherFilterSettings() {
1269
		Configure::write('Dispatcher.filters', array(
1270
			'TestFilterDispatcher' => array('service' => 'google.com')
1271
		));
1272
		$Dispatcher = new Dispatcher();
1273
		$url = new CakeRequest('some_pages/index');
1274
		$response = $this->getMock('CakeResponse');
1275
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1276
		$settings = $url->param('settings');
1277
		$this->assertEquals($settings, array('service' => 'google.com'));
1278
	}
1279
 
1280
/**
1281
 * Tests that attaching an inexistent class as filter will throw an exception
1282
 *
1283
 * @expectedException MissingDispatcherFilterException
1284
 * @return void
1285
 */
1286
	public function testDispatcherFilterSuscriberMissing() {
1287
		App::build(array(
1288
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
1289
		), App::RESET);
1290
 
1291
		CakePlugin::load('TestPlugin');
1292
		Configure::write('Dispatcher.filters', array(
1293
			array('callable' => 'TestPlugin.NotAFilter')
1294
		));
1295
		$dispatcher = new TestDispatcher();
1296
		$request = new CakeRequest('/');
1297
		$response = $this->getMock('CakeResponse', array('send'));
1298
		$dispatcher->dispatch($request, $response);
1299
	}
1300
 
1301
/**
1302
 * Tests it is possible to attach single callables as filters
1303
 *
1304
 * @return void
1305
 */
1306
	public function testDispatcherFilterCallable() {
1307
		App::build(array(
1308
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
1309
		), App::RESET);
1310
 
1311
		$dispatcher = new TestDispatcher();
1312
		Configure::write('Dispatcher.filters', array(
1313
			array('callable' => array($dispatcher, 'filterTest'), 'on' => 'before')
1314
		));
1315
 
1316
		$request = new CakeRequest('/');
1317
		$response = $this->getMock('CakeResponse', array('send'));
1318
		$dispatcher->dispatch($request, $response);
1319
		$this->assertEquals('Dispatcher.beforeDispatch', $request->params['eventName']);
1320
 
1321
		$dispatcher = new TestDispatcher();
1322
		Configure::write('Dispatcher.filters', array(
1323
			array('callable' => array($dispatcher, 'filterTest'), 'on' => 'after')
1324
		));
1325
 
1326
		$request = new CakeRequest('/');
1327
		$response = $this->getMock('CakeResponse', array('send'));
1328
		$dispatcher->dispatch($request, $response);
1329
		$this->assertEquals('Dispatcher.afterDispatch', $request->params['eventName']);
1330
 
1331
		// Test that it is possible to skip the route connection process
1332
		$dispatcher = new TestDispatcher();
1333
		Configure::write('Dispatcher.filters', array(
1334
			array('callable' => array($dispatcher, 'filterTest2'), 'on' => 'before', 'priority' => 1)
1335
		));
1336
 
1337
		$request = new CakeRequest('/');
1338
		$response = $this->getMock('CakeResponse', array('send'));
1339
		$dispatcher->dispatch($request, $response);
1340
		$this->assertEmpty($dispatcher->controller);
1341
		$expected = array('controller' => null, 'action' => null, 'plugin' => null, 'named' => array(), 'pass' => array());
1342
		$this->assertEquals($expected, $request->params);
1343
 
1344
		$dispatcher = new TestDispatcher();
1345
		Configure::write('Dispatcher.filters', array(
1346
			array('callable' => array($dispatcher, 'filterTest2'), 'on' => 'before', 'priority' => 1)
1347
		));
1348
 
1349
		$request = new CakeRequest('/');
1350
		$request->params['return'] = true;
1351
		$response = $this->getMock('CakeResponse', array('send'));
1352
		$response->body('this is a body');
1353
		$result = $dispatcher->dispatch($request, $response);
1354
		$this->assertEquals('this is a body', $result);
1355
 
1356
		$request = new CakeRequest('/');
1357
		$response = $this->getMock('CakeResponse', array('send'));
1358
		$response->expects($this->once())->method('send');
1359
		$response->body('this is a body');
1360
		$result = $dispatcher->dispatch($request, $response);
1361
		$this->assertNull($result);
1362
	}
1363
 
1364
/**
1365
 * testChangingParamsFromBeforeFilter method
1366
 *
1367
 * @return void
1368
 */
1369
	public function testChangingParamsFromBeforeFilter() {
1370
		$Dispatcher = new TestDispatcher();
1371
		$response = $this->getMock('CakeResponse');
1372
		$url = new CakeRequest('some_posts/index/param:value/param2:value2');
1373
 
1374
		try {
1375
			$Dispatcher->dispatch($url, $response, array('return' => 1));
1376
			$this->fail('No exception.');
1377
		} catch (MissingActionException $e) {
1378
			$this->assertEquals('Action SomePostsController::view() could not be found.', $e->getMessage());
1379
		}
1380
 
1381
		$url = new CakeRequest('some_posts/something_else/param:value/param2:value2');
1382
		$Dispatcher->dispatch($url, $response, array('return' => 1));
1383
 
1384
		$expected = 'SomePosts';
1385
		$this->assertEquals($expected, $Dispatcher->controller->name);
1386
 
1387
		$expected = 'change';
1388
		$this->assertEquals($expected, $Dispatcher->controller->action);
1389
 
1390
		$expected = array('changed');
1391
		$this->assertSame($expected, $Dispatcher->controller->params['pass']);
1392
	}
1393
 
1394
/**
1395
 * testStaticAssets method
1396
 *
1397
 * @return void
1398
 */
1399
	public function testAssets() {
1400
		Router::reload();
1401
 
1402
		App::build(array(
1403
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
1404
			'Vendor' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS),
1405
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
1406
		));
1407
		CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
1408
		Configure::write('Dispatcher.filters', array('AssetDispatcher'));
1409
 
1410
		$Dispatcher = new TestDispatcher();
1411
		$response = $this->getMock('CakeResponse', array('_sendHeader'));
1412
 
1413
		try {
1414
			$Dispatcher->dispatch(new CakeRequest('theme/test_theme/../webroot/css/test_asset.css'), $response);
1415
			$this->fail('No exception');
1416
		} catch (MissingControllerException $e) {
1417
			$this->assertEquals('Controller class ThemeController could not be found.', $e->getMessage());
1418
		}
1419
 
1420
		try {
1421
			$Dispatcher->dispatch(new CakeRequest('theme/test_theme/pdfs'), $response);
1422
			$this->fail('No exception');
1423
		} catch (MissingControllerException $e) {
1424
			$this->assertEquals('Controller class ThemeController could not be found.', $e->getMessage());
1425
		}
1426
	}
1427
 
1428
/**
1429
 * Data provider for asset filter
1430
 *
1431
 * - theme assets.
1432
 * - plugin assets.
1433
 * - plugin assets in sub directories.
1434
 * - unknown plugin assets.
1435
 *
1436
 * @return array
1437
 */
1438
	public static function assetProvider() {
1439
		return array(
1440
			array(
1441
				'theme/test_theme/flash/theme_test.swf',
1442
				'View/Themed/TestTheme/webroot/flash/theme_test.swf'
1443
			),
1444
			array(
1445
				'theme/test_theme/pdfs/theme_test.pdf',
1446
				'View/Themed/TestTheme/webroot/pdfs/theme_test.pdf'
1447
			),
1448
			array(
1449
				'theme/test_theme/img/test.jpg',
1450
				'View/Themed/TestTheme/webroot/img/test.jpg'
1451
			),
1452
			array(
1453
				'theme/test_theme/css/test_asset.css',
1454
				'View/Themed/TestTheme/webroot/css/test_asset.css'
1455
			),
1456
			array(
1457
				'theme/test_theme/js/theme.js',
1458
				'View/Themed/TestTheme/webroot/js/theme.js'
1459
			),
1460
			array(
1461
				'theme/test_theme/js/one/theme_one.js',
1462
				'View/Themed/TestTheme/webroot/js/one/theme_one.js'
1463
			),
1464
			array(
1465
				'theme/test_theme/space%20image.text',
1466
				'View/Themed/TestTheme/webroot/space image.text'
1467
			),
1468
			array(
1469
				'test_plugin/root.js',
1470
				'Plugin/TestPlugin/webroot/root.js'
1471
			),
1472
			array(
1473
				'test_plugin/flash/plugin_test.swf',
1474
				'Plugin/TestPlugin/webroot/flash/plugin_test.swf'
1475
			),
1476
			array(
1477
				'test_plugin/pdfs/plugin_test.pdf',
1478
				'Plugin/TestPlugin/webroot/pdfs/plugin_test.pdf'
1479
			),
1480
			array(
1481
				'test_plugin/js/test_plugin/test.js',
1482
				'Plugin/TestPlugin/webroot/js/test_plugin/test.js'
1483
			),
1484
			array(
1485
				'test_plugin/css/test_plugin_asset.css',
1486
				'Plugin/TestPlugin/webroot/css/test_plugin_asset.css'
1487
			),
1488
			array(
1489
				'test_plugin/img/cake.icon.gif',
1490
				'Plugin/TestPlugin/webroot/img/cake.icon.gif'
1491
			),
1492
			array(
1493
				'plugin_js/js/plugin_js.js',
1494
				'Plugin/PluginJs/webroot/js/plugin_js.js'
1495
			),
1496
			array(
1497
				'plugin_js/js/one/plugin_one.js',
1498
				'Plugin/PluginJs/webroot/js/one/plugin_one.js'
1499
			),
1500
			array(
1501
				'test_plugin/css/unknown.extension',
1502
				'Plugin/TestPlugin/webroot/css/unknown.extension'
1503
			),
1504
			array(
1505
				'test_plugin/css/theme_one.htc',
1506
				'Plugin/TestPlugin/webroot/css/theme_one.htc'
1507
			),
1508
		);
1509
	}
1510
 
1511
/**
1512
 * Test assets
1513
 *
1514
 * @dataProvider assetProvider
1515
 * @outputBuffering enabled
1516
 * @return void
1517
 */
1518
	public function testAsset($url, $file) {
1519
		Router::reload();
1520
 
1521
		App::build(array(
1522
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
1523
			'Vendor' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS),
1524
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
1525
		));
1526
		CakePlugin::load(array('TestPlugin', 'PluginJs'));
1527
		Configure::write('Dispatcher.filters', array('AssetDispatcher'));
1528
 
1529
		$Dispatcher = new TestDispatcher();
1530
		$response = $this->getMock('CakeResponse', array('_sendHeader'));
1531
 
1532
		$Dispatcher->dispatch(new CakeRequest($url), $response);
1533
		$result = ob_get_clean();
1534
 
1535
		$path = CAKE . 'Test' . DS . 'test_app' . DS . str_replace('/', DS, $file);
1536
		$file = file_get_contents($path);
1537
		$this->assertEquals($file, $result);
1538
 
1539
		$expected = filesize($path);
1540
		$headers = $response->header();
1541
		$this->assertEquals($expected, $headers['Content-Length']);
1542
	}
1543
 
1544
/**
1545
 * test that missing asset processors trigger a 404 with no response body.
1546
 *
1547
 * @return void
1548
 */
1549
	public function testMissingAssetProcessor404() {
1550
		$response = $this->getMock('CakeResponse', array('send'));
1551
		$Dispatcher = new TestDispatcher();
1552
		Configure::write('Asset.filter', array(
1553
			'js' => '',
1554
			'css' => null
1555
		));
1556
		Configure::write('Dispatcher.filters', array('AssetDispatcher'));
1557
 
1558
		$request = new CakeRequest('ccss/cake.generic.css');
1559
		$Dispatcher->dispatch($request, $response);
1560
		$this->assertEquals('404', $response->statusCode());
1561
	}
1562
 
1563
/**
1564
 * Data provider for cached actions.
1565
 *
1566
 * - Test simple views
1567
 * - Test views with nocache tags
1568
 * - Test requests with named + passed params.
1569
 * - Test requests with query string params
1570
 * - Test themed views.
1571
 *
1572
 * @return array
1573
 */
1574
	public static function cacheActionProvider() {
1575
		return array(
1576
			array('/'),
1577
			array('test_cached_pages/index'),
1578
			array('TestCachedPages/index'),
1579
			array('test_cached_pages/test_nocache_tags'),
1580
			array('TestCachedPages/test_nocache_tags'),
1581
			array('test_cached_pages/view/param/param'),
1582
			array('test_cached_pages/view/foo:bar/value:goo'),
1583
			array('test_cached_pages/view?q=cakephp'),
1584
			array('test_cached_pages/themed'),
1585
		);
1586
	}
1587
 
1588
/**
1589
 * testFullPageCachingDispatch method
1590
 *
1591
 * @dataProvider cacheActionProvider
1592
 * @return void
1593
 */
1594
	public function testFullPageCachingDispatch($url) {
1595
		Configure::write('Cache.disable', false);
1596
		Configure::write('Cache.check', true);
1597
		Configure::write('debug', 2);
1598
 
1599
		Router::reload();
1600
		Router::connect('/', array('controller' => 'test_cached_pages', 'action' => 'index'));
1601
		Router::connect('/:controller/:action/*');
1602
 
1603
		App::build(array(
1604
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
1605
		), App::RESET);
1606
 
1607
		$dispatcher = new TestDispatcher();
1608
		$request = new CakeRequest($url);
1609
		$response = $this->getMock('CakeResponse', array('send'));
1610
 
1611
		$dispatcher->dispatch($request, $response);
1612
		$out = $response->body();
1613
 
1614
		Configure::write('Dispatcher.filters', array('CacheDispatcher'));
1615
		$request = new CakeRequest($url);
1616
		$response = $this->getMock('CakeResponse', array('send'));
1617
		$dispatcher = new TestDispatcher();
1618
		$dispatcher->dispatch($request, $response);
1619
		$cached = $response->body();
1620
 
1621
		$cached = preg_replace('/<!--+[^<>]+-->/', '', $cached);
1622
 
1623
		$this->assertTextEquals($out, $cached);
1624
 
1625
		$filename = $this->_cachePath($request->here());
1626
		unlink($filename);
1627
	}
1628
 
1629
/**
1630
 * testHttpMethodOverrides method
1631
 *
1632
 * @return void
1633
 */
1634
	public function testHttpMethodOverrides() {
1635
		Router::reload();
1636
		Router::mapResources('Posts');
1637
 
1638
		$_SERVER['REQUEST_METHOD'] = 'POST';
1639
		$dispatcher = new Dispatcher();
1640
 
1641
		$request = new CakeRequest('/posts');
1642
		$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
1643
		$dispatcher->parseParams($event);
1644
		$expected = array('pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add', '[method]' => 'POST');
1645
		foreach ($expected as $key => $value) {
1646
			$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
1647
		}
1648
 
1649
		$_SERVER['REQUEST_METHOD'] = 'GET';
1650
		$_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT';
1651
 
1652
		$request = new CakeRequest('/posts/5');
1653
		$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
1654
		$dispatcher->parseParams($event);
1655
		$expected = array(
1656
			'pass' => array('5'),
1657
			'named' => array(),
1658
			'id' => '5',
1659
			'plugin' => null,
1660
			'controller' => 'posts',
1661
			'action' => 'edit',
1662
			'[method]' => 'PUT'
1663
		);
1664
		foreach ($expected as $key => $value) {
1665
			$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
1666
		}
1667
 
1668
		unset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
1669
		$_SERVER['REQUEST_METHOD'] = 'GET';
1670
 
1671
		$request = new CakeRequest('/posts/5');
1672
		$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
1673
		$dispatcher->parseParams($event);
1674
		$expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'view', '[method]' => 'GET');
1675
		foreach ($expected as $key => $value) {
1676
			$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
1677
		}
1678
 
1679
		$_POST['_method'] = 'PUT';
1680
 
1681
		$request = new CakeRequest('/posts/5');
1682
		$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
1683
		$dispatcher->parseParams($event);
1684
		$expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'edit', '[method]' => 'PUT');
1685
		foreach ($expected as $key => $value) {
1686
			$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
1687
		}
1688
 
1689
		$_POST['_method'] = 'POST';
1690
		$_POST['data'] = array('Post' => array('title' => 'New Post'));
1691
		$_POST['extra'] = 'data';
1692
		$_SERVER = array();
1693
 
1694
		$request = new CakeRequest('/posts');
1695
		$event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
1696
		$dispatcher->parseParams($event);
1697
		$expected = array(
1698
			'pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add',
1699
			'[method]' => 'POST', 'data' => array('extra' => 'data', 'Post' => array('title' => 'New Post')),
1700
		);
1701
		foreach ($expected as $key => $value) {
1702
			$this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
1703
		}
1704
 
1705
		unset($_POST['_method']);
1706
	}
1707
 
1708
/**
1709
 * cachePath method
1710
 *
1711
 * @param string $here
1712
 * @return string
1713
 */
1714
	protected function _cachePath($here) {
1715
		$path = $here;
1716
		if ($here === '/') {
1717
			$path = 'home';
1718
		}
1719
		$path = strtolower(Inflector::slug($path));
1720
 
1721
		$filename = CACHE . 'views' . DS . $path . '.php';
1722
 
1723
		if (!file_exists($filename)) {
1724
			$filename = CACHE . 'views' . DS . $path . '_index.php';
1725
		}
1726
		return $filename;
1727
	}
1728
}