Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
13532 anikendra 1
<?php
2
/**
3
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
 *
6
 * Licensed under The MIT License
7
 * For full copyright and license information, please see the LICENSE.txt
8
 * Redistributions of files must retain the above copyright notice.
9
 *
10
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
11
 * @link          http://cakephp.org CakePHP Project
12
 * @package       Cake.Test.Case.Controller
13
 * @since         CakePHP(tm) v 1.2.0.5436
14
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
15
 */
16
 
17
App::uses('Controller', 'Controller');
18
App::uses('Router', 'Routing');
19
App::uses('CakeRequest', 'Network');
20
App::uses('CakeResponse', 'Network');
21
App::uses('SecurityComponent', 'Controller/Component');
22
App::uses('CookieComponent', 'Controller/Component');
23
 
24
/**
25
 * AppController class
26
 *
27
 * @package       Cake.Test.Case.Controller
28
 */
29
class ControllerTestAppController extends Controller {
30
 
31
/**
32
 * helpers property
33
 *
34
 * @var array
35
 */
36
	public $helpers = array('Html');
37
 
38
/**
39
 * uses property
40
 *
41
 * @var array
42
 */
43
	public $uses = array('ControllerPost');
44
 
45
/**
46
 * components property
47
 *
48
 * @var array
49
 */
50
	public $components = array('Cookie');
51
}
52
 
53
/**
54
 * ControllerPost class
55
 *
56
 * @package       Cake.Test.Case.Controller
57
 */
58
class ControllerPost extends CakeTestModel {
59
 
60
/**
61
 * useTable property
62
 *
63
 * @var string
64
 */
65
	public $useTable = 'posts';
66
 
67
/**
68
 * invalidFields property
69
 *
70
 * @var array
71
 */
72
	public $invalidFields = array('name' => 'error_msg');
73
 
74
/**
75
 * lastQuery property
76
 *
77
 * @var mixed null
78
 */
79
	public $lastQuery = null;
80
 
81
/**
82
 * beforeFind method
83
 *
84
 * @param mixed $query
85
 * @return void
86
 */
87
	public function beforeFind($query) {
88
		$this->lastQuery = $query;
89
	}
90
 
91
/**
92
 * find method
93
 *
94
 * @param string $type
95
 * @param array $options
96
 * @return void
97
 */
98
	public function find($type = 'first', $options = array()) {
99
		if ($type === 'popular') {
100
			$conditions = array($this->name . '.' . $this->primaryKey . ' > ' => '1');
101
			$options = Hash::merge($options, compact('conditions'));
102
			return parent::find('all', $options);
103
		}
104
		return parent::find($type, $options);
105
	}
106
 
107
}
108
 
109
/**
110
 * ControllerPostsController class
111
 *
112
 * @package       Cake.Test.Case.Controller
113
 */
114
class ControllerCommentsController extends ControllerTestAppController {
115
 
116
	protected $_mergeParent = 'ControllerTestAppController';
117
}
118
 
119
/**
120
 * ControllerComment class
121
 *
122
 * @package       Cake.Test.Case.Controller
123
 */
124
class ControllerComment extends CakeTestModel {
125
 
126
/**
127
 * name property
128
 *
129
 * @var string
130
 */
131
	public $name = 'Comment';
132
 
133
/**
134
 * useTable property
135
 *
136
 * @var string
137
 */
138
	public $useTable = 'comments';
139
 
140
/**
141
 * data property
142
 *
143
 * @var array
144
 */
145
	public $data = array('name' => 'Some Name');
146
 
147
/**
148
 * alias property
149
 *
150
 * @var string
151
 */
152
	public $alias = 'ControllerComment';
153
}
154
 
155
/**
156
 * ControllerAlias class
157
 *
158
 * @package       Cake.Test.Case.Controller
159
 */
160
class ControllerAlias extends CakeTestModel {
161
 
162
/**
163
 * alias property
164
 *
165
 * @var string
166
 */
167
	public $alias = 'ControllerSomeAlias';
168
 
169
/**
170
 * useTable property
171
 *
172
 * @var string
173
 */
174
	public $useTable = 'posts';
175
}
176
 
177
/**
178
 * NameTest class
179
 *
180
 * @package       Cake.Test.Case.Controller
181
 */
182
class NameTest extends CakeTestModel {
183
 
184
/**
185
 * name property
186
 * @var string
187
 */
188
	public $name = 'Name';
189
 
190
/**
191
 * useTable property
192
 * @var string
193
 */
194
	public $useTable = 'comments';
195
 
196
/**
197
 * alias property
198
 *
199
 * @var string
200
 */
201
	public $alias = 'Name';
202
}
203
 
204
/**
205
 * TestController class
206
 *
207
 * @package       Cake.Test.Case.Controller
208
 */
209
class TestController extends ControllerTestAppController {
210
 
211
/**
212
 * helpers property
213
 *
214
 * @var array
215
 */
216
	public $helpers = array('Session');
217
 
218
/**
219
 * components property
220
 *
221
 * @var array
222
 */
223
	public $components = array('Security');
224
 
225
/**
226
 * uses property
227
 *
228
 * @var array
229
 */
230
	public $uses = array('ControllerComment', 'ControllerAlias');
231
 
232
	protected $_mergeParent = 'ControllerTestAppController';
233
 
234
/**
235
 * index method
236
 *
237
 * @param mixed $testId
238
 * @param mixed $test2Id
239
 * @return void
240
 */
241
	public function index($testId, $testTwoId) {
242
		$this->data = array(
243
			'testId' => $testId,
244
			'test2Id' => $testTwoId
245
		);
246
	}
247
 
248
/**
249
 * view method
250
 *
251
 * @param mixed $testId
252
 * @param mixed $test2Id
253
 * @return void
254
 */
255
	public function view($testId, $testTwoId) {
256
		$this->data = array(
257
			'testId' => $testId,
258
			'test2Id' => $testTwoId
259
		);
260
	}
261
 
262
	public function returner() {
263
		return 'I am from the controller.';
264
	}
265
 
266
	//@codingStandardsIgnoreStart
267
	protected function protected_m() {
268
	}
269
 
270
	private function private_m() {
271
	}
272
 
273
	public function _hidden() {
274
	}
275
	//@codingStandardsIgnoreEnd
276
 
277
	public function admin_add() {
278
	}
279
 
280
}
281
 
