CrawlerTrait.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: yunwuxin <448901948@qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace think\testing;
  12. use think\Error;
  13. use think\Exception;
  14. use think\exception\ThrowableError;
  15. use think\facade\App;
  16. use think\facade\Cookie;
  17. use think\facade\Request;
  18. use think\facade\Response;
  19. use think\facade\Route;
  20. use think\helper\Arr;
  21. use think\helper\Str;
  22. trait CrawlerTrait
  23. {
  24. use InteractsWithPages;
  25. protected $currentUri;
  26. protected $serverVariables = [];
  27. /** @var Response */
  28. protected $response;
  29. public function get($uri, array $headers = [])
  30. {
  31. $server = $this->transformHeadersToServerVars($headers);
  32. $this->call('GET', $uri, [], [], [], $server);
  33. return $this;
  34. }
  35. public function post($uri, array $data = [], array $headers = [])
  36. {
  37. $server = $this->transformHeadersToServerVars($headers);
  38. $this->call('POST', $uri, $data, [], [], $server);
  39. return $this;
  40. }
  41. public function put($uri, array $data = [], array $headers = [])
  42. {
  43. $server = $this->transformHeadersToServerVars($headers);
  44. $this->call('PUT', $uri, $data, [], [], $server);
  45. return $this;
  46. }
  47. public function delete($uri, array $data = [], array $headers = [])
  48. {
  49. $server = $this->transformHeadersToServerVars($headers);
  50. $this->call('DELETE', $uri, $data, [], [], $server);
  51. return $this;
  52. }
  53. public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
  54. {
  55. $this->currentUri = $this->prepareUrlForRequest($uri);
  56. $request = Request::create(
  57. $this->currentUri, $method, $parameters,
  58. $cookies, $files, array_replace($this->serverVariables, $server)
  59. );
  60. try {
  61. Route::setRequest($request);
  62. $response = App::bindTo('request', $request)->run();
  63. } catch (Exception $e) {
  64. $response = Error::getExceptionHandler()->render($e);
  65. } catch (\Throwable $e) {
  66. $response = Error::getExceptionHandler()->render(new ThrowableError($e));
  67. }
  68. return $this->response = $response;
  69. }
  70. public function seeJson($data = null, $negate = false)
  71. {
  72. if (is_null($data)) {
  73. $this->assertJson(
  74. $this->response->getContent(), "JSON was not returned from [{$this->currentUri}]."
  75. );
  76. return $this;
  77. }
  78. return $this->seeJsonContains($data, $negate);
  79. }
  80. public function seeJsonEquals(array $data)
  81. {
  82. $actual = json_encode(Arr::sortRecursive(
  83. json_decode($this->response->getContent(), true)
  84. ));
  85. $this->assertEquals(json_encode(Arr::sortRecursive($data)), $actual);
  86. return $this;
  87. }
  88. protected function seeJsonContains(array $data, $negate = false)
  89. {
  90. $method = $negate ? 'assertFalse' : 'assertTrue';
  91. $actual = json_decode($this->response->getContent(), true);
  92. if (is_null($actual) || false === $actual) {
  93. return $this->fail('Invalid JSON was returned from the route. Perhaps an exception was thrown?');
  94. }
  95. $actual = json_encode(Arr::sortRecursive(
  96. (array) $actual
  97. ));
  98. foreach (Arr::sortRecursive($data) as $key => $value) {
  99. $expected = $this->formatToExpectedJson($key, $value);
  100. $this->{$method}(
  101. Str::contains($actual, $expected),
  102. ($negate ? 'Found unexpected' : 'Unable to find') . " JSON fragment [{$expected}] within [{$actual}]."
  103. );
  104. }
  105. return $this;
  106. }
  107. /**
  108. * Format the given key and value into a JSON string for expectation checks.
  109. *
  110. * @param string $key
  111. * @param mixed $value
  112. * @return string
  113. */
  114. protected function formatToExpectedJson($key, $value)
  115. {
  116. $expected = json_encode([$key => $value]);
  117. if (Str::startsWith($expected, '{')) {
  118. $expected = substr($expected, 1);
  119. }
  120. if (Str::endsWith($expected, '}')) {
  121. $expected = substr($expected, 0, -1);
  122. }
  123. return $expected;
  124. }
  125. protected function seeModule($module)
  126. {
  127. $this->assertEquals($module, request()->module());
  128. return $this;
  129. }
  130. protected function seeController($controller)
  131. {
  132. $this->assertEquals($controller, request()->controller());
  133. return $this;
  134. }
  135. protected function seeAction($action)
  136. {
  137. $this->assertEquals($action, request()->action());
  138. return $this;
  139. }
  140. protected function seeStatusCode($status)
  141. {
  142. $this->assertEquals($status, $this->response->getCode());
  143. return $this;
  144. }
  145. protected function seeHeader($headerName, $value = null)
  146. {
  147. $headers = $this->response->getHeader();
  148. $this->assertTrue(!empty($headers[$headerName]), "Header [{$headerName}] not present on response.");
  149. if (!is_null($value)) {
  150. $this->assertEquals(
  151. $headers[$headerName], $value,
  152. "Header [{$headerName}] was found, but value [{$headers[$headerName]}] does not match [{$value}]."
  153. );
  154. }
  155. return $this;
  156. }
  157. protected function seeCookie($cookieName, $value = null)
  158. {
  159. $exist = Cookie::has($cookieName);
  160. $this->assertTrue($exist, "Cookie [{$cookieName}] not present on response.");
  161. if (!is_null($value)) {
  162. $cookie = Cookie::get($cookieName);
  163. $this->assertEquals(
  164. $cookie, $value,
  165. "Cookie [{$cookieName}] was found, but value [{$cookie}] does not match [{$value}]."
  166. );
  167. }
  168. return $this;
  169. }
  170. protected function withServerVariables(array $server)
  171. {
  172. $this->serverVariables = $server;
  173. return $this;
  174. }
  175. protected function transformHeadersToServerVars(array $headers)
  176. {
  177. $server = [];
  178. $prefix = 'HTTP_';
  179. foreach ($headers as $name => $value) {
  180. $name = strtr(strtoupper($name), '-', '_');
  181. if (!Str::startsWith($name, $prefix) && 'CONTENT_TYPE' != $name) {
  182. $name = $prefix . $name;
  183. }
  184. $server[$name] = $value;
  185. }
  186. return $server;
  187. }
  188. }