Skip to content

Commit

Permalink
Make ExceptionRenderer properties protected.
Browse files Browse the repository at this point in the history
  • Loading branch information
ADmad committed Jul 26, 2018
1 parent 6ab102e commit 86c03ea
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 41 deletions.
74 changes: 70 additions & 4 deletions src/Error/ExceptionRenderer.php
Expand Up @@ -56,28 +56,28 @@ class ExceptionRenderer implements ExceptionRendererInterface
*
* @var \Exception
*/
public $error;
protected $error;

/**
* Controller instance.
*
* @var \Cake\Controller\Controller
*/
public $controller;
protected $controller;

/**
* Template to render for Cake\Core\Exception\Exception
*
* @var string
*/
public $template = '';
protected $template = '';

/**
* The method corresponding to the Exception this object is for.
*
* @var string
*/
public $method = '';
protected $method = '';

/**
* If set, this will be request used to create the controller that will render
Expand Down Expand Up @@ -426,4 +426,70 @@ protected function _shutdown()

return $result->getData('response');
}

/**
* Magic accessor for properties made protected.
*
* @param string $name Name of the attribute to get.
* @return mixed
*/
public function __get($name)
{
$protected = [
'error',
'controller',
'template',
'method',
];
if (in_array($name, $protected, true)) {
deprecationWarning(sprintf(
'ExceptionRenderer::$%s is now protected and should no longer be accessed in public context.',
$name
));
}

return $this->{$name};
}

/**
* Magic setter for properties made protected.
*
* @param string $name Name to property.
* @param mixed $value Value for property.
* @return void
*/
public function __set($name, $value)
{
$protected = [
'error',
'controller',
'template',
'method',
];
if (in_array($name, $protected, true)) {
deprecationWarning(sprintf(
'ExceptionRenderer::$%s is now protected and should no longer be accessed in public context.',
$name
));
}

$this->{$name} = $value;
}

