Skip to content

Commit

Permalink
Extend dispatcher implementations to resolve URLs.
Browse files Browse the repository at this point in the history
I'm not overly happy with this approach but it does enable
HttpApplications to use RoutingMiddleware and also use URL arrays for
their tests.

The Router state needs to be reset after the test URL has been generated
to avoid duplicate named route errors.

Refs #12150
Refs #12146
  • Loading branch information
markstory committed Jun 5, 2018
1 parent d5c82b4 commit 135957d
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 22 deletions.
18 changes: 16 additions & 2 deletions src/TestSuite/IntegrationTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,8 @@ public function options($url)
protected function _sendRequest($url, $method, $data = [])
{
$dispatcher = $this->_makeDispatcher();
$url = $dispatcher->resolveUrl($url);

try {
$request = $this->_buildRequest($url, $method, $data);
$response = $dispatcher->execute($request);
Expand Down Expand Up @@ -661,14 +663,14 @@ protected function _addTokens($url, $data)
/**
* Creates a valid request url and parameter array more like Request::_url()
*
* @param string|array $url The URL
* @param string $url The URL
* @return array Qualified URL and the query parameters
*/
protected function _url($url)
{
// re-create URL in ServerRequest's context so
// query strings are encoded as expected
$request = new ServerRequest(['url' => Router::url($url)]);
$request = new ServerRequest(['url' => $url]);
$url = $request->getRequestTarget();

$query = '';
Expand All @@ -681,6 +683,18 @@ protected function _url($url)
return [$path, $query];
}

/**
* Convert an array URL into a string so we can dispatch it.
*
* This requires loading routes.
*
* @param array $url The routing URL to resolve.
* @return string The resolved route.
*/
protected function resolveRoute(array $url)
{
}

/**
* Get the response body as string
*
Expand Down
12 changes: 12 additions & 0 deletions src/TestSuite/LegacyRequestDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use Cake\Http\ServerRequest;
use Cake\Routing\DispatcherFactory;
use Cake\Routing\Router;
use Cake\TestSuite\Stub\Response;

/**
Expand All @@ -41,6 +42,17 @@ public function __construct($test)
$this->_test = $test;
}

/**
* Resolve the user provided URL into the actual request URL.
*
* @param array|string $url The URL array/string to resolve.
* @return string
*/
public function resolveUrl($url)
{
return Router::url($url);
}

/**
* Run a request and get the response.
*
Expand Down
44 changes: 24 additions & 20 deletions src/TestSuite/MiddlewareDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,38 +81,38 @@ public function __construct($test, $class = null, $constructorArgs = null)
} catch (ReflectionException $e) {
throw new LogicException(sprintf('Cannot load "%s" for use in integration testing.', $this->_class));
}

$this->bootstrap();
$this->loadRoutes();
}

/**
* Application bootstrap wrapper.
*
* Calls `bootstrap()` and `events()` if application implements `EventApplicationInterface`.
* After the application is bootstrapped and events are attached, plugins are bootstrapped
* and have their events attached.
* Resolve the provided URL into a string.
*
* @return void
* @param array|string $url The URL array/string to resolve.
* @return string
*/
protected function bootstrap()
public function resolveUrl($url)
{
$this->app->bootstrap();
if ($this->app instanceof PluginApplicationInterface) {
$this->app->pluginBootstrap();
// If we need to resolve a Route URL but there are no routes, load routes.
if (is_array($url) && count(Router::getRouteCollection()->routes()) === 0) {
return $this->resolveRoute($url);
}

return Router::url($url);
}

/**
* Ensure that the application's routes are loaded.
* Convert a URL array into a string URL via routing.
*
* Console commands and shells often need to generate URLs.
*
* @return void
* @param array $url The url to resolve
* @return string
*/
protected function loadRoutes()
protected function resolveRoute(array $url)
{
Router::reload();
// Simulate application bootstrap and route loading.
// We need both to ensure plugins are loaded.
$this->app->bootstrap();
if ($this->app instanceof PluginApplicationInterface) {
$this->app->pluginBootstrap();
}
$builder = Router::createRouteBuilder('/');

if ($this->app instanceof HttpApplicationInterface) {
Expand All @@ -121,6 +121,11 @@ protected function loadRoutes()
if ($this->app instanceof PluginApplicationInterface) {
$this->app->pluginRoutes($builder);
}

$out = Router::url($url);
Router::reload();

return $out;
}

/**
Expand All @@ -138,7 +143,6 @@ public function execute($request)
[$this->_test, 'controllerSpy']
);

Router::reload();
$server = new Server($this->app);
$psrRequest = $this->_createRequest($request);

Expand Down
14 changes: 14 additions & 0 deletions tests/TestCase/TestSuite/IntegrationTestCaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,20 @@ public function testArrayUrls()
$this->assertEquals('value', $this->viewVariable('test'));
}

/**
* Test array URLs with an empty router.
*
* @return void
*/
public function testArrayUrlsEmptyRouter()
{
Router::reload();
$this->assertFalse(Router::$initialized);

$this->post(['controller' => 'Posts', 'action' => 'index']);
$this->assertEquals('value', $this->viewVariable('test'));
}

/**
* Test flash and cookie assertions
*
Expand Down

0 comments on commit 135957d

Please sign in to comment.