From 6df72c65afd2300367655f9d7b937d6e238fe088 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 23 Mar 2014 23:55:45 -0400 Subject: [PATCH] Fix admin template generation. --- src/Console/Command/Task/ViewTask.php | 150 ++++------ .../Console/Command/Task/ViewTaskTest.php | 258 ++++++------------ .../Controller/Admin/PostsController.php | 9 +- 3 files changed, 138 insertions(+), 279 deletions(-) diff --git a/src/Console/Command/Task/ViewTask.php b/src/Console/Command/Task/ViewTask.php index a6402ba7f4c..349fd6fccda 100644 --- a/src/Console/Command/Task/ViewTask.php +++ b/src/Console/Command/Task/ViewTask.php @@ -76,13 +76,20 @@ class ViewTask extends BakeTask { */ public $noTemplateActions = ['delete']; +/** + * Override the name so the base class can do the right thing. + * + * @var string + */ + public $name = 'Template'; + /** * Override initialize * * @return void */ public function initialize() { - $this->path = current(App::path('View')); + $this->path = current(App::path('Template')); } /** @@ -106,13 +113,12 @@ public function execute() { } $action = null; - $this->controller($this->args[0]); - - $this->Project->interactive = false; if (strtolower($this->args[0]) === 'all') { return $this->all(); } + $this->controller($this->args[0]); + if (isset($this->args[1])) { $this->template = $this->args[1]; } @@ -144,7 +150,9 @@ public function execute() { * @return void */ public function controller($name) { + $name = $this->_controllerName($name); $this->controllerName = $name; + $plugin = $prefix = null; if (!empty($this->params['plugin'])) { $plugin = $this->params['plugin'] . '.'; @@ -155,6 +163,20 @@ public function controller($name) { $this->controllerClass = App::className($plugin . $prefix . $name, 'Controller', 'Controller'); } +/** + * Get the path base for views. + * + * @return string + */ + public function getPath() { + $path = parent::getPath(); + if (!empty($this->params['prefix'])) { + $path .= Inflector::camelize($this->params['prefix']) . DS; + } + $path .= $this->controllerName . DS; + return $path; + } + /** * Get a list of actions that can / should have views baked for them. * @@ -163,25 +185,17 @@ public function controller($name) { protected function _methodsToBake() { $base = Configure::read('App.namespace'); - $methods = array_diff( - array_map('strtolower', get_class_methods($this->controllerClass)), - array_map('strtolower', get_class_methods($base . '\Controller\AppController')) - ); - $scaffoldActions = false; + $methods = []; + if (class_exists($this->controllerClass)) { + $methods = array_diff( + array_map('strtolower', get_class_methods($this->controllerClass)), + array_map('strtolower', get_class_methods($base . '\Controller\AppController')) + ); + } if (empty($methods)) { - $scaffoldActions = true; $methods = $this->scaffoldActions; } - $adminRoute = $this->Project->getPrefix(); foreach ($methods as $i => $method) { - if ($adminRoute && !empty($this->params['admin'])) { - if ($scaffoldActions) { - $methods[$i] = $adminRoute . $method; - continue; - } elseif (strpos($method, $adminRoute) === false) { - unset($methods[$i]); - } - } if ($method[0] === '_') { unset($methods[$i]); } @@ -195,88 +209,32 @@ protected function _methodsToBake() { * @return void */ public function all() { - $this->Controller->interactive = false; - $tables = $this->Controller->listAll($this->connection, false); - - $actions = null; - if (isset($this->args[1])) { - $actions = [$this->args[1]]; - } - $this->interactive = false; - foreach ($tables as $table) { - $model = $this->_modelName($table); - $this->controller($model); - if (class_exists($model)) { - $vars = $this->_loadController(); - if (!$actions) { - $actions = $this->_methodsToBake(); - } - $this->bakeActions($actions, $vars); - $actions = null; - } - } - } - -/** - * Handles interactive baking - * - * @return void - */ - protected function _interactive() { - $this->hr(); - $this->out(sprintf("Bake View\nPath: %s", $this->getPath())); - $this->hr(); - - $this->DbConfig->interactive = $this->Controller->interactive = $this->interactive = true; - - if (empty($this->connection)) { - $this->connection = $this->DbConfig->getConfig(); - } - $this->Controller->connection = $this->connection; - $this->controllerName = $this->Controller->getName(); - - $prompt = __d('cake_console', "Would you like bake to build your views interactively?\nWarning: Choosing no will overwrite %s views if it exist.", $this->controllerName); - $interactive = $this->in($prompt, ['y', 'n'], 'n'); - - if (strtolower($interactive) === 'n') { - $this->interactive = false; - } - - $prompt = __d('cake_console', "Would you like to create some CRUD views\n(index, add, view, edit) for this controller?\nNOTE: Before doing so, you'll need to create your controller\nand model classes (including associated models)."); - $wannaDoScaffold = $this->in($prompt, ['y', 'n'], 'y'); - - $wannaDoAdmin = $this->in(__d('cake_console', "Would you like to create the views for admin routing?"), ['y', 'n'], 'n'); + $tables = $this->Controller->listAll(); - if (strtolower($wannaDoScaffold) === 'y' || strtolower($wannaDoAdmin) === 'y') { - $vars = $this->_loadController(); - if (strtolower($wannaDoScaffold) === 'y') { - $actions = $this->scaffoldActions; - $this->bakeActions($actions, $vars); - } - if (strtolower($wannaDoAdmin) === 'y') { - $admin = $this->Project->getPrefix(); - $regularActions = $this->scaffoldActions; - $adminActions = []; - foreach ($regularActions as $action) { - $adminActions[] = $admin . $action; - } - $this->bakeActions($adminActions, $vars); - } - $this->hr(); - $this->out(); - $this->out(__d('cake_console', "View Scaffolding Complete.\n")); - } else { - $this->customAction(); + foreach ($tables as $table) { + $this->args[0] = $table; + $this->execute(); } } /** * Loads Controller and sets variables for the template - * Available template variables - * 'modelClass', 'primaryKey', 'displayField', 'singularVar', 'pluralVar', - * 'singularHumanName', 'pluralHumanName', 'fields', 'foreignKeys', - * 'belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany' + * Available template variables: + * + * - 'modelClass' + * - 'primaryKey' + * - 'displayField' + * - 'singularVar' + * - 'pluralVar' + * - 'singularHumanName' + * - 'pluralHumanName' + * - 'fields' + * - 'foreignKeys', + * - 'belongsTo' + * - 'hasOne' + * - 'hasMany' + * - 'hasAndBelongsToMany' * * @return array Returns an variables to be made available to a view template */ @@ -291,7 +249,7 @@ protected function _loadController() { } if (!class_exists($this->controllerClass)) { - $file = $controllerClass . '.php'; + $file = $this->controllerClass . '.php'; $this->err(__d( 'cake_console', "The file '%s' could not be found.\nIn order to bake a view, you'll need to first create the controller.", @@ -392,7 +350,7 @@ public function bake($action, $content = '') { } $this->out("\n" . __d('cake_console', 'Baking `%s` view file...', $action), 1, Shell::QUIET); $path = $this->getPath(); - $filename = $path . $this->controllerName . DS . Inflector::underscore($action) . '.ctp'; + $filename = $path . Inflector::underscore($action) . '.ctp'; return $this->createFile($filename, $content); } diff --git a/tests/TestCase/Console/Command/Task/ViewTaskTest.php b/tests/TestCase/Console/Command/Task/ViewTaskTest.php index 8fd9be917dd..66aa5853f8a 100644 --- a/tests/TestCase/Console/Command/Task/ViewTaskTest.php +++ b/tests/TestCase/Console/Command/Task/ViewTaskTest.php @@ -85,7 +85,7 @@ class ViewTaskTest extends TestCase { * * @var array */ - public $fixtures = array('core.article', 'core.comment', 'core.articles_tag', 'core.tag'); + public $fixtures = array('core.article', 'core.post', 'core.comment', 'core.articles_tag', 'core.tag'); /** * setUp method @@ -97,11 +97,20 @@ class ViewTaskTest extends TestCase { public function setUp() { parent::setUp(); + Configure::write('App.namespace', 'TestApp'); + $this->_setupTask(['in', 'err', 'createFile', '_stop']); + + TableRegistry::get('ViewTaskComments', [ + 'className' => __NAMESPACE__ . '\ViewTaskCommentsTable', + ]); + } + + protected function _setupTask($methods) { $out = $this->getMock('Cake\Console\ConsoleOutput', [], [], '', false); $in = $this->getMock('Cake\Console\ConsoleInput', [], [], '', false); $this->Task = $this->getMock('Cake\Console\Command\Task\ViewTask', - ['in', 'err', 'createFile', '_stop'], + $methods, [$out, $out, $in] ); $this->Task->Template = new TemplateTask($out, $out, $in); @@ -113,12 +122,6 @@ public function setUp() { $this->Task->path = TMP; $this->Task->Template->params['theme'] = 'default'; $this->Task->Template->templatePaths = ['default' => CAKE . 'Console/Templates/default/']; - - Configure::write('App.namespace', 'TestApp'); - - TableRegistry::get('ViewTaskComments', [ - 'className' => __NAMESPACE__ . '\ViewTaskCommentsTable', - ]); } /** @@ -146,6 +149,17 @@ public function testController() { ); } +/** + * Test the controller() method. + * + * @dataProvider nameVariations + * @return void + */ + public function testControllerVariations($name) { + $this->Task->controller($name); + $this->assertEquals('ViewTaskComments', $this->Task->controllerName); + } + /** * Test controller method with plugins. * @@ -153,10 +167,10 @@ public function testController() { */ public function testControllerPlugin() { $this->Task->params['plugin'] = 'TestPlugin'; - $this->Task->controller('TestPlugin'); - $this->assertEquals('TestPlugin', $this->Task->controllerName); + $this->Task->controller('Tests'); + $this->assertEquals('Tests', $this->Task->controllerName); $this->assertEquals( - 'TestPlugin\Controller\TestPluginController', + 'TestPlugin\Controller\TestsController', $this->Task->controllerClass ); } @@ -184,6 +198,46 @@ public function testControllerPrefix() { ); } +/** + * Test getPath() + * + * @return void + */ + public function testGetPath() { + $this->Task->controllerName = 'Posts'; + $this->Task->path = '/path/Template/'; + + $result = $this->Task->getPath(); + $this->assertEquals('/path/Template/Posts/', $result); + + $this->Task->params['prefix'] = 'admin'; + $result = $this->Task->getPath(); + $this->assertEquals('/path/Template/Admin/Posts/', $result); + } + +/** + * Test getPath with plugins. + * + * @return void + */ + public function testGetPathPlugin() { + $this->Task->controllerName = 'Posts'; + $this->Task->path = '/path/Template/'; + + $pluginPath = APP . 'Plugin/TestPlugin/'; + Plugin::load('TestPlugin', array('path' => $pluginPath)); + + $this->Task->params['plugin'] = $this->Task->plugin = 'TestPlugin'; + $result = $this->Task->getPath(); + $this->assertEquals($pluginPath . 'Template/Posts/', $result); + + $this->Task->params['prefix'] = 'admin'; + $result = $this->Task->getPath(); + $this->assertEquals($pluginPath . 'Template/Admin/Posts/', $result); + + Plugin::unload('TestPlugin'); + } + /** * Test getContent and parsing of Templates. * @@ -309,8 +363,8 @@ public function testBakeIndex() { * @return void */ public function testBakeWithNoTemplate() { - $this->markTestIncomplete('Model baking will not work as models do not work.'); $this->Task->controllerName = 'ViewTaskComments'; + $this->Task->controllerClass = __NAMESPACE__ . '\ViewTaskCommentsController'; $this->Task->expects($this->never())->method('createFile'); $this->Task->bake('delete', true); @@ -323,7 +377,6 @@ public function testBakeWithNoTemplate() { */ public function testBakeWithPlugin() { $this->markTestIncomplete('Model baking will not work as models do not work.'); - $this->markTestIncomplete('Still fails because of issues with modelClass'); $this->Task->controllerName = 'ViewTaskComments'; $this->Task->plugin = 'TestTest'; @@ -350,10 +403,11 @@ public function testBakeWithPlugin() { * @return void */ public function testBakeActions() { - $this->markTestIncomplete('Model baking will not work as models do not work.'); $this->Task->controllerName = 'ViewTaskComments'; + $this->Task->controllerClass = __NAMESPACE__ . '\ViewTaskCommentsController'; - $this->Task->expects($this->at(0))->method('createFile') + $this->Task->expects($this->at(0)) + ->method('createFile') ->with( TMP . 'ViewTaskComments/view.ctp', $this->stringContains('View Task Comments') @@ -378,8 +432,8 @@ public function testBakeActions() { * @return void */ public function testCustomAction() { - $this->markTestIncomplete('Model baking will not work as models do not work.'); $this->Task->controllerName = 'ViewTaskComments'; + $this->Task->controllerClass = __NAMESPACE__ . '\ViewTaskCommentsController'; $this->Task->expects($this->any())->method('in') ->will($this->onConsecutiveCalls('', 'my_action', 'y')); @@ -399,44 +453,11 @@ public function testCustomAction() { * @return void */ public function testExecuteIntoAll() { - $this->markTestIncomplete('Model baking will not work as models do not work.'); + $this->_setupTask(['in', 'err', 'createFile', 'all', '_stop']); $this->Task->args[0] = 'all'; - $this->Task->Controller->expects($this->once())->method('listAll') - ->will($this->returnValue(array('view_task_comments'))); - - $this->Task->expects($this->at(0))->method('createFile') - ->with( - TMP . 'ViewTaskComments/index.ctp', - $this->anything() - ); - $this->Task->expects($this->at(1))->method('createFile') - ->with( - TMP . 'ViewTaskComments/add.ctp', - $this->anything() - ); - $this->Task->expects($this->exactly(2))->method('createFile'); - - $this->Task->execute(); - } - -/** - * Test all() with action parameter - * - * @return void - */ - public function testExecuteIntoAllWithActionName() { - $this->markTestIncomplete('Model baking will not work as models do not work.'); - $this->Task->args = array('all', 'index'); - - $this->Task->Controller->expects($this->once())->method('listAll') - ->will($this->returnValue(array('view_task_comments'))); - - $this->Task->expects($this->once())->method('createFile') - ->with( - TMP . 'ViewTaskComments/index.ctp', - $this->anything() - ); + $this->Task->expects($this->once()) + ->method('all'); $this->Task->execute(); } @@ -493,29 +514,6 @@ public static function nameVariations() { return array(array('ViewTaskComments'), array('ViewTaskComment'), array('view_task_comment')); } -/** - * test that both plural and singular forms can be used for baking views. - * - * @dataProvider nameVariations - * @return void - */ - public function testExecuteWithControllerVariations($name) { - $this->markTestIncomplete('Model baking will not work as models do not work.'); - $this->Task->args = array($name); - - $this->Task->expects($this->at(0))->method('createFile') - ->with( - TMP . 'ViewTaskComments/index.ctp', - $this->anything() - ); - $this->Task->expects($this->at(1))->method('createFile') - ->with( - TMP . 'ViewTaskComments/add.ctp', - $this->anything() - ); - $this->Task->execute(); - } - /** * test `cake bake view $controller --admin` * Which only bakes admin methods, not non-admin methods. @@ -523,71 +521,21 @@ public function testExecuteWithControllerVariations($name) { * @return void */ public function testExecuteWithControllerAndAdminFlag() { - $this->markTestIncomplete('Model baking will not work as models do not work.'); - $_back = Configure::read('Routing'); - Configure::write('Routing.prefixes', array('admin')); - $this->Task->args[0] = 'ViewTaskArticles'; - $this->Task->params['admin'] = 1; - - $this->Task->Project->expects($this->any())->method('getPrefix')->will($this->returnValue('admin_')); + $this->Task->args[0] = 'Posts'; + $this->Task->params['prefix'] = 'Admin'; - $this->Task->expects($this->exactly(4))->method('createFile'); + $this->Task->expects($this->exactly(2)) + ->method('createFile'); - $views = array('admin_index.ctp', 'admin_add.ctp', 'admin_view.ctp', 'admin_edit.ctp'); + $views = array('index.ctp', 'add.ctp'); foreach ($views as $i => $view) { $this->Task->expects($this->at($i))->method('createFile') ->with( - TMP . 'ViewTaskArticles/' . $view, + TMP . 'Admin/Posts/' . $view, $this->anything() ); } $this->Task->execute(); - Configure::write('Routing', $_back); - } - -/** - * test execute into interactive. - * - * @return void - */ - public function testExecuteInteractive() { - $this->markTestIncomplete('Model baking will not work as models do not work.'); - $this->Task->connection = 'test'; - $this->Task->args = array(); - $this->Task->params = array(); - - $this->Task->Controller->expects($this->once())->method('getName') - ->will($this->returnValue('ViewTaskComments')); - - $this->Task->expects($this->any())->method('in') - ->will($this->onConsecutiveCalls('y', 'y', 'n')); - - $this->Task->expects($this->at(3))->method('createFile') - ->with( - TMP . 'ViewTaskComments/index.ctp', - $this->stringContains('ViewTaskComment') - ); - - $this->Task->expects($this->at(4))->method('createFile') - ->with( - TMP . 'ViewTaskComments/view.ctp', - $this->stringContains('ViewTaskComment') - ); - - $this->Task->expects($this->at(5))->method('createFile') - ->with( - TMP . 'ViewTaskComments/add.ctp', - $this->stringContains('Add View Task Comment') - ); - - $this->Task->expects($this->at(6))->method('createFile') - ->with( - TMP . 'ViewTaskComments/edit.ctp', - $this->stringContains('Edit View Task Comment') - ); - - $this->Task->expects($this->exactly(4))->method('createFile'); - $this->Task->execute(); } /** @@ -609,54 +557,6 @@ public function testExecuteWithAlternateTemplates() { $this->Task->execute(); } -/** - * test execute into interactive() with admin methods. - * - * @return void - */ - public function testExecuteInteractiveWithAdmin() { - $this->markTestIncomplete('Model baking will not work as models do not work.'); - Configure::write('Routing.prefixes', array('admin')); - $this->Task->connection = 'test'; - $this->Task->args = array(); - - $this->Task->Controller->expects($this->once())->method('getName') - ->will($this->returnValue('ViewTaskComments')); - - $this->Task->Project->expects($this->once())->method('getPrefix') - ->will($this->returnValue('admin_')); - - $this->Task->expects($this->any())->method('in') - ->will($this->onConsecutiveCalls('y', 'n', 'y')); - - $this->Task->expects($this->at(3))->method('createFile') - ->with( - TMP . 'ViewTaskComments/admin_index.ctp', - $this->stringContains('ViewTaskComment') - ); - - $this->Task->expects($this->at(4))->method('createFile') - ->with( - TMP . 'ViewTaskComments/admin_view.ctp', - $this->stringContains('ViewTaskComment') - ); - - $this->Task->expects($this->at(5))->method('createFile') - ->with( - TMP . 'ViewTaskComments/admin_add.ctp', - $this->stringContains('Add View Task Comment') - ); - - $this->Task->expects($this->at(6))->method('createFile') - ->with( - TMP . 'ViewTaskComments/admin_edit.ctp', - $this->stringContains('Edit View Task Comment') - ); - - $this->Task->expects($this->exactly(4))->method('createFile'); - $this->Task->execute(); - } - /** * test getting templates, make sure noTemplateActions works and prefixed template is used before generic one. * diff --git a/tests/test_app/TestApp/Controller/Admin/PostsController.php b/tests/test_app/TestApp/Controller/Admin/PostsController.php index b2aba7c1213..8350139e519 100644 --- a/tests/test_app/TestApp/Controller/Admin/PostsController.php +++ b/tests/test_app/TestApp/Controller/Admin/PostsController.php @@ -30,17 +30,18 @@ class PostsController extends Controller { public $components = array(); /** - * components + * index action * - * @var array + * @return void */ - public $uses = array(); + public function index() { + } /** * index action * * @return void */ - public function index() { + public function add() { } }