/**
* Returns an array that can be used to describe the internal state of this
* object.
*
* @return array
*/
public function __debugInfo()
{
return [
'error' => $this->error,
'request' => $this->request,
'controller' => $this->controller,
'template' => $this->template,
'method' => $this->method,
];
}
}
106 changes: 69 additions & 37 deletions tests/TestCase/Error/ExceptionRendererTest.php
Expand Up @@ -118,6 +118,10 @@ public function index()
*/
class MyCustomExceptionRenderer extends ExceptionRenderer
{
public function setController($controller)
{
$this->controller = $controller;
}

/**
* custom error message type.
Expand Down Expand Up @@ -196,7 +200,10 @@ public function testControllerInstanceForPrefixedRequest()

$ExceptionRenderer = new MyCustomExceptionRenderer($exception, $request);

$this->assertInstanceOf(ErrorController::class, $ExceptionRenderer->controller);
$this->assertInstanceOf(
ErrorController::class,
$ExceptionRenderer->__debugInfo()['controller']
);

Configure::write('App.namespace', $namespace);
}
Expand Down Expand Up @@ -230,7 +237,10 @@ public function testSubclassMethodsNotBeingConvertedDebug0()

$result = $ExceptionRenderer->render();

$this->assertEquals('missingWidgetThing', $ExceptionRenderer->method);
$this->assertEquals(
'missingWidgetThing',
$ExceptionRenderer->__debugInfo()['method']
);
$this->assertEquals(
'widget thing is missing',
(string)$result->getBody(),
Expand Down Expand Up @@ -269,8 +279,11 @@ public function testConstruction()
$exception = new NotFoundException('Page not found');
$ExceptionRenderer = new ExceptionRenderer($exception);

$this->assertInstanceOf('Cake\Controller\ErrorController', $ExceptionRenderer->controller);
$this->assertEquals($exception, $ExceptionRenderer->error);
$this->assertInstanceOf(
'Cake\Controller\ErrorController',
$ExceptionRenderer->__debugInfo()['controller']
);
$this->assertEquals($exception, $ExceptionRenderer->__debugInfo()['error']);
}

/**
Expand All @@ -284,12 +297,15 @@ public function testExceptionMessageCoercion()
$exception = new MissingActionException('Secret info not to be leaked');
$ExceptionRenderer = new ExceptionRenderer($exception);

$this->assertInstanceOf('Cake\Controller\ErrorController', $ExceptionRenderer->controller);
$this->assertEquals($exception, $ExceptionRenderer->error);
$this->assertInstanceOf(
'Cake\Controller\ErrorController',
$ExceptionRenderer->__debugInfo()['controller']
);
$this->assertEquals($exception, $ExceptionRenderer->__debugInfo()['error']);

$result = (string)$ExceptionRenderer->render()->getBody();

$this->assertEquals('error400', $ExceptionRenderer->template);
$this->assertEquals('error400', $ExceptionRenderer->__debugInfo()['template']);
$this->assertContains('Not Found', $result);
$this->assertNotContains('Secret info not to be leaked', $result);
}
Expand Down Expand Up @@ -522,7 +538,10 @@ public function testMissingController()

$result = (string)$ExceptionRenderer->render()->getBody();

$this->assertEquals('missingController', $ExceptionRenderer->template);
$this->assertEquals(
'missingController',
$ExceptionRenderer->__debugInfo()['template']
);
$this->assertContains('Missing Controller', $result);
$this->assertContains('<em>PostsController</em>', $result);
}
Expand All @@ -543,7 +562,10 @@ public function testMissingControllerLowerCase()

$result = (string)$ExceptionRenderer->render()->getBody();

$this->assertEquals('missingController', $ExceptionRenderer->template);
$this->assertEquals(
'missingController',
$ExceptionRenderer->__debugInfo()['template']
);
$this->assertContains('Missing Controller', $result);
$this->assertContains('<em>PostsController</em>', $result);
}
Expand Down Expand Up @@ -715,21 +737,23 @@ public function testExceptionNameMangling()
public function testMissingRenderSafe()
{
$exception = new MissingHelperException(['class' => 'Fail']);
$ExceptionRenderer = new ExceptionRenderer($exception);
$ExceptionRenderer = new MyCustomExceptionRenderer($exception);

$ExceptionRenderer->controller = $this->getMockBuilder('Cake\Controller\Controller')
$controller = $this->getMockBuilder('Cake\Controller\Controller')
->setMethods(['render'])
->getMock();
$ExceptionRenderer->controller->helpers = ['Fail', 'Boom'];
$ExceptionRenderer->controller->request = new ServerRequest;
$ExceptionRenderer->controller->expects($this->at(0))
$controller->helpers = ['Fail', 'Boom'];
$controller->request = new ServerRequest;
$controller->expects($this->at(0))
->method('render')
->with('missingHelper')
->will($this->throwException($exception));

$ExceptionRenderer->setController($controller);

$response = $ExceptionRenderer->render();
sort($ExceptionRenderer->controller->helpers);
$this->assertEquals(['Form', 'Html'], $ExceptionRenderer->controller->helpers);
sort($controller->helpers);
$this->assertEquals(['Form', 'Html'], $controller->helpers);
$this->assertContains('Helper class Fail', (string)$response->getBody());
}

Expand All @@ -741,16 +765,18 @@ public function testMissingRenderSafe()
public function testRenderExceptionInBeforeRender()
{
$exception = new NotFoundException('Not there, sorry');
$ExceptionRenderer = new ExceptionRenderer($exception);
$ExceptionRenderer = new MyCustomExceptionRenderer($exception);

$ExceptionRenderer->controller = $this->getMockBuilder('Cake\Controller\Controller')
$controller = $this->getMockBuilder('Cake\Controller\Controller')
->setMethods(['beforeRender'])
->getMock();
$ExceptionRenderer->controller->request = new ServerRequest;
$ExceptionRenderer->controller->expects($this->any())
$controller->request = new ServerRequest;
$controller->expects($this->any())
->method('beforeRender')
->will($this->throwException($exception));

$ExceptionRenderer->setController($controller);

$response = $ExceptionRenderer->render();
$this->assertContains('Not there, sorry', (string)$response->getBody());
}
Expand All @@ -764,25 +790,27 @@ public function testMissingLayoutPathRenderSafe()
{
$this->called = false;
$exception = new NotFoundException();
$ExceptionRenderer = new ExceptionRenderer($exception);
$ExceptionRenderer = new MyCustomExceptionRenderer($exception);

$ExceptionRenderer->controller = new Controller();
$ExceptionRenderer->controller->helpers = ['Fail', 'Boom'];
$ExceptionRenderer->controller->getEventManager()->on(
$controller = new Controller();
$controller->helpers = ['Fail', 'Boom'];
$controller->getEventManager()->on(
'Controller.beforeRender',
function (Event $event) {
$this->called = true;
$event->getSubject()->viewBuilder()->setLayoutPath('boom');
}
);
$ExceptionRenderer->controller->request = new ServerRequest;
$controller->setRequest(new ServerRequest);

$ExceptionRenderer->setController($controller);

$response = $ExceptionRenderer->render();
$this->assertEquals('text/html', $response->getType());
$this->assertContains('Not Found', (string)$response->getBody());
$this->assertTrue($this->called, 'Listener added was not triggered.');
$this->assertEquals('', $ExceptionRenderer->controller->viewBuilder()->getLayoutPath());
$this->assertEquals('Error', $ExceptionRenderer->controller->viewBuilder()->getTemplatePath());
$this->assertEquals('', $controller->viewBuilder()->getLayoutPath());
$this->assertEquals('Error', $controller->viewBuilder()->getTemplatePath());
}

/**
Expand All @@ -793,20 +821,22 @@ function (Event $event) {
public function testMissingPluginRenderSafe()
{
$exception = new NotFoundException();
$ExceptionRenderer = new ExceptionRenderer($exception);
$ExceptionRenderer = new MyCustomExceptionRenderer($exception);

$ExceptionRenderer->controller = $this->getMockBuilder('Cake\Controller\Controller')
$controller = $this->getMockBuilder('Cake\Controller\Controller')
->setMethods(['render'])
->getMock();
$ExceptionRenderer->controller->setPlugin('TestPlugin');
$ExceptionRenderer->controller->request = $this->getMockBuilder('Cake\Http\ServerRequest')->getMock();
$controller->setPlugin('TestPlugin');
$controller->request = $this->getMockBuilder('Cake\Http\ServerRequest')->getMock();

$exception = new MissingPluginException(['plugin' => 'TestPlugin']);
$ExceptionRenderer->controller->expects($this->once())
$controller->expects($this->once())
->method('render')
->with('error400')
->will($this->throwException($exception));

$ExceptionRenderer->setController($controller);

$response = $ExceptionRenderer->render();
$body = (string)$response->getBody();
$this->assertNotContains('test plugin error500', $body);
Expand All @@ -822,20 +852,22 @@ public function testMissingPluginRenderSafeWithPlugin()
{
$this->loadPlugins(['TestPlugin']);
$exception = new NotFoundException();
$ExceptionRenderer = new ExceptionRenderer($exception);
$ExceptionRenderer = new MyCustomExceptionRenderer($exception);

$ExceptionRenderer->controller = $this->getMockBuilder('Cake\Controller\Controller')
$controller = $this->getMockBuilder('Cake\Controller\Controller')
->setMethods(['render'])
->getMock();
$ExceptionRenderer->controller->setPlugin('TestPlugin');
$ExceptionRenderer->controller->request = $this->getMockBuilder('Cake\Http\ServerRequest')->getMock();
$controller->setPlugin('TestPlugin');
$controller->request = $this->getMockBuilder('Cake\Http\ServerRequest')->getMock();

$exception = new MissingPluginException(['plugin' => 'TestPluginTwo']);
$ExceptionRenderer->controller->expects($this->once())
$controller->expects($this->once())
->method('render')
->with('error400')
->will($this->throwException($exception));

$ExceptionRenderer->setController($controller);

$response = $ExceptionRenderer->render();
$body = (string)$response->getBody();
$this->assertContains('test plugin error500', $body);
Expand Down

0 comments on commit 86c03ea

Please sign in to comment.