PageRenderTime 27ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/laravel/lumen-framework/src/Testing/Concerns/MakesHttpRequests.php

https://gitlab.com/systemovich/lumen-test
PHP | 453 lines | 208 code | 74 blank | 171 comment | 16 complexity | b254ee42addf16c2ebe487e43d52dff0 MD5 | raw file
  1. <?php
  2. namespace Laravel\Lumen\Testing\Concerns;
  3. use Illuminate\Support\Str;
  4. use Illuminate\Http\Request;
  5. use PHPUnit_Framework_Assert as PHPUnit;
  6. trait MakesHttpRequests
  7. {
  8. /**
  9. * The last response returned by the application.
  10. *
  11. * @var \Illuminate\Http\Response
  12. */
  13. protected $response;
  14. /**
  15. * The current URL being viewed.
  16. *
  17. * @var string
  18. */
  19. protected $currentUri;
  20. /**
  21. * Visit the given URI with a JSON request.
  22. *
  23. * @param string $method
  24. * @param string $uri
  25. * @param array $data
  26. * @param array $headers
  27. * @return $this
  28. */
  29. public function json($method, $uri, array $data = [], array $headers = [])
  30. {
  31. $content = json_encode($data);
  32. $headers = array_merge([
  33. 'CONTENT_LENGTH' => mb_strlen($content, '8bit'),
  34. 'CONTENT_TYPE' => 'application/json',
  35. 'Accept' => 'application/json',
  36. ], $headers);
  37. $this->call(
  38. $method, $uri, [], [], [], $this->transformHeadersToServerVars($headers), $content
  39. );
  40. return $this;
  41. }
  42. /**
  43. * Visit the given URI with a GET request.
  44. *
  45. * @param string $uri
  46. * @param array $headers
  47. * @return $this
  48. */
  49. public function get($uri, array $headers = [])
  50. {
  51. $server = $this->transformHeadersToServerVars($headers);
  52. $this->call('GET', $uri, [], [], [], $server);
  53. return $this;
  54. }
  55. /**
  56. * Visit the given URI with a POST request.
  57. *
  58. * @param string $uri
  59. * @param array $data
  60. * @param array $headers
  61. * @return $this
  62. */
  63. public function post($uri, array $data = [], array $headers = [])
  64. {
  65. $server = $this->transformHeadersToServerVars($headers);
  66. $this->call('POST', $uri, $data, [], [], $server);
  67. return $this;
  68. }
  69. /**
  70. * Visit the given URI with a PUT request.
  71. *
  72. * @param string $uri
  73. * @param array $data
  74. * @param array $headers
  75. * @return $this
  76. */
  77. public function put($uri, array $data = [], array $headers = [])
  78. {
  79. $server = $this->transformHeadersToServerVars($headers);
  80. $this->call('PUT', $uri, $data, [], [], $server);
  81. return $this;
  82. }
  83. /**
  84. * Visit the given URI with a PATCH request.
  85. *
  86. * @param string $uri
  87. * @param array $data
  88. * @param array $headers
  89. * @return $this
  90. */
  91. public function patch($uri, array $data = [], array $headers = [])
  92. {
  93. $server = $this->transformHeadersToServerVars($headers);
  94. $this->call('PATCH', $uri, $data, [], [], $server);
  95. return $this;
  96. }
  97. /**
  98. * Visit the given URI with a DELETE request.
  99. *
  100. * @param string $uri
  101. * @param array $data
  102. * @param array $headers
  103. * @return $this
  104. */
  105. public function delete($uri, array $data = [], array $headers = [])
  106. {
  107. $server = $this->transformHeadersToServerVars($headers);
  108. $this->call('DELETE', $uri, $data, [], [], $server);
  109. return $this;
  110. }
  111. /**
  112. * Send the given request through the application.
  113. *
  114. * This method allows you to fully customize the entire Request object.
  115. *
  116. * @param \Illuminate\Http\Request $request
  117. * @return $this
  118. */
  119. public function handle(Request $request)
  120. {
  121. $this->currentUri = $request->fullUrl();
  122. $this->response = $this->app->prepareResponse($this->app->handle($request));
  123. return $this;
  124. }
  125. /**
  126. * Assert that the response contains JSON.
  127. *
  128. * @param array|null $data
  129. * @return $this
  130. */
  131. protected function shouldReturnJson(array $data = null)
  132. {
  133. return $this->receiveJson($data);
  134. }
  135. /**
  136. * Assert that the response contains JSON.
  137. *
  138. * @param array|null $data
  139. * @return $this|null
  140. */
  141. protected function receiveJson($data = null)
  142. {
  143. return $this->seeJson($data);
  144. }
  145. /**
  146. * Assert that the response contains an exact JSON array.
  147. *
  148. * @param array $data
  149. * @return $this
  150. */
  151. public function seeJsonEquals(array $data)
  152. {
  153. $actual = json_encode(array_sort_recursive(
  154. json_decode($this->response->getContent(), true)
  155. ));
  156. $this->assertEquals(json_encode(array_sort_recursive($data)), $actual);
  157. return $this;
  158. }
  159. /**
  160. * Assert that the response contains JSON.
  161. *
  162. * @param array|null $data
  163. * @param bool $negate
  164. * @return $this
  165. */
  166. public function seeJson(array $data = null, $negate = false)
  167. {
  168. if (is_null($data)) {
  169. $this->assertJson(
  170. $this->response->getContent(), "JSON was not returned from [{$this->currentUri}]."
  171. );
  172. return $this;
  173. }
  174. return $this->seeJsonContains($data, $negate);
  175. }
  176. /**
  177. * Assert that the response doesn't contain JSON.
  178. *
  179. * @param array|null $data
  180. * @return $this
  181. */
  182. public function dontSeeJson(array $data = null)
  183. {
  184. return $this->seeJson($data, true);
  185. }
  186. /**
  187. * Assert that the JSON response has a given structure.
  188. *
  189. * @param array|null $structure
  190. * @param array|null $responseData
  191. * @return $this
  192. */
  193. public function seeJsonStructure(array $structure = null, $responseData = null)
  194. {
  195. if (is_null($structure)) {
  196. return $this->seeJson();
  197. }
  198. if (! $responseData) {
  199. $responseData = json_decode($this->response->getContent(), true);
  200. }
  201. foreach ($structure as $key => $value) {
  202. if (is_array($value) && $key === '*') {
  203. $this->assertInternalType('array', $responseData);
  204. foreach ($responseData as $responseDataItem) {
  205. $this->seeJsonStructure($structure['*'], $responseDataItem);
  206. }
  207. } elseif (is_array($value)) {
  208. $this->assertArrayHasKey($key, $responseData);
  209. $this->seeJsonStructure($structure[$key], $responseData[$key]);
  210. } else {
  211. $this->assertArrayHasKey($value, $responseData);
  212. }
  213. }
  214. return $this;
  215. }
  216. /**
  217. * Assert that the response contains the given JSON.
  218. *
  219. * @param array $data
  220. * @param bool $negate
  221. * @return $this
  222. */
  223. protected function seeJsonContains(array $data, $negate = false)
  224. {
  225. $method = $negate ? 'assertFalse' : 'assertTrue';
  226. $actual = json_decode($this->response->getContent(), true);
  227. if (is_null($actual) || $actual === false) {
  228. return $this->fail('Invalid JSON was returned from the route. Perhaps an exception was thrown?');
  229. }
  230. $actual = json_encode(array_sort_recursive(
  231. (array) $actual
  232. ));
  233. foreach (array_sort_recursive($data) as $key => $value) {
  234. $expected = $this->formatToExpectedJson($key, $value);
  235. $this->{$method}(
  236. Str::contains($actual, $expected),
  237. ($negate ? 'Found unexpected' : 'Unable to find')." JSON fragment [{$expected}] within [{$actual}]."
  238. );
  239. }
  240. return $this;
  241. }
  242. /**
  243. * Format the given key and value into a JSON string for expectation checks.
  244. *
  245. * @param string $key
  246. * @param mixed $value
  247. * @return string
  248. */
  249. protected function formatToExpectedJson($key, $value)
  250. {
  251. $expected = json_encode([$key => $value]);
  252. if (Str::startsWith($expected, '{')) {
  253. $expected = substr($expected, 1);
  254. }
  255. if (Str::endsWith($expected, '}')) {
  256. $expected = substr($expected, 0, -1);
  257. }
  258. return $expected;
  259. }
  260. /**
  261. * Call the given URI and return the Response.
  262. *
  263. * @param string $method
  264. * @param string $uri
  265. * @param array $parameters
  266. * @param array $cookies
  267. * @param array $files
  268. * @param array $server
  269. * @param string $content
  270. * @return \Illuminate\Http\Response
  271. */
  272. public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
  273. {
  274. $this->currentUri = $this->prepareUrlForRequest($uri);
  275. $request = Request::create(
  276. $this->currentUri, $method, $parameters,
  277. $cookies, $files, $server, $content
  278. );
  279. return $this->response = $this->app->prepareResponse(
  280. $this->app->handle($request)
  281. );
  282. }
  283. /**
  284. * Turn the given URI into a fully qualified URL.
  285. *
  286. * @param string $uri
  287. * @return string
  288. */
  289. protected function prepareUrlForRequest($uri)
  290. {
  291. if (Str::startsWith($uri, '/')) {
  292. $uri = substr($uri, 1);
  293. }
  294. if (! Str::startsWith($uri, 'http')) {
  295. $uri = $this->baseUrl.'/'.$uri;
  296. }
  297. return trim($uri, '/');
  298. }
  299. /**
  300. * Transform headers array to array of $_SERVER vars with HTTP_* format.
  301. *
  302. * @param array $headers
  303. * @return array
  304. */
  305. protected function transformHeadersToServerVars(array $headers)
  306. {
  307. $server = [];
  308. $prefix = 'HTTP_';
  309. foreach ($headers as $name => $value) {
  310. $name = strtr(strtoupper($name), '-', '_');
  311. if (! starts_with($name, $prefix) && $name != 'CONTENT_TYPE') {
  312. $name = $prefix.$name;
  313. }
  314. $server[$name] = $value;
  315. }
  316. return $server;
  317. }
  318. /**
  319. * Assert that the client response has an OK status code.
  320. *
  321. * @return void
  322. */
  323. public function assertResponseOk()
  324. {
  325. $actual = $this->response->getStatusCode();
  326. return PHPUnit::assertTrue($this->response->isOk(), "Expected status code 200, got {$actual}.");
  327. }
  328. /**
  329. * Assert that the client response has a given code.
  330. *
  331. * @param int $code
  332. * @return void
  333. */
  334. public function assertResponseStatus($code)
  335. {
  336. $actual = $this->response->getStatusCode();
  337. return PHPUnit::assertEquals($code, $this->response->getStatusCode(), "Expected status code {$code}, got {$actual}.");
  338. }
  339. /**
  340. * Asserts that the status code of the response matches the given code.
  341. *
  342. * @param int $status
  343. * @return $this
  344. */
  345. protected function seeStatusCode($status)
  346. {
  347. $this->assertResponseStatus($status);
  348. return $this;
  349. }
  350. /**
  351. * Asserts that the response contains the given header and equals the optional value.
  352. *
  353. * @param string $headerName
  354. * @param mixed $value
  355. * @return $this
  356. */
  357. protected function seeHeader($headerName, $value = null)
  358. {
  359. $headers = $this->response->headers;
  360. $this->assertTrue($headers->has($headerName), "Header [{$headerName}] not present on response.");
  361. if (! is_null($value)) {
  362. $this->assertEquals(
  363. $headers->get($headerName), $value,
  364. "Header [{$headerName}] was found, but value [{$headers->get($headerName)}] does not match [{$value}]."
  365. );
  366. }
  367. return $this;
  368. }
  369. /**
  370. * Disable middleware for the test.
  371. *
  372. * @return $this
  373. */
  374. public function withoutMiddleware()
  375. {
  376. $this->app->instance('middleware.disable', true);
  377. return $this;
  378. }
  379. }