From 991d03580682462f90bcd5c4e666c42c63a28252 Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 30 Jun 2010 22:34:33 -0400 Subject: [PATCH] Fixing respondAs() so it can be called multiple times. Test cases added for respondAs. Fixes #842 --- .../controller/components/request_handler.php | 19 +++++++---- .../components/request_handler.test.php | 33 ++++++++++++++++++- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/cake/libs/controller/components/request_handler.php b/cake/libs/controller/components/request_handler.php index dbbdfe2c9fe..f8b58f0cded 100644 --- a/cake/libs/controller/components/request_handler.php +++ b/cake/libs/controller/components/request_handler.php @@ -690,7 +690,6 @@ function renderAs(&$controller, $type) { * like 'application/x-shockwave'. * @param array $options If $type is a friendly type name that is associated with * more than one type of content, $index is used to select which content-type to use. - * * @return boolean Returns false if the friendly type name given in $type does * not exist in the type map, or if the Content-type header has * already been set by this method. @@ -699,9 +698,6 @@ function renderAs(&$controller, $type) { */ function respondAs($type, $options = array()) { $this->__initializeTypes(); - if ($this->__responseTypeSet != null) { - return false; - } if (!array_key_exists($type, $this->__requestContent) && strpos($type, '/') === false) { return false; } @@ -738,10 +734,10 @@ function respondAs($type, $options = array()) { $header .= '; charset=' . $options['charset']; } if (!empty($options['attachment'])) { - header("Content-Disposition: attachment; filename=\"{$options['attachment']}\""); + $this->_header("Content-Disposition: attachment; filename=\"{$options['attachment']}\""); } if (Configure::read() < 2 && !defined('CAKEPHP_SHELL')) { - @header($header); + $this->_header($header); } $this->__responseTypeSet = $cType; return true; @@ -749,6 +745,17 @@ function respondAs($type, $options = array()) { return false; } +/** + * Wrapper for header() so calls can be easily tested. + * + * @param string $header The header to be sent. + * @return void + * @access protected + */ + function _header($header) { + header($header); + } + /** * Returns the current response type (Content-type header), or null if none has been set * diff --git a/cake/tests/cases/libs/controller/components/request_handler.test.php b/cake/tests/cases/libs/controller/components/request_handler.test.php index 420ecd4054e..ef370070f50 100644 --- a/cake/tests/cases/libs/controller/components/request_handler.test.php +++ b/cake/tests/cases/libs/controller/components/request_handler.test.php @@ -20,7 +20,7 @@ App::import('Controller', 'Controller', false); App::import('Component', array('RequestHandler')); -Mock::generatePartial('RequestHandlerComponent', 'NoStopRequestHandler', array('_stop')); +Mock::generatePartial('RequestHandlerComponent', 'NoStopRequestHandler', array('_stop', '_header')); Mock::generatePartial('Controller', 'RequestHandlerMockController', array('header')); /** @@ -308,6 +308,37 @@ function testRenderAs() { $this->assertEqual($this->Controller->viewPath, 'request_handler_test' . DS . 'js'); } +/** + * test that respondAs works as expected. + * + * @return void + */ + function testRespondAs() { + $RequestHandler = new NoStopRequestHandler(); + $RequestHandler->expectAt(0, '_header', array('Content-Type: application/json')); + $RequestHandler->expectAt(1, '_header', array('Content-Type: text/xml')); + + $result = $RequestHandler->respondAs('json'); + $this->assertTrue($result); + + $result = $RequestHandler->respondAs('text/xml'); + $this->assertTrue($result); + } + +/** + * test that attachment headers work with respondAs + * + * @return void + */ + function testRespondAsWithAttachment() { + $RequestHandler = new NoStopRequestHandler(); + $RequestHandler->expectAt(0, '_header', array('Content-Disposition: attachment; filename="myfile.xml"')); + $RequestHandler->expectAt(1, '_header', array('Content-Type: text/xml')); + + $result = $RequestHandler->respondAs('xml', array('attachment' => 'myfile.xml')); + $this->assertTrue($result); + } + /** * test that calling renderAs() more than once continues to work. *