From b9143dc7d451d6307aebbf1a74dbaf60248204dd Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Tue, 14 Dec 2010 19:58:27 -0800 Subject: [PATCH] Added ControllerTestCase class for testing controllers. Fixes #1244 --- cake/libs/controller/controller.php | 4 +- cake/libs/dispatcher.php | 16 +- cake/libs/object_collection.php | 14 + cake/libs/router.php | 8 +- cake/tests/cases/libs/all_test_suite.test.php | 1 + .../cases/libs/controller_test_case.test.php | 407 ++++++++++++++++++ .../cases/libs/object_collection.test.php | 20 + cake/tests/lib/controller_test_case.php | 312 ++++++++++++++ cake/tests/lib/test_manager.php | 1 + cake/tests/test_app/config/routes.php | 26 ++ .../controllers/tests_apps_controller.php | 4 + .../test_app/views/layouts/json/default.ctp | 1 + .../test_app/views/tests_apps/json/index.ctp | 1 + 13 files changed, 809 insertions(+), 6 deletions(-) create mode 100644 cake/tests/cases/libs/controller_test_case.test.php create mode 100644 cake/tests/lib/controller_test_case.php create mode 100644 cake/tests/test_app/config/routes.php create mode 100644 cake/tests/test_app/views/layouts/json/default.ctp create mode 100644 cake/tests/test_app/views/tests_apps/json/index.ctp diff --git a/cake/libs/controller/controller.php b/cake/libs/controller/controller.php index 9afc3e315..724fa93aa 100644 --- a/cake/libs/controller/controller.php +++ b/cake/libs/controller/controller.php @@ -301,7 +301,7 @@ class Controller extends Object { $this->methods = array_diff($childMethods, $parentMethods); if ($request instanceof CakeRequest) { - $this->_setRequest($request); + $this->setRequest($request); } $this->getResponse(); parent::__construct(); @@ -377,7 +377,7 @@ class Controller extends Object { * @param CakeRequest $request * @return void */ - protected function _setRequest(CakeRequest $request) { + public function setRequest(CakeRequest $request) { $this->request = $request; $this->plugin = isset($request->params['plugin']) ? $request->params['plugin'] : null; diff --git a/cake/libs/dispatcher.php b/cake/libs/dispatcher.php index 4f35138c8..0b498b5b2 100644 --- a/cake/libs/dispatcher.php +++ b/cake/libs/dispatcher.php @@ -99,8 +99,8 @@ class Dispatcher { return; } - $request = $this->parseParams($request, $additionalParams); - $controller = $this->_getController($request); + $this->request = $this->parseParams($request, $additionalParams); + $controller = $this->_getController($this->request); if (!is_object($controller)) { Router::setRequestInfo($request); @@ -198,7 +198,7 @@ class Dispatcher { if (count(Router::$routes) > 0) { $namedExpressions = Router::getNamedExpressions(); extract($namedExpressions); - include CONFIGS . 'routes.php'; + $this->__loadRoutes(); } $params = Router::parse($request->url); @@ -250,6 +250,16 @@ class Dispatcher { return false; } +/** + * Loads route configuration + * + * @return void + * @access protected + */ + protected function __loadRoutes() { + include CONFIGS . 'routes.php'; + } + /** * Outputs cached dispatch view cache * diff --git a/cake/libs/object_collection.php b/cake/libs/object_collection.php index d91f62cc9..a9750f3e8 100644 --- a/cake/libs/object_collection.php +++ b/cake/libs/object_collection.php @@ -221,6 +221,20 @@ abstract class ObjectCollection { $this->_enabled = array_values(array_diff($this->_enabled, (array)$name)); } +/** + * Adds or overwrites an instatiated object to the collection + * + * @param string $name Name of the object + * @param Object $object The object to use + */ + public function set($name = null, $object = null) { + if (!empty($name) && !empty($object)) { + list($plugin, $name) = pluginSplit($name); + $this->_loaded[$name] = $object; + } + return $this->_loaded; + } + /** * Normalizes an object array, creates an array that makes lazy loading * easier diff --git a/cake/libs/router.php b/cake/libs/router.php index 91261c6ce..a4408b92f 100644 --- a/cake/libs/router.php +++ b/cake/libs/router.php @@ -250,6 +250,9 @@ class Router { throw new RouterException(__('Route classes must extend CakeRoute')); } unset($options['routeClass']); + if ($routeClass == 'RedirectRoute' && isset($defaults['redirect'])) { + $defaults = $defaults['redirect']; + } } self::$routes[] = new $routeClass($route, $defaults, $options); return self::$routes; @@ -284,9 +287,12 @@ class Router { * @see routes * @return array Array of routes */ - public static function redirect($route, $url, $options) { + public static function redirect($route, $url, $options = array()) { App::import('Core', 'route/RedirectRoute'); $options['routeClass'] = 'RedirectRoute'; + if (is_string($url)) { + $url = array('redirect' => $url); + } return self::connect($route, $url, $options); } diff --git a/cake/tests/cases/libs/all_test_suite.test.php b/cake/tests/cases/libs/all_test_suite.test.php index 9c6a46e6a..f1d52c2dc 100644 --- a/cake/tests/cases/libs/all_test_suite.test.php +++ b/cake/tests/cases/libs/all_test_suite.test.php @@ -40,6 +40,7 @@ class AllTestSuiteTest extends PHPUnit_Framework_TestSuite { $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'cake_test_case.test.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'cake_test_fixture.test.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'html_coverage_report.test.php'); + $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'controller_test_case.test.php'); return $suite; } } \ No newline at end of file diff --git a/cake/tests/cases/libs/controller_test_case.test.php b/cake/tests/cases/libs/controller_test_case.test.php new file mode 100644 index 000000000..db66d0a9d --- /dev/null +++ b/cake/tests/cases/libs/controller_test_case.test.php @@ -0,0 +1,407 @@ + array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS), + 'controllers' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'controllers' . DS), + 'models' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'models' . DS), + 'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS) + )); + $this->Case = new ControllerTestCase(); + Router::reload(); + } + +/** + * teardown + * + * @return void + */ + function tearDown() { + $this->Case->controller = null; + App::build(); + } + +/** + * Test that ControllerTestCase::generate() creates mock objects correctly + */ + function testGenerate() { + $Posts = $this->Case->generate('Posts'); + $this->Case->assertEquals($Posts->name, 'Posts'); + $this->Case->assertEquals($Posts->modelClass, 'Post'); + $this->Case->assertNull($Posts->response->send()); + + $Posts = $this->Case->generate('Posts', array( + 'methods' => array( + 'render' + ) + )); + $this->Case->assertNull($Posts->render('index')); + + $Posts = $this->Case->generate('Posts', array( + 'models' => array('Post'), + 'components' => array('RequestHandler') + )); + $this->Case->assertNull($Posts->Post->save(array())); + $this->Case->assertNull($Posts->Post->find('all')); + $this->Case->assertEquals($Posts->Post->useTable, 'posts'); + $this->Case->assertNull($Posts->RequestHandler->isAjax()); + + $Posts = $this->Case->generate('Posts', array( + 'models' => array( + 'Post' => true + ) + )); + $this->Case->assertNull($Posts->Post->save(array())); + $this->Case->assertNull($Posts->Post->find('all')); + + $Posts = $this->Case->generate('Posts', array( + 'models' => array( + 'Post' => array('save'), + ) + )); + $this->Case->assertNull($Posts->Post->save(array())); + $this->Case->assertIsA($Posts->Post->find('all'), 'array'); + + $Posts = $this->Case->generate('Posts', array( + 'models' => array('Post'), + 'components' => array( + 'RequestHandler' => array('isPut'), + 'Email' => array('send'), + 'Session' + ) + )); + $Posts->RequestHandler->expects($this->once()) + ->method('isPut') + ->will($this->returnValue(true)); + $this->assertTrue($Posts->RequestHandler->isPut()); + + $Posts->Auth->Session->expects($this->any()) + ->method('write') + ->will($this->returnValue('written!')); + $this->assertEquals($Posts->Auth->Session->write('something'), 'written!'); + } + +/** + * Tests testAction + */ + function testTestAction() { + $Controller = $this->Case->generate('TestsApps'); + $this->Case->testAction('/tests_apps/index'); + $this->Case->assertIsA($this->Case->controller->viewVars, 'array'); + + $this->Case->testAction('/tests_apps/set_action'); + $results = $this->Case->controller->viewVars; + $expected = array( + 'var' => 'string' + ); + $this->Case->assertEquals($expected, $results); + + $result = $this->Case->controller->response->body(); + $this->Case->assertPattern('/This is the TestsAppsController index view/', $result); + + $this->Case->testAction('/tests_apps/redirect_to'); + $results = $this->Case->headers; + $expected = array( + 'Location' => 'http://cakephp.org' + ); + $this->Case->assertEquals($expected, $results); + } + +/** + * Tests using loaded routes during tests + */ + function testUseRoutes() { + include TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config' . DS . 'routes.php'; + $controller = $this->Case->generate('TestsApps'); + $controller->Components->load('RequestHandler'); + $result = $this->Case->testAction('/tests_apps/index.json', array('return' => 'view')); + $result = json_decode($result, true); + $expected = array('cakephp' => 'cool'); + $this->Case->assertEquals($result, $expected); + + include TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config' . DS . 'routes.php'; + $result = $this->Case->testAction('/some_alias'); + $this->Case->assertEquals($result, 5); + + include TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config' . DS . 'routes.php'; + $this->Case->testAction('/redirect_me_now'); + $result = $this->Case->headers['Location']; + $this->Case->assertEquals($result, 'http://cakephp.org'); + + include TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config' . DS . 'routes.php'; + $this->Case->testAction('/redirect_me'); + $result = $this->Case->headers['Location']; + $this->Case->assertEquals($result, Router::url(array('controller' => 'tests_apps', 'action' => 'some_method'), true)); + } + +/** + * Tests not using loaded routes during tests + */ + function testSkipRoutes() { + include TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config' . DS . 'routes.php'; + + $this->Case->loadRoutes = false; + + $this->expectException('MissingActionException'); + $result = $this->Case->testAction('/tests_apps/index.json', array('return' => 'view')); + } + +/** + * Tests backwards compatibility with setting the return type + */ + function testBCSetReturn() { + $this->Case->autoMock = true; + + $result = $this->Case->testAction('/tests_apps/some_method'); + $this->Case->assertEquals($result, 5); + + $data = array('var' => 'set'); + $result = $this->Case->testAction('/tests_apps_posts/post_var', array( + 'data' => $data, + 'return' => 'vars' + )); + $this->Case->assertEquals($result['data'], $data); + + $result = $this->Case->testAction('/tests_apps/set_action', array( + 'return' => 'view' + )); + $this->Case->assertEquals($result, 'This is the TestsAppsController index view'); + + $result = $this->Case->testAction('/tests_apps/set_action', array( + 'return' => 'contents' + )); + $this->Case->assertPattern('/Case->assertPattern('/This is the TestsAppsController index view/', $result); + $this->Case->assertPattern('/<\/html>/', $result); + } + +/** + * Tests sending POST data to testAction + */ + function testTestActionPostData() { + $this->Case->autoMock = true; + + $data = array( + 'Post' => array( + 'name' => 'Some Post' + ) + ); + $this->Case->testAction('/tests_apps_posts/post_var', array( + 'data' => $data + )); + $this->Case->assertEquals($this->Case->controller->viewVars['data'], $data); + $this->Case->assertEquals($this->Case->controller->data, $data); + + $this->Case->testAction('/tests_apps_posts/post_var/named:param', array( + 'data' => $data + )); + $expected = array( + 'named' => 'param' + ); + $this->Case->assertEqual($this->Case->controller->request->named, $expected); + $this->Case->assertEquals($this->Case->controller->data, $data); + + $result = $this->Case->testAction('/tests_apps_posts/post_var', array( + 'return' => 'vars', + 'method' => 'post', + 'data' => array( + 'name' => 'is jonas', + 'pork' => 'and beans', + ) + )); + $this->assertEqual(array_keys($result['data']), array('name', 'pork')); + + $result = $this->Case->testAction('/tests_apps_posts/add', array('return' => 'vars')); + $this->assertTrue(array_key_exists('posts', $result)); + $this->assertEqual(count($result['posts']), 4); + } + +/** + * Tests sending GET data to testAction + */ + function testTestActionGetData() { + $this->Case->autoMock = true; + + $result = $this->Case->testAction('/tests_apps_posts/url_var', array( + 'method' => 'get', + 'data' => array( + 'some' => 'var', + 'lackof' => 'creativity' + ) + )); + $this->Case->assertEquals($this->Case->controller->request->query['some'], 'var'); + $this->Case->assertEquals($this->Case->controller->request->query['lackof'], 'creativity'); + + $result = $this->Case->testAction('/tests_apps_posts/url_var/var1:value1/var2:val2', array( + 'return' => 'vars', + 'method' => 'get', + )); + $this->assertTrue(isset($result['params']['url']['url'])); + $this->assertEqual(array_keys($result['params']['named']), array('var1', 'var2')); + + $result = $this->Case->testAction('/tests_apps_posts/url_var/gogo/val2', array( + 'return' => 'vars', + 'method' => 'get', + )); + $this->assertEqual($result['params']['pass'], array('gogo', 'val2')); + + $result = $this->Case->testAction('/tests_apps_posts/url_var', array( + 'return' => 'vars', + 'method' => 'get', + 'data' => array( + 'red' => 'health', + 'blue' => 'mana' + ) + )); + $this->assertTrue(isset($result['params']['url']['red'])); + $this->assertTrue(isset($result['params']['url']['blue'])); + $this->assertTrue(isset($result['params']['url']['url'])); + } + +/** + * Tests autoMock ability + */ + function testAutoMock() { + $this->Case->autoMock = true; + $this->Case->testAction('/tests_apps/set_action'); + $results = $this->Case->controller->viewVars; + $expected = array( + 'var' => 'string' + ); + $this->Case->assertEquals($expected, $results); + } + +/** + * Test using testAction and not mocking + */ + function testNoMocking() { + $result = $this->Case->testAction('/tests_apps/some_method'); + $this->Case->assertEquals($result, 5); + + $data = array('var' => 'set'); + $result = $this->Case->testAction('/tests_apps_posts/post_var', array( + 'data' => $data, + 'return' => 'vars' + )); + $this->Case->assertEquals($result['data'], $data); + + $result = $this->Case->testAction('/tests_apps/set_action', array( + 'return' => 'view' + )); + $this->Case->assertEquals($result, 'This is the TestsAppsController index view'); + + $result = $this->Case->testAction('/tests_apps/set_action', array( + 'return' => 'contents' + )); + $this->Case->assertPattern('/Case->assertPattern('/This is the TestsAppsController index view/', $result); + $this->Case->assertPattern('/<\/html>/', $result); + } + +} \ No newline at end of file diff --git a/cake/tests/cases/libs/object_collection.test.php b/cake/tests/cases/libs/object_collection.test.php index fd51cbecd..ac5fb5a4c 100644 --- a/cake/tests/cases/libs/object_collection.test.php +++ b/cake/tests/cases/libs/object_collection.test.php @@ -133,6 +133,26 @@ class ObjectCollectionTest extends CakeTestCase { $this->assertEquals(array('Second'), $result, 'enabled objects are wrong'); } +/** + * Tests set() + * + * @return void + */ + function testSet() { + $this->Objects->load('First'); + + $result = $this->Objects->attached(); + $this->assertEquals(array('First'), $result, 'loaded objects are wrong'); + + $result = $this->Objects->set('First', new SecondGenericObject()); + $this->assertIsA($result['First'], 'SecondGenericObject', 'set failed'); + + $result = $this->Objects->set('Second', new SecondGenericObject()); + $this->assertIsA($result['Second'], 'SecondGenericObject', 'set failed'); + + $this->assertEquals(count($result), 2); + } + /** * creates mock classes for testing * diff --git a/cake/tests/lib/controller_test_case.php b/cake/tests/lib/controller_test_case.php new file mode 100644 index 000000000..d65650601 --- /dev/null +++ b/cake/tests/lib/controller_test_case.php @@ -0,0 +1,312 @@ + + * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) + * + * Licensed under The MIT License + * Redistributions of files must retain the above copyright notice + * + * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests + * @package cake + * @subpackage cake.cake.tests.libs + * @since CakePHP(tm) v 2.0 + * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + */ + +PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT'); + +require_once CAKE . 'libs' . DS . 'dispatcher.php'; +require_once CAKE_TESTS_LIB . 'cake_test_case.php'; +App::import('Core', array('Router', 'CakeRequest', 'CakeResponse', 'Helper')); + +/** + * ControllerTestDispatcher class + * + * @package cake + * @subpackage cake.cake.tests.lib + */ +class ControllerTestDispatcher extends Dispatcher { + +/** + * The controller to use in the dispatch process + * + * @var Controller + */ + public $testController = null; + +/** + * Use custom routes during tests + * + * @var boolean + */ + public $loadRoutes = true; + +/** + * Returns the test controller + * + * @return Controller + */ + function _getController($request) { + if ($this->testController === null) { + $this->testController = parent::_getController($request); + } + $this->testController->helpers = array_merge(array('InterceptContent'), $this->testController->helpers); + $this->testController->setRequest($request); + $this->testController->response = $this->response; + return $this->testController; + } + +/** + * Loads routes and resets if the test case dictates it should + * + * @return void + * @access private + */ + protected function __loadRoutes() { + parent::__loadRoutes(); + if (!$this->loadRoutes) { + Router::reload(); + } + } +} + +/** + * InterceptContentHelper class + * + * @package cake + * @subpackage cake.cake.tests.lib + */ +class InterceptContentHelper extends Helper { + +/** + * Intercepts and stores the contents of the view before the layout is rendered + * + * @param string $viewFile The view file + */ + function afterRender($viewFile) { + $this->_View->_viewNoLayout = $this->_View->output; + $this->_View->Helpers->unload('InterceptContent'); + } +} + +/** + * ControllerTestCase class + * + * @package cake + * @subpackage cake.cake.tests.lib + */ +class ControllerTestCase extends CakeTestCase { + +/** + * The controller to test in testAction + * + * @var Controller + */ + public $controller = null; + +/** + * Automatically mock controllers that aren't mocked + * + * @var boolean + */ + public $autoMock = false; + +/** + * Use custom routes during tests + * + * @var boolean + */ + public $loadRoutes = true; + +/** + * The resulting view vars of the last testAction call + * + * @var array + */ + public $vars = null; + +/** + * The resulting rendered view of the last testAction call + * + * @var string + */ + public $view = null; + +/** + * The resulting rendered layout+view of the last testAction call + * + * @var string + */ + public $contents = null; + +/** + * The returned result of the dispatch (requestAction), if any + * + * @var string + */ + public $result = null; + +/** + * The headers that would have been sent by the action + * + * @var string + */ + public $headers = null; + +/** + * Used to enable calling ControllerTestCase::testAction() without the testing + * framework thinking that it's a test case + * + * @param string $name The name of the function + * @param array $arguments Array of arguments + * @return Function + */ + public function __call($name, $arguments) { + if ($name == 'testAction') { + return call_user_func_array(array($this, '_testAction'), $arguments); + } + } + +/** + * Tests a controller action. + * + * ### Options: + * - `data` POST or GET data to pass + * - `method` POST or GET + * + * @param string $url The url to test + * @param array $options See options + */ + private function _testAction($url = '', $options = array()) { + $this->vars = $this->result = $this->view = $this->contents = $this->headers = null; + + $options = array_merge(array( + 'data' => array(), + 'method' => 'POST', + 'return' => 'result' + ), $options); + + if (strtoupper($options['method']) == 'GET') { + $_GET = $options['data']; + $_POST = array(); + } else { + $_POST = array('data' => $options['data']); + $_GET = array(); + } + $request = new CakeRequest($url); + $Dispatch = new ControllerTestDispatcher(); + foreach (Router::$routes as $route) { + if (is_a($route, 'RedirectRoute')) { + $route->response = $this->getMock('CakeResponse', array('send')); + } + } + $Dispatch->loadRoutes = $this->loadRoutes; + $request = $Dispatch->parseParams($request); + if (!isset($request->params['controller'])) { + $this->headers = Router::currentRoute()->response->header(); + return; + } + if ($this->controller !== null && Inflector::camelize($request->params['controller']) !== $this->controller->name) { + $this->controller = null; + } + if ($this->controller === null && $this->autoMock) { + $this->generate(Inflector::camelize($request->params['controller'])); + } + $params = array(); + if ($options['return'] == 'result') { + $params['return'] = 1; + $params['bare'] = 1; + $params['requested'] = 1; + } + $Dispatch->testController = $this->controller; + $Dispatch->response = $this->getMock('CakeResponse', array('send')); + $this->result = $Dispatch->dispatch($request, $params); + $this->controller = $Dispatch->testController; + if ($options['return'] != 'result') { + $this->vars = $this->controller->View->viewVars; + $this->view = $this->controller->View->_viewNoLayout; + $this->contents = $this->controller->response->body(); + } + $this->headers = $Dispatch->response->header(); + return $this->{$options['return']}; + } + +/** + * Generates a mocked controller and mocks any classes passed to `$mocks`. By + * default, `_stop()` is stubbed as is sending the response headers, so to not + * interfere with testing. + * + * ### Mocks: + * - `methods` Methods to mock on the controller. `_stop()` is mocked by default + * - `models` Models to mock. Models are added to the ClassRegistry so they any + * time they are instatiated the mock will be created. Pass as key value pairs + * with the value being specific methods on the model to mock. If `true` or + * no value is passed, the entire model will be mocked. + * - `components` Components to mock. Components are only mocked on this controller + * and not within each other (i.e., components on components) + * + * @param string $controller Controller name + * @param array $mocks List of classes and methods to mock + * @return Controller Mocked controller + */ + public function generate($controller, $mocks = array()) { + if (!class_exists($controller.'Controller') && App::import('Controller', $controller) === false) { + throw new MissingControllerException(array('controller' => $controller.'Controller')); + } + ClassRegistry::flush(); + + $mocks = array_merge_recursive(array( + 'methods' => array('_stop'), + 'models' => array(), + 'components' => array() + ), (array)$mocks); + + $_controller = $this->getMock($controller.'Controller', $mocks['methods'], array(), '', false); + $_controller->name = $controller; + $_controller->__construct(); + + foreach ($mocks['models'] as $model => $methods) { + if (is_string($methods)) { + $model = $methods; + $methods = true; + } + if ($methods === true) { + $methods = array(); + } + ClassRegistry::init($model); + $_model = $this->getMock($model, $methods, array(), '', false); + $_model->name = $model; + $_model->__construct(); + ClassRegistry::removeObject($model); + ClassRegistry::addObject($model, $_model); + } + + foreach ($mocks['components'] as $component => $methods) { + if (is_string($methods)) { + $component = $methods; + $methods = true; + } + if ($methods === true) { + $methods = array(); + } + if (!App::import('Component', $component)) { + throw new MissingComponentFileException(array( + 'file' => Inflector::underscore($component) . '.php', + 'class' => $componentClass + )); + } + $_component = $this->getMock($component.'Component', $methods, array(), '', false); + $_controller->Components->set($component, $_component); + } + + $_controller->constructClasses(); + + $this->controller = $_controller; + return $this->controller; + } +} \ No newline at end of file diff --git a/cake/tests/lib/test_manager.php b/cake/tests/lib/test_manager.php index f4f5b4571..9322db04e 100644 --- a/cake/tests/lib/test_manager.php +++ b/cake/tests/lib/test_manager.php @@ -89,6 +89,7 @@ class TestManager { */ public function __construct($params = array()) { require_once(CAKE_TESTS_LIB . 'cake_test_case.php'); + require_once(CAKE_TESTS_LIB . 'controller_test_case.php'); $this->params = $params; if (isset($params['app'])) { diff --git a/cake/tests/test_app/config/routes.php b/cake/tests/test_app/config/routes.php new file mode 100644 index 000000000..17fdccf25 --- /dev/null +++ b/cake/tests/test_app/config/routes.php @@ -0,0 +1,26 @@ + 'tests_apps', 'action' => 'some_method')); +Router::redirect('/redirect_me_now', 'http://cakephp.org'); +Router::redirect('/redirect_me', array('controller' => 'tests_apps', 'action' => 'some_method')); \ No newline at end of file diff --git a/cake/tests/test_app/controllers/tests_apps_controller.php b/cake/tests/test_app/controllers/tests_apps_controller.php index 28ed43f53..f7f2faf9f 100644 --- a/cake/tests/test_app/controllers/tests_apps_controller.php +++ b/cake/tests/test_app/controllers/tests_apps_controller.php @@ -32,4 +32,8 @@ class TestsAppsController extends AppController { $this->set('var', 'string'); $this->render('index'); } + + function redirect_to() { + $this->redirect('http://cakephp.org'); + } } diff --git a/cake/tests/test_app/views/layouts/json/default.ctp b/cake/tests/test_app/views/layouts/json/default.ctp new file mode 100644 index 000000000..3f290130e --- /dev/null +++ b/cake/tests/test_app/views/layouts/json/default.ctp @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/cake/tests/test_app/views/tests_apps/json/index.ctp b/cake/tests/test_app/views/tests_apps/json/index.ctp new file mode 100644 index 000000000..49236e795 --- /dev/null +++ b/cake/tests/test_app/views/tests_apps/json/index.ctp @@ -0,0 +1 @@ +{"cakephp":"cool"} \ No newline at end of file