PageRenderTime 25ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Test/PHPUnit/Constraint/ResponseHeader.php

https://github.com/mfairchild365/zf2
PHP | 395 lines | 193 code | 38 blank | 164 comment | 22 complexity | 35b4ac282195a88e70e6bfd29fb8ddd0 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Test
  17. * @subpackage PHPUnit
  18. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. /**
  22. * @namespace
  23. */
  24. namespace Zend\Test\PHPUnit\Constraint;
  25. use Zend\Controller\Response;
  26. /**
  27. * Response header PHPUnit Constraint
  28. *
  29. * @uses PHPUnit_Framework_Constraint
  30. * @uses \Zend\Test\PHPUnit\Constraint\Exception\ConstraintException
  31. * @category Zend
  32. * @package Zend_Test
  33. * @subpackage PHPUnit
  34. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  35. * @license http://framework.zend.com/license/new-bsd New BSD License
  36. */
  37. class ResponseHeader extends \PHPUnit_Framework_Constraint
  38. {
  39. /**#@+
  40. * Assertion type constants
  41. */
  42. const ASSERT_RESPONSE_CODE = 'assertResponseCode';
  43. const ASSERT_HEADER = 'assertHeader';
  44. const ASSERT_HEADER_CONTAINS = 'assertHeaderContains';
  45. const ASSERT_HEADER_REGEX = 'assertHeaderRegex';
  46. /**#@-*/
  47. /**
  48. * Current assertion type
  49. * @var string
  50. */
  51. protected $_assertType = null;
  52. /**
  53. * Available assertion types
  54. * @var array
  55. */
  56. protected $_assertTypes = array(
  57. self::ASSERT_RESPONSE_CODE,
  58. self::ASSERT_HEADER,
  59. self::ASSERT_HEADER_CONTAINS,
  60. self::ASSERT_HEADER_REGEX,
  61. );
  62. /**
  63. * @var int Response code
  64. */
  65. protected $_code = 200;
  66. /**
  67. * @var string Header
  68. */
  69. protected $_header = null;
  70. /**
  71. * @var string pattern against which to compare header content
  72. */
  73. protected $_match = null;
  74. /**
  75. * Whether or not assertion is negated
  76. * @var bool
  77. */
  78. protected $_negate = false;
  79. /**
  80. * Constructor; setup constraint state
  81. *
  82. * @return void
  83. */
  84. public function __construct()
  85. {
  86. }
  87. /**
  88. * Indicate negative match
  89. *
  90. * @param bool $flag
  91. * @return void
  92. */
  93. public function setNegate($flag = true)
  94. {
  95. $this->_negate = $flag;
  96. }
  97. /**
  98. * Evaluate an object to see if it fits the constraints
  99. *
  100. * @param \Zend\Controller\Response\AbstractResponse $other String to examine
  101. * @param null|string Assertion type
  102. * @return bool
  103. */
  104. public function evaluate($other, $assertType = null)
  105. {
  106. if (!$other instanceof Response\AbstractResponse) {
  107. throw new Exception\ConstraintException('Header constraint assertions require a response object');
  108. }
  109. if (strstr($assertType, 'Not')) {
  110. $this->setNegate(true);
  111. $assertType = str_replace('Not', '', $assertType);
  112. }
  113. if (!in_array($assertType, $this->_assertTypes)) {
  114. throw new Exception\ConstraintException(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__));
  115. }
  116. $this->_assertType = $assertType;
  117. $response = $other;
  118. $argv = func_get_args();
  119. $argc = func_num_args();
  120. switch ($assertType) {
  121. case self::ASSERT_RESPONSE_CODE:
  122. if (3 > $argc) {
  123. throw new Exception\ConstraintException('No response code provided against which to match');
  124. }
  125. $this->_code = $code = $argv[2];
  126. return ($this->_negate)
  127. ? $this->_notCode($response, $code)
  128. : $this->_code($response, $code);
  129. case self::ASSERT_HEADER:
  130. if (3 > $argc) {
  131. throw new Exception\ConstraintException('No header provided against which to match');
  132. }
  133. $this->_header = $header = $argv[2];
  134. return ($this->_negate)
  135. ? $this->_notHeader($response, $header)
  136. : $this->_header($response, $header);
  137. case self::ASSERT_HEADER_CONTAINS:
  138. if (4 > $argc) {
  139. throw new Exception\ConstraintException('Both a header name and content to match are required for ' . __FUNCTION__);
  140. }
  141. $this->_header = $header = $argv[2];
  142. $this->_match = $match = $argv[3];
  143. return ($this->_negate)
  144. ? $this->_notHeaderContains($response, $header, $match)
  145. : $this->_headerContains($response, $header, $match);
  146. case self::ASSERT_HEADER_REGEX:
  147. if (4 > $argc) {
  148. throw new Exception\ConstraintException('Both a header name and content to match are required for ' . __FUNCTION__);
  149. }
  150. $this->_header = $header = $argv[2];
  151. $this->_match = $match = $argv[3];
  152. return ($this->_negate)
  153. ? $this->_notHeaderRegex($response, $header, $match)
  154. : $this->_headerRegex($response, $header, $match);
  155. default:
  156. throw new Exception\ConstraintException('Invalid assertion type ' . __FUNCTION__);
  157. }
  158. }
  159. /**
  160. * Report Failure
  161. *
  162. * @see PHPUnit_Framework_Constraint for implementation details
  163. * @param mixed $other
  164. * @param string $description Additional message to display
  165. * @param bool $not
  166. * @return void
  167. * @throws PHPUnit_Framework_ExpectationFailedException
  168. */
  169. public function fail($other, $description, $not = false)
  170. {
  171. switch ($this->_assertType) {
  172. case self::ASSERT_RESPONSE_CODE:
  173. $failure = 'Failed asserting response code "%s"';
  174. if ($this->_negate) {
  175. $failure = 'Failed asserting response code IS NOT "%s"';
  176. }
  177. $failure = sprintf($failure, $this->_code);
  178. break;
  179. case self::ASSERT_HEADER:
  180. $failure = 'Failed asserting response header "%s" found';
  181. if ($this->_negate) {
  182. $failure = 'Failed asserting response response header "%s" WAS NOT found';
  183. }
  184. $failure = sprintf($failure, $this->_header);
  185. break;
  186. case self::ASSERT_HEADER_CONTAINS:
  187. $failure = 'Failed asserting response header "%s" exists and contains "%s"';
  188. if ($this->_negate) {
  189. $failure = 'Failed asserting response header "%s" DOES NOT CONTAIN "%s"';
  190. }
  191. $failure = sprintf($failure, $this->_header, $this->_match);
  192. break;
  193. case self::ASSERT_HEADER_REGEX:
  194. $failure = 'Failed asserting response header "%s" exists and matches regex "%s"';
  195. if ($this->_negate) {
  196. $failure = 'Failed asserting response header "%s" DOES NOT MATCH regex "%s"';
  197. }
  198. $failure = sprintf($failure, $this->_header, $this->_match);
  199. break;
  200. default:
  201. throw new Exception\ConstraintException('Invalid assertion type ' . __FUNCTION__);
  202. }
  203. if (!empty($description)) {
  204. $failure = $description . "\n" . $failure;
  205. }
  206. throw new Exception\ConstraintException($failure);
  207. }
  208. /**
  209. * Complete implementation
  210. *
  211. * @return string
  212. */
  213. public function toString()
  214. {
  215. return '';
  216. }
  217. /**
  218. * Compare response code for positive match
  219. *
  220. * @param \Zend\Controller\Response\AbstractResponse $response
  221. * @param int $code
  222. * @return bool
  223. */
  224. protected function _code(Response\AbstractResponse $response, $code)
  225. {
  226. $test = $this->_getCode($response);
  227. return ($test == $code);
  228. }
  229. /**
  230. * Compare response code for negative match
  231. *
  232. * @param \Zend\Controller\Response\AbstractResponse $response
  233. * @param int $code
  234. * @return bool
  235. */
  236. protected function _notCode(Response\AbstractResponse $response, $code)
  237. {
  238. $test = $this->_getCode($response);
  239. return ($test != $code);
  240. }
  241. /**
  242. * Retrieve response code
  243. *
  244. * @param \Zend\Controller\Response\AbstractResponse $response
  245. * @return int
  246. */
  247. protected function _getCode(Response\AbstractResponse $response)
  248. {
  249. $test = $response->getHttpResponseCode();
  250. if (null === $test) {
  251. $test = 200;
  252. }
  253. return $test;
  254. }
  255. /**
  256. * Positive check for response header presence
  257. *
  258. * @param \Zend\Controller\Response\AbstractResponse $response
  259. * @param string $header
  260. * @return bool
  261. */
  262. protected function _header(Response\AbstractResponse $response, $header)
  263. {
  264. return (null !== $this->_getHeader($response, $header));
  265. }
  266. /**
  267. * Negative check for response header presence
  268. *
  269. * @param \Zend\Controller\Response\AbstractResponse $response
  270. * @param string $header
  271. * @return bool
  272. */
  273. protected function _notHeader(Response\AbstractResponse $response, $header)
  274. {
  275. return (null === $this->_getHeader($response, $header));
  276. }
  277. /**
  278. * Retrieve response header
  279. *
  280. * @param \Zend\Controller\Response\AbstractResponse $response
  281. * @param string $header
  282. * @return string|null
  283. */
  284. protected function _getHeader(Response\AbstractResponse $response, $header)
  285. {
  286. $headers = $response->sendHeaders();
  287. $header = strtolower($header);
  288. if (array_key_exists($header, $headers)) {
  289. return $headers[$header];
  290. }
  291. return null;
  292. }
  293. /**
  294. * Positive check for header contents matching pattern
  295. *
  296. * @param \Zend\Controller\Response\AbstractResponse $response
  297. * @param string $header
  298. * @param string $match
  299. * @return bool
  300. */
  301. protected function _headerContains(Response\AbstractResponse $response, $header, $match)
  302. {
  303. if (null === ($fullHeader = $this->_getHeader($response, $header))) {
  304. return false;
  305. }
  306. $contents = str_replace($header . ': ', '', $fullHeader);
  307. return (strstr($contents, $match));
  308. }
  309. /**
  310. * Negative check for header contents matching pattern
  311. *
  312. * @param \Zend\Controller\Response\AbstractResponse $response
  313. * @param string $header
  314. * @param string $match
  315. * @return bool
  316. */
  317. protected function _notHeaderContains(Response\AbstractResponse $response, $header, $match)
  318. {
  319. if (null === ($fullHeader = $this->_getHeader($response, $header))) {
  320. return true;
  321. }
  322. $contents = str_replace($header . ': ', '', $fullHeader);
  323. return (!strstr($contents, $match));
  324. }
  325. /**
  326. * Positive check for header contents matching regex
  327. *
  328. * @param \Zend\Controller\Response\AbstractResponse $response
  329. * @param string $header
  330. * @param string $pattern
  331. * @return bool
  332. */
  333. protected function _headerRegex(Response\AbstractResponse $response, $header, $pattern)
  334. {
  335. if (null === ($fullHeader = $this->_getHeader($response, $header))) {
  336. return false;
  337. }
  338. $contents = str_replace($header . ': ', '', $fullHeader);
  339. return preg_match($pattern, $contents);
  340. }
  341. /**
  342. * Negative check for header contents matching regex
  343. *
  344. * @param \Zend\Controller\Response\AbstractResponse $response
  345. * @param string $header
  346. * @param string $pattern
  347. * @return bool
  348. */
  349. protected function _notHeaderRegex(Response\AbstractResponse $response, $header, $pattern)
  350. {
  351. if (null === ($fullHeader = $this->_getHeader($response, $header))) {
  352. return true;
  353. }
  354. $contents = str_replace($header . ': ', '', $fullHeader);
  355. return !preg_match($pattern, $contents);
  356. }
  357. }