ResponseTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  5. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  6. *
  7. * Licensed under The MIT License
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Http\Client;
  16. use Cake\Http\Client\Response;
  17. use Cake\Http\Cookie\CookieCollection;
  18. use Cake\TestSuite\TestCase;
  19. /**
  20. * HTTP response test.
  21. */
  22. class ResponseTest extends TestCase
  23. {
  24. /**
  25. * Test parsing headers and reading with PSR7 methods.
  26. *
  27. * @return void
  28. */
  29. public function testHeaderParsingPsr7()
  30. {
  31. $headers = [
  32. 'HTTP/1.0 200 OK',
  33. 'Content-Type : text/html;charset="UTF-8"',
  34. 'date: Tue, 25 Dec 2012 04:43:47 GMT',
  35. ];
  36. $response = new Response($headers, 'winner!');
  37. $this->assertSame('1.0', $response->getProtocolVersion());
  38. $this->assertSame(200, $response->getStatusCode());
  39. $this->assertSame('OK', $response->getReasonPhrase());
  40. $this->assertSame(
  41. 'text/html;charset="UTF-8"',
  42. $response->getHeaderLine('content-type')
  43. );
  44. $this->assertSame(
  45. 'Tue, 25 Dec 2012 04:43:47 GMT',
  46. $response->getHeaderLine('Date')
  47. );
  48. $this->assertSame('winner!', '' . $response->getBody());
  49. }
  50. /**
  51. * Test parsing headers and capturing content
  52. *
  53. * @return void
  54. */
  55. public function testHeaderParsing()
  56. {
  57. $headers = [
  58. 'HTTP/1.0 200 OK',
  59. 'Content-Type : text/html;charset="UTF-8"',
  60. 'date: Tue, 25 Dec 2012 04:43:47 GMT',
  61. ];
  62. $response = new Response($headers, 'ok');
  63. $this->assertSame(200, $response->getStatusCode());
  64. $this->assertSame('1.0', $response->getProtocolVersion());
  65. $this->assertSame(
  66. 'text/html;charset="UTF-8"',
  67. $response->getHeaderLine('content-type')
  68. );
  69. $this->assertSame(
  70. 'Tue, 25 Dec 2012 04:43:47 GMT',
  71. $response->getHeaderLine('Date')
  72. );
  73. $this->assertSame(
  74. 'text/html;charset="UTF-8"',
  75. $response->getHeaderLine('Content-Type')
  76. );
  77. $headers = [
  78. 'HTTP/1.0 200',
  79. ];
  80. $response = new Response($headers, 'ok');
  81. $this->assertSame('1.0', $response->getProtocolVersion());
  82. $this->assertSame(200, $response->getStatusCode());
  83. }
  84. /**
  85. * Test getStringBody()
  86. *
  87. * @return void
  88. */
  89. public function getStringBody()
  90. {
  91. $response = new Response([], 'string');
  92. $this->assertSame('string', $response->getStringBody());
  93. }
  94. /**
  95. * Test accessor for json
  96. *
  97. * @return void
  98. */
  99. public function testBodyJson()
  100. {
  101. $data = [
  102. 'property' => 'value',
  103. ];
  104. $encoded = json_encode($data);
  105. $response = new Response([], $encoded);
  106. $this->assertSame($data['property'], $response->getJson()['property']);
  107. $data = '';
  108. $response = new Response([], $data);
  109. $this->assertNull($response->getJson());
  110. $data = json_encode([]);
  111. $response = new Response([], $data);
  112. $this->assertIsArray($response->getJson());
  113. $data = json_encode(null);
  114. $response = new Response([], $data);
  115. $this->assertNull($response->getJson());
  116. $data = json_encode(false);
  117. $response = new Response([], $data);
  118. $this->assertFalse($response->getJson());
  119. $data = json_encode('');
  120. $response = new Response([], $data);
  121. $this->assertSame('', $response->getJson());
  122. }
  123. /**
  124. * Test accessor for json when set with PSR7 methods.
  125. *
  126. * @return void
  127. */
  128. public function testBodyJsonPsr7()
  129. {
  130. $data = [
  131. 'property' => 'value',
  132. ];
  133. $encoded = json_encode($data);
  134. $response = new Response([], '');
  135. $response->getBody()->write($encoded);
  136. $this->assertEquals($data, $response->getJson());
  137. }
  138. /**
  139. * Test accessor for xml
  140. *
  141. * @return void
  142. */
  143. public function testBodyXml()
  144. {
  145. $data = <<<XML
  146. <?xml version="1.0" encoding="utf-8"?>
  147. <root>
  148. <test>Test</test>
  149. </root>
  150. XML;
  151. $response = new Response([], $data);
  152. $this->assertSame('Test', (string)$response->getXml()->test);
  153. $data = '';
  154. $response = new Response([], $data);
  155. $this->assertNull($response->getXml());
  156. }
  157. /**
  158. * Test isOk()
  159. *
  160. * @return void
  161. */
  162. public function testIsOk()
  163. {
  164. $headers = [
  165. 'HTTP/1.1 200 OK',
  166. 'Content-Type: text/html',
  167. ];
  168. $response = new Response($headers, 'ok');
  169. $this->assertTrue($response->isOk());
  170. $headers = [
  171. 'HTTP/1.1 201 Created',
  172. 'Content-Type: text/html',
  173. ];
  174. $response = new Response($headers, 'ok');
  175. $this->assertTrue($response->isOk());
  176. $headers = [
  177. 'HTTP/1.1 202 Accepted',
  178. 'Content-Type: text/html',
  179. ];
  180. $response = new Response($headers, 'ok');
  181. $this->assertTrue($response->isOk());
  182. $headers = [
  183. 'HTTP/1.1 203 Non-Authoritative Information',
  184. 'Content-Type: text/html',
  185. ];
  186. $response = new Response($headers, 'ok');
  187. $this->assertTrue($response->isOk());
  188. $headers = [
  189. 'HTTP/1.1 204 No Content',
  190. 'Content-Type: text/html',
  191. ];
  192. $response = new Response($headers, 'ok');
  193. $this->assertTrue($response->isOk());
  194. $headers = [
  195. 'HTTP/1.1 301 Moved Permanently',
  196. 'Content-Type: text/html',
  197. ];
  198. $response = new Response($headers, '');
  199. $this->assertTrue($response->isOk());
  200. $headers = [
  201. 'HTTP/1.0 404 Not Found',
  202. 'Content-Type: text/html',
  203. ];
  204. $response = new Response($headers, '');
  205. $this->assertFalse($response->isOk());
  206. }
  207. /**
  208. * provider for isSuccess.
  209. *
  210. * @return array
  211. */
  212. public static function isSuccessProvider()
  213. {
  214. return [
  215. [
  216. true,
  217. new Response([
  218. 'HTTP/1.1 200 OK',
  219. 'Content-Type: text/html',
  220. ], 'ok'),
  221. ],
  222. [
  223. true,
  224. new Response([
  225. 'HTTP/1.1 201 Created',
  226. 'Content-Type: text/html',
  227. ], 'ok'),
  228. ],
  229. [
  230. true,
  231. new Response([
  232. 'HTTP/1.1 202 Accepted',
  233. 'Content-Type: text/html',
  234. ], 'ok'),
  235. ],
  236. [
  237. true,
  238. new Response([
  239. 'HTTP/1.1 203 Non-Authoritative Information',
  240. 'Content-Type: text/html',
  241. ], 'ok'),
  242. ],
  243. [
  244. true,
  245. new Response([
  246. 'HTTP/1.1 204 No Content',
  247. 'Content-Type: text/html',
  248. ], ''),
  249. ],
  250. [
  251. false,
  252. new Response([
  253. 'HTTP/1.1 301 Moved Permanently',
  254. 'Content-Type: text/html',
  255. ], ''),
  256. ],
  257. [
  258. false,
  259. new Response([
  260. 'HTTP/1.0 404 Not Found',
  261. 'Content-Type: text/html',
  262. ], ''),
  263. ],
  264. ];
  265. }
  266. /**
  267. * Test isSuccess()
  268. *
  269. * @dataProvider isSuccessProvider
  270. * @return void
  271. */
  272. public function testIsSuccess($expected, Response $response)
  273. {
  274. $this->assertEquals($expected, $response->isSuccess());
  275. }
  276. /**
  277. * Test isRedirect()
  278. *
  279. * @return void
  280. */
  281. public function testIsRedirect()
  282. {
  283. $headers = [
  284. 'HTTP/1.1 200 OK',
  285. 'Content-Type: text/html',
  286. ];
  287. $response = new Response($headers, 'ok');
  288. $this->assertFalse($response->isRedirect());
  289. $headers = [
  290. 'HTTP/1.1 301 Moved Permanently',
  291. 'Location: /',
  292. 'Content-Type: text/html',
  293. ];
  294. $response = new Response($headers, '');
  295. $this->assertTrue($response->isRedirect());
  296. $headers = [
  297. 'HTTP/1.0 404 Not Found',
  298. 'Content-Type: text/html',
  299. ];
  300. $response = new Response($headers, '');
  301. $this->assertFalse($response->isRedirect());
  302. }
  303. /**
  304. * Test accessing cookies through the PSR7-like methods
  305. *
  306. * @return void
  307. */
  308. public function testGetCookies()
  309. {
  310. $headers = [
  311. 'HTTP/1.0 200 Ok',
  312. 'Set-Cookie: test=value',
  313. 'Set-Cookie: session=123abc',
  314. 'Set-Cookie: expiring=soon; Expires=Wed, 09-Jun-2021 10:18:14 GMT; Path=/; HttpOnly; Secure;',
  315. ];
  316. $response = new Response($headers, '');
  317. $this->assertNull($response->getCookie('undef'));
  318. $this->assertSame('value', $response->getCookie('test'));
  319. $this->assertSame('soon', $response->getCookie('expiring'));
  320. $result = $response->getCookieData('expiring');
  321. $this->assertSame('soon', $result['value']);
  322. $this->assertTrue($result['httponly']);
  323. $this->assertTrue($result['secure']);
  324. $this->assertSame(
  325. strtotime('Wed, 09-Jun-2021 10:18:14 GMT'),
  326. $result['expires']
  327. );
  328. $this->assertSame('/', $result['path']);
  329. $result = $response->getCookies();
  330. $this->assertCount(3, $result);
  331. $this->assertArrayHasKey('test', $result);
  332. $this->assertArrayHasKey('session', $result);
  333. $this->assertArrayHasKey('expiring', $result);
  334. }
  335. /**
  336. * Test accessing cookie collection
  337. *
  338. * @return void
  339. */
  340. public function testGetCookieCollection()
  341. {
  342. $headers = [
  343. 'HTTP/1.0 200 Ok',
  344. 'Set-Cookie: test=value',
  345. 'Set-Cookie: session=123abc',
  346. 'Set-Cookie: expiring=soon; Expires=Wed, 09-Jun-2021 10:18:14 GMT; Path=/; HttpOnly; Secure;',
  347. ];
  348. $response = new Response($headers, '');
  349. $cookies = $response->getCookieCollection();
  350. $this->assertInstanceOf(CookieCollection::class, $cookies);
  351. $this->assertTrue($cookies->has('test'));
  352. $this->assertTrue($cookies->has('session'));
  353. $this->assertTrue($cookies->has('expiring'));
  354. $this->assertSame('123abc', $cookies->get('session')->getValue());
  355. }
  356. /**
  357. * Test statusCode()
  358. *
  359. * @return void
  360. */
  361. public function testGetStatusCode()
  362. {
  363. $headers = [
  364. 'HTTP/1.0 404 Not Found',
  365. 'Content-Type: text/html',
  366. ];
  367. $response = new Response($headers, '');
  368. $this->assertSame(404, $response->getStatusCode());
  369. }
  370. /**
  371. * Test reading the encoding out.
  372. *
  373. * @return void
  374. */
  375. public function testGetEncoding()
  376. {
  377. $headers = [
  378. 'HTTP/1.0 200 Ok',
  379. ];
  380. $response = new Response($headers, '');
  381. $this->assertNull($response->getEncoding());
  382. $headers = [
  383. 'HTTP/1.0 200 Ok',
  384. 'Content-Type: text/html',
  385. ];
  386. $response = new Response($headers, '');
  387. $this->assertNull($response->getEncoding());
  388. $headers = [
  389. 'HTTP/1.0 200 Ok',
  390. 'Content-Type: text/html; charset="UTF-8"',
  391. ];
  392. $response = new Response($headers, '');
  393. $this->assertSame('UTF-8', $response->getEncoding());
  394. $headers = [
  395. 'HTTP/1.0 200 Ok',
  396. "Content-Type: text/html; charset='ISO-8859-1'",
  397. ];
  398. $response = new Response($headers, '');
  399. $this->assertSame('ISO-8859-1', $response->getEncoding());
  400. }
  401. /**
  402. * Test that gzip responses are automatically decompressed.
  403. *
  404. * @return void
  405. */
  406. public function testAutoDecodeGzipBody()
  407. {
  408. $headers = [
  409. 'HTTP/1.0 200 OK',
  410. 'Content-Encoding: gzip',
  411. 'Content-Length: 32',
  412. 'Content-Type: text/html; charset=UTF-8',
  413. ];
  414. $body = base64_decode('H4sIAAAAAAAAA/NIzcnJVyjPL8pJUQQAlRmFGwwAAAA=');
  415. $response = new Response($headers, $body);
  416. $this->assertSame('Hello world!', $response->getBody()->getContents());
  417. }
  418. }