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

https://bitbucket.org/udeshika/fake_twitter · PHP · 1338 lines · 676 code · 214 blank · 448 comment · 4 complexity · 65ceeee5d1fdad84f5b1443073566c48 MD5 · raw file

  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. public function returner() {
  242. return 'I am from the controller.';
  243. }
  244. protected function protected_m() {
  245. }
  246. private function private_m() {
  247. }
  248. public function _hidden() {
  249. }
  250. public function admin_add() {
  251. }
  252. }
  253. /**
  254. * TestComponent class
  255. *
  256. * @package Cake.Test.Case.Controller
  257. */
  258. class TestComponent extends Object {
  259. /**
  260. * beforeRedirect method
  261. *
  262. * @return void
  263. */
  264. public function beforeRedirect() {
  265. }
  266. /**
  267. * initialize method
  268. *
  269. * @return void
  270. */
  271. public function initialize(&$controller) {
  272. }
  273. /**
  274. * startup method
  275. *
  276. * @return void
  277. */
  278. public function startup(&$controller) {
  279. }
  280. /**
  281. * shutdown method
  282. *
  283. * @return void
  284. */
  285. public function shutdown(&$controller) {
  286. }
  287. /**
  288. * beforeRender callback
  289. *
  290. * @return void
  291. */
  292. public function beforeRender(&$controller) {
  293. if ($this->viewclass) {
  294. $controller->viewClass = $this->viewclass;
  295. }
  296. }
  297. }
  298. /**
  299. * AnotherTestController class
  300. *
  301. * @package Cake.Test.Case.Controller
  302. */
  303. class AnotherTestController extends ControllerTestAppController {
  304. /**
  305. * name property
  306. * @var string 'Name'
  307. */
  308. public $name = 'AnotherTest';
  309. /**
  310. * uses property
  311. *
  312. * @var array
  313. */
  314. public $uses = null;
  315. /**
  316. * merge parent
  317. *
  318. * @var string
  319. */
  320. protected $_mergeParent = 'ControllerTestAppController';
  321. }
  322. /**
  323. * ControllerTest class
  324. *
  325. * @package Cake.Test.Case.Controller
  326. */
  327. class ControllerTest extends CakeTestCase {
  328. /**
  329. * fixtures property
  330. *
  331. * @var array
  332. */
  333. public $fixtures = array('core.post', 'core.comment', 'core.name');
  334. /**
  335. * reset environment.
  336. *
  337. * @return void
  338. */
  339. public function setUp() {
  340. parent::setUp();
  341. App::objects('plugin', null, false);
  342. App::build();
  343. Router::reload();
  344. }
  345. /**
  346. * tearDown
  347. *
  348. * @return void
  349. */
  350. public function tearDown() {
  351. CakePlugin::unload();
  352. App::build();
  353. parent::tearDown();
  354. }
  355. /**
  356. * testLoadModel method
  357. *
  358. * @return void
  359. */
  360. public function testLoadModel() {
  361. $request = new CakeRequest('controller_posts/index');
  362. $response = $this->getMock('CakeResponse');
  363. $Controller = new Controller($request, $response);
  364. $this->assertFalse(isset($Controller->ControllerPost));
  365. $result = $Controller->loadModel('ControllerPost');
  366. $this->assertTrue($result);
  367. $this->assertTrue(is_a($Controller->ControllerPost, 'ControllerPost'));
  368. $this->assertTrue(in_array('ControllerPost', $Controller->uses));
  369. ClassRegistry::flush();
  370. unset($Controller);
  371. }
  372. /**
  373. * testLoadModel method from a plugin controller
  374. *
  375. * @return void
  376. */
  377. public function testLoadModelInPlugins() {
  378. App::build(array(
  379. 'plugins' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
  380. 'Controller' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Controller' . DS),
  381. 'Model' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS)
  382. ));
  383. CakePlugin::load('TestPlugin');
  384. App::uses('TestPluginAppController', 'TestPlugin.Controller');
  385. App::uses('TestPluginController', 'TestPlugin.Controller');
  386. $Controller = new TestPluginController();
  387. $Controller->plugin = 'TestPlugin';
  388. $Controller->uses = false;
  389. $this->assertFalse(isset($Controller->Comment));
  390. $result = $Controller->loadModel('Comment');
  391. $this->assertTrue($result);
  392. $this->assertInstanceOf('Comment', $Controller->Comment);
  393. $this->assertTrue(in_array('Comment', $Controller->uses));
  394. ClassRegistry::flush();
  395. unset($Controller);
  396. }
  397. /**
  398. * testConstructClasses method
  399. *
  400. * @return void
  401. */
  402. public function testConstructClasses() {
  403. $request = new CakeRequest('controller_posts/index');
  404. $Controller = new Controller($request);
  405. $Controller = new Controller($request);
  406. $Controller->uses = array('ControllerPost', 'ControllerComment');
  407. $Controller->constructClasses();
  408. $this->assertTrue(is_a($Controller->ControllerPost, 'ControllerPost'));
  409. $this->assertTrue(is_a($Controller->ControllerComment, 'ControllerComment'));
  410. $this->assertEquals($Controller->ControllerComment->name, 'Comment');
  411. unset($Controller);
  412. App::build(array('plugins' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)));
  413. CakePlugin::load('TestPlugin');
  414. $Controller = new Controller($request);
  415. $Controller->uses = array('TestPlugin.TestPluginPost');
  416. $Controller->constructClasses();
  417. $this->assertTrue(isset($Controller->TestPluginPost));
  418. $this->assertTrue(is_a($Controller->TestPluginPost, 'TestPluginPost'));
  419. unset($Controller);
  420. }
  421. /**
  422. * testAliasName method
  423. *
  424. * @return void
  425. */
  426. public function testAliasName() {
  427. $request = new CakeRequest('controller_posts/index');
  428. $Controller = new Controller($request);
  429. $Controller->uses = array('NameTest');
  430. $Controller->constructClasses();
  431. $this->assertEquals($Controller->NameTest->name, 'Name');
  432. $this->assertEquals($Controller->NameTest->alias, 'Name');
  433. unset($Controller);
  434. }
  435. /**
  436. * testFlash method
  437. *
  438. * @return void
  439. */
  440. public function testFlash() {
  441. $request = new CakeRequest('controller_posts/index');
  442. $request->webroot = '/';
  443. $request->base = '/';
  444. $Controller = new Controller($request, $this->getMock('CakeResponse', array('_sendHeader')));
  445. $Controller->flash('this should work', '/flash');
  446. $result = $Controller->response->body();
  447. $expected = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  448. <html xmlns="http://www.w3.org/1999/xhtml">
  449. <head>
  450. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  451. <title>this should work</title>
  452. <style><!--
  453. P { text-align:center; font:bold 1.1em sans-serif }
  454. A { color:#444; text-decoration:none }
  455. A:HOVER { text-decoration: underline; color:#44E }
  456. --></style>
  457. </head>
  458. <body>
  459. <p><a href="/flash">this should work</a></p>
  460. </body>
  461. </html>';
  462. $result = str_replace(array("\t", "\r\n", "\n"), "", $result);
  463. $expected = str_replace(array("\t", "\r\n", "\n"), "", $expected);
  464. $this->assertEquals($expected, $result);
  465. App::build(array(
  466. 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View'. DS)
  467. ));
  468. $Controller = new Controller($request);
  469. $Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
  470. $Controller->flash('this should work', '/flash', 1, 'ajax2');
  471. $result = $Controller->response->body();
  472. $this->assertRegExp('/Ajax!/', $result);
  473. App::build();
  474. }
  475. /**
  476. * testControllerSet method
  477. *
  478. * @return void
  479. */
  480. public function testControllerSet() {
  481. $request = new CakeRequest('controller_posts/index');
  482. $Controller = new Controller($request);
  483. $Controller->set('variable_with_underscores', null);
  484. $this->assertTrue(array_key_exists('variable_with_underscores', $Controller->viewVars));
  485. $Controller->viewVars = array();
  486. $viewVars = array('ModelName' => array('id' => 1, 'name' => 'value'));
  487. $Controller->set($viewVars);
  488. $this->assertTrue(array_key_exists('ModelName', $Controller->viewVars));
  489. $Controller->viewVars = array();
  490. $Controller->set('variable_with_underscores', 'value');
  491. $this->assertTrue(array_key_exists('variable_with_underscores', $Controller->viewVars));
  492. $Controller->viewVars = array();
  493. $viewVars = array('ModelName' => 'name');
  494. $Controller->set($viewVars);
  495. $this->assertTrue(array_key_exists('ModelName', $Controller->viewVars));
  496. $Controller->set('title', 'someTitle');
  497. $this->assertSame($Controller->viewVars['title'], 'someTitle');
  498. $this->assertTrue(empty($Controller->pageTitle));
  499. $Controller->viewVars = array();
  500. $expected = array('ModelName' => 'name', 'ModelName2' => 'name2');
  501. $Controller->set(array('ModelName', 'ModelName2'), array('name', 'name2'));
  502. $this->assertSame($Controller->viewVars, $expected);
  503. $Controller->viewVars = array();
  504. $Controller->set(array(3 => 'three', 4 => 'four'));
  505. $Controller->set(array(1 => 'one', 2 => 'two'));
  506. $expected = array(3 => 'three', 4 => 'four', 1 => 'one', 2 => 'two');
  507. $this->assertEquals($Controller->viewVars, $expected);
  508. }
  509. /**
  510. * testRender method
  511. *
  512. * @return void
  513. */
  514. public function testRender() {
  515. App::build(array(
  516. 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View'. DS)
  517. ), true);
  518. ClassRegistry::flush();
  519. $request = new CakeRequest('controller_posts/index');
  520. $request->params['action'] = 'index';
  521. $Controller = new Controller($request, new CakeResponse());
  522. $Controller->viewPath = 'Posts';
  523. $result = $Controller->render('index');
  524. $this->assertRegExp('/posts index/', (string)$result);
  525. $Controller->view = 'index';
  526. $result = $Controller->render();
  527. $this->assertRegExp('/posts index/', (string)$result);
  528. $result = $Controller->render('/Elements/test_element');
  529. $this->assertRegExp('/this is the test element/', (string)$result);
  530. $Controller->view = null;
  531. $Controller = new TestController($request, new CakeResponse());
  532. $Controller->uses = array('ControllerAlias', 'TestPlugin.ControllerComment', 'ControllerPost');
  533. $Controller->helpers = array('Html');
  534. $Controller->constructClasses();
  535. $Controller->ControllerComment->validationErrors = array('title' => 'tooShort');
  536. $expected = $Controller->ControllerComment->validationErrors;
  537. $Controller->viewPath = 'Posts';
  538. $result = $Controller->render('index');
  539. $View = $Controller->View;
  540. $this->assertTrue(isset($View->validationErrors['ControllerComment']));
  541. $this->assertEquals($expected, $View->validationErrors['ControllerComment']);
  542. $expectedModels = array(
  543. 'ControllerAlias' => array('plugin' => null, 'className' => 'ControllerAlias'),
  544. 'ControllerComment' => array('plugin' => 'TestPlugin', 'className' => 'ControllerComment'),
  545. 'ControllerPost' => array('plugin' => null, 'className' => 'ControllerPost')
  546. );
  547. $this->assertEquals($expectedModels, $Controller->request->params['models']);
  548. ClassRegistry::flush();
  549. App::build();
  550. }
  551. /**
  552. * test that a component beforeRender can change the controller view class.
  553. *
  554. * @return void
  555. */
  556. public function testComponentBeforeRenderChangingViewClass() {
  557. App::build(array(
  558. 'View' => array(
  559. CAKE . 'Test' . DS . 'test_app' . DS . 'View'. DS
  560. )
  561. ), true);
  562. $Controller = new Controller($this->getMock('CakeRequest'), new CakeResponse());
  563. $Controller->uses = array();
  564. $Controller->components = array('Test');
  565. $Controller->constructClasses();
  566. $Controller->Test->viewclass = 'Theme';
  567. $Controller->viewPath = 'Posts';
  568. $Controller->theme = 'TestTheme';
  569. $result = $Controller->render('index');
  570. $this->assertRegExp('/default test_theme layout/', (string)$result);
  571. App::build();
  572. }
  573. /**
  574. * testToBeInheritedGuardmethods method
  575. *
  576. * @return void
  577. */
  578. public function testToBeInheritedGuardmethods() {
  579. $request = new CakeRequest('controller_posts/index');
  580. $Controller = new Controller($request, $this->getMock('CakeResponse'));
  581. $this->assertTrue($Controller->beforeScaffold(''));
  582. $this->assertTrue($Controller->afterScaffoldSave(''));
  583. $this->assertTrue($Controller->afterScaffoldSaveError(''));
  584. $this->assertFalse($Controller->scaffoldError(''));
  585. }
  586. /**
  587. * Generates status codes for redirect test.
  588. *
  589. * @return void
  590. */
  591. public static function statusCodeProvider() {
  592. return array(
  593. array(300, "Multiple Choices"),
  594. array(301, "Moved Permanently"),
  595. array(302, "Found"),
  596. array(303, "See Other"),
  597. array(304, "Not Modified"),
  598. array(305, "Use Proxy"),
  599. array(307, "Temporary Redirect")
  600. );
  601. }
  602. /**
  603. * testRedirect method
  604. *
  605. * @dataProvider statusCodeProvider
  606. * @return void
  607. */
  608. public function testRedirectByCode($code, $msg) {
  609. $Controller = new Controller(null);
  610. $Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
  611. $Controller->Components = $this->getMock('ComponentCollection');
  612. $Controller->response->expects($this->once())->method('statusCode')
  613. ->with($code);
  614. $Controller->response->expects($this->once())->method('header')
  615. ->with('Location', 'http://cakephp.org');
  616. $Controller->redirect('http://cakephp.org', (int)$code, false);
  617. $this->assertFalse($Controller->autoRender);
  618. }
  619. /**
  620. * test redirecting by message
  621. *
  622. * @dataProvider statusCodeProvider
  623. * @return void
  624. */
  625. public function testRedirectByMessage($code, $msg) {
  626. $Controller = new Controller(null);
  627. $Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
  628. $Controller->Components = $this->getMock('ComponentCollection');
  629. $Controller->response->expects($this->once())->method('statusCode')
  630. ->with($code);
  631. $Controller->response->expects($this->once())->method('header')
  632. ->with('Location', 'http://cakephp.org');
  633. $Controller->redirect('http://cakephp.org', $msg, false);
  634. $this->assertFalse($Controller->autoRender);
  635. }
  636. /**
  637. * test that redirect triggers methods on the components.
  638. *
  639. * @return void
  640. */
  641. public function testRedirectTriggeringComponentsReturnNull() {
  642. $Controller = new Controller(null);
  643. $Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
  644. $Controller->Components = $this->getMock('ComponentCollection');
  645. $Controller->Components->expects($this->once())->method('trigger')
  646. ->will($this->returnValue(null));
  647. $Controller->response->expects($this->once())->method('statusCode')
  648. ->with(301);
  649. $Controller->response->expects($this->once())->method('header')
  650. ->with('Location', 'http://cakephp.org');
  651. $Controller->redirect('http://cakephp.org', 301, false);
  652. }
  653. /**
  654. * test that beforeRedirect callback returnning null doesn't affect things.
  655. *
  656. * @return void
  657. */
  658. public function testRedirectBeforeRedirectModifyingParams() {
  659. $Controller = new Controller(null);
  660. $Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
  661. $Controller->Components = $this->getMock('ComponentCollection');
  662. $Controller->Components->expects($this->once())->method('trigger')
  663. ->will($this->returnValue(array('http://book.cakephp.org')));
  664. $Controller->response->expects($this->once())->method('statusCode')
  665. ->with(301);
  666. $Controller->response->expects($this->once())->method('header')
  667. ->with('Location', 'http://book.cakephp.org');
  668. $Controller->redirect('http://cakephp.org', 301, false);
  669. }
  670. /**
  671. * test that beforeRedirect callback returnning null doesn't affect things.
  672. *
  673. * @return void
  674. */
  675. public function testRedirectBeforeRedirectModifyingParamsArrayReturn() {
  676. $Controller = $this->getMock('Controller', array('header', '_stop'));
  677. $Controller->response = $this->getMock('CakeResponse');
  678. $Controller->Components = $this->getMock('ComponentCollection');
  679. $return = array(
  680. array(
  681. 'url' => 'http://example.com/test/1',
  682. 'exit' => false,
  683. 'status' => 302
  684. ),
  685. array(
  686. 'url' => 'http://example.com/test/2',
  687. ),
  688. );
  689. $Controller->Components->expects($this->once())->method('trigger')
  690. ->will($this->returnValue($return));
  691. $Controller->response->expects($this->at(0))->method('header')
  692. ->with('Location', 'http://example.com/test/2');
  693. $Controller->response->expects($this->at(1))->method('statusCode')
  694. ->with(302);
  695. $Controller->expects($this->never())->method('_stop');
  696. $Controller->redirect('http://cakephp.org', 301);
  697. }
  698. /**
  699. * test that beforeRedirect callback returnning false in controller
  700. *
  701. * @return void
  702. */
  703. public function testRedirectBeforeRedirectInController() {
  704. $Controller = $this->getMock('Controller', array('_stop', 'beforeRedirect'));
  705. $Controller->response = $this->getMock('CakeResponse', array('header'));
  706. $Controller->Components = $this->getMock('ComponentCollection');
  707. $Controller->expects($this->once())->method('beforeRedirect')
  708. ->will($this->returnValue(false));
  709. $Controller->response->expects($this->never())->method('header');
  710. $Controller->expects($this->never())->method('_stop');
  711. $Controller->redirect('http://cakephp.org');
  712. }
  713. /**
  714. * testMergeVars method
  715. *
  716. * @return void
  717. */
  718. public function testMergeVars() {
  719. $request = new CakeRequest('controller_posts/index');
  720. $TestController = new TestController($request);
  721. $TestController->constructClasses();
  722. $testVars = get_class_vars('TestController');
  723. $appVars = get_class_vars('ControllerTestAppController');
  724. $components = is_array($appVars['components'])
  725. ? array_merge($appVars['components'], $testVars['components'])
  726. : $testVars['components'];
  727. if (!in_array('Session', $components)) {
  728. $components[] = 'Session';
  729. }
  730. $helpers = is_array($appVars['helpers'])
  731. ? array_merge($appVars['helpers'], $testVars['helpers'])
  732. : $testVars['helpers'];
  733. $uses = is_array($appVars['uses'])
  734. ? array_merge($appVars['uses'], $testVars['uses'])
  735. : $testVars['uses'];
  736. $this->assertEquals(count(array_diff_key($TestController->helpers, array_flip($helpers))), 0);
  737. $this->assertEquals(count(array_diff($TestController->uses, $uses)), 0);
  738. $this->assertEquals(count(array_diff_assoc(Set::normalize($TestController->components), Set::normalize($components))), 0);
  739. $expected = array('ControllerComment', 'ControllerAlias', 'ControllerPost');
  740. $this->assertEquals($expected, $TestController->uses, '$uses was merged incorrectly, ControllerTestAppController models should be last.');
  741. $TestController = new AnotherTestController($request);
  742. $TestController->constructClasses();
  743. $appVars = get_class_vars('ControllerTestAppController');
  744. $testVars = get_class_vars('AnotherTestController');
  745. $this->assertTrue(in_array('ControllerPost', $appVars['uses']));
  746. $this->assertNull($testVars['uses']);
  747. $this->assertFalse(property_exists($TestController, 'ControllerPost'));
  748. $TestController = new ControllerCommentsController($request);
  749. $TestController->constructClasses();
  750. $appVars = get_class_vars('ControllerTestAppController');
  751. $testVars = get_class_vars('ControllerCommentsController');
  752. $this->assertTrue(in_array('ControllerPost', $appVars['uses']));
  753. $this->assertEquals(array('ControllerPost'), $testVars['uses']);
  754. $this->assertTrue(isset($TestController->ControllerPost));
  755. $this->assertTrue(isset($TestController->ControllerComment));
  756. }
  757. /**
  758. * test that options from child classes replace those in the parent classes.
  759. *
  760. * @return void
  761. */
  762. public function testChildComponentOptionsSupercedeParents() {
  763. $request = new CakeRequest('controller_posts/index');
  764. $TestController = new TestController($request);
  765. $expected = array('foo');
  766. $TestController->components = array('Cookie' => $expected);
  767. $TestController->constructClasses();
  768. $this->assertEquals($TestController->components['Cookie'], $expected);
  769. }
  770. /**
  771. * Ensure that _mergeControllerVars is not being greedy and merging with
  772. * ControllerTestAppController when you make an instance of Controller
  773. *
  774. * @return void
  775. */
  776. public function testMergeVarsNotGreedy() {
  777. $request = new CakeRequest('controller_posts/index');
  778. $Controller = new Controller($request);
  779. $Controller->components = array();
  780. $Controller->uses = array();
  781. $Controller->constructClasses();
  782. $this->assertFalse(isset($Controller->Session));
  783. }
  784. /**
  785. * testReferer method
  786. *
  787. * @return void
  788. */
  789. public function testReferer() {
  790. $request = $this->getMock('CakeRequest');
  791. $request->expects($this->any())->method('referer')
  792. ->with(true)
  793. ->will($this->returnValue('/posts/index'));
  794. $Controller = new Controller($request);
  795. $result = $Controller->referer(null, true);
  796. $this->assertEquals($result, '/posts/index');
  797. $Controller = new Controller($request);
  798. $request->setReturnValue('referer', '/', array(true));
  799. $result = $Controller->referer(array('controller' => 'posts', 'action' => 'index'), true);
  800. $this->assertEquals($result, '/posts/index');
  801. $request = $this->getMock('CakeRequest');
  802. $request->expects($this->any())->method('referer')
  803. ->with(false)
  804. ->will($this->returnValue('http://localhost/posts/index'));
  805. $Controller = new Controller($request);
  806. $result = $Controller->referer();
  807. $this->assertEquals($result, 'http://localhost/posts/index');
  808. $Controller = new Controller(null);
  809. $result = $Controller->referer();
  810. $this->assertEquals($result, '/');
  811. }
  812. /**
  813. * testSetAction method
  814. *
  815. * @return void
  816. */
  817. public function testSetAction() {
  818. $request = new CakeRequest('controller_posts/index');
  819. $TestController = new TestController($request);
  820. $TestController->setAction('index', 1, 2);
  821. $expected = array('testId' => 1, 'test2Id' => 2);
  822. $this->assertSame($expected, $TestController->request->data);
  823. $this->assertSame('index', $TestController->view);
  824. }
  825. /**
  826. * testValidateErrors method
  827. *
  828. * @return void
  829. */
  830. public function testValidateErrors() {
  831. ClassRegistry::flush();
  832. $request = new CakeRequest('controller_posts/index');
  833. $TestController = new TestController($request);
  834. $TestController->constructClasses();
  835. $this->assertFalse($TestController->validateErrors());
  836. $this->assertEquals($TestController->validate(), 0);
  837. $TestController->ControllerComment->invalidate('some_field', 'error_message');
  838. $TestController->ControllerComment->invalidate('some_field2', 'error_message2');
  839. $comment = new ControllerComment($request);
  840. $comment->set('someVar', 'data');
  841. $result = $TestController->validateErrors($comment);
  842. $expected = array('some_field' => array('error_message'), 'some_field2' => array('error_message2'));
  843. $this->assertSame($expected, $result);
  844. $this->assertEquals($TestController->validate($comment), 2);
  845. }
  846. /**
  847. * test that validateErrors works with any old model.
  848. *
  849. * @return void
  850. */
  851. public function testValidateErrorsOnArbitraryModels() {
  852. $TestController = new TestController();
  853. $Post = new ControllerPost();
  854. $Post->validate = array('title' => 'notEmpty');
  855. $Post->set('title', '');
  856. $result = $TestController->validateErrors($Post);
  857. $expected = array('title' => array('This field cannot be left blank'));
  858. $this->assertEquals($expected, $result);
  859. }
  860. /**
  861. * testPostConditions method
  862. *
  863. * @return void
  864. */
  865. public function testPostConditions() {
  866. $request = new CakeRequest('controller_posts/index');
  867. $Controller = new Controller($request);
  868. $data = array(
  869. 'Model1' => array('field1' => '23'),
  870. 'Model2' => array('field2' => 'string'),
  871. 'Model3' => array('field3' => '23'),
  872. );
  873. $expected = array(
  874. 'Model1.field1' => '23',
  875. 'Model2.field2' => 'string',
  876. 'Model3.field3' => '23',
  877. );
  878. $result = $Controller->postConditions($data);
  879. $this->assertSame($expected, $result);
  880. $data = array();
  881. $Controller->data = array(
  882. 'Model1' => array('field1' => '23'),
  883. 'Model2' => array('field2' => 'string'),
  884. 'Model3' => array('field3' => '23'),
  885. );
  886. $expected = array(
  887. 'Model1.field1' => '23',
  888. 'Model2.field2' => 'string',
  889. 'Model3.field3' => '23',
  890. );
  891. $result = $Controller->postConditions($data);
  892. $this->assertSame($expected, $result);
  893. $data = array();
  894. $Controller->data = array();
  895. $result = $Controller->postConditions($data);
  896. $this->assertNull($result);
  897. $data = array();
  898. $Controller->data = array(
  899. 'Model1' => array('field1' => '23'),
  900. 'Model2' => array('field2' => 'string'),
  901. 'Model3' => array('field3' => '23'),
  902. );
  903. $ops = array(
  904. 'Model1.field1' => '>',
  905. 'Model2.field2' => 'LIKE',
  906. 'Model3.field3' => '<=',
  907. );
  908. $expected = array(
  909. 'Model1.field1 >' => '23',
  910. 'Model2.field2 LIKE' => "%string%",
  911. 'Model3.field3 <=' => '23',
  912. );
  913. $result = $Controller->postConditions($data, $ops);
  914. $this->assertSame($expected, $result);
  915. }
  916. /**
  917. * testControllerHttpCodes method
  918. *
  919. * @return void
  920. */
  921. public function testControllerHttpCodes() {
  922. $response = $this->getMock('CakeResponse', array('httpCodes'));
  923. $Controller = new Controller(null, $response);
  924. $Controller->response->expects($this->at(0))->method('httpCodes')->with(null);
  925. $Controller->response->expects($this->at(1))->method('httpCodes')->with(100);
  926. $Controller->httpCodes();
  927. $Controller->httpCodes(100);
  928. }
  929. /**
  930. * Tests that the startup process calls the correct functions
  931. *
  932. * @return void
  933. */
  934. public function testStartupProcess() {
  935. $Controller = $this->getMock('Controller', array('beforeFilter', 'afterFilter'));
  936. $Controller->components = array('MockStartup');
  937. $Controller->Components = $this->getMock('ComponentCollection');
  938. $Controller->expects($this->once())->method('beforeFilter');
  939. $Controller->Components->expects($this->at(0))->method('trigger')
  940. ->with('initialize', array(&$Controller));
  941. $Controller->Components->expects($this->at(1))->method('trigger')
  942. ->with('startup', array(&$Controller));
  943. $Controller->startupProcess();
  944. }
  945. /**
  946. * Tests that the shutdown process calls the correct functions
  947. *
  948. * @return void
  949. */
  950. public function testShutdownProcess() {
  951. $Controller = $this->getMock('Controller', array('beforeFilter', 'afterFilter'));
  952. $Controller->components = array('MockShutdown');
  953. $Controller->Components = $this->getMock('ComponentCollection');
  954. $Controller->expects($this->once())->method('afterFilter');
  955. $Controller->Components->expects($this->once())->method('trigger')
  956. ->with('shutdown', array(&$Controller));
  957. $Controller->shutdownProcess();
  958. }
  959. /**
  960. * test that BC works for attributes on the request object.
  961. *
  962. * @return void
  963. */
  964. public function testPropertyBackwardsCompatibility() {
  965. $request = new CakeRequest('posts/index', null);
  966. $request->addParams(array('controller' => 'posts', 'action' => 'index'));
  967. $request->data = array('Post' => array('id' => 1));
  968. $request->here = '/posts/index';
  969. $request->webroot = '/';
  970. $Controller = new TestController($request);
  971. $this->assertEquals($request->data, $Controller->data);
  972. $this->assertEquals($request->webroot, $Controller->webroot);
  973. $this->assertEquals($request->here, $Controller->here);
  974. $this->assertEquals($request->action, $Controller->action);
  975. $this->assertFalse(empty($Controller->data));
  976. $this->assertTrue(isset($Controller->data));
  977. $this->assertTrue(empty($Controller->something));
  978. $this->assertFalse(isset($Controller->something));
  979. $this->assertEquals($request, $Controller->params);
  980. $this->assertEquals($request->params['controller'], $Controller->params['controller']);
  981. }
  982. /**
  983. * test that the BC wrapper doesn't interfere with models and components.
  984. *
  985. * @return void
  986. */
  987. public function testPropertyCompatibilityAndModelsComponents() {
  988. $request = new CakeRequest('controller_posts/index');
  989. $Controller = new TestController($request);
  990. $Controller->constructClasses();
  991. $this->assertInstanceOf('SecurityComponent', $Controller->Security);
  992. $this->assertInstanceOf('ControllerComment', $Controller->ControllerComment);
  993. }
  994. /**
  995. * test that using Controller::paginate() falls back to PaginatorComponent
  996. *
  997. * @return void
  998. */
  999. public function testPaginateBackwardsCompatibility() {
  1000. $request = new CakeRequest('controller_posts/index');
  1001. $request->params['pass'] = $request->params['named'] = array();
  1002. $response = $this->getMock('CakeResponse', array('httpCodes'));
  1003. $Controller = new Controller($request, $response);
  1004. $Controller->uses = array('ControllerPost', 'ControllerComment');
  1005. $Controller->passedArgs[] = '1';
  1006. $Controller->params['url'] = array();
  1007. $Controller->constructClasses();
  1008. $expected = array('page' => 1, 'limit' => 20, 'maxLimit' => 100, 'paramType' => 'named');
  1009. $this->assertEquals($Controller->paginate, $expected);
  1010. $results = Set::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id');
  1011. $this->assertEquals($results, array(1, 2, 3));
  1012. $Controller->passedArgs = array();
  1013. $Controller->paginate = array('limit' => '-1');
  1014. $this->assertEquals($Controller->paginate, array('limit' => '-1'));
  1015. $Controller->paginate('ControllerPost');
  1016. $this->assertSame($Controller->params['paging']['ControllerPost']['page'], 1);
  1017. $this->assertSame($Controller->params['paging']['ControllerPost']['pageCount'], 3);
  1018. $this->assertSame($Controller->params['paging']['ControllerPost']['prevPage'], false);
  1019. $this->assertSame($Controller->params['paging']['ControllerPost']['nextPage'], true);
  1020. }
  1021. /**
  1022. * testMissingAction method
  1023. *
  1024. * @expectedException MissingActionException
  1025. * @expectedExceptionMessage Action TestController::missing() could not be found.
  1026. * @return void
  1027. */
  1028. public function testInvokeActionMissingAction() {
  1029. $url = new CakeRequest('test/missing');
  1030. $url->addParams(array('controller' => 'test_controller', 'action' => 'missing'));
  1031. $response = $this->getMock('CakeResponse');
  1032. $Controller = new TestController($url, $response);
  1033. $Controller->invokeAction($url);
  1034. }
  1035. /**
  1036. * test invoking private methods.
  1037. *
  1038. * @expectedException PrivateActionException
  1039. * @expectedExceptionMessage Private Action TestController::private_m() is not directly accessible.
  1040. * @return void
  1041. */
  1042. public function testInvokeActionPrivate() {
  1043. $url = new CakeRequest('test/private_m/');
  1044. $url->addParams(array('controller' => 'test_controller', 'action' => 'private_m'));
  1045. $response = $this->getMock('CakeResponse');
  1046. $Controller = new TestController($url, $response);
  1047. $Controller->invokeAction($url);
  1048. }
  1049. /**
  1050. * test invoking protected methods.
  1051. *
  1052. * @expectedException PrivateActionException
  1053. * @expectedExceptionMessage Private Action TestController::protected_m() is not directly accessible.
  1054. * @return void
  1055. */
  1056. public function testInvokeActionProtected() {
  1057. $url = new CakeRequest('test/protected_m/');
  1058. $url->addParams(array('controller' => 'test_controller', 'action' => 'protected_m'));
  1059. $response = $this->getMock('CakeResponse');
  1060. $Controller = new TestController($url, $response);
  1061. $Controller->invokeAction($url);
  1062. }
  1063. /**
  1064. * test invoking hidden methods.
  1065. *
  1066. * @expectedException PrivateActionException
  1067. * @expectedExceptionMessage Private Action TestController::_hidden() is not directly accessible.
  1068. * @return void
  1069. */
  1070. public function testInvokeActionHidden() {
  1071. $url = new CakeRequest('test/_hidden/');
  1072. $url->addParams(array('controller' => 'test_controller', 'action' => '_hidden'));
  1073. $response = $this->getMock('CakeResponse');
  1074. $Controller = new TestController($url, $response);
  1075. $Controller->invokeAction($url);
  1076. }
  1077. /**
  1078. * test invoking controller methods.
  1079. *
  1080. * @expectedException PrivateActionException
  1081. * @expectedExceptionMessage Private Action TestController::redirect() is not directly accessible.
  1082. * @return void
  1083. */
  1084. public function testInvokeActionBaseMethods() {
  1085. $url = new CakeRequest('test/redirect/');
  1086. $url->addParams(array('controller' => 'test_controller', 'action' => 'redirect'));
  1087. $response = $this->getMock('CakeResponse');
  1088. $Controller = new TestController($url, $response);
  1089. $Controller->invokeAction($url);
  1090. }
  1091. /**
  1092. * test invoking controller methods.
  1093. *
  1094. * @expectedException PrivateActionException
  1095. * @expectedExceptionMessage Private Action TestController::admin_add() is not directly accessible.
  1096. * @return void
  1097. */
  1098. public function testInvokeActionPrefixProtection() {
  1099. Router::reload();
  1100. Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
  1101. $url = new CakeRequest('test/admin_add/');
  1102. $url->addParams(array('controller' => 'test_controller', 'action' => 'admin_add'));
  1103. $response = $this->getMock('CakeResponse');
  1104. $Controller = new TestController($url, $response);
  1105. $Controller->invokeAction($url);
  1106. }
  1107. /**
  1108. * test invoking controller methods.
  1109. *
  1110. * @return void
  1111. */
  1112. public function testInvokeActionReturnValue() {
  1113. $url = new CakeRequest('test/returner/');
  1114. $url->addParams(array(
  1115. 'controller' => 'test_controller',
  1116. 'action' => 'returner',
  1117. 'pass' => array()
  1118. ));
  1119. $response = $this->getMock('CakeResponse');
  1120. $Controller = new TestController($url, $response);
  1121. $result = $Controller->invokeAction($url);
  1122. $this->assertEquals('I am from the controller.', $result);
  1123. }
  1124. }