BUG Director::test now calls RequestProcessor

This fixes https://github.com/silverstripe/silverstripe-framework/issues/2517
and provides some testing around the use of RequestProcessor in general.
This commit is contained in:
Marcus Nyeholt 2013-10-15 07:53:34 +11:00
parent 14e5c80dad
commit 7bcb180f27
3 changed files with 87 additions and 5 deletions

View File

@ -258,8 +258,18 @@ class Director implements TemplateGlobalProvider {
$request = new SS_HTTPRequest($httpMethod, $url, $getVars, $postVars, $body);
if($headers) foreach($headers as $k => $v) $request->addHeader($k, $v);
// Pre-request filtering
// @see issue #2517
$model = DataModel::inst();
$output = Injector::inst()->get('RequestProcessor')->preRequest($request, $session, $model);
if ($output === false) {
// @TODO Need to NOT proceed with the request in an elegant manner
throw new SS_HTTPResponse_Exception(_t('Director.INVALID_REQUEST', 'Invalid request'), 400);
}
// TODO: Pass in the DataModel
$result = Director::handleRequest($request, $session, DataModel::inst());
$result = Director::handleRequest($request, $session, $model);
// Ensure that the result is an SS_HTTPResponse object
if(is_string($result)) {
@ -272,6 +282,11 @@ class Director implements TemplateGlobalProvider {
}
}
$output = Injector::inst()->get('RequestProcessor')->postRequest($request, $result, $model);
if ($output === false) {
throw new SS_HTTPResponse_Exception("Invalid response");
}
// Restore the superglobals
$_REQUEST = $existingRequestVars;
$_GET = $existingGetVars;

View File

@ -683,23 +683,24 @@ class Injector {
* class name of the object to register)
*
*/
public function registerService($service, $replace=null) {
public function registerService($service, $replace = null) {
$registerAt = get_class($service);
if ($replace != null) {
$registerAt = $replace;
}
$this->specs[$registerAt] = array('class' => get_class($service));
$this->serviceCache[$registerAt] = $service;
$this->inject($service);
}
/**
* Register a service with an explicit name
*
* @deprecated since 3.1.1
*/
public function registerNamedService($name, $service) {
$this->specs[$name] = array('class' => get_class($service));
$this->serviceCache[$name] = $service;
$this->inject($service);
return $this->registerService($service, $name);
}
/**

View File

@ -344,6 +344,72 @@ class DirectorTest extends SapphireTest {
$_SERVER = $origServer;
}
public function testRequestFilterInDirectorTest() {
$filter = new TestRequestFilter;
$processor = new RequestProcessor(array($filter));
$currentProcessor = Injector::inst()->get('RequestProcessor');
Injector::inst()->registerService($processor, 'RequestProcessor');
$response = Director::test('some-dummy-url');
$this->assertEquals(1, $filter->preCalls);
$this->assertEquals(1, $filter->postCalls);
$filter->failPost = true;
$this->setExpectedException('SS_HTTPResponse_Exception');
$response = Director::test('some-dummy-url');
$this->assertEquals(2, $filter->preCalls);
$this->assertEquals(2, $filter->postCalls);
$filter->failPre = true;
$response = Director::test('some-dummy-url');
$this->assertEquals(3, $filter->preCalls);
// preCall 'false' will trigger an exception and prevent post call execution
$this->assertEquals(2, $filter->postCalls);
// swap back otherwise our wrapping test execution request may fail in the post processing later
Injector::inst()->registerService($currentProcessor, 'RequestProcessor');
}
}
class TestRequestFilter implements RequestFilter, TestOnly {
public $preCalls = 0;
public $postCalls = 0;
public $failPre = false;
public $failPost = false;
public function preRequest(\SS_HTTPRequest $request, \Session $session, \DataModel $model) {
++$this->preCalls;
if ($this->failPre) {
return false;
}
}
public function postRequest(\SS_HTTPRequest $request, \SS_HTTPResponse $response, \DataModel $model) {
++$this->postCalls;
if ($this->failPost) {
return false;
}
}
public function reset() {
$this->preCalls = 0;
$this->postCalls = 0;
}
}
class DirectorTestRequest_Controller extends Controller implements TestOnly {