282
/**
283
 * TestComponent class
284
 *
285
 * @package       Cake.Test.Case.Controller
286
 */
287
class TestComponent extends Object {
288
 
289
/**
290
 * beforeRedirect method
291
 *
292
 * @return void
293
 */
294
	public function beforeRedirect() {
295
	}
296
 
297
/**
298
 * initialize method
299
 *
300
 * @return void
301
 */
302
	public function initialize(Controller $controller) {
303
	}
304
 
305
/**
306
 * startup method
307
 *
308
 * @return void
309
 */
310
	public function startup(Controller $controller) {
311
	}
312
 
313
/**
314
 * shutdown method
315
 *
316
 * @return void
317
 */
318
	public function shutdown(Controller $controller) {
319
	}
320
 
321
/**
322
 * beforeRender callback
323
 *
324
 * @return void
325
 */
326
	public function beforeRender(Controller $controller) {
327
		if ($this->viewclass) {
328
			$controller->viewClass = $this->viewclass;
329
		}
330
	}
331
 
332
}
333
 
334
class Test2Component extends TestComponent {
335
 
336
	public $model;
337
 
338
	public function __construct(ComponentCollection $collection, $settings) {
339
		$this->controller = $collection->getController();
340
		$this->model = $this->controller->modelClass;
341
	}
342
 
343
	public function beforeRender(Controller $controller) {
344
		return false;
345
	}
346
 
347
}
348
 
349
/**
350
 * AnotherTestController class
351
 *
352
 * @package       Cake.Test.Case.Controller
353
 */
354
class AnotherTestController extends ControllerTestAppController {
355
 
356
/**
357
 * uses property
358
 *
359
 * @var array
360
 */
361
	public $uses = false;
362
 
363
/**
364
 * merge parent
365
 *
366
 * @var string
367
 */
368
	protected $_mergeParent = 'ControllerTestAppController';
369
}
370
 
371
/**
372
 * ControllerTest class
373
 *
374
 * @package       Cake.Test.Case.Controller
375
 */
376
class ControllerTest extends CakeTestCase {
377
 
378
/**
379
 * fixtures property
380
 *
381
 * @var array
382
 */
383
	public $fixtures = array(
384
		'core.post',
385
		'core.comment'
386
	);
387
 
388
/**
389
 * reset environment.
390
 *
391
 * @return void
392
 */
393
	public function setUp() {
394
		parent::setUp();
395
		App::objects('plugin', null, false);
396
		App::build();
397
		Router::reload();
398
	}
399
 
400
/**
401
 * tearDown
402
 *
403
 * @return void
404
 */
405
	public function tearDown() {
406
		parent::tearDown();
407
		CakePlugin::unload();
408
	}
409
 
410
/**
411
 * testLoadModel method
412
 *
413
 * @return void
414
 */
415
	public function testLoadModel() {
416
		$request = new CakeRequest('controller_posts/index');
417
		$response = $this->getMock('CakeResponse');
418
		$Controller = new Controller($request, $response);
419
 
420
		$this->assertFalse(isset($Controller->ControllerPost));
421
 
422
		$result = $Controller->loadModel('ControllerPost');
423
		$this->assertTrue($result);
424
		$this->assertInstanceOf('ControllerPost', $Controller->ControllerPost);
425
		$this->assertContains('ControllerPost', $Controller->uses);
426
	}
427
 
428
/**
429
 * Test loadModel() when uses = true.
430
 *
431
 * @return void
432
 */
433
	public function testLoadModelUsesTrue() {
434
		$request = new CakeRequest('controller_posts/index');
435
		$response = $this->getMock('CakeResponse');
436
		$Controller = new Controller($request, $response);
437
		$Controller->uses = true;
438
 
439
		$Controller->loadModel('ControllerPost');
440
		$this->assertInstanceOf('ControllerPost', $Controller->ControllerPost);
441
		$this->assertContains('ControllerPost', $Controller->uses);
442
	}
443
 
444
/**
445
 * testLoadModel method from a plugin controller
446
 *
447
 * @return void
448
 */
449
	public function testLoadModelInPlugins() {
450
		App::build(array(
451
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
452
			'Controller' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Controller' . DS),
453
			'Model' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS)
454
		));
455
		CakePlugin::load('TestPlugin');
456
		App::uses('TestPluginAppController', 'TestPlugin.Controller');
457
		App::uses('TestPluginController', 'TestPlugin.Controller');
458
 
459
		$Controller = new TestPluginController();
460
		$Controller->plugin = 'TestPlugin';
461
		$Controller->uses = false;
462
 
463
		$this->assertFalse(isset($Controller->Comment));
464
 
465
		$result = $Controller->loadModel('Comment');
466
		$this->assertTrue($result);
467
		$this->assertInstanceOf('Comment', $Controller->Comment);
468
		$this->assertTrue(in_array('Comment', $Controller->uses));
469
 
470
		ClassRegistry::flush();
471
		unset($Controller);
472
	}
473
 
474
/**
475
 * testConstructClasses method
476
 *
477
 * @return void
478
 */
