ControllerTest.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP Project
  12. * @since CakePHP(tm) v 1.2.0.5436
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Controller;
  16. use Cake\Controller\Component;
  17. use Cake\Controller\Controller;
  18. use Cake\Core\App;
  19. use Cake\Core\Configure;
  20. use Cake\Core\Object;
  21. use Cake\Core\Plugin;
  22. use Cake\Event\Event;
  23. use Cake\Network\Request;
  24. use Cake\Network\Response;
  25. use Cake\Routing\Router;
  26. use Cake\TestSuite\Fixture\TestModel;
  27. use Cake\TestSuite\TestCase;
  28. use Cake\Utility\ClassRegistry;
  29. use Cake\Utility\Hash;
  30. use TestPlugin\Controller\TestPluginController;
  31. /**
  32. * AppController class
  33. *
  34. */
  35. class ControllerTestAppController extends Controller {
  36. /**
  37. * helpers property
  38. *
  39. * @var array
  40. */
  41. public $helpers = array('Html');
  42. /**
  43. * uses property
  44. *
  45. * @var array
  46. */
  47. public $uses = ['Post'];
  48. /**
  49. * components property
  50. *
  51. * @var array
  52. */
  53. public $components = array('Cookie');
  54. }
  55. /**
  56. * TestController class
  57. */
  58. class TestController extends ControllerTestAppController {
  59. /**
  60. * helpers property
  61. *
  62. * @var array
  63. */
  64. public $helpers = array('Session');
  65. /**
  66. * components property
  67. *
  68. * @var array
  69. */
  70. public $components = array('Security');
  71. /**
  72. * uses property
  73. *
  74. * @var array
  75. */
  76. public $uses = array('Comment');
  77. /**
  78. * index method
  79. *
  80. * @param mixed $testId
  81. * @param mixed $test2Id
  82. * @return void
  83. */
  84. public function index($testId, $testTwoId) {
  85. $this->request->data = array(
  86. 'testId' => $testId,
  87. 'test2Id' => $testTwoId
  88. );
  89. }
  90. /**
  91. * view method
  92. *
  93. * @param mixed $testId
  94. * @param mixed $test2Id
  95. * @return void
  96. */
  97. public function view($testId, $testTwoId) {
  98. $this->request->data = array(
  99. 'testId' => $testId,
  100. 'test2Id' => $testTwoId
  101. );
  102. }
  103. public function returner() {
  104. return 'I am from the controller.';
  105. }
  106. //@codingStandardsIgnoreStart
  107. protected function protected_m() {
  108. }
  109. private function private_m() {
  110. }
  111. public function _hidden() {
  112. }
  113. //@codingStandardsIgnoreEnd
  114. public function admin_add() {
  115. }
  116. }
  117. /**
  118. * TestComponent class
  119. */
  120. class TestComponent extends Component {
  121. /**
  122. * beforeRedirect method
  123. *
  124. * @return void
  125. */
  126. public function beforeRedirect() {
  127. }
  128. /**
  129. * initialize method
  130. *
  131. * @return void
  132. */
  133. public function initialize(Event $event) {
  134. }
  135. /**
  136. * startup method
  137. *
  138. * @return void
  139. */
  140. public function startup(Event $event) {
  141. }
  142. /**
  143. * shutdown method
  144. *
  145. * @return void
  146. */
  147. public function shutdown(Event $event) {
  148. }
  149. /**
  150. * beforeRender callback
  151. *
  152. * @return void
  153. */
  154. public function beforeRender(Event $event) {
  155. $controller = $event->subject();
  156. if ($this->viewclass) {
  157. $controller->viewClass = $this->viewclass;
  158. }
  159. }
  160. }
  161. /**
  162. * AnotherTestController class
  163. *
  164. */
  165. class AnotherTestController extends ControllerTestAppController {
  166. }
  167. /**
  168. * ControllerTest class
  169. *
  170. */
  171. class ControllerTest extends TestCase {
  172. /**
  173. * fixtures property
  174. *
  175. * @var array
  176. */
  177. public $fixtures = array(
  178. 'core.post',
  179. 'core.comment'
  180. );
  181. /**
  182. * reset environment.
  183. *
  184. * @return void
  185. */
  186. public function setUp() {
  187. parent::setUp();
  188. App::objects('Plugin', null, false);
  189. Router::reload();
  190. }
  191. /**
  192. * tearDown
  193. *
  194. * @return void
  195. */
  196. public function tearDown() {
  197. parent::tearDown();
  198. Plugin::unload();
  199. }
  200. /**
  201. * testLoadModel method
  202. *
  203. * @return void
  204. */
  205. public function testLoadModel() {
  206. $this->markTestIncomplete('Need to revisit once models work again.');
  207. Configure::write('App.namespace', 'TestApp');
  208. $request = new Request('controller_posts/index');
  209. $response = $this->getMock('Cake\Network\Response');
  210. $Controller = new Controller($request, $response);
  211. $this->assertFalse(isset($Controller->Post));
  212. $result = $Controller->loadModel('Post');
  213. $this->assertTrue($result);
  214. $this->assertInstanceOf('TestApp\Model\Post', $Controller->Post);
  215. $this->assertContains('Post', $Controller->uses);
  216. ClassRegistry::flush();
  217. unset($Controller);
  218. }
  219. /**
  220. * Test loadModel() when uses = true.
  221. *
  222. * @return void
  223. */
  224. public function testLoadModelUsesTrue() {
  225. $this->markTestIncomplete('Need to revisit once models work again.');
  226. Configure::write('App.namespace', 'TestApp');
  227. $request = new Request('controller_posts/index');
  228. $response = $this->getMock('Cake\Network\Response');
  229. $Controller = new Controller($request, $response);
  230. $Controller->uses = true;
  231. $Controller->loadModel('Post');
  232. $this->assertInstanceOf('Post', $Controller->Post);
  233. $this->assertContains('Post', $Controller->uses);
  234. ClassRegistry::flush();
  235. unset($Controller);
  236. }
  237. /**
  238. * testLoadModel method from a plugin controller
  239. *
  240. * @return void
  241. */
  242. public function testLoadModelInPlugins() {
  243. $this->markTestIncomplete('Need to revisit once models work again.');
  244. Configure::write('App.namespace', 'TestApp');
  245. Plugin::load('TestPlugin');
  246. $Controller = new TestPluginController();
  247. $Controller->plugin = 'TestPlugin';
  248. $Controller->uses = false;
  249. $this->assertFalse(isset($Controller->Comment));
  250. $result = $Controller->loadModel('Comment');
  251. $this->assertTrue($result);
  252. $this->assertInstanceOf('TestApp\Model\Comment', $Controller->Comment);
  253. $this->assertTrue(in_array('Comment', $Controller->uses));
  254. ClassRegistry::flush();
  255. unset($Controller);
  256. }
  257. /**
  258. * testConstructClasses method
  259. *
  260. * @return void
  261. */
  262. public function testConstructClasses() {
  263. $this->markTestIncomplete('Need to revisit once models work again.');
  264. Configure::write('App.namespace', 'TestApp');
  265. $request = new Request('controller_posts/index');
  266. $Controller = new Controller($request);
  267. $Controller->uses = ['Post', 'Comment'];
  268. $Controller->constructClasses();
  269. $this->assertInstanceOf('TestApp\Model\Post', $Controller->Post);
  270. $this->assertInstanceOf('TestApp\Model\Comment', $Controller->Comment);
  271. $this->assertEquals('Comment', $Controller->Comment->name);
  272. unset($Controller);
  273. Plugin::load('TestPlugin');
  274. $Controller = new Controller($request);
  275. $Controller->uses = array('TestPlugin.TestPluginPost');
  276. $Controller->constructClasses();
  277. $this->assertTrue(isset($Controller->TestPluginPost));
  278. $this->assertInstanceOf('TestPlugin\Model\TestPluginPost', $Controller->TestPluginPost);
  279. }
  280. /**
  281. * testConstructClassesWithComponents method
  282. *
  283. * @return void
  284. */
  285. public function testConstructClassesWithComponents() {
  286. Configure::write('App.namespace', 'TestApp');
  287. Plugin::load('TestPlugin');
  288. $Controller = new TestPluginController(new Request(), new Response());
  289. $Controller->uses = [];
  290. $Controller->components[] = 'TestPlugin.Other';
  291. $Controller->constructClasses();
  292. $this->assertInstanceOf('TestPlugin\Controller\Component\OtherComponent', $Controller->Other);
  293. }
  294. /**
  295. * testAliasName method
  296. *
  297. * @return void
  298. */
  299. public function testAliasName() {
  300. $this->markTestIncomplete('Need to revisit once models work again.');
  301. $request = new Request('controller_posts/index');
  302. $Controller = new Controller($request);
  303. $Controller->uses = ['NameTest'];
  304. $Controller->constructClasses();
  305. $this->assertEquals('Name', $Controller->NameTest->name);
  306. $this->assertEquals('Name', $Controller->NameTest->alias);
  307. unset($Controller);
  308. }
  309. /**
  310. * testFlash method
  311. *
  312. * @return void
  313. */
  314. public function testFlash() {
  315. $request = new Request('controller_posts/index');
  316. $request->webroot = '/';
  317. $request->base = '/';
  318. $Controller = new Controller($request, $this->getMock('Cake\Network\Response', array('_sendHeader')));
  319. $Controller->flash('this should work', '/flash');
  320. $result = $Controller->response->body();
  321. $expected = '<!DOCTYPE html>
  322. <html>
  323. <head>
  324. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  325. <title>this should work</title>
  326. <style><!--
  327. P { text-align:center; font:bold 1.1em sans-serif }
  328. A { color:#444; text-decoration:none }
  329. A:HOVER { text-decoration: underline; color:#44E }
  330. --></style>
  331. </head>
  332. <body>
  333. <p><a href="/flash">this should work</a></p>
  334. </body>
  335. </html>';
  336. $result = str_replace(array("\t", "\r\n", "\n"), "", $result);
  337. $expected = str_replace(array("\t", "\r\n", "\n"), "", $expected);
  338. $this->assertEquals($expected, $result);
  339. $Controller = new Controller($request);
  340. $Controller->response = $this->getMock('Cake\Network\Response', array('_sendHeader'));
  341. $Controller->flash('this should work', '/flash', 1, 'ajax2');
  342. $result = $Controller->response->body();
  343. $this->assertRegExp('/Ajax!/', $result);
  344. }
  345. /**
  346. * testRender method
  347. *
  348. * @return void
  349. */
  350. public function testRender() {
  351. Configure::write('App.namespace', 'TestApp');
  352. ClassRegistry::flush();
  353. Plugin::load('TestPlugin');
  354. $request = new Request('controller_posts/index');
  355. $request->params['action'] = 'index';
  356. $Controller = new Controller($request, new Response());
  357. $Controller->viewPath = 'Posts';
  358. $result = $Controller->render('index');
  359. $this->assertRegExp('/posts index/', (string)$result);
  360. $Controller->view = 'index';
  361. $result = $Controller->render();
  362. $this->assertRegExp('/posts index/', (string)$result);
  363. $result = $Controller->render('/Element/test_element');
  364. $this->assertRegExp('/this is the test element/', (string)$result);
  365. $Controller->view = null;
  366. $Controller = new TestController($request, new Response());
  367. $Controller->uses = ['TestPlugin.TestPluginComment'];
  368. $Controller->helpers = array('Html');
  369. $Controller->constructClasses();
  370. $expected = ['title' => 'tooShort'];
  371. $Controller->TestPluginComment->validationErrors = $expected;
  372. $Controller->viewPath = 'Posts';
  373. $result = $Controller->render('index');
  374. $View = $Controller->View;
  375. $this->assertTrue(isset($View->validationErrors['TestPluginComment']));
  376. $this->assertEquals($expected, $View->validationErrors['TestPluginComment']);
  377. $expectedModels = [
  378. 'TestPluginComment' => [
  379. 'className' => 'TestPlugin\Model\TestPluginComment'
  380. ],
  381. 'Post' => [
  382. 'className' => 'TestApp\Model\Post'
  383. ]
  384. ];
  385. $this->assertEquals($expectedModels, $Controller->request->params['models']);
  386. }
  387. /**
  388. * test that a component beforeRender can change the controller view class.
  389. *
  390. * @return void
  391. */
  392. public function testBeforeRenderCallbackChangingViewClass() {
  393. Configure::write('App.namespace', 'TestApp');
  394. $Controller = new Controller($this->getMock('Cake\Network\Request'), new Response());
  395. $Controller->getEventManager()->attach(function ($event) {
  396. $controller = $event->subject();
  397. $controller->viewClass = 'Json';
  398. }, 'Controller.beforeRender');
  399. $Controller->set([
  400. 'test' => 'value',
  401. '_serialize' => ['test']
  402. ]);
  403. $debug = Configure::read('debug');
  404. Configure::write('debug', 0);
  405. $result = $Controller->render('index');
  406. $this->assertEquals('{"test":"value"}', $result->body());
  407. Configure::write('debug', $debug);
  408. }
  409. /**
  410. * test that a component beforeRender can change the controller view class.
  411. *
  412. * @return void
  413. */
  414. public function testBeforeRenderEventCancelsRender() {
  415. $Controller = new Controller($this->getMock('Cake\Network\Request'), new Response());
  416. $Controller->getEventManager()->attach(function ($event) {
  417. return false;
  418. }, 'Controller.beforeRender');
  419. $result = $Controller->render('index');
  420. $this->assertInstanceOf('Cake\Network\Response', $result);
  421. }
  422. /**
  423. * testToBeInheritedGuardmethods method
  424. *
  425. * @return void
  426. */
  427. public function testToBeInheritedGuardmethods() {
  428. $request = new Request('controller_posts/index');
  429. $Controller = new Controller($request, $this->getMock('Cake\Network\Response'));
  430. $this->assertTrue($Controller->beforeScaffold(''));
  431. $this->assertTrue($Controller->afterScaffoldSave(''));
  432. $this->assertTrue($Controller->afterScaffoldSaveError(''));
  433. $this->assertFalse($Controller->scaffoldError(''));
  434. }
  435. /**
  436. * Generates status codes for redirect test.
  437. *
  438. * @return void
  439. */
  440. public static function statusCodeProvider() {
  441. return array(
  442. array(300, "Multiple Choices"),
  443. array(301, "Moved Permanently"),
  444. array(302, "Found"),
  445. array(303, "See Other"),
  446. array(304, "Not Modified"),
  447. array(305, "Use Proxy"),
  448. array(307, "Temporary Redirect"),
  449. array(403, "Forbidden"),
  450. );
  451. }
  452. /**
  453. * testRedirect method
  454. *
  455. * @dataProvider statusCodeProvider
  456. * @return void
  457. */
  458. public function testRedirectByCode($code, $msg) {
  459. $Controller = new Controller(null);
  460. $Controller->response = new Response();
  461. $Controller->redirect('http://cakephp.org', (int)$code, false);
  462. $this->assertEquals($code, $Controller->response->statusCode());
  463. $this->assertEquals('http://cakephp.org', $Controller->response->header()['Location']);
  464. $this->assertFalse($Controller->autoRender);
  465. }
  466. /**
  467. * test that beforeRedirect callbacks can set the URL that is being redirected to.
  468. *
  469. * @return void
  470. */
  471. public function testRedirectBeforeRedirectModifyingUrl() {
  472. $Controller = new Controller(null);
  473. $Controller->response = new Response();
  474. $Controller->getEventManager()->attach(function ($event, $response, $url) {
  475. $response->location('http://book.cakephp.org');
  476. }, 'Controller.beforeRedirect');
  477. $Controller->redirect('http://cakephp.org', 301, false);
  478. $this->assertEquals('http://book.cakephp.org', $Controller->response->header()['Location']);
  479. $this->assertEquals(301, $Controller->response->statusCode());
  480. }
  481. /**
  482. * test that beforeRedirect callback returning null doesn't affect things.
  483. *
  484. * @return void
  485. */
  486. public function testRedirectBeforeRedirectModifyingStatusCode() {
  487. $Controller = $this->getMock('Cake\Controller\Controller', array('_stop'));
  488. $Controller->response = new Response();
  489. $Controller->getEventManager()->attach(function ($event, $response, $url) {
  490. $response->statusCode(302);
  491. }, 'Controller.beforeRedirect');
  492. $Controller->redirect('http://cakephp.org', 301, false);
  493. $this->assertEquals('http://cakephp.org', $Controller->response->header()['Location']);
  494. $this->assertEquals(302, $Controller->response->statusCode());
  495. }
  496. /**
  497. * test that beforeRedirect callback returning false in controller
  498. *
  499. * @return void
  500. */
  501. public function testRedirectBeforeRedirectListenerReturnFalse() {
  502. $Controller = $this->getMock('Cake\Controller\Controller', array('_stop'));
  503. $Controller->response = $this->getMock('Cake\Network\Response', array('header'));
  504. $Controller->getEventManager()->attach(function ($event, $response, $url, $status) {
  505. return false;
  506. }, 'Controller.beforeRedirect');
  507. $Controller->response->expects($this->never())
  508. ->method('header');
  509. $Controller->response->expects($this->never())
  510. ->method('statusCode');
  511. $Controller->expects($this->never())->method('_stop');
  512. $Controller->redirect('http://cakephp.org');
  513. }
  514. /**
  515. * testMergeVars method
  516. *
  517. * @return void
  518. */
  519. public function testMergeVars() {
  520. $request = new Request();
  521. $TestController = new TestController($request);
  522. $TestController->constructClasses();
  523. $expected = [
  524. 'Html' => null,
  525. 'Session' => null
  526. ];
  527. $this->assertEquals($expected, $TestController->helpers);
  528. $expected = [
  529. 'Session' => null,
  530. 'Security' => null,
  531. 'Cookie' => null,
  532. ];
  533. $this->assertEquals($expected, $TestController->components);
  534. $expected = array('Comment', 'Post');
  535. $this->assertEquals(
  536. $expected,
  537. $TestController->uses,
  538. '$uses was merged incorrectly, ControllerTestAppController models should be last.'
  539. );
  540. $TestController = new AnotherTestController($request);
  541. $TestController->constructClasses();
  542. $this->assertEquals('AnotherTest', $TestController->modelClass);
  543. $this->assertEquals(
  544. ['AnotherTest', 'Post'],
  545. $TestController->uses,
  546. 'Incorrect uses when controller does not define $uses.'
  547. );
  548. }
  549. /**
  550. * test that options from child classes replace those in the parent classes.
  551. *
  552. * @return void
  553. */
  554. public function testChildComponentOptionsSupercedeParents() {
  555. $request = new Request('controller_posts/index');
  556. $TestController = new TestController($request);
  557. $expected = array('foo');
  558. $TestController->components = array('Cookie' => $expected);
  559. $TestController->constructClasses();
  560. $this->assertEquals($expected, $TestController->components['Cookie']);
  561. }
  562. /**
  563. * Ensure that _mergeControllerVars is not being greedy and merging with
  564. * ControllerTestAppController when you make an instance of Controller
  565. *
  566. * @return void
  567. */
  568. public function testMergeVarsNotGreedy() {
  569. $request = new Request('controller_posts/index');
  570. $Controller = new Controller($request);
  571. $Controller->components = array();
  572. $Controller->uses = array();
  573. $Controller->constructClasses();
  574. $this->assertFalse(isset($Controller->Session));
  575. }
  576. /**
  577. * Ensure that $modelClass is correct even when Controller::$uses
  578. * has been iterated, eg: by a Component, or event handlers.
  579. *
  580. * @return void
  581. */
  582. public function testMergeVarsModelClass() {
  583. $request = new Request();
  584. $Controller = new Controller($request);
  585. $Controller->uses = array('Test', 'TestAlias');
  586. $lastModel = end($Controller->uses);
  587. $Controller->constructClasses();
  588. $this->assertEquals($Controller->uses[0], $Controller->modelClass);
  589. }
  590. /**
  591. * testReferer method
  592. *
  593. * @return void
  594. */
  595. public function testReferer() {
  596. $request = $this->getMock('Cake\Network\Request');
  597. $request->expects($this->any())->method('referer')
  598. ->with(true)
  599. ->will($this->returnValue('/posts/index'));
  600. $Controller = new Controller($request);
  601. $result = $Controller->referer(null, true);
  602. $this->assertEquals('/posts/index', $result);
  603. $Controller = new Controller($request);
  604. $request->setReturnValue('referer', '/', array(true));
  605. $result = $Controller->referer(array('controller' => 'posts', 'action' => 'index'), true);
  606. $this->assertEquals('/posts/index', $result);
  607. $request = $this->getMock('Cake\Network\Request');
  608. $request->expects($this->any())->method('referer')
  609. ->with(false)
  610. ->will($this->returnValue('http://localhost/posts/index'));
  611. $Controller = new Controller($request);
  612. $result = $Controller->referer();
  613. $this->assertEquals('http://localhost/posts/index', $result);
  614. $Controller = new Controller(null);
  615. $result = $Controller->referer();
  616. $this->assertEquals('/', $result);
  617. }
  618. /**
  619. * testSetAction method
  620. *
  621. * @return void
  622. */
  623. public function testSetAction() {
  624. $request = new Request('controller_posts/index');
  625. $TestController = new TestController($request);
  626. $TestController->setAction('view', 1, 2);
  627. $expected = array('testId' => 1, 'test2Id' => 2);
  628. $this->assertSame($expected, $TestController->request->data);
  629. $this->assertSame('view', $TestController->request->params['action']);
  630. $this->assertSame('view', $TestController->view);
  631. }
  632. /**
  633. * testValidateErrors method
  634. *
  635. * @return void
  636. */
  637. public function testValidateErrors() {
  638. ClassRegistry::flush();
  639. $request = new Request('controller_posts/index');
  640. $TestController = new TestController($request);
  641. $TestController->constructClasses();
  642. $this->assertFalse($TestController->validateErrors());
  643. $this->assertEquals(0, $TestController->validate());
  644. $TestController->Comment->invalidate('some_field', 'error_message');
  645. $TestController->Comment->invalidate('some_field2', 'error_message2');
  646. $comment = new \TestApp\Model\Comment($request);
  647. $comment->set('someVar', 'data');
  648. $result = $TestController->validateErrors($comment);
  649. $expected = array('some_field' => array('error_message'), 'some_field2' => array('error_message2'));
  650. $this->assertSame($expected, $result);
  651. $this->assertEquals(2, $TestController->validate($comment));
  652. }
  653. /**
  654. * test that validateErrors works with any old model.
  655. *
  656. * @return void
  657. */
  658. public function testValidateErrorsOnArbitraryModels() {
  659. Configure::write('Config.language', 'eng');
  660. $TestController = new TestController();
  661. $Post = new \TestApp\Model\Post();
  662. $Post->validate = array('title' => 'notEmpty');
  663. $Post->set('title', '');
  664. $result = $TestController->validateErrors($Post);
  665. $expected = array('title' => array('The provided value is invalid'));
  666. $this->assertEquals($expected, $result);
  667. }
  668. /**
  669. * Tests that the startup process calls the correct functions
  670. *
  671. * @return void
  672. */
  673. public function testStartupProcess() {
  674. $Controller = $this->getMock('Cake\Controller\Controller', array('getEventManager'));
  675. $eventManager = $this->getMock('Cake\Event\EventManager');
  676. $eventManager->expects($this->at(0))->method('dispatch')
  677. ->with(
  678. $this->logicalAnd(
  679. $this->isInstanceOf('Cake\Event\Event'),
  680. $this->attributeEqualTo('_name', 'Controller.initialize'),
  681. $this->attributeEqualTo('_subject', $Controller)
  682. )
  683. );
  684. $eventManager->expects($this->at(1))->method('dispatch')
  685. ->with(
  686. $this->logicalAnd(
  687. $this->isInstanceOf('Cake\Event\Event'),
  688. $this->attributeEqualTo('_name', 'Controller.startup'),
  689. $this->attributeEqualTo('_subject', $Controller)
  690. )
  691. );
  692. $Controller->expects($this->exactly(2))->method('getEventManager')
  693. ->will($this->returnValue($eventManager));
  694. $Controller->startupProcess();
  695. }
  696. /**
  697. * Tests that the shutdown process calls the correct functions
  698. *
  699. * @return void
  700. */
  701. public function testShutdownProcess() {
  702. $Controller = $this->getMock('Cake\Controller\Controller', array('getEventManager'));
  703. $eventManager = $this->getMock('Cake\Event\EventManager');
  704. $eventManager->expects($this->once())->method('dispatch')
  705. ->with(
  706. $this->logicalAnd(
  707. $this->isInstanceOf('Cake\Event\Event'),
  708. $this->attributeEqualTo('_name', 'Controller.shutdown'),
  709. $this->attributeEqualTo('_subject', $Controller)
  710. )
  711. );
  712. $Controller->expects($this->once())->method('getEventManager')
  713. ->will($this->returnValue($eventManager));
  714. $Controller->shutdownProcess();
  715. }
  716. /**
  717. * test that using Controller::paginate() falls back to PaginatorComponent
  718. *
  719. * @return void
  720. */
  721. public function testPaginateBackwardsCompatibility() {
  722. $this->markTestIncomplete('Need to revisit once models work again.');
  723. $request = new Request('controller_posts/index');
  724. $request->params['pass'] = array();
  725. $response = $this->getMock('Cake\Network\Response', ['httpCodes']);
  726. $Controller = new Controller($request, $response);
  727. $Controller->uses = ['Post', 'Comment'];
  728. $Controller->passedArgs[] = '1';
  729. $Controller->request->query['url'] = [];
  730. $Controller->constructClasses();
  731. $expected = ['page' => 1, 'limit' => 20, 'maxLimit' => 100];
  732. $this->assertEquals($expected, $Controller->paginate);
  733. $results = Hash::extract($Controller->paginate('Post'), '{n}.Post.id');
  734. $this->assertEquals([1, 2, 3], $results);
  735. $Controller->paginate = array('limit' => '1');
  736. $this->assertEquals(array('limit' => '1'), $Controller->paginate);
  737. $Controller->paginate('Post');
  738. $this->assertSame($Controller->request->params['paging']['Post']['page'], 1);
  739. $this->assertSame($Controller->request->params['paging']['Post']['pageCount'], 3);
  740. $this->assertSame($Controller->request->params['paging']['Post']['prevPage'], false);
  741. $this->assertSame($Controller->request->params['paging']['Post']['nextPage'], true);
  742. }
  743. /**
  744. * testMissingAction method
  745. *
  746. * @expectedException Cake\Error\MissingActionException
  747. * @expectedExceptionMessage Action TestController::missing() could not be found.
  748. * @return void
  749. */
  750. public function testInvokeActionMissingAction() {
  751. $url = new Request('test/missing');
  752. $url->addParams(array('controller' => 'test_controller', 'action' => 'missing'));
  753. $response = $this->getMock('Cake\Network\Response');
  754. $Controller = new TestController($url, $response);
  755. $Controller->invokeAction($url);
  756. }
  757. /**
  758. * test invoking private methods.
  759. *
  760. * @expectedException Cake\Error\PrivateActionException
  761. * @expectedExceptionMessage Private Action TestController::private_m() is not directly accessible.
  762. * @return void
  763. */
  764. public function testInvokeActionPrivate() {
  765. $url = new Request('test/private_m/');
  766. $url->addParams(array('controller' => 'test_controller', 'action' => 'private_m'));
  767. $response = $this->getMock('Cake\Network\Response');
  768. $Controller = new TestController($url, $response);
  769. $Controller->invokeAction($url);
  770. }
  771. /**
  772. * test invoking protected methods.
  773. *
  774. * @expectedException Cake\Error\PrivateActionException
  775. * @expectedExceptionMessage Private Action TestController::protected_m() is not directly accessible.
  776. * @return void
  777. */
  778. public function testInvokeActionProtected() {
  779. $url = new Request('test/protected_m/');
  780. $url->addParams(array('controller' => 'test_controller', 'action' => 'protected_m'));
  781. $response = $this->getMock('Cake\Network\Response');
  782. $Controller = new TestController($url, $response);
  783. $Controller->invokeAction($url);
  784. }
  785. /**
  786. * test invoking hidden methods.
  787. *
  788. * @expectedException Cake\Error\PrivateActionException
  789. * @expectedExceptionMessage Private Action TestController::_hidden() is not directly accessible.
  790. * @return void
  791. */
  792. public function testInvokeActionHidden() {
  793. $url = new Request('test/_hidden/');
  794. $url->addParams(array('controller' => 'test_controller', 'action' => '_hidden'));
  795. $response = $this->getMock('Cake\Network\Response');
  796. $Controller = new TestController($url, $response);
  797. $Controller->invokeAction($url);
  798. }
  799. /**
  800. * test invoking controller methods.
  801. *
  802. * @expectedException Cake\Error\PrivateActionException
  803. * @expectedExceptionMessage Private Action TestController::redirect() is not directly accessible.
  804. * @return void
  805. */
  806. public function testInvokeActionBaseMethods() {
  807. $url = new Request('test/redirect/');
  808. $url->addParams(array('controller' => 'test_controller', 'action' => 'redirect'));
  809. $response = $this->getMock('Cake\Network\Response');
  810. $Controller = new TestController($url, $response);
  811. $Controller->invokeAction($url);
  812. }
  813. /**
  814. * test invoking controller methods.
  815. *
  816. * @expectedException Cake\Error\PrivateActionException
  817. * @expectedExceptionMessage Private Action TestController::admin_add() is not directly accessible.
  818. * @return void
  819. */
  820. public function testInvokeActionPrefixProtection() {
  821. Router::reload();
  822. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  823. $url = new Request('test/admin_add/');
  824. $url->addParams(array('controller' => 'test_controller', 'action' => 'admin_add'));
  825. $response = $this->getMock('Cake\Network\Response');
  826. $Controller = new TestController($url, $response);
  827. $Controller->invokeAction($url);
  828. }
  829. /**
  830. * test invoking controller methods.
  831. *
  832. * @return void
  833. */
  834. public function testInvokeActionReturnValue() {
  835. $url = new Request('test/returner/');
  836. $url->addParams(array(
  837. 'controller' => 'test_controller',
  838. 'action' => 'returner',
  839. 'pass' => array()
  840. ));
  841. $response = $this->getMock('Cake\Network\Response');
  842. $Controller = new TestController($url, $response);
  843. $result = $Controller->invokeAction($url);
  844. $this->assertEquals('I am from the controller.', $result);
  845. }
  846. /**
  847. * test that a classes namespace is used in the viewPath.
  848. *
  849. * @return void
  850. */
  851. public function testViewPathConventions() {
  852. $request = new Request('admin/posts');
  853. $request->addParams(array(
  854. 'prefix' => 'admin'
  855. ));
  856. $response = $this->getMock('Cake\Network\Response');
  857. $Controller = new \TestApp\Controller\Admin\PostsController($request, $response);
  858. $this->assertEquals('Admin/Posts', $Controller->viewPath);
  859. $request = new Request('pages/home');
  860. $Controller = new \TestApp\Controller\PagesController($request, $response);
  861. $this->assertEquals('Pages', $Controller->viewPath);
  862. }
  863. }