ControllerTest.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909
  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 1.2.0
  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\Plugin;
  21. use Cake\Event\Event;
  22. use Cake\Network\Request;
  23. use Cake\Network\Response;
  24. use Cake\ORM\TableRegistry;
  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. * modelClass property
  44. *
  45. * @var string
  46. */
  47. public $modelClass = 'Posts';
  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. * modelClass property
  73. *
  74. * @var string
  75. */
  76. public $modelClass = 'Comments';
  77. /**
  78. * index method
  79. *
  80. * @param mixed $testId
  81. * @param mixed $testTwoId
  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 $testTwoId
  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. * @param Event $event
  132. * @return void
  133. */
  134. public function initialize(Event $event) {
  135. }
  136. /**
  137. * startup method
  138. *
  139. * @param Event $event
  140. * @return void
  141. */
  142. public function startup(Event $event) {
  143. }
  144. /**
  145. * shutdown method
  146. *
  147. * @param Event $event
  148. * @return void
  149. */
  150. public function shutdown(Event $event) {
  151. }
  152. /**
  153. * beforeRender callback
  154. *
  155. * @param Event $event
  156. * @return void
  157. */
  158. public function beforeRender(Event $event) {
  159. $controller = $event->subject();
  160. if ($this->viewclass) {
  161. $controller->viewClass = $this->viewclass;
  162. }
  163. }
  164. }
  165. /**
  166. * AnotherTestController class
  167. *
  168. */
  169. class AnotherTestController extends ControllerTestAppController {
  170. }
  171. /**
  172. * ControllerTest class
  173. *
  174. */
  175. class ControllerTest extends TestCase {
  176. /**
  177. * fixtures property
  178. *
  179. * @var array
  180. */
  181. public $fixtures = array(
  182. 'core.post',
  183. 'core.comment',
  184. 'core.article',
  185. 'core.articles_tag',
  186. 'core.tag'
  187. );
  188. /**
  189. * reset environment.
  190. *
  191. * @return void
  192. */
  193. public function setUp() {
  194. parent::setUp();
  195. Configure::write('App.namespace', 'TestApp');
  196. Router::reload();
  197. }
  198. /**
  199. * tearDown
  200. *
  201. * @return void
  202. */
  203. public function tearDown() {
  204. parent::tearDown();
  205. Plugin::unload();
  206. }
  207. /**
  208. * test autoload modelClass
  209. *
  210. * @return void
  211. */
  212. public function testTableAutoload() {
  213. $request = new Request('controller_posts/index');
  214. $response = $this->getMock('Cake\Network\Response');
  215. $Controller = new Controller($request, $response);
  216. $Controller->modelClass = 'Articles';
  217. $this->assertInstanceOf(
  218. 'TestApp\Model\Table\ArticlesTable',
  219. $Controller->Articles
  220. );
  221. }
  222. /**
  223. * testLoadModel method
  224. *
  225. * @return void
  226. */
  227. public function testLoadModel() {
  228. $request = new Request('controller_posts/index');
  229. $response = $this->getMock('Cake\Network\Response');
  230. $Controller = new Controller($request, $response);
  231. $this->assertFalse(isset($Controller->Articles));
  232. $result = $Controller->loadModel('Articles');
  233. $this->assertTrue($result);
  234. $this->assertInstanceOf(
  235. 'TestApp\Model\Table\ArticlesTable',
  236. $Controller->Articles
  237. );
  238. }
  239. /**
  240. * testLoadModel method from a plugin controller
  241. *
  242. * @return void
  243. */
  244. public function testLoadModelInPlugins() {
  245. Plugin::load('TestPlugin');
  246. $Controller = new TestPluginController();
  247. $Controller->plugin = 'TestPlugin';
  248. $this->assertFalse(isset($Controller->TestPluginComments));
  249. $result = $Controller->loadModel('TestPlugin.TestPluginComments');
  250. $this->assertTrue($result);
  251. $this->assertInstanceOf(
  252. 'TestPlugin\Model\Table\TestPluginCommentsTable',
  253. $Controller->TestPluginComments
  254. );
  255. }
  256. /**
  257. * Test that the constructor sets modelClass properly.
  258. *
  259. * @return void
  260. */
  261. public function testConstructSetModelClass() {
  262. Plugin::load('TestPlugin');
  263. $request = new Request();
  264. $response = new Response();
  265. $controller = new \TestApp\Controller\PostsController($request, $response);
  266. $this->assertEquals('Posts', $controller->modelClass);
  267. $this->assertInstanceOf('Cake\ORM\Table', $controller->Posts);
  268. $controller = new \TestApp\Controller\Admin\PostsController($request, $response);
  269. $this->assertEquals('Posts', $controller->modelClass);
  270. $this->assertInstanceOf('Cake\ORM\Table', $controller->Posts);
  271. $request->params['plugin'] = 'TestPlugin';
  272. $controller = new \TestPlugin\Controller\Admin\CommentsController($request, $response);
  273. $this->assertEquals('TestPlugin.Comments', $controller->modelClass);
  274. $this->assertInstanceOf('TestPlugin\Model\Table\CommentsTable', $controller->Comments);
  275. }
  276. /**
  277. * testConstructClassesWithComponents method
  278. *
  279. * @return void
  280. */
  281. public function testConstructClassesWithComponents() {
  282. Plugin::load('TestPlugin');
  283. $Controller = new TestPluginController(new Request(), new Response());
  284. $Controller->components[] = 'TestPlugin.Other';
  285. $Controller->constructClasses();
  286. $this->assertInstanceOf('TestPlugin\Controller\Component\OtherComponent', $Controller->Other);
  287. }
  288. /**
  289. * testRender method
  290. *
  291. * @return void
  292. */
  293. public function testRender() {
  294. Plugin::load('TestPlugin');
  295. $request = new Request('controller_posts/index');
  296. $request->params['action'] = 'index';
  297. $Controller = new Controller($request, new Response());
  298. $Controller->viewPath = 'Posts';
  299. $result = $Controller->render('index');
  300. $this->assertRegExp('/posts index/', (string)$result);
  301. $Controller->view = 'index';
  302. $result = $Controller->render();
  303. $this->assertRegExp('/posts index/', (string)$result);
  304. $result = $Controller->render('/Element/test_element');
  305. $this->assertRegExp('/this is the test element/', (string)$result);
  306. $Controller->view = null;
  307. }
  308. /**
  309. * test that a component beforeRender can change the controller view class.
  310. *
  311. * @return void
  312. */
  313. public function testBeforeRenderCallbackChangingViewClass() {
  314. $Controller = new Controller(new Request, new Response());
  315. $Controller->eventManager()->attach(function ($event) {
  316. $controller = $event->subject();
  317. $controller->viewClass = 'Json';
  318. }, 'Controller.beforeRender');
  319. $Controller->set([
  320. 'test' => 'value',
  321. '_serialize' => ['test']
  322. ]);
  323. $debug = Configure::read('debug');
  324. Configure::write('debug', false);
  325. $result = $Controller->render('index');
  326. $this->assertEquals('{"test":"value"}', $result->body());
  327. Configure::write('debug', $debug);
  328. }
  329. /**
  330. * test that a component beforeRender can change the controller view class.
  331. *
  332. * @return void
  333. */
  334. public function testBeforeRenderEventCancelsRender() {
  335. $Controller = new Controller(new Request, new Response());
  336. $Controller->eventManager()->attach(function ($event) {
  337. return false;
  338. }, 'Controller.beforeRender');
  339. $result = $Controller->render('index');
  340. $this->assertInstanceOf('Cake\Network\Response', $result);
  341. }
  342. /**
  343. * Generates status codes for redirect test.
  344. *
  345. * @return void
  346. */
  347. public static function statusCodeProvider() {
  348. return array(
  349. array(300, "Multiple Choices"),
  350. array(301, "Moved Permanently"),
  351. array(302, "Found"),
  352. array(303, "See Other"),
  353. array(304, "Not Modified"),
  354. array(305, "Use Proxy"),
  355. array(307, "Temporary Redirect"),
  356. array(403, "Forbidden"),
  357. );
  358. }
  359. /**
  360. * testRedirect method
  361. *
  362. * @dataProvider statusCodeProvider
  363. * @return void
  364. */
  365. public function testRedirectByCode($code, $msg) {
  366. $Controller = new Controller(null);
  367. $Controller->response = new Response();
  368. $response = $Controller->redirect('http://cakephp.org', (int)$code, false);
  369. $this->assertEquals($code, $response->statusCode());
  370. $this->assertEquals('http://cakephp.org', $response->header()['Location']);
  371. $this->assertFalse($Controller->autoRender);
  372. }
  373. /**
  374. * test that beforeRedirect callbacks can set the URL that is being redirected to.
  375. *
  376. * @return void
  377. */
  378. public function testRedirectBeforeRedirectModifyingUrl() {
  379. $Controller = new Controller(null);
  380. $Controller->response = new Response();
  381. $Controller->eventManager()->attach(function ($event, $url, $response) {
  382. $response->location('http://book.cakephp.org');
  383. }, 'Controller.beforeRedirect');
  384. $response = $Controller->redirect('http://cakephp.org', 301);
  385. $this->assertEquals('http://book.cakephp.org', $response->header()['Location']);
  386. $this->assertEquals(301, $response->statusCode());
  387. }
  388. /**
  389. * test that beforeRedirect callback returning null doesn't affect things.
  390. *
  391. * @return void
  392. */
  393. public function testRedirectBeforeRedirectModifyingStatusCode() {
  394. $Response = $this->getMock('Cake\Network\Response', array('stop'));
  395. $Controller = new Controller(null, $Response);
  396. $Controller->eventManager()->attach(function ($event, $url, $response) {
  397. $response->statusCode(302);
  398. }, 'Controller.beforeRedirect');
  399. $response = $Controller->redirect('http://cakephp.org', 301, false);
  400. $this->assertEquals('http://cakephp.org', $response->header()['Location']);
  401. $this->assertEquals(302, $response->statusCode());
  402. }
  403. /**
  404. * test that beforeRedirect callback returning false in controller
  405. *
  406. * @return void
  407. */
  408. public function testRedirectBeforeRedirectListenerReturnFalse() {
  409. $Response = $this->getMock('Cake\Network\Response', array('stop', 'header'));
  410. $Controller = new Controller(null, $Response);
  411. $Controller->eventManager()->attach(function ($event, $url, $response) {
  412. return false;
  413. }, 'Controller.beforeRedirect');
  414. $Controller->response->expects($this->never())
  415. ->method('stop');
  416. $Controller->response->expects($this->never())
  417. ->method('header');
  418. $Controller->response->expects($this->never())
  419. ->method('statusCode');
  420. $result = $Controller->redirect('http://cakephp.org');
  421. $this->assertNull($result);
  422. }
  423. /**
  424. * testMergeVars method
  425. *
  426. * @return void
  427. */
  428. public function testMergeVars() {
  429. $request = new Request();
  430. $TestController = new TestController($request);
  431. $TestController->constructClasses();
  432. $expected = [
  433. 'Html' => null,
  434. 'Session' => null
  435. ];
  436. $this->assertEquals($expected, $TestController->helpers);
  437. $expected = [
  438. 'Security' => null,
  439. 'Cookie' => null,
  440. ];
  441. $this->assertEquals($expected, $TestController->components);
  442. $TestController = new AnotherTestController($request);
  443. $TestController->constructClasses();
  444. $this->assertEquals(
  445. 'Posts',
  446. $TestController->modelClass,
  447. 'modelClass should not be overwritten when defined.'
  448. );
  449. }
  450. /**
  451. * test that options from child classes replace those in the parent classes.
  452. *
  453. * @return void
  454. */
  455. public function testChildComponentOptionsSupercedeParents() {
  456. $request = new Request('controller_posts/index');
  457. $TestController = new TestController($request);
  458. $expected = array('foo');
  459. $TestController->components = array('Cookie' => $expected);
  460. $TestController->constructClasses();
  461. $this->assertEquals($expected, $TestController->components['Cookie']);
  462. }
  463. /**
  464. * Ensure that _mergeControllerVars is not being greedy and merging with
  465. * ControllerTestAppController when you make an instance of Controller
  466. *
  467. * @return void
  468. */
  469. public function testMergeVarsNotGreedy() {
  470. $request = new Request('controller_posts/index');
  471. $Controller = new Controller($request);
  472. $Controller->components = [];
  473. $Controller->constructClasses();
  474. $this->assertFalse(isset($Controller->Session));
  475. }
  476. /**
  477. * testReferer method
  478. *
  479. * @return void
  480. */
  481. public function testReferer() {
  482. $request = $this->getMock('Cake\Network\Request', ['referer']);
  483. $request->expects($this->any())->method('referer')
  484. ->with(true)
  485. ->will($this->returnValue('/posts/index'));
  486. $Controller = new Controller($request);
  487. $result = $Controller->referer(null, true);
  488. $this->assertEquals('/posts/index', $result);
  489. $request = $this->getMock('Cake\Network\Request', ['referer']);
  490. $request->expects($this->any())->method('referer')
  491. ->with(true)
  492. ->will($this->returnValue('/posts/index'));
  493. $Controller = new Controller($request);
  494. $result = $Controller->referer(array('controller' => 'posts', 'action' => 'index'), true);
  495. $this->assertEquals('/posts/index', $result);
  496. $request = $this->getMock('Cake\Network\Request', ['referer']);
  497. $request->expects($this->any())->method('referer')
  498. ->with(false)
  499. ->will($this->returnValue('http://localhost/posts/index'));
  500. $Controller = new Controller($request);
  501. $result = $Controller->referer();
  502. $this->assertEquals('http://localhost/posts/index', $result);
  503. $Controller = new Controller(null);
  504. $result = $Controller->referer();
  505. $this->assertEquals('/', $result);
  506. }
  507. /**
  508. * testSetAction method
  509. *
  510. * @return void
  511. */
  512. public function testSetAction() {
  513. $request = new Request('controller_posts/index');
  514. $TestController = new TestController($request);
  515. $TestController->setAction('view', 1, 2);
  516. $expected = array('testId' => 1, 'test2Id' => 2);
  517. $this->assertSame($expected, $TestController->request->data);
  518. $this->assertSame('view', $TestController->request->params['action']);
  519. $this->assertSame('view', $TestController->view);
  520. }
  521. /**
  522. * Tests that the startup process calls the correct functions
  523. *
  524. * @return void
  525. */
  526. public function testStartupProcess() {
  527. $Controller = $this->getMock('Cake\Controller\Controller', array('eventManager'));
  528. $eventManager = $this->getMock('Cake\Event\EventManager');
  529. $eventManager->expects($this->at(0))->method('dispatch')
  530. ->with(
  531. $this->logicalAnd(
  532. $this->isInstanceOf('Cake\Event\Event'),
  533. $this->attributeEqualTo('_name', 'Controller.initialize'),
  534. $this->attributeEqualTo('_subject', $Controller)
  535. )
  536. )
  537. ->will($this->returnValue($this->getMock('Cake\Event\Event', null, [], '', false)));
  538. $eventManager->expects($this->at(1))->method('dispatch')
  539. ->with(
  540. $this->logicalAnd(
  541. $this->isInstanceOf('Cake\Event\Event'),
  542. $this->attributeEqualTo('_name', 'Controller.startup'),
  543. $this->attributeEqualTo('_subject', $Controller)
  544. )
  545. )
  546. ->will($this->returnValue($this->getMock('Cake\Event\Event', null, [], '', false)));
  547. $Controller->expects($this->exactly(2))->method('eventManager')
  548. ->will($this->returnValue($eventManager));
  549. $Controller->startupProcess();
  550. }
  551. /**
  552. * Tests that the shutdown process calls the correct functions
  553. *
  554. * @return void
  555. */
  556. public function testShutdownProcess() {
  557. $Controller = $this->getMock('Cake\Controller\Controller', array('eventManager'));
  558. $eventManager = $this->getMock('Cake\Event\EventManager');
  559. $eventManager->expects($this->once())->method('dispatch')
  560. ->with(
  561. $this->logicalAnd(
  562. $this->isInstanceOf('Cake\Event\Event'),
  563. $this->attributeEqualTo('_name', 'Controller.shutdown'),
  564. $this->attributeEqualTo('_subject', $Controller)
  565. )
  566. )
  567. ->will($this->returnValue($this->getMock('Cake\Event\Event', null, [], '', false)));
  568. $Controller->expects($this->once())->method('eventManager')
  569. ->will($this->returnValue($eventManager));
  570. $Controller->shutdownProcess();
  571. }
  572. /**
  573. * test using Controller::paginate()
  574. *
  575. * @return void
  576. */
  577. public function testPaginate() {
  578. $request = new Request('controller_posts/index');
  579. $request->params['pass'] = array();
  580. $response = $this->getMock('Cake\Network\Response', ['httpCodes']);
  581. $Controller = new Controller($request, $response);
  582. $Controller->request->query['url'] = [];
  583. $Controller->constructClasses();
  584. $this->assertEquals([], $Controller->paginate);
  585. $this->assertNotContains('Paginator', $Controller->helpers);
  586. $this->assertArrayNotHasKey('Paginator', $Controller->helpers);
  587. $results = $Controller->paginate('Posts');
  588. $this->assertInstanceOf('Cake\ORM\ResultSet', $results);
  589. $this->assertContains('Paginator', $Controller->helpers, 'Paginator should be added.');
  590. $results = $Controller->paginate(TableRegistry::get('Posts'));
  591. $this->assertInstanceOf('Cake\ORM\ResultSet', $results);
  592. $this->assertSame($Controller->request->params['paging']['Posts']['page'], 1);
  593. $this->assertSame($Controller->request->params['paging']['Posts']['pageCount'], 1);
  594. $this->assertSame($Controller->request->params['paging']['Posts']['prevPage'], false);
  595. $this->assertSame($Controller->request->params['paging']['Posts']['nextPage'], false);
  596. }
  597. /**
  598. * test that paginate uses modelClass property.
  599. *
  600. * @return void
  601. */
  602. public function testPaginateUsesModelClass() {
  603. $request = new Request('controller_posts/index');
  604. $request->params['pass'] = array();
  605. $response = $this->getMock('Cake\Network\Response', ['httpCodes']);
  606. $Controller = new Controller($request, $response);
  607. $Controller->request->query['url'] = [];
  608. $Controller->constructClasses();
  609. $Controller->modelClass = 'Posts';
  610. $results = $Controller->paginate();
  611. $this->assertInstanceOf('Cake\ORM\ResultSet', $results);
  612. }
  613. /**
  614. * testMissingAction method
  615. *
  616. * @expectedException \Cake\Controller\Error\MissingActionException
  617. * @expectedExceptionMessage Action TestController::missing() could not be found.
  618. * @return void
  619. */
  620. public function testInvokeActionMissingAction() {
  621. $url = new Request('test/missing');
  622. $url->addParams(array('controller' => 'test_controller', 'action' => 'missing'));
  623. $response = $this->getMock('Cake\Network\Response');
  624. $Controller = new TestController($url, $response);
  625. $Controller->invokeAction();
  626. }
  627. /**
  628. * test invoking private methods.
  629. *
  630. * @expectedException \Cake\Controller\Error\PrivateActionException
  631. * @expectedExceptionMessage Private Action TestController::private_m() is not directly accessible.
  632. * @return void
  633. */
  634. public function testInvokeActionPrivate() {
  635. $url = new Request('test/private_m/');
  636. $url->addParams(array('controller' => 'test_controller', 'action' => 'private_m'));
  637. $response = $this->getMock('Cake\Network\Response');
  638. $Controller = new TestController($url, $response);
  639. $Controller->invokeAction();
  640. }
  641. /**
  642. * test invoking protected methods.
  643. *
  644. * @expectedException \Cake\Controller\Error\PrivateActionException
  645. * @expectedExceptionMessage Private Action TestController::protected_m() is not directly accessible.
  646. * @return void
  647. */
  648. public function testInvokeActionProtected() {
  649. $url = new Request('test/protected_m/');
  650. $url->addParams(array('controller' => 'test_controller', 'action' => 'protected_m'));
  651. $response = $this->getMock('Cake\Network\Response');
  652. $Controller = new TestController($url, $response);
  653. $Controller->invokeAction();
  654. }
  655. /**
  656. * test invoking hidden methods.
  657. *
  658. * @expectedException \Cake\Controller\Error\PrivateActionException
  659. * @expectedExceptionMessage Private Action TestController::_hidden() is not directly accessible.
  660. * @return void
  661. */
  662. public function testInvokeActionHidden() {
  663. $url = new Request('test/_hidden/');
  664. $url->addParams(array('controller' => 'test_controller', 'action' => '_hidden'));
  665. $response = $this->getMock('Cake\Network\Response');
  666. $Controller = new TestController($url, $response);
  667. $Controller->invokeAction();
  668. }
  669. /**
  670. * test invoking controller methods.
  671. *
  672. * @expectedException \Cake\Controller\Error\PrivateActionException
  673. * @expectedExceptionMessage Private Action TestController::redirect() is not directly accessible.
  674. * @return void
  675. */
  676. public function testInvokeActionBaseMethods() {
  677. $url = new Request('test/redirect/');
  678. $url->addParams(array('controller' => 'test_controller', 'action' => 'redirect'));
  679. $response = $this->getMock('Cake\Network\Response');
  680. $Controller = new TestController($url, $response);
  681. $Controller->invokeAction();
  682. }
  683. /**
  684. * test invoking controller methods.
  685. *
  686. * @return void
  687. */
  688. public function testInvokeActionReturnValue() {
  689. $url = new Request('test/returner/');
  690. $url->addParams(array(
  691. 'controller' => 'test_controller',
  692. 'action' => 'returner',
  693. 'pass' => array()
  694. ));
  695. $response = $this->getMock('Cake\Network\Response');
  696. $Controller = new TestController($url, $response);
  697. $result = $Controller->invokeAction();
  698. $this->assertEquals('I am from the controller.', $result);
  699. }
  700. /**
  701. * test that a classes namespace is used in the viewPath.
  702. *
  703. * @return void
  704. */
  705. public function testViewPathConventions() {
  706. $request = new Request('admin/posts');
  707. $request->addParams(array(
  708. 'prefix' => 'admin'
  709. ));
  710. $response = $this->getMock('Cake\Network\Response');
  711. $Controller = new \TestApp\Controller\Admin\PostsController($request, $response);
  712. $this->assertEquals('Admin' . DS . 'Posts', $Controller->viewPath);
  713. $request = new Request('pages/home');
  714. $Controller = new \TestApp\Controller\PagesController($request, $response);
  715. $this->assertEquals('Pages', $Controller->viewPath);
  716. }
  717. /**
  718. * Test the components() method.
  719. *
  720. * @return void
  721. */
  722. public function testComponents() {
  723. $request = new Request('/');
  724. $response = $this->getMock('Cake\Network\Response');
  725. $controller = new TestController($request, $response);
  726. $this->assertInstanceOf('Cake\Controller\ComponentRegistry', $controller->components());
  727. $result = $controller->components();
  728. $this->assertSame($result, $controller->components());
  729. }
  730. /**
  731. * Test adding a component
  732. *
  733. * @return void
  734. */
  735. public function testAddComponent() {
  736. $request = new Request('/');
  737. $response = $this->getMock('Cake\Network\Response');
  738. $controller = new TestController($request, $response);
  739. $result = $controller->addComponent('Paginator');
  740. $this->assertInstanceOf('Cake\Controller\Component\PaginatorComponent', $result);
  741. $this->assertSame($result, $controller->Paginator);
  742. $registry = $controller->components();
  743. $this->assertTrue(isset($registry->Paginator));
  744. }
  745. /**
  746. * Testing that when you paginate, your options persist over to your custom finder.
  747. * Using fixture data, this tests by uses matching() in both places.
  748. * If the Table gets the 'tags' array successfully, it will do a matching().
  749. *
  750. * @return void
  751. */
  752. public function testPaginateSendsFinderOptions() {
  753. $request = new Request('/');
  754. $request->params['pass'] = array();
  755. $response = $this->getMock('Cake\Network\Response');
  756. $testTags = [2, 3];
  757. $Controller = new Controller($request, $response);
  758. $Controller->loadModel('Articles');
  759. $this->assertInstanceOf('Cake\ORM\Table', $Controller->Articles);
  760. $this->assertInstanceOf('Cake\ORM\Association\BelongsToMany', $Controller->Articles->Tags);
  761. $Controller->paginate = [
  762. 'Articles' => [
  763. 'finder' => 'customTags',
  764. 'tags' => $testTags,
  765. 'maxLimit' => 1000
  766. ]
  767. ];
  768. $result = $Controller->paginate('Articles')->count();
  769. $expected = $Controller->Articles->find('all')->contain(['Tags'])->matching('Tags', function($q) use ($testTags) {
  770. return $q->where(['Tags.id IN' => $testTags]);
  771. })->count();
  772. $this->assertEquals($expected, $result);
  773. }
  774. }