ControllerTest.php 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422
  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->uses = array('ControllerPost', 'ControllerComment');
  424. $Controller->constructClasses();
  425. $this->assertTrue(is_a($Controller->ControllerPost, 'ControllerPost'));
  426. $this->assertTrue(is_a($Controller->ControllerComment, 'ControllerComment'));
  427. $this->assertEquals($Controller->ControllerComment->name, 'Comment');
  428. unset($Controller);
  429. App::build(array('plugins' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)));
  430. CakePlugin::load('TestPlugin');
  431. $Controller = new Controller($request);
  432. $Controller->uses = array('TestPlugin.TestPluginPost');
  433. $Controller->constructClasses();
  434. $this->assertTrue(isset($Controller->TestPluginPost));
  435. $this->assertTrue(is_a($Controller->TestPluginPost, 'TestPluginPost'));
  436. }
  437. /**
  438. * testAliasName method
  439. *
  440. * @return void
  441. */
  442. public function testAliasName() {
  443. $request = new CakeRequest('controller_posts/index');
  444. $Controller = new Controller($request);
  445. $Controller->uses = array('NameTest');
  446. $Controller->constructClasses();
  447. $this->assertEquals($Controller->NameTest->name, 'Name');
  448. $this->assertEquals($Controller->NameTest->alias, 'Name');
  449. unset($Controller);
  450. }
  451. /**
  452. * testFlash method
  453. *
  454. * @return void
  455. */
  456. public function testFlash() {
  457. $request = new CakeRequest('controller_posts/index');
  458. $request->webroot = '/';
  459. $request->base = '/';
  460. $Controller = new Controller($request, $this->getMock('CakeResponse', array('_sendHeader')));
  461. $Controller->flash('this should work', '/flash');
  462. $result = $Controller->response->body();
  463. $expected = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  464. <html xmlns="http://www.w3.org/1999/xhtml">
  465. <head>
  466. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  467. <title>this should work</title>
  468. <style><!--
  469. P { text-align:center; font:bold 1.1em sans-serif }
  470. A { color:#444; text-decoration:none }
  471. A:HOVER { text-decoration: underline; color:#44E }
  472. --></style>
  473. </head>
  474. <body>
  475. <p><a href="/flash">this should work</a></p>
  476. </body>
  477. </html>';
  478. $result = str_replace(array("\t", "\r\n", "\n"), "", $result);
  479. $expected = str_replace(array("\t", "\r\n", "\n"), "", $expected);
  480. $this->assertEquals($expected, $result);
  481. App::build(array(
  482. 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View'. DS)
  483. ));
  484. $Controller = new Controller($request);
  485. $Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
  486. $Controller->flash('this should work', '/flash', 1, 'ajax2');
  487. $result = $Controller->response->body();
  488. $this->assertRegExp('/Ajax!/', $result);
  489. App::build();
  490. }
  491. /**
  492. * testControllerSet method
  493. *
  494. * @return void
  495. */
  496. public function testControllerSet() {
  497. $request = new CakeRequest('controller_posts/index');
  498. $Controller = new Controller($request);
  499. $Controller->set('variable_with_underscores', null);
  500. $this->assertTrue(array_key_exists('variable_with_underscores', $Controller->viewVars));
  501. $Controller->viewVars = array();
  502. $viewVars = array('ModelName' => array('id' => 1, 'name' => 'value'));
  503. $Controller->set($viewVars);
  504. $this->assertTrue(array_key_exists('ModelName', $Controller->viewVars));
  505. $Controller->viewVars = array();
  506. $Controller->set('variable_with_underscores', 'value');
  507. $this->assertTrue(array_key_exists('variable_with_underscores', $Controller->viewVars));
  508. $Controller->viewVars = array();
  509. $viewVars = array('ModelName' => 'name');
  510. $Controller->set($viewVars);
  511. $this->assertTrue(array_key_exists('ModelName', $Controller->viewVars));
  512. $Controller->set('title', 'someTitle');
  513. $this->assertSame($Controller->viewVars['title'], 'someTitle');
  514. $this->assertTrue(empty($Controller->pageTitle));
  515. $Controller->viewVars = array();
  516. $expected = array('ModelName' => 'name', 'ModelName2' => 'name2');
  517. $Controller->set(array('ModelName', 'ModelName2'), array('name', 'name2'));
  518. $this->assertSame($Controller->viewVars, $expected);
  519. $Controller->viewVars = array();
  520. $Controller->set(array(3 => 'three', 4 => 'four'));
  521. $Controller->set(array(1 => 'one', 2 => 'two'));
  522. $expected = array(3 => 'three', 4 => 'four', 1 => 'one', 2 => 'two');
  523. $this->assertEquals($Controller->viewVars, $expected);
  524. }
  525. /**
  526. * testRender method
  527. *
  528. * @return void
  529. */
  530. public function testRender() {
  531. App::build(array(
  532. 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View'. DS)
  533. ), App::RESET);
  534. ClassRegistry::flush();
  535. $request = new CakeRequest('controller_posts/index');
  536. $request->params['action'] = 'index';
  537. $Controller = new Controller($request, new CakeResponse());
  538. $Controller->viewPath = 'Posts';
  539. $result = $Controller->render('index');
  540. $this->assertRegExp('/posts index/', (string)$result);
  541. $Controller->view = 'index';
  542. $result = $Controller->render();
  543. $this->assertRegExp('/posts index/', (string)$result);
  544. $result = $Controller->render('/Elements/test_element');
  545. $this->assertRegExp('/this is the test element/', (string)$result);
  546. $Controller->view = null;
  547. $Controller = new TestController($request, new CakeResponse());
  548. $Controller->uses = array('ControllerAlias', 'TestPlugin.ControllerComment', 'ControllerPost');
  549. $Controller->helpers = array('Html');
  550. $Controller->constructClasses();
  551. $Controller->ControllerComment->validationErrors = array('title' => 'tooShort');
  552. $expected = $Controller->ControllerComment->validationErrors;
  553. $Controller->viewPath = 'Posts';
  554. $result = $Controller->render('index');
  555. $View = $Controller->View;
  556. $this->assertTrue(isset($View->validationErrors['ControllerComment']));
  557. $this->assertEquals($expected, $View->validationErrors['ControllerComment']);
  558. $expectedModels = array(
  559. 'ControllerAlias' => array('plugin' => null, 'className' => 'ControllerAlias'),
  560. 'ControllerComment' => array('plugin' => 'TestPlugin', 'className' => 'ControllerComment'),
  561. 'ControllerPost' => array('plugin' => null, 'className' => 'ControllerPost')
  562. );
  563. $this->assertEquals($expectedModels, $Controller->request->params['models']);
  564. ClassRegistry::flush();
  565. App::build();
  566. }
  567. /**
  568. * test that a component beforeRender can change the controller view class.
  569. *
  570. * @return void
  571. */
  572. public function testComponentBeforeRenderChangingViewClass() {
  573. App::build(array(
  574. 'View' => array(
  575. CAKE . 'Test' . DS . 'test_app' . DS . 'View'. DS
  576. )
  577. ), true);
  578. $Controller = new Controller($this->getMock('CakeRequest'), new CakeResponse());
  579. $Controller->uses = array();
  580. $Controller->components = array('Test');
  581. $Controller->constructClasses();
  582. $Controller->Test->viewclass = 'Theme';
  583. $Controller->viewPath = 'Posts';
  584. $Controller->theme = 'TestTheme';
  585. $result = $Controller->render('index');
  586. $this->assertRegExp('/default test_theme layout/', (string)$result);
  587. App::build();
  588. }
  589. /**
  590. * test that a component beforeRender can change the controller view class.
  591. *
  592. * @return void
  593. */
  594. public function testComponentCancelRender() {
  595. $Controller = new Controller($this->getMock('CakeRequest'), new CakeResponse());
  596. $Controller->uses = array();
  597. $Controller->components = array('Test2');
  598. $Controller->constructClasses();
  599. $result = $Controller->render('index');
  600. $this->assertInstanceOf('CakeResponse', $result);
  601. }
  602. /**
  603. * testToBeInheritedGuardmethods method
  604. *
  605. * @return void
  606. */
  607. public function testToBeInheritedGuardmethods() {
  608. $request = new CakeRequest('controller_posts/index');
  609. $Controller = new Controller($request, $this->getMock('CakeResponse'));
  610. $this->assertTrue($Controller->beforeScaffold(''));
  611. $this->assertTrue($Controller->afterScaffoldSave(''));
  612. $this->assertTrue($Controller->afterScaffoldSaveError(''));
  613. $this->assertFalse($Controller->scaffoldError(''));
  614. }
  615. /**
  616. * Generates status codes for redirect test.
  617. *
  618. * @return void
  619. */
  620. public static function statusCodeProvider() {
  621. return array(
  622. array(300, "Multiple Choices"),
  623. array(301, "Moved Permanently"),
  624. array(302, "Found"),
  625. array(303, "See Other"),
  626. array(304, "Not Modified"),
  627. array(305, "Use Proxy"),
  628. array(307, "Temporary Redirect")
  629. );
  630. }
  631. /**
  632. * testRedirect method
  633. *
  634. * @dataProvider statusCodeProvider
  635. * @return void
  636. */
  637. public function testRedirectByCode($code, $msg) {
  638. $Controller = new Controller(null);
  639. $Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
  640. $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
  641. $Controller->response->expects($this->once())->method('statusCode')
  642. ->with($code);
  643. $Controller->response->expects($this->once())->method('header')
  644. ->with('Location', 'http://cakephp.org');
  645. $Controller->redirect('http://cakephp.org', (int)$code, false);
  646. $this->assertFalse($Controller->autoRender);
  647. }
  648. /**
  649. * test redirecting by message
  650. *
  651. * @dataProvider statusCodeProvider
  652. * @return void
  653. */
  654. public function testRedirectByMessage($code, $msg) {
  655. $Controller = new Controller(null);
  656. $Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
  657. $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
  658. $Controller->response->expects($this->once())->method('statusCode')
  659. ->with($code);
  660. $Controller->response->expects($this->once())->method('header')
  661. ->with('Location', 'http://cakephp.org');
  662. $Controller->redirect('http://cakephp.org', $msg, false);
  663. $this->assertFalse($Controller->autoRender);
  664. }
  665. /**
  666. * test that redirect triggers methods on the components.
  667. *
  668. * @return void
  669. */
  670. public function testRedirectTriggeringComponentsReturnNull() {
  671. $Controller = new Controller(null);
  672. $Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
  673. $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
  674. $Controller->Components->expects($this->once())->method('trigger')
  675. ->will($this->returnValue(null));
  676. $Controller->response->expects($this->once())->method('statusCode')
  677. ->with(301);
  678. $Controller->response->expects($this->once())->method('header')
  679. ->with('Location', 'http://cakephp.org');
  680. $Controller->redirect('http://cakephp.org', 301, false);
  681. }
  682. /**
  683. * test that beforeRedirect callback returning null doesn't affect things.
  684. *
  685. * @return void
  686. */
  687. public function testRedirectBeforeRedirectModifyingParams() {
  688. $Controller = new Controller(null);
  689. $Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
  690. $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
  691. $Controller->Components->expects($this->once())->method('trigger')
  692. ->will($this->returnValue(array('http://book.cakephp.org')));
  693. $Controller->response->expects($this->once())->method('statusCode')
  694. ->with(301);
  695. $Controller->response->expects($this->once())->method('header')
  696. ->with('Location', 'http://book.cakephp.org');
  697. $Controller->redirect('http://cakephp.org', 301, false);
  698. }
  699. /**
  700. * test that beforeRedirect callback returning null doesn't affect things.
  701. *
  702. * @return void
  703. */
  704. public function testRedirectBeforeRedirectModifyingParamsArrayReturn() {
  705. $Controller = $this->getMock('Controller', array('header', '_stop'));
  706. $Controller->response = $this->getMock('CakeResponse');
  707. $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
  708. $return = array(
  709. array(
  710. 'url' => 'http://example.com/test/1',
  711. 'exit' => false,
  712. 'status' => 302
  713. ),
  714. array(
  715. 'url' => 'http://example.com/test/2',
  716. ),
  717. );
  718. $Controller->Components->expects($this->once())->method('trigger')
  719. ->will($this->returnValue($return));
  720. $Controller->response->expects($this->once())->method('header')
  721. ->with('Location', 'http://example.com/test/2');
  722. $Controller->response->expects($this->at(1))->method('statusCode')
  723. ->with(302);
  724. $Controller->expects($this->never())->method('_stop');
  725. $Controller->redirect('http://cakephp.org', 301);
  726. }
  727. /**
  728. * test that beforeRedirect callback returning false in controller
  729. *
  730. * @return void
  731. */
  732. public function testRedirectBeforeRedirectInController() {
  733. $Controller = $this->getMock('Controller', array('_stop', 'beforeRedirect'));
  734. $Controller->response = $this->getMock('CakeResponse', array('header'));
  735. $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
  736. $Controller->expects($this->once())->method('beforeRedirect')
  737. ->with('http://cakephp.org')
  738. ->will($this->returnValue(false));
  739. $Controller->response->expects($this->never())->method('header');
  740. $Controller->expects($this->never())->method('_stop');
  741. $Controller->redirect('http://cakephp.org');
  742. }
  743. /**
  744. * testMergeVars method
  745. *
  746. * @return void
  747. */
  748. public function testMergeVars() {
  749. $request = new CakeRequest('controller_posts/index');
  750. $TestController = new TestController($request);
  751. $TestController->constructClasses();
  752. $testVars = get_class_vars('TestController');
  753. $appVars = get_class_vars('ControllerTestAppController');
  754. $components = is_array($appVars['components'])
  755. ? array_merge($appVars['components'], $testVars['components'])
  756. : $testVars['components'];
  757. if (!in_array('Session', $components)) {
  758. $components[] = 'Session';
  759. }
  760. $helpers = is_array($appVars['helpers'])
  761. ? array_merge($appVars['helpers'], $testVars['helpers'])
  762. : $testVars['helpers'];
  763. $uses = is_array($appVars['uses'])
  764. ? array_merge($appVars['uses'], $testVars['uses'])
  765. : $testVars['uses'];
  766. $this->assertEquals(count(array_diff_key($TestController->helpers, array_flip($helpers))), 0);
  767. $this->assertEquals(count(array_diff($TestController->uses, $uses)), 0);
  768. $this->assertEquals(count(array_diff_assoc(Set::normalize($TestController->components), Set::normalize($components))), 0);
  769. $expected = array('ControllerComment', 'ControllerAlias', 'ControllerPost');
  770. $this->assertEquals($expected, $TestController->uses, '$uses was merged incorrectly, ControllerTestAppController models should be last.');
  771. $TestController = new AnotherTestController($request);
  772. $TestController->constructClasses();
  773. $appVars = get_class_vars('ControllerTestAppController');
  774. $testVars = get_class_vars('AnotherTestController');
  775. $this->assertTrue(in_array('ControllerPost', $appVars['uses']));
  776. $this->assertNull($testVars['uses']);
  777. $this->assertFalse(property_exists($TestController, 'ControllerPost'));
  778. $TestController = new ControllerCommentsController($request);
  779. $TestController->constructClasses();
  780. $appVars = get_class_vars('ControllerTestAppController');
  781. $testVars = get_class_vars('ControllerCommentsController');
  782. $this->assertTrue(in_array('ControllerPost', $appVars['uses']));
  783. $this->assertEquals(array('ControllerPost'), $testVars['uses']);
  784. $this->assertTrue(isset($TestController->ControllerPost));
  785. $this->assertTrue(isset($TestController->ControllerComment));
  786. }
  787. /**
  788. * test that options from child classes replace those in the parent classes.
  789. *
  790. * @return void
  791. */
  792. public function testChildComponentOptionsSupercedeParents() {
  793. $request = new CakeRequest('controller_posts/index');
  794. $TestController = new TestController($request);
  795. $expected = array('foo');
  796. $TestController->components = array('Cookie' => $expected);
  797. $TestController->constructClasses();
  798. $this->assertEquals($TestController->components['Cookie'], $expected);
  799. }
  800. /**
  801. * Ensure that _mergeControllerVars is not being greedy and merging with
  802. * ControllerTestAppController when you make an instance of Controller
  803. *
  804. * @return void
  805. */
  806. public function testMergeVarsNotGreedy() {
  807. $request = new CakeRequest('controller_posts/index');
  808. $Controller = new Controller($request);
  809. $Controller->components = array();
  810. $Controller->uses = array();
  811. $Controller->constructClasses();
  812. $this->assertFalse(isset($Controller->Session));
  813. }
  814. /**
  815. * testReferer method
  816. *
  817. * @return void
  818. */
  819. public function testReferer() {
  820. $request = $this->getMock('CakeRequest');
  821. $request->expects($this->any())->method('referer')
  822. ->with(true)
  823. ->will($this->returnValue('/posts/index'));
  824. $Controller = new Controller($request);
  825. $result = $Controller->referer(null, true);
  826. $this->assertEquals($result, '/posts/index');
  827. $Controller = new Controller($request);
  828. $request->setReturnValue('referer', '/', array(true));
  829. $result = $Controller->referer(array('controller' => 'posts', 'action' => 'index'), true);
  830. $this->assertEquals($result, '/posts/index');
  831. $request = $this->getMock('CakeRequest');
  832. $request->expects($this->any())->method('referer')
  833. ->with(false)
  834. ->will($this->returnValue('http://localhost/posts/index'));
  835. $Controller = new Controller($request);
  836. $result = $Controller->referer();
  837. $this->assertEquals($result, 'http://localhost/posts/index');
  838. $Controller = new Controller(null);
  839. $result = $Controller->referer();
  840. $this->assertEquals($result, '/');
  841. }
  842. /**
  843. * testSetAction method
  844. *
  845. * @return void
  846. */
  847. public function testSetAction() {
  848. $request = new CakeRequest('controller_posts/index');
  849. $TestController = new TestController($request);
  850. $TestController->setAction('view', 1, 2);
  851. $expected = array('testId' => 1, 'test2Id' => 2);
  852. $this->assertSame($expected, $TestController->request->data);
  853. $this->assertSame('view', $TestController->request->params['action']);
  854. $this->assertSame('view', $TestController->view);
  855. }
  856. /**
  857. * testValidateErrors method
  858. *
  859. * @return void
  860. */
  861. public function testValidateErrors() {
  862. ClassRegistry::flush();
  863. $request = new CakeRequest('controller_posts/index');
  864. $TestController = new TestController($request);
  865. $TestController->constructClasses();
  866. $this->assertFalse($TestController->validateErrors());
  867. $this->assertEquals($TestController->validate(), 0);
  868. $TestController->ControllerComment->invalidate('some_field', 'error_message');
  869. $TestController->ControllerComment->invalidate('some_field2', 'error_message2');
  870. $comment = new ControllerComment($request);
  871. $comment->set('someVar', 'data');
  872. $result = $TestController->validateErrors($comment);
  873. $expected = array('some_field' => array('error_message'), 'some_field2' => array('error_message2'));
  874. $this->assertSame($expected, $result);
  875. $this->assertEquals($TestController->validate($comment), 2);
  876. }
  877. /**
  878. * test that validateErrors works with any old model.
  879. *
  880. * @return void
  881. */
  882. public function testValidateErrorsOnArbitraryModels() {
  883. $TestController = new TestController();
  884. $Post = new ControllerPost();
  885. $Post->validate = array('title' => 'notEmpty');
  886. $Post->set('title', '');
  887. $result = $TestController->validateErrors($Post);
  888. $expected = array('title' => array('This field cannot be left blank'));
  889. $this->assertEquals($expected, $result);
  890. }
  891. /**
  892. * testPostConditions method
  893. *
  894. * @return void
  895. */
  896. public function testPostConditions() {
  897. $request = new CakeRequest('controller_posts/index');
  898. $Controller = new Controller($request);
  899. $data = array(
  900. 'Model1' => array('field1' => '23'),
  901. 'Model2' => array('field2' => 'string'),
  902. 'Model3' => array('field3' => '23'),
  903. );
  904. $expected = array(
  905. 'Model1.field1' => '23',
  906. 'Model2.field2' => 'string',
  907. 'Model3.field3' => '23',
  908. );
  909. $result = $Controller->postConditions($data);
  910. $this->assertSame($expected, $result);
  911. $data = array();
  912. $Controller->data = array(
  913. 'Model1' => array('field1' => '23'),
  914. 'Model2' => array('field2' => 'string'),
  915. 'Model3' => array('field3' => '23'),
  916. );
  917. $expected = array(
  918. 'Model1.field1' => '23',
  919. 'Model2.field2' => 'string',
  920. 'Model3.field3' => '23',
  921. );
  922. $result = $Controller->postConditions($data);
  923. $this->assertSame($expected, $result);
  924. $data = array();
  925. $Controller->data = array();
  926. $result = $Controller->postConditions($data);
  927. $this->assertNull($result);
  928. $data = array();
  929. $Controller->data = array(
  930. 'Model1' => array('field1' => '23'),
  931. 'Model2' => array('field2' => 'string'),
  932. 'Model3' => array('field3' => '23'),
  933. );
  934. $ops = array(
  935. 'Model1.field1' => '>',
  936. 'Model2.field2' => 'LIKE',
  937. 'Model3.field3' => '<=',
  938. );
  939. $expected = array(
  940. 'Model1.field1 >' => '23',
  941. 'Model2.field2 LIKE' => "%string%",
  942. 'Model3.field3 <=' => '23',
  943. );
  944. $result = $Controller->postConditions($data, $ops);
  945. $this->assertSame($expected, $result);
  946. }
  947. /**
  948. * testControllerHttpCodes method
  949. *
  950. * @return void
  951. */
  952. public function testControllerHttpCodes() {
  953. $response = $this->getMock('CakeResponse', array('httpCodes'));
  954. $Controller = new Controller(null, $response);
  955. $Controller->response->expects($this->at(0))->method('httpCodes')->with(null);
  956. $Controller->response->expects($this->at(1))->method('httpCodes')->with(100);
  957. $Controller->httpCodes();
  958. $Controller->httpCodes(100);
  959. }
  960. /**
  961. * Tests that the startup process calls the correct functions
  962. *
  963. * @return void
  964. */
  965. public function testStartupProcess() {
  966. $Controller = $this->getMock('Controller', array('getEventManager'));
  967. $eventManager = $this->getMock('CakeEventManager');
  968. $eventManager->expects($this->at(0))->method('dispatch')
  969. ->with(
  970. $this->logicalAnd(
  971. $this->isInstanceOf('CakeEvent'),
  972. $this->attributeEqualTo('_name', 'Controller.initialize'),
  973. $this->attributeEqualTo('_subject', $Controller)
  974. )
  975. );
  976. $eventManager->expects($this->at(1))->method('dispatch')
  977. ->with(
  978. $this->logicalAnd(
  979. $this->isInstanceOf('CakeEvent'),
  980. $this->attributeEqualTo('_name', 'Controller.startup'),
  981. $this->attributeEqualTo('_subject', $Controller)
  982. )
  983. );
  984. $Controller->expects($this->exactly(2))->method('getEventManager')
  985. ->will($this->returnValue($eventManager));
  986. $Controller->startupProcess();
  987. }
  988. /**
  989. * Tests that the shutdown process calls the correct functions
  990. *
  991. * @return void
  992. */
  993. public function testStartupProcessIndirect() {
  994. $Controller = $this->getMock('Controller', array('beforeFilter'));
  995. $Controller->components = array('MockShutdown');
  996. $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
  997. $Controller->expects($this->once())->method('beforeFilter');
  998. $Controller->Components->expects($this->exactly(2))->method('trigger')->with($this->isInstanceOf('CakeEvent'));
  999. $Controller->startupProcess();
  1000. }
  1001. /**
  1002. * Tests that the shutdown process calls the correct functions
  1003. *
  1004. * @return void
  1005. */
  1006. public function testShutdownProcess() {
  1007. $Controller = $this->getMock('Controller', array('getEventManager'));
  1008. $eventManager = $this->getMock('CakeEventManager');
  1009. $eventManager->expects($this->once())->method('dispatch')
  1010. ->with(
  1011. $this->logicalAnd(
  1012. $this->isInstanceOf('CakeEvent'),
  1013. $this->attributeEqualTo('_name', 'Controller.shutdown'),
  1014. $this->attributeEqualTo('_subject', $Controller)
  1015. )
  1016. );
  1017. $Controller->expects($this->once())->method('getEventManager')
  1018. ->will($this->returnValue($eventManager));
  1019. $Controller->shutdownProcess();
  1020. }
  1021. /**
  1022. * Tests that the shutdown process calls the correct functions
  1023. *
  1024. * @return void
  1025. */
  1026. public function testShutdownProcessIndirect() {
  1027. $Controller = $this->getMock('Controller', array('afterFilter'));
  1028. $Controller->components = array('MockShutdown');
  1029. $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
  1030. $Controller->expects($this->once())->method('afterFilter');
  1031. $Controller->Components->expects($this->exactly(1))->method('trigger')->with($this->isInstanceOf('CakeEvent'));
  1032. $Controller->shutdownProcess();
  1033. }
  1034. /**
  1035. * test that BC works for attributes on the request object.
  1036. *
  1037. * @return void
  1038. */
  1039. public function testPropertyBackwardsCompatibility() {
  1040. $request = new CakeRequest('posts/index', null);
  1041. $request->addParams(array('controller' => 'posts', 'action' => 'index'));
  1042. $request->data = array('Post' => array('id' => 1));
  1043. $request->here = '/posts/index';
  1044. $request->webroot = '/';
  1045. $Controller = new TestController($request);
  1046. $this->assertEquals($request->data, $Controller->data);
  1047. $this->assertEquals($request->webroot, $Controller->webroot);
  1048. $this->assertEquals($request->here, $Controller->here);
  1049. $this->assertEquals($request->action, $Controller->action);
  1050. $this->assertFalse(empty($Controller->data));
  1051. $this->assertTrue(isset($Controller->data));
  1052. $this->assertTrue(empty($Controller->something));
  1053. $this->assertFalse(isset($Controller->something));
  1054. $this->assertEquals($request, $Controller->params);
  1055. $this->assertEquals($request->params['controller'], $Controller->params['controller']);
  1056. }
  1057. /**
  1058. * test that the BC wrapper doesn't interfere with models and components.
  1059. *
  1060. * @return void
  1061. */
  1062. public function testPropertyCompatibilityAndModelsComponents() {
  1063. $request = new CakeRequest('controller_posts/index');
  1064. $Controller = new TestController($request);
  1065. $Controller->constructClasses();
  1066. $this->assertInstanceOf('SecurityComponent', $Controller->Security);
  1067. $this->assertInstanceOf('ControllerComment', $Controller->ControllerComment);
  1068. }
  1069. /**
  1070. * test that using Controller::paginate() falls back to PaginatorComponent
  1071. *
  1072. * @return void
  1073. */
  1074. public function testPaginateBackwardsCompatibility() {
  1075. $request = new CakeRequest('controller_posts/index');
  1076. $request->params['pass'] = $request->params['named'] = array();
  1077. $response = $this->getMock('CakeResponse', array('httpCodes'));
  1078. $Controller = new Controller($request, $response);
  1079. $Controller->uses = array('ControllerPost', 'ControllerComment');
  1080. $Controller->passedArgs[] = '1';
  1081. $Controller->params['url'] = array();
  1082. $Controller->constructClasses();
  1083. $expected = array('page' => 1, 'limit' => 20, 'maxLimit' => 100, 'paramType' => 'named');
  1084. $this->assertEquals($Controller->paginate, $expected);
  1085. $results = Set::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id');
  1086. $this->assertEquals($results, array(1, 2, 3));
  1087. $Controller->passedArgs = array();
  1088. $Controller->paginate = array('limit' => '-1');
  1089. $this->assertEquals($Controller->paginate, array('limit' => '-1'));
  1090. $Controller->paginate('ControllerPost');
  1091. $this->assertSame($Controller->params['paging']['ControllerPost']['page'], 1);
  1092. $this->assertSame($Controller->params['paging']['ControllerPost']['pageCount'], 3);
  1093. $this->assertSame($Controller->params['paging']['ControllerPost']['prevPage'], false);
  1094. $this->assertSame($Controller->params['paging']['ControllerPost']['nextPage'], true);
  1095. }
  1096. /**
  1097. * testMissingAction method
  1098. *
  1099. * @expectedException MissingActionException
  1100. * @expectedExceptionMessage Action TestController::missing() could not be found.
  1101. * @return void
  1102. */
  1103. public function testInvokeActionMissingAction() {
  1104. $url = new CakeRequest('test/missing');
  1105. $url->addParams(array('controller' => 'test_controller', 'action' => 'missing'));
  1106. $response = $this->getMock('CakeResponse');
  1107. $Controller = new TestController($url, $response);
  1108. $Controller->invokeAction($url);
  1109. }
  1110. /**
  1111. * test invoking private methods.
  1112. *
  1113. * @expectedException PrivateActionException
  1114. * @expectedExceptionMessage Private Action TestController::private_m() is not directly accessible.
  1115. * @return void
  1116. */
  1117. public function testInvokeActionPrivate() {
  1118. $url = new CakeRequest('test/private_m/');
  1119. $url->addParams(array('controller' => 'test_controller', 'action' => 'private_m'));
  1120. $response = $this->getMock('CakeResponse');
  1121. $Controller = new TestController($url, $response);
  1122. $Controller->invokeAction($url);
  1123. }
  1124. /**
  1125. * test invoking protected methods.
  1126. *
  1127. * @expectedException PrivateActionException
  1128. * @expectedExceptionMessage Private Action TestController::protected_m() is not directly accessible.
  1129. * @return void
  1130. */
  1131. public function testInvokeActionProtected() {
  1132. $url = new CakeRequest('test/protected_m/');
  1133. $url->addParams(array('controller' => 'test_controller', 'action' => 'protected_m'));
  1134. $response = $this->getMock('CakeResponse');
  1135. $Controller = new TestController($url, $response);
  1136. $Controller->invokeAction($url);
  1137. }
  1138. /**
  1139. * test invoking hidden methods.
  1140. *
  1141. * @expectedException PrivateActionException
  1142. * @expectedExceptionMessage Private Action TestController::_hidden() is not directly accessible.
  1143. * @return void
  1144. */
  1145. public function testInvokeActionHidden() {
  1146. $url = new CakeRequest('test/_hidden/');
  1147. $url->addParams(array('controller' => 'test_controller', 'action' => '_hidden'));
  1148. $response = $this->getMock('CakeResponse');
  1149. $Controller = new TestController($url, $response);
  1150. $Controller->invokeAction($url);
  1151. }
  1152. /**
  1153. * test invoking controller methods.
  1154. *
  1155. * @expectedException PrivateActionException
  1156. * @expectedExceptionMessage Private Action TestController::redirect() is not directly accessible.
  1157. * @return void
  1158. */
  1159. public function testInvokeActionBaseMethods() {
  1160. $url = new CakeRequest('test/redirect/');
  1161. $url->addParams(array('controller' => 'test_controller', 'action' => 'redirect'));
  1162. $response = $this->getMock('CakeResponse');
  1163. $Controller = new TestController($url, $response);
  1164. $Controller->invokeAction($url);
  1165. }
  1166. /**
  1167. * test invoking controller methods.
  1168. *
  1169. * @expectedException PrivateActionException
  1170. * @expectedExceptionMessage Private Action TestController::admin_add() is not directly accessible.
  1171. * @return void
  1172. */
  1173. public function testInvokeActionPrefixProtection() {
  1174. Router::reload();
  1175. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  1176. $url = new CakeRequest('test/admin_add/');
  1177. $url->addParams(array('controller' => 'test_controller', 'action' => 'admin_add'));
  1178. $response = $this->getMock('CakeResponse');
  1179. $Controller = new TestController($url, $response);
  1180. $Controller->invokeAction($url);
  1181. }
  1182. /**
  1183. * test invoking controller methods.
  1184. *
  1185. * @return void
  1186. */
  1187. public function testInvokeActionReturnValue() {
  1188. $url = new CakeRequest('test/returner/');
  1189. $url->addParams(array(
  1190. 'controller' => 'test_controller',
  1191. 'action' => 'returner',
  1192. 'pass' => array()
  1193. ));
  1194. $response = $this->getMock('CakeResponse');
  1195. $Controller = new TestController($url, $response);
  1196. $result = $Controller->invokeAction($url);
  1197. $this->assertEquals('I am from the controller.', $result);
  1198. }
  1199. }