Skip to content
Permalink
Browse files

Extend dispatcher implementations to resolve URLs.

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 135957df21e54436ece2a068457c9c3ea02458eb
@@ -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);
@@ -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 = '';
@@ -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
*
@@ -15,6 +15,7 @@
use Cake\Http\ServerRequest;
use Cake\Routing\DispatcherFactory;
use Cake\Routing\Router;
use Cake\TestSuite\Stub\Response;
/**
@@ -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.
*
@@ -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) {
@@ -121,6 +121,11 @@ protected function loadRoutes()
if ($this->app instanceof PluginApplicationInterface) {
$this->app->pluginRoutes($builder);
}
$out = Router::url($url);
Router::reload();
return $out;
}
/**
@@ -138,7 +143,6 @@ public function execute($request)
[$this->_test, 'controllerSpy']
);
Router::reload();
$server = new Server($this->app);
$psrRequest = $this->_createRequest($request);
@@ -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
*

0 comments on commit 135957d

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