Skip to content
Permalink
Browse files

Load routing in console environments.

Ensure that the CommandRunner framework uses the application routes()
hook to load routes. This enables the routes shell and other
commands/shells to generate URLs properly.

Refs #12030
  • Loading branch information...
markstory committed May 1, 2018
1 parent 0cb6d51 commit 933151f9f4c2df2f57688d555e53ce4c8740a59e
Showing with 54 additions and 11 deletions.
  1. +19 −0 src/Console/CommandRunner.php
  2. +35 −11 tests/TestCase/Console/CommandRunnerTest.php
@@ -26,6 +26,7 @@
use Cake\Event\EventDispatcherInterface;
use Cake\Event\EventDispatcherTrait;
use Cake\Event\EventManager;
use Cake\Routing\Router;
use Cake\Utility\Inflector;
use InvalidArgumentException;
use RuntimeException;
@@ -145,6 +146,7 @@ public function run(array $argv, ConsoleIo $io = null)
}
$this->checkCollection($commands, 'pluginConsole');
$this->dispatchEvent('Console.buildCommands', ['commands' => $commands]);
$this->loadRoutes();
if (empty($argv)) {
throw new RuntimeException("Cannot run any commands. No arguments received.");
@@ -358,4 +360,21 @@ protected function createShell($className, ConsoleIo $io)
return $shell;
}
/**
* Ensure that the application's routes are loaded.
*
* Console commands and shells often need to generate URLs.
*
* @return void
*/
protected function loadRoutes()
{
$builder = Router::createRouteBuilder('/');
$this->app->routes($builder);
if ($this->app instanceof PluginApplicationInterface) {
$this->app->pluginRoutes($builder);
}
}
}
@@ -24,6 +24,7 @@
use Cake\Event\EventList;
use Cake\Event\EventManager;
use Cake\Http\BaseApplication;
use Cake\Routing\Router;
use Cake\TestSuite\Stub\ConsoleOutput;
use Cake\TestSuite\TestCase;
use InvalidArgumentException;
@@ -160,7 +161,7 @@ public function testRunMissingRootCommand()
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Cannot run any commands. No arguments received.');
$app = $this->getMockBuilder(BaseApplication::class)
->setMethods(['middleware', 'bootstrap'])
->setMethods(['middleware', 'bootstrap', 'routes'])
->setConstructorArgs([$this->config])
->getMock();
@@ -178,7 +179,7 @@ public function testRunInvalidCommand()
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Unknown command `cake nope`. Run `cake --help` to get the list of valid commands.');
$app = $this->getMockBuilder(BaseApplication::class)
->setMethods(['middleware', 'bootstrap'])
->setMethods(['middleware', 'bootstrap', 'routes'])
->setConstructorArgs([$this->config])
->getMock();
@@ -194,7 +195,7 @@ public function testRunInvalidCommand()
public function testRunHelpLongOption()
{
$app = $this->getMockBuilder(BaseApplication::class)
->setMethods(['middleware', 'bootstrap'])
->setMethods(['middleware', 'bootstrap', 'routes'])
->setConstructorArgs([$this->config])
->getMock();
@@ -216,7 +217,7 @@ public function testRunHelpLongOption()
public function testRunHelpShortOption()
{
$app = $this->getMockBuilder(BaseApplication::class)
->setMethods(['middleware', 'bootstrap'])
->setMethods(['middleware', 'bootstrap', 'routes'])
->setConstructorArgs([$this->config])
->getMock();
@@ -237,7 +238,7 @@ public function testRunHelpShortOption()
public function testRunNoCommand()
{
$app = $this->getMockBuilder(BaseApplication::class)
->setMethods(['middleware', 'bootstrap'])
->setMethods(['middleware', 'bootstrap', 'routes'])
->setConstructorArgs([$this->config])
->getMock();
@@ -260,7 +261,7 @@ public function testRunNoCommand()
public function testRunVersionAlias()
{
$app = $this->getMockBuilder(BaseApplication::class)
->setMethods(['middleware', 'bootstrap'])
->setMethods(['middleware', 'bootstrap', 'routes'])
->setConstructorArgs([$this->config])
->getMock();
@@ -278,7 +279,7 @@ public function testRunVersionAlias()
public function testRunValidCommand()
{
$app = $this->getMockBuilder(BaseApplication::class)
->setMethods(['middleware', 'bootstrap'])
->setMethods(['middleware', 'bootstrap', 'routes'])
->setConstructorArgs([$this->config])
->getMock();
@@ -301,7 +302,7 @@ public function testRunValidCommand()
public function testRunValidCommandInflection()
{
$app = $this->getMockBuilder(BaseApplication::class)
->setMethods(['middleware', 'bootstrap'])
->setMethods(['middleware', 'bootstrap', 'routes'])
->setConstructorArgs([$this->config])
->getMock();
@@ -432,7 +433,7 @@ public function testRunValidCommandClassHelp()
public function testRunTriggersBuildCommandsEvent()
{
$app = $this->getMockBuilder(BaseApplication::class)
->setMethods(['middleware', 'bootstrap'])
->setMethods(['middleware', 'bootstrap', 'routes'])
->setConstructorArgs([$this->config])
->getMock();
@@ -454,7 +455,10 @@ public function testRunTriggersBuildCommandsEvent()
public function testRunCallsPluginHookMethods()
{
$app = $this->getMockBuilder(BaseApplication::class)
->setMethods(['middleware', 'bootstrap', 'pluginBootstrap', 'pluginEvents', 'pluginConsole'])
->setMethods([
'middleware', 'bootstrap', 'routes',
'pluginBootstrap', 'pluginConsole', 'pluginRoutes'
])
->setConstructorArgs([$this->config])
->getMock();
@@ -468,17 +472,37 @@ public function testRunCallsPluginHookMethods()
->will($this->returnCallback(function ($commands) {
return $commands;
}));
$app->expects($this->at(3))->method('routes');
$app->expects($this->at(4))->method('pluginRoutes');
$output = new ConsoleOutput();
$runner = new CommandRunner($app, 'cake');
$result = $runner->run(['cake', '--version'], $this->getMockIo($output));
$this->assertContains(Configure::version(), $output->messages()[0]);
}
/**
* Test that run() loads routing.
*
* @return void
*/
public function testRunLoadsRoutes()
{
$app = $this->getMockBuilder(BaseApplication::class)
->setMethods(['middleware', 'bootstrap'])
->setConstructorArgs([TEST_APP . 'config' . DS])
->getMock();
$output = new ConsoleOutput();
$runner = new CommandRunner($app, 'cake');
$runner->run(['cake', '--version'], $this->getMockIo($output));
$this->assertGreaterThan(2, count(Router::getRouteCollection()->routes()));
}
protected function makeAppWithCommands($commands)
{
$app = $this->getMockBuilder(BaseApplication::class)
->setMethods(['middleware', 'bootstrap', 'console'])
->setMethods(['middleware', 'bootstrap', 'console', 'routes'])
->setConstructorArgs([$this->config])
->getMock();
$collection = new CommandCollection($commands);

0 comments on commit 933151f

Please sign in to comment.
You can’t perform that action at this time.