File indexing completed on 2024-12-29 05:28:07

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_ResponseHeader34 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  Zend_Controller_Response_Abstract $other String to examine
0111      * @param  null|string Assertion type
0112      * @return bool
0113      */
0114     public function evaluate($other, $assertType = null)
0115     {
0116         if (!$other instanceof Zend_Controller_Response_Abstract) {
0117             // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
0118             throw new Zend_Test_PHPUnit_Constraint_Exception('Header constraint assertions require a response object');
0119         }
0120 
0121         if (strstr($assertType, 'Not')) {
0122             $this->setNegate(true);
0123             $assertType = str_replace('Not', '', $assertType);
0124         }
0125 
0126         if (!in_array($assertType, $this->_assertTypes)) {
0127             // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
0128             throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__));
0129         }
0130 
0131         $this->_assertType = $assertType;
0132 
0133         $response = $other;
0134         $argv     = func_get_args();
0135         $argc     = func_num_args();
0136 
0137         switch ($assertType) {
0138             case self::ASSERT_RESPONSE_CODE:
0139                 if (3 > $argc) {
0140                     // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
0141                     throw new Zend_Test_PHPUnit_Constraint_Exception('No response code provided against which to match');
0142                 }
0143                 $this->_code = $code = $argv[2];
0144                 return ($this->_negate)
0145                     ? $this->_notCode($response, $code)
0146                     : $this->_code($response, $code);
0147             case self::ASSERT_HEADER:
0148                 if (3 > $argc) {
0149                     // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
0150                     throw new Zend_Test_PHPUnit_Constraint_Exception('No header provided against which to match');
0151                 }
0152                 $this->_header = $header = $argv[2];
0153                 return ($this->_negate)
0154                     ? $this->_notHeader($response, $header)
0155                     : $this->_header($response, $header);
0156             case self::ASSERT_HEADER_CONTAINS:
0157                 if (4 > $argc) {
0158                     // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
0159                     throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . __FUNCTION__);
0160                 }
0161                 $this->_header = $header = $argv[2];
0162                 $this->_match  = $match  = $argv[3];
0163                 return ($this->_negate)
0164                     ? $this->_notHeaderContains($response, $header, $match)
0165                     : $this->_headerContains($response, $header, $match);
0166             case self::ASSERT_HEADER_REGEX:
0167                 if (4 > $argc) {
0168                     // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
0169                     throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . __FUNCTION__);
0170                 }
0171                 $this->_header = $header = $argv[2];
0172                 $this->_match  = $match  = $argv[3];
0173                 return ($this->_negate)
0174                     ? $this->_notHeaderRegex($response, $header, $match)
0175                     : $this->_headerRegex($response, $header, $match);
0176             default:
0177                 // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
0178                 throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . __FUNCTION__);
0179         }
0180     }
0181 
0182     /**
0183      * Report Failure
0184      *
0185      * @see    PHPUnit_Framework_Constraint for implementation details
0186      * @param  mixed $other
0187      * @param  string $description Additional message to display
0188      * @param  bool $not
0189      * @return void
0190      * @throws PHPUnit_Framework_ExpectationFailedException
0191      */
0192     public function fail($other, $description, $not = false)
0193     {
0194         // require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
0195         switch ($this->_assertType) {
0196             case self::ASSERT_RESPONSE_CODE:
0197                 $failure = 'Failed asserting response code "%s"';
0198                 if ($this->_negate) {
0199                     $failure = 'Failed asserting response code IS NOT "%s"';
0200                 }
0201                 $failure = sprintf($failure, $this->_code);
0202                 if (!$this->_negate && $this->_actualCode) {
0203                     $failure .= sprintf(PHP_EOL . 'Was "%s"', $this->_actualCode);
0204                 }
0205                 break;
0206             case self::ASSERT_HEADER:
0207                 $failure = 'Failed asserting response header "%s" found';
0208                 if ($this->_negate) {
0209                     $failure = 'Failed asserting response response header "%s" WAS NOT found';
0210                 }
0211                 $failure = sprintf($failure, $this->_header);
0212                 break;
0213             case self::ASSERT_HEADER_CONTAINS:
0214                 $failure = 'Failed asserting response header "%s" exists and contains "%s"';
0215                 if ($this->_negate) {
0216                     $failure = 'Failed asserting response header "%s" DOES NOT CONTAIN "%s"';
0217                 }
0218                 $failure = sprintf($failure, $this->_header, $this->_match);
0219                 break;
0220             case self::ASSERT_HEADER_REGEX:
0221                 $failure = 'Failed asserting response header "%s" exists and matches regex "%s"';
0222                 if ($this->_negate) {
0223                     $failure = 'Failed asserting response header "%s" DOES NOT MATCH regex "%s"';
0224                 }
0225                 $failure = sprintf($failure, $this->_header, $this->_match);
0226                 break;
0227             default:
0228                 throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . __FUNCTION__);
0229         }
0230 
0231         if (!empty($description)) {
0232             $failure = $description . "\n" . $failure;
0233         }
0234 
0235         throw new Zend_Test_PHPUnit_Constraint_Exception($failure);
0236     }
0237 
0238     /**
0239      * Complete implementation
0240      *
0241      * @return string
0242      */
0243     public function toString()
0244     {
0245         return '';
0246     }
0247 
0248     /**
0249      * Compare response code for positive match
0250      *
0251      * @param  Zend_Controller_Response_Abstract $response
0252      * @param  int $code
0253      * @return bool
0254      */
0255     protected function _code(Zend_Controller_Response_Abstract $response, $code)
0256     {
0257         $test = $this->_getCode($response);
0258         $this->_actualCode = $test;
0259         return ($test == $code);
0260     }
0261 
0262     /**
0263      * Compare response code for negative match
0264      *
0265      * @param  Zend_Controller_Response_Abstract $response
0266      * @param  int $code
0267      * @return bool
0268      */
0269     protected function _notCode(Zend_Controller_Response_Abstract $response, $code)
0270     {
0271         $test = $this->_getCode($response);
0272         return ($test != $code);
0273     }
0274 
0275     /**
0276      * Retrieve response code
0277      *
0278      * @param  Zend_Controller_Response_Abstract $response
0279      * @return int
0280      */
0281     protected function _getCode(Zend_Controller_Response_Abstract $response)
0282     {
0283         $test = $response->getHttpResponseCode();
0284         if (null === $test) {
0285             $test = 200;
0286         }
0287         return $test;
0288     }
0289 
0290     /**
0291      * Positive check for response header presence
0292      *
0293      * @param  Zend_Controller_Response_Abstract $response
0294      * @param  string $header
0295      * @return bool
0296      */
0297     protected function _header(Zend_Controller_Response_Abstract $response, $header)
0298     {
0299         return (null !== $this->_getHeader($response, $header));
0300     }
0301 
0302     /**
0303      * Negative check for response header presence
0304      *
0305      * @param  Zend_Controller_Response_Abstract $response
0306      * @param  string $header
0307      * @return bool
0308      */
0309     protected function _notHeader(Zend_Controller_Response_Abstract $response, $header)
0310     {
0311         return (null === $this->_getHeader($response, $header));
0312     }
0313 
0314     /**
0315      * Retrieve response header
0316      *
0317      * @param  Zend_Controller_Response_Abstract $response
0318      * @param  string $header
0319      * @return string|null
0320      */
0321     protected function _getHeader(Zend_Controller_Response_Abstract $response, $header)
0322     {
0323         $headers = $response->sendHeaders();
0324         $header  = strtolower($header);
0325         if (array_key_exists($header, $headers)) {
0326             return $headers[$header];
0327         }
0328         return null;
0329     }
0330 
0331     /**
0332      * Positive check for header contents matching pattern
0333      *
0334      * @param  Zend_Controller_Response_Abstract $response
0335      * @param  string $header
0336      * @param  string $match
0337      * @return bool
0338      */
0339     protected function _headerContains(Zend_Controller_Response_Abstract $response, $header, $match)
0340     {
0341         if (null === ($fullHeader = $this->_getHeader($response, $header))) {
0342             return false;
0343         }
0344 
0345         $contents = str_replace($header . ': ', '', $fullHeader);
0346 
0347         return (strstr($contents, $match) !== false);
0348     }
0349 
0350     /**
0351      * Negative check for header contents matching pattern
0352      *
0353      * @param  Zend_Controller_Response_Abstract $response
0354      * @param  string $header
0355      * @param  string $match
0356      * @return bool
0357      */
0358     protected function _notHeaderContains(Zend_Controller_Response_Abstract $response, $header, $match)
0359     {
0360         if (null === ($fullHeader = $this->_getHeader($response, $header))) {
0361             return true;
0362         }
0363 
0364         $contents = str_replace($header . ': ', '', $fullHeader);
0365 
0366         return (strstr($contents, $match) === false);
0367     }
0368 
0369     /**
0370      * Positive check for header contents matching regex
0371      *
0372      * @param  Zend_Controller_Response_Abstract $response
0373      * @param  string $header
0374      * @param  string $pattern
0375      * @return bool
0376      */
0377     protected function _headerRegex(Zend_Controller_Response_Abstract $response, $header, $pattern)
0378     {
0379         if (null === ($fullHeader = $this->_getHeader($response, $header))) {
0380             return false;
0381         }
0382 
0383         $contents = str_replace($header . ': ', '', $fullHeader);
0384 
0385         return preg_match($pattern, $contents);
0386     }
0387 
0388     /**
0389      * Negative check for header contents matching regex
0390      *
0391      * @param  Zend_Controller_Response_Abstract $response
0392      * @param  string $header
0393      * @param  string $pattern
0394      * @return bool
0395      */
0396     protected function _notHeaderRegex(Zend_Controller_Response_Abstract $response, $header, $pattern)
0397     {
0398         if (null === ($fullHeader = $this->_getHeader($response, $header))) {
0399             return true;
0400         }
0401 
0402         $contents = str_replace($header . ': ', '', $fullHeader);
0403 
0404         return !preg_match($pattern, $contents);
0405     }
0406 }