Revision 148 | Blame | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed
<?phpnamespace Illuminate\Foundation\Testing\Concerns;use Illuminate\Contracts\Http\Kernel as HttpKernel;use Illuminate\Cookie\CookieValuePrefix;use Illuminate\Http\Request;use Illuminate\Testing\LoggedExceptionCollection;use Illuminate\Testing\TestResponse;use Symfony\Component\HttpFoundation\File\UploadedFile as SymfonyUploadedFile;use Symfony\Component\HttpFoundation\Request as SymfonyRequest;trait MakesHttpRequests{/*** Additional headers for the request.** @var array*/protected $defaultHeaders = [];/*** Additional cookies for the request.** @var array*/protected $defaultCookies = [];/*** Additional cookies will not be encrypted for the request.** @var array*/protected $unencryptedCookies = [];/*** Additional server variables for the request.** @var array*/protected $serverVariables = [];/*** Indicates whether redirects should be followed.** @var bool*/protected $followRedirects = false;/*** Indicates whether cookies should be encrypted.** @var bool*/protected $encryptCookies = true;/*** Indicated whether JSON requests should be performed "with credentials" (cookies).** @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials** @var bool*/protected $withCredentials = false;/*** The latest test response (if any).** @var \Illuminate\Testing\TestResponse|null*/public static $latestResponse;/*** Define additional headers to be sent with the request.** @param array $headers* @return $this*/public function withHeaders(array $headers){$this->defaultHeaders = array_merge($this->defaultHeaders, $headers);return $this;}/*** Add a header to be sent with the request.** @param string $name* @param string $value* @return $this*/public function withHeader(string $name, string $value){$this->defaultHeaders[$name] = $value;return $this;}/*** Add an authorization token for the request.** @param string $token* @param string $type* @return $this*/public function withToken(string $token, string $type = 'Bearer'){return $this->withHeader('Authorization', $type.' '.$token);}/*** Add a basic authentication header to the request with the given credentials.** @param string $username* @param string $password* @return $this*/public function withBasicAuth(string $username, string $password){return $this->withToken(base64_encode("$username:$password"), 'Basic');}/*** Remove the authorization token from the request.** @return $this*/public function withoutToken(){unset($this->defaultHeaders['Authorization']);return $this;}/*** Flush all the configured headers.** @return $this*/public function flushHeaders(){$this->defaultHeaders = [];return $this;}/*** Define a set of server variables to be sent with the requests.** @param array $server* @return $this*/public function withServerVariables(array $server){$this->serverVariables = $server;return $this;}/*** Disable middleware for the test.** @param string|array|null $middleware* @return $this*/public function withoutMiddleware($middleware = null){if (is_null($middleware)) {$this->app->instance('middleware.disable', true);return $this;}foreach ((array) $middleware as $abstract) {$this->app->instance($abstract, new class{public function handle($request, $next){return $next($request);}});}return $this;}/*** Enable the given middleware for the test.** @param string|array|null $middleware* @return $this*/public function withMiddleware($middleware = null){if (is_null($middleware)) {unset($this->app['middleware.disable']);return $this;}foreach ((array) $middleware as $abstract) {unset($this->app[$abstract]);}return $this;}/*** Define additional cookies to be sent with the request.** @param array $cookies* @return $this*/public function withCookies(array $cookies){$this->defaultCookies = array_merge($this->defaultCookies, $cookies);return $this;}/*** Add a cookie to be sent with the request.** @param string $name* @param string $value* @return $this*/public function withCookie(string $name, string $value){$this->defaultCookies[$name] = $value;return $this;}/*** Define additional cookies will not be encrypted before sending with the request.** @param array $cookies* @return $this*/public function withUnencryptedCookies(array $cookies){$this->unencryptedCookies = array_merge($this->unencryptedCookies, $cookies);return $this;}/*** Add a cookie will not be encrypted before sending with the request.** @param string $name* @param string $value* @return $this*/public function withUnencryptedCookie(string $name, string $value){$this->unencryptedCookies[$name] = $value;return $this;}/*** Automatically follow any redirects returned from the response.** @return $this*/public function followingRedirects(){$this->followRedirects = true;return $this;}/*** Include cookies and authorization headers for JSON requests.** @return $this*/public function withCredentials(){$this->withCredentials = true;return $this;}/*** Disable automatic encryption of cookie values.** @return $this*/public function disableCookieEncryption(){$this->encryptCookies = false;return $this;}/*** Set the referer header and previous URL session value in order to simulate a previous request.** @param string $url* @return $this*/public function from(string $url){$this->app['session']->setPreviousUrl($url);return $this->withHeader('referer', $url);}/*** Visit the given URI with a GET request.** @param string $uri* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function get($uri, array $headers = []){$server = $this->transformHeadersToServerVars($headers);$cookies = $this->prepareCookiesForRequest();return $this->call('GET', $uri, [], $cookies, [], $server);}/*** Visit the given URI with a GET request, expecting a JSON response.** @param string $uri* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function getJson($uri, array $headers = []){return $this->json('GET', $uri, [], $headers);}/*** Visit the given URI with a POST request.** @param string $uri* @param array $data* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function post($uri, array $data = [], array $headers = []){$server = $this->transformHeadersToServerVars($headers);$cookies = $this->prepareCookiesForRequest();return $this->call('POST', $uri, $data, $cookies, [], $server);}/*** Visit the given URI with a POST request, expecting a JSON response.** @param string $uri* @param array $data* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function postJson($uri, array $data = [], array $headers = []){return $this->json('POST', $uri, $data, $headers);}/*** Visit the given URI with a PUT request.** @param string $uri* @param array $data* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function put($uri, array $data = [], array $headers = []){$server = $this->transformHeadersToServerVars($headers);$cookies = $this->prepareCookiesForRequest();return $this->call('PUT', $uri, $data, $cookies, [], $server);}/*** Visit the given URI with a PUT request, expecting a JSON response.** @param string $uri* @param array $data* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function putJson($uri, array $data = [], array $headers = []){return $this->json('PUT', $uri, $data, $headers);}/*** Visit the given URI with a PATCH request.** @param string $uri* @param array $data* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function patch($uri, array $data = [], array $headers = []){$server = $this->transformHeadersToServerVars($headers);$cookies = $this->prepareCookiesForRequest();return $this->call('PATCH', $uri, $data, $cookies, [], $server);}/*** Visit the given URI with a PATCH request, expecting a JSON response.** @param string $uri* @param array $data* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function patchJson($uri, array $data = [], array $headers = []){return $this->json('PATCH', $uri, $data, $headers);}/*** Visit the given URI with a DELETE request.** @param string $uri* @param array $data* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function delete($uri, array $data = [], array $headers = []){$server = $this->transformHeadersToServerVars($headers);$cookies = $this->prepareCookiesForRequest();return $this->call('DELETE', $uri, $data, $cookies, [], $server);}/*** Visit the given URI with a DELETE request, expecting a JSON response.** @param string $uri* @param array $data* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function deleteJson($uri, array $data = [], array $headers = []){return $this->json('DELETE', $uri, $data, $headers);}/*** Visit the given URI with an OPTIONS request.** @param string $uri* @param array $data* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function options($uri, array $data = [], array $headers = []){$server = $this->transformHeadersToServerVars($headers);$cookies = $this->prepareCookiesForRequest();return $this->call('OPTIONS', $uri, $data, $cookies, [], $server);}/*** Visit the given URI with an OPTIONS request, expecting a JSON response.** @param string $uri* @param array $data* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function optionsJson($uri, array $data = [], array $headers = []){return $this->json('OPTIONS', $uri, $data, $headers);}/*** Visit the given URI with a HEAD request.** @param string $uri* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function head($uri, array $headers = []){$server = $this->transformHeadersToServerVars($headers);$cookies = $this->prepareCookiesForRequest();return $this->call('HEAD', $uri, [], $cookies, [], $server);}/*** Call the given URI with a JSON request.** @param string $method* @param string $uri* @param array $data* @param array $headers* @return \Illuminate\Testing\TestResponse*/public function json($method, $uri, array $data = [], array $headers = []){$files = $this->extractFilesFromDataArray($data);$content = json_encode($data);$headers = array_merge(['CONTENT_LENGTH' => mb_strlen($content, '8bit'),'CONTENT_TYPE' => 'application/json','Accept' => 'application/json',], $headers);return $this->call($method,$uri,[],$this->prepareCookiesForJsonRequest(),$files,$this->transformHeadersToServerVars($headers),$content);}/*** Call the given URI and return the Response.** @param string $method* @param string $uri* @param array $parameters* @param array $cookies* @param array $files* @param array $server* @param string|null $content* @return \Illuminate\Testing\TestResponse*/public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null){$kernel = $this->app->make(HttpKernel::class);$files = array_merge($files, $this->extractFilesFromDataArray($parameters));$symfonyRequest = SymfonyRequest::create($this->prepareUrlForRequest($uri), $method, $parameters,$cookies, $files, array_replace($this->serverVariables, $server), $content);$response = $kernel->handle($request = Request::createFromBase($symfonyRequest));$kernel->terminate($request, $response);if ($this->followRedirects) {$response = $this->followRedirects($response);}return static::$latestResponse = $this->createTestResponse($response);}/*** Turn the given URI into a fully qualified URL.** @param string $uri* @return string*/protected function prepareUrlForRequest($uri){if (str_starts_with($uri, '/')) {$uri = substr($uri, 1);}return trim(url($uri), '/');}/*** Transform headers array to array of $_SERVER vars with HTTP_* format.** @param array $headers* @return array*/protected function transformHeadersToServerVars(array $headers){return collect(array_merge($this->defaultHeaders, $headers))->mapWithKeys(function ($value, $name) {$name = strtr(strtoupper($name), '-', '_');return [$this->formatServerHeaderKey($name) => $value];})->all();}/*** Format the header name for the server array.** @param string $name* @return string*/protected function formatServerHeaderKey($name){if (! str_starts_with($name, 'HTTP_') && $name !== 'CONTENT_TYPE' && $name !== 'REMOTE_ADDR') {return 'HTTP_'.$name;}return $name;}/*** Extract the file uploads from the given data array.** @param array $data* @return array*/protected function extractFilesFromDataArray(&$data){$files = [];foreach ($data as $key => $value) {if ($value instanceof SymfonyUploadedFile) {$files[$key] = $value;unset($data[$key]);}if (is_array($value)) {$files[$key] = $this->extractFilesFromDataArray($value);$data[$key] = $value;}}return $files;}/*** If enabled, encrypt cookie values for request.** @return array*/protected function prepareCookiesForRequest(){if (! $this->encryptCookies) {return array_merge($this->defaultCookies, $this->unencryptedCookies);}return collect($this->defaultCookies)->map(function ($value, $key) {return encrypt(CookieValuePrefix::create($key, app('encrypter')->getKey()).$value, false);})->merge($this->unencryptedCookies)->all();}/*** If enabled, add cookies for JSON requests.** @return array*/protected function prepareCookiesForJsonRequest(){return $this->withCredentials ? $this->prepareCookiesForRequest() : [];}/*** Follow a redirect chain until a non-redirect is received.** @param \Illuminate\Http\Response $response* @return \Illuminate\Http\Response|\Illuminate\Testing\TestResponse*/protected function followRedirects($response){$this->followRedirects = false;while ($response->isRedirect()) {$response = $this->get($response->headers->get('Location'));}return $response;}/*** Create the test response instance from the given response.** @param \Illuminate\Http\Response $response* @return \Illuminate\Testing\TestResponse*/protected function createTestResponse($response){return tap(TestResponse::fromBaseResponse($response), function ($response) {$response->withExceptions($this->app->bound(LoggedExceptionCollection::class)? $this->app->make(LoggedExceptionCollection::class): new LoggedExceptionCollection);});}}