File indexing completed on 2024-06-23 05:55:48

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 }