ControllerTest.php 38 KB

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