ControllerTest.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023
  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 TestApp\Controller\Admin\PostsController;
  31. use TestPlugin\Controller\TestPluginController;
  32. /**
  33. * AppController class
  34. *
  35. */
  36. class ControllerTestAppController extends Controller
  37. {
  38. /**
  39. * helpers property
  40. *
  41. * @var array
  42. */
  43. public $helpers = ['Html'];
  44. /**
  45. * modelClass property
  46. *
  47. * @var string
  48. */
  49. public $modelClass = 'Posts';
  50. /**
  51. * components property
  52. *
  53. * @var array
  54. */
  55. public $components = ['Cookie'];
  56. }
  57. /**
  58. * TestController class
  59. */
  60. class TestController extends ControllerTestAppController
  61. {
  62. /**
  63. * Theme property
  64. *
  65. * @var string
  66. */
  67. public $theme = 'Foo';
  68. /**
  69. * helpers property
  70. *
  71. * @var array
  72. */
  73. public $helpers = ['Html'];
  74. /**
  75. * components property
  76. *
  77. * @var array
  78. */
  79. public $components = ['Security'];
  80. /**
  81. * modelClass property
  82. *
  83. * @var string
  84. */
  85. public $modelClass = 'Comments';
  86. /**
  87. * beforeFilter handler
  88. *
  89. * @param \Cake\Event\Event $event
  90. * @retun void
  91. */
  92. public function beforeFilter(Event $event)
  93. {
  94. }
  95. /**
  96. * index method
  97. *
  98. * @param mixed $testId
  99. * @param mixed $testTwoId
  100. * @return void
  101. */
  102. public function index($testId, $testTwoId)
  103. {
  104. $this->request->data = [
  105. 'testId' => $testId,
  106. 'test2Id' => $testTwoId
  107. ];
  108. }
  109. /**
  110. * view method
  111. *
  112. * @param mixed $testId
  113. * @param mixed $testTwoId
  114. * @return void
  115. */
  116. public function view($testId, $testTwoId)
  117. {
  118. $this->request->data = [
  119. 'testId' => $testId,
  120. 'test2Id' => $testTwoId
  121. ];
  122. }
  123. public function returner()
  124. {
  125. return 'I am from the controller.';
  126. }
  127. //@codingStandardsIgnoreStart
  128. protected function protected_m()
  129. {
  130. }
  131. private function private_m()
  132. {
  133. }
  134. public function _hidden()
  135. {
  136. }
  137. //@codingStandardsIgnoreEnd
  138. public function admin_add()
  139. {
  140. }
  141. }
  142. /**
  143. * TestComponent class
  144. */
  145. class TestComponent extends Component
  146. {
  147. /**
  148. * beforeRedirect method
  149. *
  150. * @return void
  151. */
  152. public function beforeRedirect()
  153. {
  154. }
  155. /**
  156. * initialize method
  157. *
  158. * @param array $config
  159. * @return void
  160. */
  161. public function initialize(array $config)
  162. {
  163. }
  164. /**
  165. * startup method
  166. *
  167. * @param Event $event
  168. * @return void
  169. */
  170. public function startup(Event $event)
  171. {
  172. }
  173. /**
  174. * shutdown method
  175. *
  176. * @param Event $event
  177. * @return void
  178. */
  179. public function shutdown(Event $event)
  180. {
  181. }
  182. /**
  183. * beforeRender callback
  184. *
  185. * @param Event $event
  186. * @return void
  187. */
  188. public function beforeRender(Event $event)
  189. {
  190. $controller = $event->subject();
  191. if ($this->viewclass) {
  192. $controller->viewClass = $this->viewclass;
  193. }
  194. }
  195. }
  196. /**
  197. * AnotherTestController class
  198. *
  199. */
  200. class AnotherTestController extends ControllerTestAppController
  201. {
  202. }
  203. /**
  204. * ControllerTest class
  205. *
  206. */
  207. class ControllerTest extends TestCase
  208. {
  209. /**
  210. * fixtures property
  211. *
  212. * @var array
  213. */
  214. public $fixtures = [
  215. 'core.comments',
  216. 'core.posts'
  217. ];
  218. /**
  219. * reset environment.
  220. *
  221. * @return void
  222. */
  223. public function setUp()
  224. {
  225. parent::setUp();
  226. Configure::write('App.namespace', 'TestApp');
  227. Router::reload();
  228. }
  229. /**
  230. * tearDown
  231. *
  232. * @return void
  233. */
  234. public function tearDown()
  235. {
  236. parent::tearDown();
  237. Plugin::unload();
  238. }
  239. /**
  240. * test autoload modelClass
  241. *
  242. * @return void
  243. */
  244. public function testTableAutoload()
  245. {
  246. $request = new Request('controller_posts/index');
  247. $response = $this->getMock('Cake\Network\Response');
  248. $Controller = new Controller($request, $response);
  249. $Controller->modelClass = 'SiteArticles';
  250. $this->assertFalse($Controller->Articles);
  251. $this->assertInstanceOf(
  252. 'Cake\ORM\Table',
  253. $Controller->SiteArticles
  254. );
  255. unset($Controller->SiteArticles);
  256. $Controller->modelClass = 'Articles';
  257. $this->assertFalse($Controller->SiteArticles);
  258. $this->assertInstanceOf(
  259. 'TestApp\Model\Table\ArticlesTable',
  260. $Controller->Articles
  261. );
  262. }
  263. /**
  264. * testLoadModel method
  265. *
  266. * @return void
  267. */
  268. public function testLoadModel()
  269. {
  270. $request = new Request('controller_posts/index');
  271. $response = $this->getMock('Cake\Network\Response');
  272. $Controller = new Controller($request, $response);
  273. $this->assertFalse(isset($Controller->Articles));
  274. $result = $Controller->loadModel('Articles');
  275. $this->assertInstanceOf(
  276. 'TestApp\Model\Table\ArticlesTable',
  277. $result
  278. );
  279. $this->assertInstanceOf(
  280. 'TestApp\Model\Table\ArticlesTable',
  281. $Controller->Articles
  282. );
  283. }
  284. /**
  285. * testLoadModel method from a plugin controller
  286. *
  287. * @return void
  288. */
  289. public function testLoadModelInPlugins()
  290. {
  291. Plugin::load('TestPlugin');
  292. $Controller = new TestPluginController();
  293. $Controller->plugin = 'TestPlugin';
  294. $this->assertFalse(isset($Controller->TestPluginComments));
  295. $result = $Controller->loadModel('TestPlugin.TestPluginComments');
  296. $this->assertInstanceOf(
  297. 'TestPlugin\Model\Table\TestPluginCommentsTable',
  298. $result
  299. );
  300. $this->assertInstanceOf(
  301. 'TestPlugin\Model\Table\TestPluginCommentsTable',
  302. $Controller->TestPluginComments
  303. );
  304. }
  305. /**
  306. * Test that the constructor sets modelClass properly.
  307. *
  308. * @return void
  309. */
  310. public function testConstructSetModelClass()
  311. {
  312. Plugin::load('TestPlugin');
  313. $request = new Request();
  314. $response = new Response();
  315. $controller = new \TestApp\Controller\PostsController($request, $response);
  316. $this->assertEquals('Posts', $controller->modelClass);
  317. $this->assertInstanceOf('Cake\ORM\Table', $controller->Posts);
  318. $controller = new \TestApp\Controller\Admin\PostsController($request, $response);
  319. $this->assertEquals('Posts', $controller->modelClass);
  320. $this->assertInstanceOf('Cake\ORM\Table', $controller->Posts);
  321. $request->params['plugin'] = 'TestPlugin';
  322. $controller = new \TestPlugin\Controller\Admin\CommentsController($request, $response);
  323. $this->assertEquals('TestPlugin.Comments', $controller->modelClass);
  324. $this->assertInstanceOf('TestPlugin\Model\Table\CommentsTable', $controller->Comments);
  325. }
  326. /**
  327. * testConstructClassesWithComponents method
  328. *
  329. * @return void
  330. */
  331. public function testConstructClassesWithComponents()
  332. {
  333. Plugin::load('TestPlugin');
  334. $Controller = new TestPluginController(new Request(), new Response());
  335. $Controller->loadComponent('TestPlugin.Other');
  336. $this->assertInstanceOf('TestPlugin\Controller\Component\OtherComponent', $Controller->Other);
  337. }
  338. /**
  339. * testRender method
  340. *
  341. * @return void
  342. */
  343. public function testRender()
  344. {
  345. Plugin::load('TestPlugin');
  346. $request = new Request('controller_posts/index');
  347. $request->params['action'] = 'index';
  348. $Controller = new Controller($request, new Response());
  349. $Controller->viewBuilder()->templatePath('Posts');
  350. $result = $Controller->render('index');
  351. $this->assertRegExp('/posts index/', (string)$result);
  352. $Controller->viewBuilder()->template('index');
  353. $result = $Controller->render();
  354. $this->assertRegExp('/posts index/', (string)$result);
  355. $result = $Controller->render('/Element/test_element');
  356. $this->assertRegExp('/this is the test element/', (string)$result);
  357. }
  358. /**
  359. * test that a component beforeRender can change the controller view class.
  360. *
  361. * @return void
  362. */
  363. public function testBeforeRenderCallbackChangingViewClass()
  364. {
  365. $Controller = new Controller(new Request, new Response());
  366. $Controller->eventManager()->on('Controller.beforeRender', function ($event) {
  367. $controller = $event->subject();
  368. $controller->viewClass = 'Json';
  369. });
  370. $Controller->set([
  371. 'test' => 'value',
  372. '_serialize' => ['test']
  373. ]);
  374. $debug = Configure::read('debug');
  375. Configure::write('debug', false);
  376. $result = $Controller->render('index');
  377. $this->assertEquals('{"test":"value"}', $result->body());
  378. Configure::write('debug', $debug);
  379. }
  380. /**
  381. * test that a component beforeRender can change the controller view class.
  382. *
  383. * @return void
  384. */
  385. public function testBeforeRenderEventCancelsRender()
  386. {
  387. $Controller = new Controller(new Request, new Response());
  388. $Controller->eventManager()->attach(function ($event) {
  389. return false;
  390. }, 'Controller.beforeRender');
  391. $result = $Controller->render('index');
  392. $this->assertInstanceOf('Cake\Network\Response', $result);
  393. }
  394. /**
  395. * Generates status codes for redirect test.
  396. *
  397. * @return void
  398. */
  399. public static function statusCodeProvider()
  400. {
  401. return [
  402. [300, "Multiple Choices"],
  403. [301, "Moved Permanently"],
  404. [302, "Found"],
  405. [303, "See Other"],
  406. [304, "Not Modified"],
  407. [305, "Use Proxy"],
  408. [307, "Temporary Redirect"],
  409. [403, "Forbidden"],
  410. ];
  411. }
  412. /**
  413. * testRedirect method
  414. *
  415. * @dataProvider statusCodeProvider
  416. * @return void
  417. */
  418. public function testRedirectByCode($code, $msg)
  419. {
  420. $Controller = new Controller(null, new Response());
  421. $response = $Controller->redirect('http://cakephp.org', (int)$code, false);
  422. $this->assertEquals($code, $response->statusCode());
  423. $this->assertEquals('http://cakephp.org', $response->header()['Location']);
  424. $this->assertFalse($Controller->autoRender);
  425. }
  426. /**
  427. * test that beforeRedirect callbacks can set the URL that is being redirected to.
  428. *
  429. * @return void
  430. */
  431. public function testRedirectBeforeRedirectModifyingUrl()
  432. {
  433. $Controller = new Controller(null, new Response());
  434. $Controller->eventManager()->attach(function ($event, $url, $response) {
  435. $response->location('http://book.cakephp.org');
  436. }, 'Controller.beforeRedirect');
  437. $response = $Controller->redirect('http://cakephp.org', 301);
  438. $this->assertEquals('http://book.cakephp.org', $response->header()['Location']);
  439. $this->assertEquals(301, $response->statusCode());
  440. }
  441. /**
  442. * test that beforeRedirect callback returning null doesn't affect things.
  443. *
  444. * @return void
  445. */
  446. public function testRedirectBeforeRedirectModifyingStatusCode()
  447. {
  448. $Response = $this->getMock('Cake\Network\Response', ['stop']);
  449. $Controller = new Controller(null, $Response);
  450. $Controller->eventManager()->attach(function ($event, $url, $response) {
  451. $response->statusCode(302);
  452. }, 'Controller.beforeRedirect');
  453. $response = $Controller->redirect('http://cakephp.org', 301, false);
  454. $this->assertEquals('http://cakephp.org', $response->header()['Location']);
  455. $this->assertEquals(302, $response->statusCode());
  456. }
  457. /**
  458. * test that beforeRedirect callback returning false in controller
  459. *
  460. * @return void
  461. */
  462. public function testRedirectBeforeRedirectListenerReturnFalse()
  463. {
  464. $Response = $this->getMock('Cake\Network\Response', ['stop', 'header']);
  465. $Controller = new Controller(null, $Response);
  466. $Controller->eventManager()->attach(function ($event, $url, $response) {
  467. return false;
  468. }, 'Controller.beforeRedirect');
  469. $Controller->response->expects($this->never())
  470. ->method('stop');
  471. $Controller->response->expects($this->never())
  472. ->method('header');
  473. $Controller->response->expects($this->never())
  474. ->method('statusCode');
  475. $result = $Controller->redirect('http://cakephp.org');
  476. $this->assertNull($result);
  477. }
  478. /**
  479. * testMergeVars method
  480. *
  481. * @return void
  482. */
  483. public function testMergeVars()
  484. {
  485. $request = new Request();
  486. $TestController = new TestController($request);
  487. $expected = [
  488. 'Html' => null,
  489. ];
  490. $this->assertEquals($expected, $TestController->helpers);
  491. $expected = [
  492. 'Security' => null,
  493. 'Cookie' => null,
  494. ];
  495. $this->assertEquals($expected, $TestController->components);
  496. $TestController = new AnotherTestController($request);
  497. $this->assertEquals(
  498. 'Posts',
  499. $TestController->modelClass,
  500. 'modelClass should not be overwritten when defined.'
  501. );
  502. }
  503. /**
  504. * testReferer method
  505. *
  506. * @return void
  507. */
  508. public function testReferer()
  509. {
  510. $request = $this->getMock('Cake\Network\Request', ['referer']);
  511. $request->expects($this->any())->method('referer')
  512. ->with(true)
  513. ->will($this->returnValue('/posts/index'));
  514. $Controller = new Controller($request);
  515. $result = $Controller->referer(null, true);
  516. $this->assertEquals('/posts/index', $result);
  517. $request = $this->getMock('Cake\Network\Request', ['referer']);
  518. $request->expects($this->any())->method('referer')
  519. ->with(true)
  520. ->will($this->returnValue('/posts/index'));
  521. $Controller = new Controller($request);
  522. $result = $Controller->referer(['controller' => 'posts', 'action' => 'index'], true);
  523. $this->assertEquals('/posts/index', $result);
  524. $request = $this->getMock('Cake\Network\Request', ['referer']);
  525. $request->expects($this->any())->method('referer')
  526. ->with(false)
  527. ->will($this->returnValue('http://localhost/posts/index'));
  528. $Controller = new Controller($request);
  529. $result = $Controller->referer();
  530. $this->assertEquals('http://localhost/posts/index', $result);
  531. $Controller = new Controller(null);
  532. $result = $Controller->referer();
  533. $this->assertEquals('/', $result);
  534. }
  535. /**
  536. * Test that the referer is not absolute if it is '/'.
  537. *
  538. * This avoids the base path being applied twice on string urls.
  539. *
  540. * @return void
  541. */
  542. public function testRefererSlash()
  543. {
  544. $request = $this->getMock('Cake\Network\Request', ['referer']);
  545. $request->base = '/base';
  546. Router::pushRequest($request);
  547. $request->expects($this->any())->method('referer')
  548. ->will($this->returnValue('/'));
  549. $controller = new Controller($request);
  550. $result = $controller->referer('/', true);
  551. $this->assertEquals('/', $result);
  552. $controller = new Controller($request);
  553. $result = $controller->referer('/some/path', true);
  554. $this->assertEquals('/base/some/path', $result);
  555. }
  556. /**
  557. * testSetAction method
  558. *
  559. * @return void
  560. */
  561. public function testSetAction()
  562. {
  563. $request = new Request('controller_posts/index');
  564. $TestController = new TestController($request);
  565. $TestController->setAction('view', 1, 2);
  566. $expected = ['testId' => 1, 'test2Id' => 2];
  567. $this->assertSame($expected, $TestController->request->data);
  568. $this->assertSame('view', $TestController->request->params['action']);
  569. }
  570. /**
  571. * Tests that the startup process calls the correct functions
  572. *
  573. * @return void
  574. */
  575. public function testStartupProcess()
  576. {
  577. $eventManager = $this->getMock('Cake\Event\EventManager');
  578. $controller = new Controller(null, null, null, $eventManager);
  579. $eventManager->expects($this->at(0))->method('dispatch')
  580. ->with(
  581. $this->logicalAnd(
  582. $this->isInstanceOf('Cake\Event\Event'),
  583. $this->attributeEqualTo('_name', 'Controller.initialize'),
  584. $this->attributeEqualTo('_subject', $controller)
  585. )
  586. )
  587. ->will($this->returnValue($this->getMock('Cake\Event\Event', null, [], '', false)));
  588. $eventManager->expects($this->at(1))->method('dispatch')
  589. ->with(
  590. $this->logicalAnd(
  591. $this->isInstanceOf('Cake\Event\Event'),
  592. $this->attributeEqualTo('_name', 'Controller.startup'),
  593. $this->attributeEqualTo('_subject', $controller)
  594. )
  595. )
  596. ->will($this->returnValue($this->getMock('Cake\Event\Event', null, [], '', false)));
  597. $controller->startupProcess();
  598. }
  599. /**
  600. * Tests that the shutdown process calls the correct functions
  601. *
  602. * @return void
  603. */
  604. public function testShutdownProcess()
  605. {
  606. $eventManager = $this->getMock('Cake\Event\EventManager');
  607. $controller = new Controller(null, null, null, $eventManager);
  608. $eventManager->expects($this->once())->method('dispatch')
  609. ->with(
  610. $this->logicalAnd(
  611. $this->isInstanceOf('Cake\Event\Event'),
  612. $this->attributeEqualTo('_name', 'Controller.shutdown'),
  613. $this->attributeEqualTo('_subject', $controller)
  614. )
  615. )
  616. ->will($this->returnValue($this->getMock('Cake\Event\Event', null, [], '', false)));
  617. $controller->shutdownProcess();
  618. }
  619. /**
  620. * test using Controller::paginate()
  621. *
  622. * @return void
  623. */
  624. public function testPaginate()
  625. {
  626. $request = new Request('controller_posts/index');
  627. $request->params['pass'] = [];
  628. $response = $this->getMock('Cake\Network\Response', ['httpCodes']);
  629. $Controller = new Controller($request, $response);
  630. $Controller->request->query['url'] = [];
  631. $this->assertEquals([], $Controller->paginate);
  632. $this->assertNotContains('Paginator', $Controller->helpers);
  633. $this->assertArrayNotHasKey('Paginator', $Controller->helpers);
  634. $results = $Controller->paginate('Posts');
  635. $this->assertInstanceOf('Cake\Datasource\ResultSetInterface', $results);
  636. $results = $Controller->paginate(TableRegistry::get('Posts'));
  637. $this->assertInstanceOf('Cake\Datasource\ResultSetInterface', $results);
  638. $this->assertSame($Controller->request->params['paging']['Posts']['page'], 1);
  639. $this->assertSame($Controller->request->params['paging']['Posts']['pageCount'], 1);
  640. $this->assertSame($Controller->request->params['paging']['Posts']['prevPage'], false);
  641. $this->assertSame($Controller->request->params['paging']['Posts']['nextPage'], false);
  642. }
  643. /**
  644. * test that paginate uses modelClass property.
  645. *
  646. * @return void
  647. */
  648. public function testPaginateUsesModelClass()
  649. {
  650. $request = new Request('controller_posts/index');
  651. $request->params['pass'] = [];
  652. $response = $this->getMock('Cake\Network\Response', ['httpCodes']);
  653. $Controller = new Controller($request, $response);
  654. $Controller->request->query['url'] = [];
  655. $Controller->modelClass = 'Posts';
  656. $results = $Controller->paginate();
  657. $this->assertInstanceOf('Cake\Datasource\ResultSetInterface', $results);
  658. }
  659. /**
  660. * testMissingAction method
  661. *
  662. * @expectedException \Cake\Controller\Exception\MissingActionException
  663. * @expectedExceptionMessage Action TestController::missing() could not be found, or is not accessible.
  664. * @return void
  665. */
  666. public function testInvokeActionMissingAction()
  667. {
  668. $url = new Request('test/missing');
  669. $url->addParams(['controller' => 'Test', 'action' => 'missing']);
  670. $response = $this->getMock('Cake\Network\Response');
  671. $Controller = new TestController($url, $response);
  672. $Controller->invokeAction();
  673. }
  674. /**
  675. * test invoking private methods.
  676. *
  677. * @expectedException \Cake\Controller\Exception\MissingActionException
  678. * @expectedExceptionMessage Action TestController::private_m() could not be found, or is not accessible.
  679. * @return void
  680. */
  681. public function testInvokeActionPrivate()
  682. {
  683. $url = new Request('test/private_m/');
  684. $url->addParams(['controller' => 'Test', 'action' => 'private_m']);
  685. $response = $this->getMock('Cake\Network\Response');
  686. $Controller = new TestController($url, $response);
  687. $Controller->invokeAction();
  688. }
  689. /**
  690. * test invoking protected methods.
  691. *
  692. * @expectedException \Cake\Controller\Exception\MissingActionException
  693. * @expectedExceptionMessage Action TestController::protected_m() could not be found, or is not accessible.
  694. * @return void
  695. */
  696. public function testInvokeActionProtected()
  697. {
  698. $url = new Request('test/protected_m/');
  699. $url->addParams(['controller' => 'Test', 'action' => 'protected_m']);
  700. $response = $this->getMock('Cake\Network\Response');
  701. $Controller = new TestController($url, $response);
  702. $Controller->invokeAction();
  703. }
  704. /**
  705. * test invoking controller methods.
  706. *
  707. * @expectedException \Cake\Controller\Exception\MissingActionException
  708. * @expectedExceptionMessage Action TestController::redirect() could not be found, or is not accessible.
  709. * @return void
  710. */
  711. public function testInvokeActionBaseMethods()
  712. {
  713. $url = new Request('test/redirect/');
  714. $url->addParams(['controller' => 'Test', 'action' => 'redirect']);
  715. $response = $this->getMock('Cake\Network\Response');
  716. $Controller = new TestController($url, $response);
  717. $Controller->invokeAction();
  718. }
  719. /**
  720. * test invoking controller methods.
  721. *
  722. * @return void
  723. */
  724. public function testInvokeActionReturnValue()
  725. {
  726. $url = new Request('test/returner/');
  727. $url->addParams([
  728. 'controller' => 'Test',
  729. 'action' => 'returner',
  730. 'pass' => []
  731. ]);
  732. $response = $this->getMock('Cake\Network\Response');
  733. $Controller = new TestController($url, $response);
  734. $result = $Controller->invokeAction();
  735. $this->assertEquals('I am from the controller.', $result);
  736. }
  737. /**
  738. * test that a classes namespace is used in the viewPath.
  739. *
  740. * @return void
  741. */
  742. public function testViewPathConventions()
  743. {
  744. $request = new Request('admin/posts');
  745. $request->addParams([
  746. 'prefix' => 'admin'
  747. ]);
  748. $response = $this->getMock('Cake\Network\Response');
  749. $Controller = new \TestApp\Controller\Admin\PostsController($request, $response);
  750. $Controller->eventManager()->on('Controller.beforeRender', function (Event $e) {
  751. return $e->subject()->response;
  752. });
  753. $Controller->render();
  754. $this->assertEquals('Admin' . DS . 'Posts', $Controller->viewBuilder()->templatePath());
  755. $request->addParams([
  756. 'prefix' => 'admin/super'
  757. ]);
  758. $response = $this->getMock('Cake\Network\Response');
  759. $Controller = new \TestApp\Controller\Admin\PostsController($request, $response);
  760. $Controller->eventManager()->on('Controller.beforeRender', function (Event $e) {
  761. return $e->subject()->response;
  762. });
  763. $Controller->render();
  764. $this->assertEquals('Admin' . DS . 'Super' . DS . 'Posts', $Controller->viewBuilder()->templatePath());
  765. $request = new Request('pages/home');
  766. $request->addParams([
  767. 'prefix' => false
  768. ]);
  769. $Controller = new \TestApp\Controller\PagesController($request, $response);
  770. $Controller->eventManager()->on('Controller.beforeRender', function (Event $e) {
  771. return $e->subject()->response;
  772. });
  773. $Controller->render();
  774. $this->assertEquals('Pages', $Controller->viewBuilder()->templatePath());
  775. }
  776. /**
  777. * Test the components() method.
  778. *
  779. * @return void
  780. */
  781. public function testComponents()
  782. {
  783. $request = new Request('/');
  784. $response = $this->getMock('Cake\Network\Response');
  785. $controller = new TestController($request, $response);
  786. $this->assertInstanceOf('Cake\Controller\ComponentRegistry', $controller->components());
  787. $result = $controller->components();
  788. $this->assertSame($result, $controller->components());
  789. }
  790. /**
  791. * Test the components() method with the custom ObjectRegistry.
  792. *
  793. * @return void
  794. */
  795. public function testComponentsWithCustomRegistry()
  796. {
  797. $request = new Request('/');
  798. $response = $this->getMock('Cake\Network\Response');
  799. $componentRegistry = $this->getMock('Cake\Controller\ComponentRegistry', ['offsetGet']);
  800. $controller = new TestController($request, $response, null, null, $componentRegistry);
  801. $this->assertInstanceOf(get_class($componentRegistry), $controller->components());
  802. $result = $controller->components();
  803. $this->assertSame($result, $controller->components());
  804. }
  805. /**
  806. * Test adding a component
  807. *
  808. * @return void
  809. */
  810. public function testLoadComponent()
  811. {
  812. $request = new Request('/');
  813. $response = $this->getMock('Cake\Network\Response');
  814. $controller = new TestController($request, $response);
  815. $result = $controller->loadComponent('Paginator');
  816. $this->assertInstanceOf('Cake\Controller\Component\PaginatorComponent', $result);
  817. $this->assertSame($result, $controller->Paginator);
  818. $registry = $controller->components();
  819. $this->assertTrue(isset($registry->Paginator));
  820. }
  821. /**
  822. * Test adding a component that is a duplicate.
  823. *
  824. * @return void
  825. */
  826. public function testLoadComponentDuplicate()
  827. {
  828. $request = new Request('/');
  829. $response = $this->getMock('Cake\Network\Response');
  830. $controller = new TestController($request, $response);
  831. $this->assertNotEmpty($controller->loadComponent('Paginator'));
  832. $this->assertNotEmpty($controller->loadComponent('Paginator'));
  833. try {
  834. $controller->loadComponent('Paginator', ['bad' => 'settings']);
  835. $this->fail('No exception');
  836. } catch (\RuntimeException $e) {
  837. $this->assertContains('The "Paginator" alias has already been loaded', $e->getMessage());
  838. }
  839. }
  840. /**
  841. * Test the isAction method.
  842. *
  843. * @return void
  844. */
  845. public function testIsAction()
  846. {
  847. $request = new Request('/');
  848. $response = $this->getMock('Cake\Network\Response');
  849. $controller = new TestController($request, $response);
  850. $this->assertFalse($controller->isAction('redirect'));
  851. $this->assertFalse($controller->isAction('beforeFilter'));
  852. $this->assertTrue($controller->isAction('index'));
  853. }
  854. /**
  855. * Test declared deprecated properties like $theme are properly passed to view.
  856. *
  857. * @return void
  858. */
  859. public function testDeclaredDeprecatedProperty()
  860. {
  861. $controller = new TestController(new Request(), new Response());
  862. $theme = $controller->theme;
  863. // @codingStandardsIgnoreStart
  864. $this->assertEquals($theme, @$controller->createView()->theme);
  865. // @codingStandardsIgnoreEnd
  866. }
  867. /**
  868. * Test that view variables are being set after the beforeRender event gets dispatched
  869. *
  870. * @return void
  871. */
  872. public function testBeforeRenderViewVariables()
  873. {
  874. $controller = new PostsController();
  875. $controller->eventManager()->on('Controller.beforeRender', function (Event $event) {
  876. /* @var Controller $controller */
  877. $controller = $event->subject();
  878. $controller->set('testVariable', 'test');
  879. });
  880. $controller->render('index');
  881. $this->assertArrayHasKey('testVariable', $controller->View->viewVars);
  882. }
  883. }