File indexing completed on 2025-02-23 05:32:49
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Test 0017 * @subpackage PHPUnit 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 */ 0022 0023 /** 0024 * Response header PHPUnit Constraint 0025 * 0026 * @uses PHPUnit_Framework_Constraint 0027 * @category Zend 0028 * @package Zend_Test 0029 * @subpackage PHPUnit 0030 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0031 * @license http://framework.zend.com/license/new-bsd New BSD License 0032 */ 0033 class Zend_Test_PHPUnit_Constraint_ResponseHeader37 extends PHPUnit_Framework_Constraint 0034 { 0035 /**#@+ 0036 * Assertion type constants 0037 */ 0038 const ASSERT_RESPONSE_CODE = 'assertResponseCode'; 0039 const ASSERT_HEADER = 'assertHeader'; 0040 const ASSERT_HEADER_CONTAINS = 'assertHeaderContains'; 0041 const ASSERT_HEADER_REGEX = 'assertHeaderRegex'; 0042 /**#@-*/ 0043 0044 /** 0045 * Current assertion type 0046 * @var string 0047 */ 0048 protected $_assertType = null; 0049 0050 /** 0051 * Available assertion types 0052 * @var array 0053 */ 0054 protected $_assertTypes = array( 0055 self::ASSERT_RESPONSE_CODE, 0056 self::ASSERT_HEADER, 0057 self::ASSERT_HEADER_CONTAINS, 0058 self::ASSERT_HEADER_REGEX, 0059 ); 0060 0061 /** 0062 * @var int Response code 0063 */ 0064 protected $_code = 200; 0065 0066 /** 0067 * @var int Actual response code 0068 */ 0069 protected $_actualCode = null; 0070 0071 /** 0072 * @var string Header 0073 */ 0074 protected $_header = null; 0075 0076 /** 0077 * @var string pattern against which to compare header content 0078 */ 0079 protected $_match = null; 0080 0081 /** 0082 * Whether or not assertion is negated 0083 * @var bool 0084 */ 0085 protected $_negate = false; 0086 0087 /** 0088 * Constructor; setup constraint state 0089 * 0090 * @return void 0091 */ 0092 public function __construct() 0093 { 0094 } 0095 0096 /** 0097 * Indicate negative match 0098 * 0099 * @param bool $flag 0100 * @return void 0101 */ 0102 public function setNegate($flag = true) 0103 { 0104 $this->_negate = $flag; 0105 } 0106 0107 /** 0108 * Evaluate an object to see if it fits the constraints 0109 * 0110 * @param object of Zend_Controller_Response_Abstract to be evaluated 0111 * @param null|string Assertion type 0112 * @param int|string HTTP response code to evaluate against | header string (haystack) 0113 * @param string (optional) match (needle), may be required depending on assertion type 0114 * @return bool 0115 * NOTE: 0116 * Drastic changes up to PHPUnit 3.5.15 this was: 0117 * public function evaluate($other, $assertType = null) 0118 * In PHPUnit 3.6.0 they changed the interface into this: 0119 * public function evaluate($other, $description = '', $returnResult = FALSE) 0120 * We use the new interface for PHP-strict checking, but emulate the old one 0121 */ 0122 public function evaluate($response, $assertType = '', $variable = FALSE) 0123 { 0124 if (!$response instanceof Zend_Controller_Response_Abstract) { 0125 // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; 0126 throw new Zend_Test_PHPUnit_Constraint_Exception('Header constraint assertions require a response object'); 0127 } 0128 0129 if (strstr($assertType, 'Not')) { 0130 $this->setNegate(true); 0131 $assertType = str_replace('Not', '', $assertType); 0132 } 0133 0134 if (!in_array($assertType, $this->_assertTypes)) { 0135 // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; 0136 throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__)); 0137 } 0138 0139 $this->_assertType = $assertType; 0140 0141 $argv = func_get_args(); 0142 $argc = func_num_args(); 0143 0144 switch ($assertType) { 0145 case self::ASSERT_RESPONSE_CODE: 0146 if (3 > $argc) { 0147 // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; 0148 throw new Zend_Test_PHPUnit_Constraint_Exception('No response code provided against which to match'); 0149 } 0150 $this->_code = $code = $argv[2]; 0151 return ($this->_negate) 0152 ? $this->_notCode($response, $code) 0153 : $this->_code($response, $code); 0154 case self::ASSERT_HEADER: 0155 if (3 > $argc) { 0156 // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; 0157 throw new Zend_Test_PHPUnit_Constraint_Exception('No header provided against which to match'); 0158 } 0159 $this->_header = $header = $argv[2]; 0160 return ($this->_negate) 0161 ? $this->_notHeader($response, $header) 0162 : $this->_header($response, $header); 0163 case self::ASSERT_HEADER_CONTAINS: 0164 if (4 > $argc) { 0165 // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; 0166 throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . $assertType); 0167 } 0168 $this->_header = $header = $argv[2]; 0169 $this->_match = $match = $argv[3]; 0170 return ($this->_negate) 0171 ? $this->_notHeaderContains($response, $header, $match) 0172 : $this->_headerContains($response, $header, $match); 0173 case self::ASSERT_HEADER_REGEX: 0174 if (4 > $argc) { 0175 // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; 0176 throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . $assertType); 0177 } 0178 $this->_header = $header = $argv[2]; 0179 $this->_match = $match = $argv[3]; 0180 return ($this->_negate) 0181 ? $this->_notHeaderRegex($response, $header, $match) 0182 : $this->_headerRegex($response, $header, $match); 0183 default: 0184 // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; 0185 throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . $assertType); 0186 } 0187 } 0188 0189 /** 0190 * Report Failure 0191 * 0192 * @see PHPUnit_Framework_Constraint for implementation details 0193 * @param mixed CSS selector path 0194 * @param string Failure description 0195 * @param object Cannot be used, null 0196 * @return void 0197 * @throws PHPUnit_Framework_ExpectationFailedException 0198 * NOTE: 0199 * Drastic changes up to PHPUnit 3.5.15 this was: 0200 * public function fail($other, $description, $not = false) 0201 * In PHPUnit 3.6.0 they changed the interface into this: 0202 * protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL) 0203 * We use the new interface for PHP-strict checking 0204 */ 0205 public function fail($other, $description, PHPUnit_Framework_ComparisonFailure $cannot_be_used = NULL) 0206 { 0207 // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php'; 0208 switch ($this->_assertType) { 0209 case self::ASSERT_RESPONSE_CODE: 0210 $failure = 'Failed asserting response code "%s"'; 0211 if ($this->_negate) { 0212 $failure = 'Failed asserting response code IS NOT "%s"'; 0213 } 0214 $failure = sprintf($failure, $this->_code); 0215 if (!$this->_negate && $this->_actualCode) { 0216 $failure .= sprintf(PHP_EOL . 'Was "%s"', $this->_actualCode); 0217 } 0218 break; 0219 case self::ASSERT_HEADER: 0220 $failure = 'Failed asserting response header "%s" found'; 0221 if ($this->_negate) { 0222 $failure = 'Failed asserting response response header "%s" WAS NOT found'; 0223 } 0224 $failure = sprintf($failure, $this->_header); 0225 break; 0226 case self::ASSERT_HEADER_CONTAINS: 0227 $failure = 'Failed asserting response header "%s" exists and contains "%s"'; 0228 if ($this->_negate) { 0229 $failure = 'Failed asserting response header "%s" DOES NOT CONTAIN "%s"'; 0230 } 0231 $failure = sprintf($failure, $this->_header, $this->_match); 0232 break; 0233 case self::ASSERT_HEADER_REGEX: 0234 $failure = 'Failed asserting response header "%s" exists and matches regex "%s"'; 0235 if ($this->_negate) { 0236 $failure = 'Failed asserting response header "%s" DOES NOT MATCH regex "%s"'; 0237 } 0238 $failure = sprintf($failure, $this->_header, $this->_match); 0239 break; 0240 default: 0241 throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . __FUNCTION__); 0242 } 0243 0244 if (!empty($description)) { 0245 $failure = $description . "\n" . $failure; 0246 } 0247 0248 throw new Zend_Test_PHPUnit_Constraint_Exception($failure); 0249 } 0250 0251 /** 0252 * Complete implementation 0253 * 0254 * @return string 0255 */ 0256 public function toString() 0257 { 0258 return ''; 0259 } 0260 0261 /** 0262 * Compare response code for positive match 0263 * 0264 * @param Zend_Controller_Response_Abstract $response 0265 * @param int $code 0266 * @return bool 0267 */ 0268 protected function _code(Zend_Controller_Response_Abstract $response, $code) 0269 { 0270 $test = $this->_getCode($response); 0271 $this->_actualCode = $test; 0272 return ($test == $code); 0273 } 0274 0275 /** 0276 * Compare response code for negative match 0277 * 0278 * @param Zend_Controller_Response_Abstract $response 0279 * @param int $code 0280 * @return bool 0281 */ 0282 protected function _notCode(Zend_Controller_Response_Abstract $response, $code) 0283 { 0284 $test = $this->_getCode($response); 0285 return ($test != $code); 0286 } 0287 0288 /** 0289 * Retrieve response code 0290 * 0291 * @param Zend_Controller_Response_Abstract $response 0292 * @return int 0293 */ 0294 protected function _getCode(Zend_Controller_Response_Abstract $response) 0295 { 0296 $test = $response->getHttpResponseCode(); 0297 if (null === $test) { 0298 $test = 200; 0299 } 0300 return $test; 0301 } 0302 0303 /** 0304 * Positive check for response header presence 0305 * 0306 * @param Zend_Controller_Response_Abstract $response 0307 * @param string $header 0308 * @return bool 0309 */ 0310 protected function _header(Zend_Controller_Response_Abstract $response, $header) 0311 { 0312 return (null !== $this->_getHeader($response, $header)); 0313 } 0314 0315 /** 0316 * Negative check for response header presence 0317 * 0318 * @param Zend_Controller_Response_Abstract $response 0319 * @param string $header 0320 * @return bool 0321 */ 0322 protected function _notHeader(Zend_Controller_Response_Abstract $response, $header) 0323 { 0324 return (null === $this->_getHeader($response, $header)); 0325 } 0326 0327 /** 0328 * Retrieve response header 0329 * 0330 * @param Zend_Controller_Response_Abstract $response 0331 * @param string $header 0332 * @return string|null 0333 */ 0334 protected function _getHeader(Zend_Controller_Response_Abstract $response, $header) 0335 { 0336 $headers = $response->sendHeaders(); 0337 $header = strtolower($header); 0338 if (array_key_exists($header, $headers)) { 0339 return $headers[$header]; 0340 } 0341 return null; 0342 } 0343 0344 /** 0345 * Positive check for header contents matching pattern 0346 * 0347 * @param Zend_Controller_Response_Abstract $response 0348 * @param string $header 0349 * @param string $match 0350 * @return bool 0351 */ 0352 protected function _headerContains(Zend_Controller_Response_Abstract $response, $header, $match) 0353 { 0354 if (null === ($fullHeader = $this->_getHeader($response, $header))) { 0355 return false; 0356 } 0357 0358 $contents = str_replace($header . ': ', '', $fullHeader); 0359 0360 return (strstr($contents, $match) !== false); 0361 } 0362 0363 /** 0364 * Negative check for header contents matching pattern 0365 * 0366 * @param Zend_Controller_Response_Abstract $response 0367 * @param string $header 0368 * @param string $match 0369 * @return bool 0370 */ 0371 protected function _notHeaderContains(Zend_Controller_Response_Abstract $response, $header, $match) 0372 { 0373 if (null === ($fullHeader = $this->_getHeader($response, $header))) { 0374 return true; 0375 } 0376 0377 $contents = str_replace($header . ': ', '', $fullHeader); 0378 0379 return (strstr($contents, $match) === false); 0380 } 0381 0382 /** 0383 * Positive check for header contents matching regex 0384 * 0385 * @param Zend_Controller_Response_Abstract $response 0386 * @param string $header 0387 * @param string $pattern 0388 * @return bool 0389 */ 0390 protected function _headerRegex(Zend_Controller_Response_Abstract $response, $header, $pattern) 0391 { 0392 if (null === ($fullHeader = $this->_getHeader($response, $header))) { 0393 return false; 0394 } 0395 0396 $contents = str_replace($header . ': ', '', $fullHeader); 0397 0398 return preg_match($pattern, $contents); 0399 } 0400 0401 /** 0402 * Negative check for header contents matching regex 0403 * 0404 * @param Zend_Controller_Response_Abstract $response 0405 * @param string $header 0406 * @param string $pattern 0407 * @return bool 0408 */ 0409 protected function _notHeaderRegex(Zend_Controller_Response_Abstract $response, $header, $pattern) 0410 { 0411 if (null === ($fullHeader = $this->_getHeader($response, $header))) { 0412 return true; 0413 } 0414 0415 $contents = str_replace($header . ': ', '', $fullHeader); 0416 0417 return !preg_match($pattern, $contents); 0418 } 0419 }