From e1c3da80198dc386c8484117d10a9f737a2cd265 Mon Sep 17 00:00:00 2001 From: Anton Terekhov Date: Sun, 11 Nov 2012 20:42:48 +0400 Subject: [PATCH] Reworked AJax action HTTP code and HTTP content. Added new HTTP template to process HTTP code output --- app/ErrorAction.php | 51 +++++++++++++++++++++------------------ app/FrontController.php | 6 ++++- tests/app/ErrorActionTest.php | 45 +++++++++++++++++++++++++--------- tests/app/FrontControllerTest.php | 43 +++++++++++++++++++++++++++++++-- 4 files changed, 106 insertions(+), 39 deletions(-) diff --git a/app/ErrorAction.php b/app/ErrorAction.php index ed24c53..f85a8d6 100644 --- a/app/ErrorAction.php +++ b/app/ErrorAction.php @@ -5,18 +5,18 @@ * @package Majestic * @subpackage app * @since 2010-02-25 - * @version SVN: $Id$ - * @filesource $URL$ */ class ErrorAction extends Action { /** - * @var ErrorException + * @var ErrorException|ErrorHTTPException */ public $exception; + protected $ajax_error = false; + public function __construct($exception) { $this->exception = $exception; @@ -27,18 +27,22 @@ class ErrorAction extends Action { $this->template = 500; if ($this->exception instanceof Error404Exception) { - if ($this->isAjaxActionError()) { - if (!headers_sent()) { - header('HTTP/1.0 404 Not Found'); - die(); - } - } $this->template = 404; + } elseif ($this->exception instanceof ErrorHTTPException) { + $this->template = 'HTTP'; } $this->logError(); $this->sendHTTPCode(); } + public function fetch() + { + if ($this->isAjaxActionError()) { + return $this->exception->getMessage(); + } + return parent::fetch(); + } + protected function getTemplate() { return '/actions/' . $this->template; @@ -46,22 +50,19 @@ class ErrorAction extends Action protected function sendHttpCode() { - if (headers_sent()) { - return; - } switch ($this->template) { case 404: - header('HTTP/1.0 404 Not Found'); - break; + case 'HTTP': + header($this->exception->getHTTPHeader()); + break; default: header('HTTP/1.0 500 Internal Server Error'); } } - + protected function logError() { if ($this->template == 500) { - $error = 0; $ex = $this->exception; if ($ex instanceof ErrorException) { @@ -83,7 +84,7 @@ class ErrorAction extends Action break; } $message = 'PHP ' . $error . ': ' . $ex->getMessage() . ' in ' . $ex->getFile() - . ' on line ' . $ex->getLine(); + . ' on line ' . $ex->getLine(); error_log($message); } } @@ -94,12 +95,14 @@ class ErrorAction extends Action */ protected function isAjaxActionError() { - $trace = $this->exception->getTrace(); - foreach ($trace as $line) { - if (isset($line['class']) && $line['class'] === 'AjaxAction') { - return true; - } - } - return false; + return $this->ajax_error; + } + + /** + * Set if exception was thrown from AjaxAction subclass + */ + public function setAjaxError() + { + $this->ajax_error = true; } } \ No newline at end of file diff --git a/app/FrontController.php b/app/FrontController.php index cbf4c65..4d8f75e 100644 --- a/app/FrontController.php +++ b/app/FrontController.php @@ -142,7 +142,11 @@ class FrontController */ $layout = new $layout_class(); $layout->setException($e); - return $layout->fetch(new ErrorAction($e)); + $error_action = new ErrorAction($e); + if (isset($action) && is_subclass_of($action, 'AjaxAction')) { + $error_action->setAjax(); + } + return $layout->fetch($error_action); } } } \ No newline at end of file diff --git a/tests/app/ErrorActionTest.php b/tests/app/ErrorActionTest.php index 15a8896..22fa903 100644 --- a/tests/app/ErrorActionTest.php +++ b/tests/app/ErrorActionTest.php @@ -12,6 +12,9 @@ require_once dirname(__FILE__) . '/Action_TestCase.php'; require_once dirname(__FILE__) . '/../../app/ErrorAction.php'; +require_once dirname(__FILE__) . '/../../exception/GeneralException.php'; +require_once dirname(__FILE__) . '/../../exception/ErrorHTTPException.php'; +require_once dirname(__FILE__) . '/../../exception/Error404Exception.php'; class ErrorActionTest extends Action_TestCase { @@ -24,10 +27,9 @@ class ErrorActionTest extends Action_TestCase $this->log = ini_get('error_log'); ini_set('error_log', '/dev/null'); - set_exit_overload(function() - { - return false; - }); + set_exit_overload(function () { + return false; + }); } /** @@ -96,13 +98,15 @@ class ErrorActionTest extends Action_TestCase public function testError404WithAjax() { $this->setConstants(false); - $exception = $this->getMock('Error404Exception', array('getMessage', 'getFile', 'getLine', 'getTrace')); - $exception->expects($this->once()) - ->method('getTrace') - ->will($this->returnValue(array('one' => array('class' => 'AjaxAction')))); + $exception = new Error404Exception('Some message'); + $controller = FrontController::getInstance(); + $controller->setView('SomeView'); $action = new ErrorAction($exception); + $action->setAjaxError(); $this->assertSame($exception, $action->exception); + $result = $action->fetch(); + $this->assertSame('Some message', $result); } /** @@ -111,13 +115,30 @@ class ErrorActionTest extends Action_TestCase public function testError404NoAjax() { $this->setConstants(false); - $exception = $this->getMock('Error404Exception', array('getMessage', 'getFile', 'getLine', 'getTrace')); - $exception->expects($this->once()) - ->method('getTrace') - ->will($this->returnValue(array('one' => array('class' => 'Action')))); + $exception = new Error404Exception('Some message'); + $controller = FrontController::getInstance(); + $controller->setView('SomeView'); $action = new ErrorAction($exception); $this->assertSame($exception, $action->exception); + $result = $action->fetch(); + $this->assertSame('/actions/404', $result['template']); + } + + /** + * @runInSeparateProcess + */ + public function testErrorHTTP() + { + $this->setConstants(false); + $exception = new ErrorHTTPException('Some message', 410); + + $controller = FrontController::getInstance(); + $controller->setView('SomeView'); + $action = new ErrorAction($exception); + $this->assertSame($exception, $action->exception); + $result = $action->fetch(); + $this->assertSame('/actions/HTTP', $result['template']); } private function setConstants($val = false) diff --git a/tests/app/FrontControllerTest.php b/tests/app/FrontControllerTest.php index 0385889..8496bd8 100644 --- a/tests/app/FrontControllerTest.php +++ b/tests/app/FrontControllerTest.php @@ -26,10 +26,9 @@ require_once dirname(__FILE__) . '/../../app/FrontController.php'; require_once dirname(__FILE__) . '/../../app/Action.php'; require_once dirname(__FILE__) . '/../../app/AjaxAction.php'; - class FrontControllerTest extends PHPUnit_Framework_TestCase { - + public function run(PHPUnit_Framework_TestResult $result = NULL) { $this->setPreserveGlobalState(false); @@ -133,6 +132,8 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase { $this->setConstants(false); $controller = FrontController::getInstance(); + $result = $controller->execute(); + $controller = FrontController::getInstance(); $this->assertNull($controller->execute()); } @@ -193,6 +194,24 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase $result = $controller->execute(); $this->assertNull($result); } + + /** + * @runInSeparateProcess + */ + public function testExecuteWithLayoutProfiler() + { + Config::set('PROFILER', true); + $this->getMock('userAction'); + $this->getMock('DefaultLayout', array('fetch'), array(), 'DefaultLayoutMock'); + $_SERVER['REQUEST_URI'] = '/user/account/213'; + $this->setConstants(true); + $controller = FrontController::getInstance(); + $router = $controller->getRouter(); + $router->add('user', 'user/account/:id', 'user'); + $result = $controller->execute(); + $this->assertNull($result); + } + /** * @runInSeparateProcess */ @@ -209,6 +228,23 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase $this->assertNull($result); } + /** + * @runInSeparateProcess + */ + public function testExecuteWithAjaxActionProfiler() + { + Config::set('PROFILER', true); + $this->getMock('userAction'); + $this->getMock('DefaultLayout', array('fetch'), array(), 'DefaultLayoutMock'); + $_SERVER['REQUEST_URI'] = '/user/account/213'; + $this->setConstants(true); + $controller = FrontController::getInstance(); + $router = $controller->getRouter(); + $router->add('user', 'user/account/:id', 'NewAjax'); + $result = $controller->execute(); + $this->assertNull($result); + } + private function setConstants($val = false) { @@ -237,6 +273,9 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase } } +/** + * Used in testExecuteWithAjaxAction + */ class NewAjaxAction extends AjaxAction{ protected function execute() {} } \ No newline at end of file