PageRenderTime 59ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Cake/Test/Case/Controller/ControllerTest.php

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