479
	public function testConstructClasses() {
480
		$request = new CakeRequest('controller_posts/index');
481
 
482
		$Controller = new Controller($request);
483
		$Controller->uses = array('ControllerPost', 'ControllerComment');
484
		$Controller->constructClasses();
485
		$this->assertInstanceOf('ControllerPost', $Controller->ControllerPost);
486
		$this->assertInstanceOf('ControllerComment', $Controller->ControllerComment);
487
 
488
		$this->assertEquals('Comment', $Controller->ControllerComment->name);
489
 
490
		unset($Controller);
491
 
492
		App::build(array('Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)));
493
		CakePlugin::load('TestPlugin');
494
 
495
		$Controller = new Controller($request);
496
		$Controller->uses = array('TestPlugin.TestPluginPost');
497
		$Controller->constructClasses();
498
 
499
		$this->assertTrue(isset($Controller->TestPluginPost));
500
		$this->assertInstanceOf('TestPluginPost', $Controller->TestPluginPost);
501
	}
502
 
503
/**
504
 * testConstructClassesWithComponents method
505
 *
506
 * @return void
507
 */
508
	public function testConstructClassesWithComponents() {
509
		$Controller = new TestPluginController(new CakeRequest(), new CakeResponse());
510
		$Controller->uses = array('NameTest');
511
		$Controller->components[] = 'Test2';
512
 
513
		$Controller->constructClasses();
514
		$this->assertEquals('NameTest', $Controller->Test2->model);
515
		$this->assertEquals('Name', $Controller->NameTest->name);
516
		$this->assertEquals('Name', $Controller->NameTest->alias);
517
	}
518
 
519
/**
520
 * testAliasName method
521
 *
522
 * @return void
523
 */
524
	public function testAliasName() {
525
		$request = new CakeRequest('controller_posts/index');
526
		$Controller = new Controller($request);
527
		$Controller->uses = array('NameTest');
528
		$Controller->constructClasses();
529
 
530
		$this->assertEquals('Name', $Controller->NameTest->name);
531
		$this->assertEquals('Name', $Controller->NameTest->alias);
532
 
533
		unset($Controller);
534
	}
535
 
536
/**
537
 * testFlash method
538
 *
539
 * @return void
540
 */
541
	public function testFlash() {
542
		$request = new CakeRequest('controller_posts/index');
543
		$request->webroot = '/';
544
		$request->base = '/';
545
 
546
		$Controller = new Controller($request, $this->getMock('CakeResponse', array('_sendHeader')));
547
		$Controller->flash('this should work', '/flash');
548
		$result = $Controller->response->body();
549
 
550
		$expected = '<!DOCTYPE html>
551
		<html>
552
		<head>
553
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
554
		<title>this should work</title>
555
		<style><!--
556
		P { text-align:center; font:bold 1.1em sans-serif }
557
		A { color:#444; text-decoration:none }
558
		A:HOVER { text-decoration: underline; color:#44E }
559
		--></style>
560
		</head>
561
		<body>
562
		<p><a href="/flash">this should work</a></p>
563
		</body>
564
		</html>';
565
		$result = str_replace(array("\t", "\r\n", "\n"), "", $result);
566
		$expected = str_replace(array("\t", "\r\n", "\n"), "", $expected);
567
		$this->assertEquals($expected, $result);
568
 
569
		App::build(array(
570
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
571
		));
572
		$Controller = new Controller($request);
573
		$Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
574
		$Controller->flash('this should work', '/flash', 1, 'ajax2');
575
		$result = $Controller->response->body();
576
		$this->assertRegExp('/Ajax!/', $result);
577
		App::build();
578
	}
579
 
580
/**
581
 * testControllerSet method
582
 *
583
 * @return void
584
 */
585
	public function testControllerSet() {
586
		$request = new CakeRequest('controller_posts/index');
587
		$Controller = new Controller($request);
588
 
589
		$Controller->set('variable_with_underscores', null);
590
		$this->assertTrue(array_key_exists('variable_with_underscores', $Controller->viewVars));
591
 
592
		$Controller->viewVars = array();
593
		$viewVars = array('ModelName' => array('id' => 1, 'name' => 'value'));
594
		$Controller->set($viewVars);
595
		$this->assertTrue(array_key_exists('ModelName', $Controller->viewVars));
596
 
597
		$Controller->viewVars = array();
598
		$Controller->set('variable_with_underscores', 'value');
599
		$this->assertTrue(array_key_exists('variable_with_underscores', $Controller->viewVars));
600
 
601
		$Controller->viewVars = array();
602
		$viewVars = array('ModelName' => 'name');
603
		$Controller->set($viewVars);
604
		$this->assertTrue(array_key_exists('ModelName', $Controller->viewVars));
605
 
606
		$Controller->set('title', 'someTitle');
607
		$this->assertSame($Controller->viewVars['title'], 'someTitle');
608
		$this->assertTrue(empty($Controller->pageTitle));
609
 
610
		$Controller->viewVars = array();
611
		$expected = array('ModelName' => 'name', 'ModelName2' => 'name2');
612
		$Controller->set(array('ModelName', 'ModelName2'), array('name', 'name2'));
613
		$this->assertSame($expected, $Controller->viewVars);
614
 
615
		$Controller->viewVars = array();
616
		$Controller->set(array(3 => 'three', 4 => 'four'));
617
		$Controller->set(array(1 => 'one', 2 => 'two'));
618
		$expected = array(3 => 'three', 4 => 'four', 1 => 'one', 2 => 'two');
619
		$this->assertEquals($expected, $Controller->viewVars);
620
	}
621
 
622
/**
623
 * testRender method
624
 *
625
 * @return void
626
 */
627
	public function testRender() {
628
		App::build(array(
629
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
630
		), App::RESET);
631
		ClassRegistry::flush();
632
		$request = new CakeRequest('controller_posts/index');
633
		$request->params['action'] = 'index';
634
 
635
		$Controller = new Controller($request, new CakeResponse());
636
		$Controller->viewPath = 'Posts';
637
 
638
		$result = $Controller->render('index');
639
		$this->assertRegExp('/posts index/', (string)$result);
640
 
641
		$Controller->view = 'index';
642
		$result = $Controller->render();
643
		$this->assertRegExp('/posts index/', (string)$result);
644
 
645
		$result = $Controller->render('/Elements/test_element');
646
		$this->assertRegExp('/this is the test element/', (string)$result);
647
		$Controller->view = null;
648
 
649
		$Controller = new TestController($request, new CakeResponse());
650
		$Controller->uses = array('ControllerAlias', 'TestPlugin.ControllerComment', 'ControllerPost');
651
		$Controller->helpers = array('Html');
652
		$Controller->constructClasses();
653
		$Controller->ControllerComment->validationErrors = array('title' => 'tooShort');
654
		$expected = $Controller->ControllerComment->validationErrors;
655
 
656
		$Controller->viewPath = 'Posts';
657
		$result = $Controller->render('index');
658
		$View = $Controller->View;
659
		$this->assertTrue(isset($View->validationErrors['ControllerComment']));
660
		$this->assertEquals($expected, $View->validationErrors['ControllerComment']);
661
 
662
		$expectedModels = array(
663
			'ControllerAlias' => array('plugin' => null, 'className' => 'ControllerAlias'),
664
			'ControllerComment' => array('plugin' => 'TestPlugin', 'className' => 'ControllerComment'),
665
			'ControllerPost' => array('plugin' => null, 'className' => 'ControllerPost')
666
		);
667
		$this->assertEquals($expectedModels, $Controller->request->params['models']);
668
 
669
		ClassRegistry::flush();
670
		App::build();
671
	}
672
 
673
/**
674
 * test that a component beforeRender can change the controller view class.
675
 *
676
 * @return void
677
 */
678
	public function testComponentBeforeRenderChangingViewClass() {
679
		App::build(array(
680
			'View' => array(
681
				CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS
682
			)
683
		), true);
684
		$Controller = new Controller($this->getMock('CakeRequest'), new CakeResponse());
685
		$Controller->uses = array();
686
		$Controller->components = array('Test');
687
		$Controller->constructClasses();
688
		$Controller->Test->viewclass = 'Theme';
689
		$Controller->viewPath = 'Posts';
690
		$Controller->theme = 'TestTheme';
691
		$result = $Controller->render('index');
692
		$this->assertRegExp('/default test_theme layout/', (string)$result);
693
		App::build();
694
	}
695
 
696
/**
697
 * test that a component beforeRender can change the controller view class.
698
 *
699
 * @return void
700
 */
701
	public function testComponentCancelRender() {
702
		$Controller = new Controller($this->getMock('CakeRequest'), new CakeResponse());
703
		$Controller->uses = array();
704
		$Controller->components = array('Test2');
705
		$Controller->constructClasses();
706
		$result = $Controller->render('index');
707
		$this->assertInstanceOf('CakeResponse', $result);
708
	}
709
 
710
/**
711
 * testToBeInheritedGuardmethods method
712
 *
713
 * @return void
714
 */
715
	public function testToBeInheritedGuardmethods() {
716
		$request = new CakeRequest('controller_posts/index');
717
 
718
		$Controller = new Controller($request, $this->getMock('CakeResponse'));
719
		$this->assertTrue($Controller->beforeScaffold(''));
720
		$this->assertTrue($Controller->afterScaffoldSave(''));
721
		$this->assertTrue($Controller->afterScaffoldSaveError(''));
722
		$this->assertFalse($Controller->scaffoldError(''));
723
	}
724
 
725
/**
726
 * Generates status codes for redirect test.
727
 *
728
 * @return void
729
 */
730
	public static function statusCodeProvider() {
731
		return array(
732
			array(300, "Multiple Choices"),
733
			array(301, "Moved Permanently"),
734
			array(302, "Found"),
735
			array(303, "See Other"),
736
			array(304, "Not Modified"),
737
			array(305, "Use Proxy"),
738
			array(307, "Temporary Redirect"),
739
			array(403, "Forbidden"),
740
		);
741
	}
742
 
743
/**
744
 * testRedirect method
745
 *
746
 * @dataProvider statusCodeProvider
747
 * @return void
748
 */
749
	public function testRedirectByCode($code, $msg) {
750
		$Controller = new Controller(null);
751
		$Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
752
 
753
		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
754
 
755
		$Controller->response->expects($this->once())->method('statusCode')
756
			->with($code);
757
		$Controller->response->expects($this->once())->method('header')
758
			->with('Location', 'http://cakephp.org');
759
 
760
		$Controller->redirect('http://cakephp.org', (int)$code, false);
761
		$this->assertFalse($Controller->autoRender);
762
	}
763
 
764
/**
765
 * test redirecting by message
766
 *
767
 * @dataProvider statusCodeProvider
768
 * @return void
769
 */
770
	public function testRedirectByMessage($code, $msg) {
771
		$Controller = new Controller(null);
772
		$Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
773
 
774
		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
775
 
776
		$Controller->response->expects($this->once())->method('statusCode')
777
			->with($code);
778
 
779
		$Controller->response->expects($this->once())->method('header')
780
			->with('Location', 'http://cakephp.org');
781
 
782
		$Controller->redirect('http://cakephp.org', $msg, false);
783
		$this->assertFalse($Controller->autoRender);
784
	}
785
 
786
/**
787
 * test that redirect triggers methods on the components.
788
 *
789
 * @return void
790
 */
791
	public function testRedirectTriggeringComponentsReturnNull() {
792
		$Controller = new Controller(null);
793
		$Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
794
		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
795
 
796
		$Controller->Components->expects($this->once())->method('trigger')
797
			->will($this->returnValue(null));
798
 
799
		$Controller->response->expects($this->once())->method('statusCode')
800
			->with(301);
801
 
802
		$Controller->response->expects($this->once())->method('header')
803
			->with('Location', 'http://cakephp.org');
804
 
805
		$Controller->redirect('http://cakephp.org', 301, false);
806
	}
807
 
808
/**
809
 * test that beforeRedirect callback returning null doesn't affect things.
810
 *
811
 * @return void
812
 */
813
	public function testRedirectBeforeRedirectModifyingParams() {
814
		$Controller = new Controller(null);
815
		$Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
816
		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
817
 
818
		$Controller->Components->expects($this->once())->method('trigger')
819
			->will($this->returnValue(array('http://book.cakephp.org')));
820
 
821
		$Controller->response->expects($this->once())->method('statusCode')
822
			->with(301);
823
 
824
		$Controller->response->expects($this->once())->method('header')
825
			->with('Location', 'http://book.cakephp.org');
826
 
827
		$Controller->redirect('http://cakephp.org', 301, false);
828
	}
829
 
830
/**
831
 * test that beforeRedirect callback returning null doesn't affect things.
832
 *
833
 * @return void
834
 */
835
	public function testRedirectBeforeRedirectModifyingParamsArrayReturn() {
836
		$Controller = $this->getMock('Controller', array('header', '_stop'));
837
		$Controller->response = $this->getMock('CakeResponse');
838
		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
839
 
840
		$return = array(
841
			array(
842
				'url' => 'http://example.com/test/1',
843
				'exit' => false,
844
				'status' => 302
845
			),
846
			array(
847
				'url' => 'http://example.com/test/2',
848
			),
849
		);
850
		$Controller->Components->expects($this->once())->method('trigger')
851
			->will($this->returnValue($return));
852
 
853
		$Controller->response->expects($this->once())->method('header')
854
			->with('Location', 'http://example.com/test/2');
855
 
856
		$Controller->response->expects($this->at(1))->method('statusCode')
857
			->with(302);
858
 
859
		$Controller->expects($this->never())->method('_stop');
860
		$Controller->redirect('http://cakephp.org', 301);
861
	}
862
 
863
/**
864
 * test that beforeRedirect callback returning false in controller
865
 *
866
 * @return void
867
 */
868
	public function testRedirectBeforeRedirectInController() {
869
		$Controller = $this->getMock('Controller', array('_stop', 'beforeRedirect'));
870
		$Controller->response = $this->getMock('CakeResponse', array('header'));
871
		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
872
 
873
		$Controller->expects($this->once())->method('beforeRedirect')
874
			->with('http://cakephp.org')
875
			->will($this->returnValue(false));
876
		$Controller->response->expects($this->never())->method('header');
877
		$Controller->expects($this->never())->method('_stop');
878
		$Controller->redirect('http://cakephp.org');
879
	}
880
 
881
/**
882
 * Test that beforeRedirect works with returning an array from the controller method.
883
 *
884
 * @return void
885
 */
886
	public function testRedirectBeforeRedirectInControllerWithArray() {
887
		$Controller = $this->getMock('Controller', array('_stop', 'beforeRedirect'));
888
		$Controller->response = $this->getMock('CakeResponse', array('header'));
889
		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
890
 
891
		$Controller->expects($this->once())
892
			->method('beforeRedirect')
893
			->with('http://cakephp.org', null, true)
894
			->will($this->returnValue(array(
895
				'url' => 'http://example.org',
896
				'status' => 302,
897
				'exit' => true
898
			)));
899
 
900
		$Controller->response->expects($this->at(0))
901
			->method('header')
902
			->with('Location', 'http://example.org');
903
 
904
		$Controller->expects($this->once())->method('_stop');
905
		$Controller->redirect('http://cakephp.org');
906
	}
907
 
908
/**
909
 * testMergeVars method
910
 *
911
 * @return void
912
 */
913
	public function testMergeVars() {
914
		$request = new CakeRequest('controller_posts/index');
915
 
916
		$TestController = new TestController($request);
917
		$TestController->constructClasses();
918
 
919
		$testVars = get_class_vars('TestController');
920
		$appVars = get_class_vars('ControllerTestAppController');
921
 
922
		$components = is_array($appVars['components'])
923
						? array_merge($appVars['components'], $testVars['components'])
924
						: $testVars['components'];
925
		if (!in_array('Session', $components)) {
926
			$components[] = 'Session';
927
		}
928
		$helpers = is_array($appVars['helpers'])
929
					? array_merge($appVars['helpers'], $testVars['helpers'])
930
					: $testVars['helpers'];
931
		$uses = is_array($appVars['uses'])
932
					? array_merge($appVars['uses'], $testVars['uses'])
933
					: $testVars['uses'];
934
 
935
		$this->assertEquals(0, count(array_diff_key($TestController->helpers, array_flip($helpers))));
936
		$this->assertEquals(0, count(array_diff($TestController->uses, $uses)));
937
		$this->assertEquals(count(array_diff_assoc(Hash::normalize($TestController->components), Hash::normalize($components))), 0);
938
 
939
		$expected = array('ControllerComment', 'ControllerAlias', 'ControllerPost');
940
		$this->assertEquals($expected, $TestController->uses, '$uses was merged incorrectly, ControllerTestAppController models should be last.');
941
 
942
		$TestController = new AnotherTestController($request);
943
		$TestController->constructClasses();
944
 
945
		$appVars = get_class_vars('ControllerTestAppController');
946
		$testVars = get_class_vars('AnotherTestController');
947
 
948
		$this->assertTrue(in_array('ControllerPost', $appVars['uses']));
949
		$this->assertFalse($testVars['uses']);
950
 
951
		$this->assertFalse(property_exists($TestController, 'ControllerPost'));
952
 
953
		$TestController = new ControllerCommentsController($request);
954
		$TestController->constructClasses();
955
 
956
		$appVars = get_class_vars('ControllerTestAppController');
957
		$testVars = get_class_vars('ControllerCommentsController');
958
 
959
		$this->assertTrue(in_array('ControllerPost', $appVars['uses']));
960
		$this->assertEquals(array('ControllerPost'), $testVars['uses']);
961
 
962
		$this->assertTrue(isset($TestController->ControllerPost));
963
		$this->assertTrue(isset($TestController->ControllerComment));
964
	}
965
 
966
/**
967
 * test that options from child classes replace those in the parent classes.
968
 *
969
 * @return void
970
 */
971
	public function testChildComponentOptionsSupercedeParents() {
972
		$request = new CakeRequest('controller_posts/index');
973
 
974
		$TestController = new TestController($request);
975
 
976
		$expected = array('foo');
977
		$TestController->components = array('Cookie' => $expected);
978
		$TestController->constructClasses();
979
		$this->assertEquals($expected, $TestController->components['Cookie']);
980
	}
981
 
982
/**
983
 * Ensure that _mergeControllerVars is not being greedy and merging with
984
 * ControllerTestAppController when you make an instance of Controller
985
 *
986
 * @return void
987
 */
988
	public function testMergeVarsNotGreedy() {
989
		$request = new CakeRequest('controller_posts/index');
990
 
991
		$Controller = new Controller($request);
992
		$Controller->components = array();
993
		$Controller->uses = array();
994
		$Controller->constructClasses();
995
 
996
		$this->assertFalse(isset($Controller->Session));
997
	}
998
 
999
/**
1000
 * testReferer method
1001
 *
1002
 * @return void
1003
 */
1004
	public function testReferer() {
1005
		$request = $this->getMock('CakeRequest');
1006
 
1007
		$request->expects($this->any())->method('referer')
1008
			->with(true)
1009
			->will($this->returnValue('/posts/index'));
1010
 
1011
		$Controller = new Controller($request);
1012
		$result = $Controller->referer(null, true);
1013
		$this->assertEquals('/posts/index', $result);
1014
 
1015
		$Controller = new Controller($request);
1016
		$request->setReturnValue('referer', '/', array(true));
1017
		$result = $Controller->referer(array('controller' => 'posts', 'action' => 'index'), true);
1018
		$this->assertEquals('/posts/index', $result);
1019
 
1020
		$request = $this->getMock('CakeRequest');
1021
 
1022
		$request->expects($this->any())->method('referer')
1023
			->with(false)
1024
			->will($this->returnValue('http://localhost/posts/index'));
1025
 
1026
		$Controller = new Controller($request);
1027
		$result = $Controller->referer();
1028
		$this->assertEquals('http://localhost/posts/index', $result);
1029
 
1030
		$Controller = new Controller(null);
1031
		$result = $Controller->referer();
1032
		$this->assertEquals('/', $result);
1033
	}
1034
 
1035
/**
1036
 * testSetAction method
1037
 *
1038
 * @return void
1039
 */
1040
	public function testSetAction() {
1041
		$request = new CakeRequest('controller_posts/index');
1042
 
1043
		$TestController = new TestController($request);
1044
		$TestController->setAction('view', 1, 2);
1045
		$expected = array('testId' => 1, 'test2Id' => 2);
1046
		$this->assertSame($expected, $TestController->request->data);
1047
		$this->assertSame('view', $TestController->request->params['action']);
1048
		$this->assertSame('view', $TestController->view);
1049
	}
1050
 
1051
/**
1052
 * testValidateErrors method
1053
 *
1054
 * @return void
1055
 */
1056
	public function testValidateErrors() {
1057
		ClassRegistry::flush();
1058
		$request = new CakeRequest('controller_posts/index');
1059
 
1060
		$TestController = new TestController($request);
1061
		$TestController->constructClasses();
1062
		$this->assertFalse($TestController->validateErrors());
1063
		$this->assertEquals(0, $TestController->validate());
1064
 
1065
		$TestController->ControllerComment->invalidate('some_field', 'error_message');
1066
		$TestController->ControllerComment->invalidate('some_field2', 'error_message2');
1067
 
1068
		$comment = new ControllerComment($request);
1069
		$comment->set('someVar', 'data');
1070
		$result = $TestController->validateErrors($comment);
1071
		$expected = array('some_field' => array('error_message'), 'some_field2' => array('error_message2'));
1072
		$this->assertSame($expected, $result);
1073
		$this->assertEquals(2, $TestController->validate($comment));
1074
	}
1075
 
1076
/**
1077
 * test that validateErrors works with any old model.
1078
 *
1079
 * @return void
1080
 */
1081
	public function testValidateErrorsOnArbitraryModels() {
1082
		Configure::write('Config.language', 'eng');
1083
		$TestController = new TestController();
1084
 
1085
		$Post = new ControllerPost();
1086
		$Post->validate = array('title' => 'notEmpty');
1087
		$Post->set('title', '');
1088
		$result = $TestController->validateErrors($Post);
1089
 
1090
		$expected = array('title' => array('This field cannot be left blank'));
1091
		$this->assertEquals($expected, $result);
1092
	}
1093
 
1094
/**
1095
 * testPostConditions method
1096
 *
1097
 * @return void
1098
 */
1099
	public function testPostConditions() {
1100
		$request = new CakeRequest('controller_posts/index');
1101
 
1102
		$Controller = new Controller($request);
1103
 
1104
		$data = array(
1105
			'Model1' => array('field1' => '23'),
1106
			'Model2' => array('field2' => 'string'),
1107
			'Model3' => array('field3' => '23'),
1108
		);
1109
		$expected = array(
1110
			'Model1.field1' => '23',
1111
			'Model2.field2' => 'string',
1112
			'Model3.field3' => '23',
1113
		);
1114
		$result = $Controller->postConditions($data);
1115
		$this->assertSame($expected, $result);
1116
 
1117
		$data = array();
1118
		$Controller->data = array(
1119
			'Model1' => array('field1' => '23'),
1120
			'Model2' => array('field2' => 'string'),
1121
			'Model3' => array('field3' => '23'),
1122
		);
1123
		$expected = array(
1124
			'Model1.field1' => '23',
1125
			'Model2.field2' => 'string',
1126
			'Model3.field3' => '23',
1127
		);
1128
		$result = $Controller->postConditions($data);
1129
		$this->assertSame($expected, $result);
1130
 
1131
		$data = array();
1132
		$Controller->data = array();
1133
		$result = $Controller->postConditions($data);
1134
		$this->assertNull($result);
1135
 
1136
		$data = array();
1137
		$Controller->data = array(
1138
			'Model1' => array('field1' => '23'),
1139
			'Model2' => array('field2' => 'string'),
1140
			'Model3' => array('field3' => '23'),
1141
		);
1142
		$ops = array(
1143
			'Model1.field1' => '>',
1144
			'Model2.field2' => 'LIKE',
1145
			'Model3.field3' => '<=',
1146
		);
1147
		$expected = array(
1148
			'Model1.field1 >' => '23',
1149
			'Model2.field2 LIKE' => "%string%",
1150
			'Model3.field3 <=' => '23',
1151
		);
1152
		$result = $Controller->postConditions($data, $ops);
1153
		$this->assertSame($expected, $result);
1154
	}
1155
 
1156
/**
1157
 * testControllerHttpCodes method
1158
 *
1159
 * @return void
1160
 */
1161
	public function testControllerHttpCodes() {
1162
		$response = $this->getMock('CakeResponse', array('httpCodes'));
1163
		$Controller = new Controller(null, $response);
1164
		$Controller->response->expects($this->at(0))->method('httpCodes')->with(null);
1165
		$Controller->response->expects($this->at(1))->method('httpCodes')->with(100);
1166
		$Controller->httpCodes();
1167
		$Controller->httpCodes(100);
1168
	}
1169
 
1170
/**
1171
 * Tests that the startup process calls the correct functions
1172
 *
1173
 * @return void
1174
 */
1175
	public function testStartupProcess() {
1176
		$Controller = $this->getMock('Controller', array('getEventManager'));
1177
 
1178
		$eventManager = $this->getMock('CakeEventManager');
1179
		$eventManager->expects($this->at(0))->method('dispatch')
1180
			->with(
1181
				$this->logicalAnd(
1182
					$this->isInstanceOf('CakeEvent'),
1183
					$this->attributeEqualTo('_name', 'Controller.initialize'),
1184
					$this->attributeEqualTo('_subject', $Controller)
1185
				)
1186
			);
1187
		$eventManager->expects($this->at(1))->method('dispatch')
1188
			->with(
1189
				$this->logicalAnd(
1190
					$this->isInstanceOf('CakeEvent'),
1191
					$this->attributeEqualTo('_name', 'Controller.startup'),
1192
					$this->attributeEqualTo('_subject', $Controller)
1193
				)
1194
			);
1195
		$Controller->expects($this->exactly(2))->method('getEventManager')
1196
			->will($this->returnValue($eventManager));
1197
		$Controller->startupProcess();
1198
	}
1199
 
1200
/**
1201
 * Tests that the shutdown process calls the correct functions
1202
 *
1203
 * @return void
1204
 */
1205
	public function testStartupProcessIndirect() {
1206
		$Controller = $this->getMock('Controller', array('beforeFilter'));
1207
 
1208
		$Controller->components = array('MockShutdown');
1209
		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
1210
 
1211
		$Controller->expects($this->once())->method('beforeFilter');
1212
		$Controller->Components->expects($this->exactly(2))->method('trigger')->with($this->isInstanceOf('CakeEvent'));
1213
 
1214
		$Controller->startupProcess();
1215
	}
1216
 
1217
/**
1218
 * Tests that the shutdown process calls the correct functions
1219
 *
1220
 * @return void
1221
 */
1222
	public function testShutdownProcess() {
1223
		$Controller = $this->getMock('Controller', array('getEventManager'));
1224
 
1225
		$eventManager = $this->getMock('CakeEventManager');
1226
		$eventManager->expects($this->once())->method('dispatch')
1227
			->with(
1228
				$this->logicalAnd(
1229
					$this->isInstanceOf('CakeEvent'),
1230
					$this->attributeEqualTo('_name', 'Controller.shutdown'),
1231
					$this->attributeEqualTo('_subject', $Controller)
1232
				)
1233
			);
1234
		$Controller->expects($this->once())->method('getEventManager')
1235
			->will($this->returnValue($eventManager));
1236
		$Controller->shutdownProcess();
1237
	}
1238
 
1239
/**
1240
 * Tests that the shutdown process calls the correct functions
1241
 *
1242
 * @return void
1243
 */
1244
	public function testShutdownProcessIndirect() {
1245
		$Controller = $this->getMock('Controller', array('afterFilter'));
1246
 
1247
		$Controller->components = array('MockShutdown');
1248
		$Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
1249
 
1250
		$Controller->expects($this->once())->method('afterFilter');
1251
		$Controller->Components->expects($this->exactly(1))->method('trigger')->with($this->isInstanceOf('CakeEvent'));
1252
 
1253
		$Controller->shutdownProcess();
1254
	}
1255
 
1256
/**
1257
 * test that BC works for attributes on the request object.
1258
 *
1259
 * @return void
1260
 */
1261
	public function testPropertyBackwardsCompatibility() {
1262
		$request = new CakeRequest('posts/index', false);
1263
		$request->addParams(array('controller' => 'posts', 'action' => 'index'));
1264
		$request->data = array('Post' => array('id' => 1));
1265
		$request->here = '/posts/index';
1266
		$request->webroot = '/';
1267
 
1268
		$Controller = new TestController($request);
1269
		$this->assertEquals($request->data, $Controller->data);
1270
		$this->assertEquals($request->webroot, $Controller->webroot);
1271
		$this->assertEquals($request->here, $Controller->here);
1272
		$this->assertEquals($request->action, $Controller->action);
1273
 
1274
		$this->assertFalse(empty($Controller->data));
1275
		$this->assertTrue(isset($Controller->data));
1276
		$this->assertTrue(empty($Controller->something));
1277
		$this->assertFalse(isset($Controller->something));
1278
 
1279
		$this->assertEquals($request, $Controller->params);
1280
		$this->assertEquals($request->params['controller'], $Controller->params['controller']);
1281
	}
1282
 
1283
/**
1284
 * test that the BC wrapper doesn't interfere with models and components.
1285
 *
1286
 * @return void
1287
 */
1288
	public function testPropertyCompatibilityAndModelsComponents() {
1289
		$request = new CakeRequest('controller_posts/index');
1290
 
1291
		$Controller = new TestController($request);
1292
		$Controller->constructClasses();
1293
		$this->assertInstanceOf('SecurityComponent', $Controller->Security);
1294
		$this->assertInstanceOf('ControllerComment', $Controller->ControllerComment);
1295
	}
1296
 
1297
/**
1298
 * test that using Controller::paginate() falls back to PaginatorComponent
1299
 *
1300
 * @return void
1301
 */
1302
	public function testPaginateBackwardsCompatibility() {
1303
		$request = new CakeRequest('controller_posts/index');
1304
		$request->params['pass'] = $request->params['named'] = array();
1305
		$response = $this->getMock('CakeResponse', array('httpCodes'));
1306
 
1307
		$Controller = new Controller($request, $response);
1308
		$Controller->uses = array('ControllerPost', 'ControllerComment');
1309
		$Controller->passedArgs[] = '1';
1310
		$Controller->params['url'] = array();
1311
		$Controller->constructClasses();
1312
		$expected = array('page' => 1, 'limit' => 20, 'maxLimit' => 100, 'paramType' => 'named');
1313
		$this->assertEquals($expected, $Controller->paginate);
1314
 
1315
		$results = Hash::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id');
1316
		$this->assertEquals(array(1, 2, 3), $results);
1317
 
1318
		$Controller->passedArgs = array();
1319
		$Controller->paginate = array('limit' => '1');
1320
		$this->assertEquals(array('limit' => '1'), $Controller->paginate);
1321
		$Controller->paginate('ControllerPost');
1322
		$this->assertSame($Controller->params['paging']['ControllerPost']['page'], 1);
1323
		$this->assertSame($Controller->params['paging']['ControllerPost']['pageCount'], 3);
1324
		$this->assertFalse($Controller->params['paging']['ControllerPost']['prevPage']);
1325
		$this->assertTrue($Controller->params['paging']['ControllerPost']['nextPage']);
1326
	}
1327
 
1328
/**
1329
 * testMissingAction method
1330
 *
1331
 * @expectedException MissingActionException
1332
 * @expectedExceptionMessage Action TestController::missing() could not be found.
1333
 * @return void
1334
 */
1335
	public function testInvokeActionMissingAction() {
1336
		$url = new CakeRequest('test/missing');
1337
		$url->addParams(array('controller' => 'test_controller', 'action' => 'missing'));
1338
		$response = $this->getMock('CakeResponse');
1339
 
1340
		$Controller = new TestController($url, $response);
1341
		$Controller->invokeAction($url);
1342
	}
1343
 
1344
/**
1345
 * test invoking private methods.
1346
 *
1347
 * @expectedException PrivateActionException
1348
 * @expectedExceptionMessage Private Action TestController::private_m() is not directly accessible.
1349
 * @return void
1350
 */
1351
	public function testInvokeActionPrivate() {
1352
		$url = new CakeRequest('test/private_m/');
1353
		$url->addParams(array('controller' => 'test_controller', 'action' => 'private_m'));
1354
		$response = $this->getMock('CakeResponse');
1355
 
1356
		$Controller = new TestController($url, $response);
1357
		$Controller->invokeAction($url);
1358
	}
1359
 
1360
/**
1361
 * test invoking protected methods.
1362
 *
1363
 * @expectedException PrivateActionException
1364
 * @expectedExceptionMessage Private Action TestController::protected_m() is not directly accessible.
1365
 * @return void
1366
 */
1367
	public function testInvokeActionProtected() {
1368
		$url = new CakeRequest('test/protected_m/');
1369
		$url->addParams(array('controller' => 'test_controller', 'action' => 'protected_m'));
1370
		$response = $this->getMock('CakeResponse');
1371
 
1372
		$Controller = new TestController($url, $response);
1373
		$Controller->invokeAction($url);
1374
	}
1375
 
1376
/**
1377
 * test invoking hidden methods.
1378
 *
1379
 * @expectedException PrivateActionException
1380
 * @expectedExceptionMessage Private Action TestController::_hidden() is not directly accessible.
1381
 * @return void
1382
 */
1383
	public function testInvokeActionHidden() {
1384
		$url = new CakeRequest('test/_hidden/');
1385
		$url->addParams(array('controller' => 'test_controller', 'action' => '_hidden'));
1386
		$response = $this->getMock('CakeResponse');
1387
 
1388
		$Controller = new TestController($url, $response);
1389
		$Controller->invokeAction($url);
1390
	}
1391
 
1392
/**
1393
 * test invoking controller methods.
1394
 *
1395
 * @expectedException PrivateActionException
1396
 * @expectedExceptionMessage Private Action TestController::redirect() is not directly accessible.
1397
 * @return void
1398
 */
1399
	public function testInvokeActionBaseMethods() {
1400
		$url = new CakeRequest('test/redirect/');
1401
		$url->addParams(array('controller' => 'test_controller', 'action' => 'redirect'));
1402
		$response = $this->getMock('CakeResponse');
1403
 
1404
		$Controller = new TestController($url, $response);
1405
		$Controller->invokeAction($url);
1406
	}
1407
 
1408
/**
1409
 * test invoking controller methods.
1410
 *
1411
 * @expectedException PrivateActionException
1412
 * @expectedExceptionMessage Private Action TestController::admin_add() is not directly accessible.
1413
 * @return void
1414
 */
1415
	public function testInvokeActionPrefixProtection() {
1416
		Router::reload();
1417
		Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
1418
 
1419
		$url = new CakeRequest('test/admin_add/');
1420
		$url->addParams(array('controller' => 'test_controller', 'action' => 'admin_add'));
1421
		$response = $this->getMock('CakeResponse');
1422
 
1423
		$Controller = new TestController($url, $response);
1424
		$Controller->invokeAction($url);
1425
	}
1426
 
1427
/**
1428
 * test invoking controller methods.
1429
 *
1430
 * @return void
1431
 */
1432
	public function testInvokeActionReturnValue() {
1433
		$url = new CakeRequest('test/returner/');
1434
		$url->addParams(array(
1435
			'controller' => 'test_controller',
1436
			'action' => 'returner',
1437
			'pass' => array()
1438
		));
1439
		$response = $this->getMock('CakeResponse');
1440
 
1441
		$Controller = new TestController($url, $response);
1442
		$result = $Controller->invokeAction($url);
1443
		$this->assertEquals('I am from the controller.', $result);
1444
	}
1445
 
1446
}