Skip to content
This repository was archived by the owner on May 29, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@
}
},
"autoload-dev": {
"classmap": ["tests/_support", "tests/functional"]
"classmap": ["tests/_support"]
}
}
144 changes: 51 additions & 93 deletions src/Connector.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UploadedFileInterface;
use Psr\Http\Message\UriInterface;
use Jasny\HttpMessage\Response;
use Jasny\HttpMessage\ServerRequest;
use Jasny\HttpMessage\UploadedFile;
use Jasny\HttpMessage\Uri;
use Jasny\HttpMessage\Stream;
use Jasny\HttpMessage\OutputBufferStream;
use Jasny\Router;
use Jasny\Codeception\RequestConvertor;
use Jasny\Codeception\ResponseConvertor;
use Symfony\Component\BrowserKit\Client;
use Symfony\Component\BrowserKit\Request as BrowserKitRequest;
use Symfony\Component\BrowserKit\Response as BrowserKitResponse;
Expand All @@ -39,6 +36,16 @@ class Connector extends Client
*/
protected $baseResponse;

/**
* @var RequestConvertor
*/
protected $requestConvertor;

/**
* @var ResponseConvertor
*/
protected $responseConvertor;


/**
* Set the router
Expand Down Expand Up @@ -118,16 +125,22 @@ public function getBaseResponse()
return $this->baseResponse;
}


/**
* Reset the request and response.
* This is only required when the request and/or response are bound to the global environment.
* Reset the request
*/
public function reset()
protected function resetInput()
{
if (isset($this->baseRequest) && $this->baseRequest instanceof ServerRequest && $this->baseRequest->isStale()) {
$this->baseRequest = $this->baseRequest->revive();
}
}

/**
* Reset the response
*/
protected function resetOutput()
{
if (isset($this->baseResponse) && $this->baseResponse instanceof Response && $this->baseResponse->isStale()) {
$this->baseResponse = $this->baseResponse->revive();
}
Expand All @@ -137,120 +150,65 @@ public function reset()
$this->baseResponse = $this->baseResponse->withBody(clone $this->baseResponse->getBody());
}
}



/**
* Build a full URI from a request
*
* @param BrowserKitRequest $request
* @return array [Uri, queryParams]
* Reset the request and response.
* This is only required when the request and/or response are bound to the global environment.
*/
protected function buildFullUri(BrowserKitRequest $request)
public function reset()
{
$uri = new Uri($request->getUri());

$queryParams = [];
parse_str($uri->getQuery(), $queryParams);

if ($request->getMethod() === 'GET') {
$queryParams = array_merge($queryParams, $request->getParameters());
$uri = $uri->withQuery(http_build_query($queryParams));
}

return [$uri, $queryParams];
$this->resetInput();
$this->resetOutput();
}


/**
* Get additional server params from request.
* @internal It would be nicer if this was solved by Jasny Http Message
* Set the request convertor
*
* @param BrowserKitRequest $request
* @param UriInterface $uri
* @param array $queryParams
* @return array
* @param RequestConvertor $convertor
*/
protected function determineServerParams(BrowserKitRequest $request, UriInterface $uri, array $queryParams)
public function setRequestConvertor(RequestConvertor $convertor)
{
return [
'REQUEST_METHOD' => $request->getMethod(),
'QUERY_STRING' => http_build_query($queryParams),
'REQUEST_URI' => (string)($uri->withScheme('')->withHost('')->withPort('')->withUserInfo(''))
];
$this->requestConvertor = $convertor;
}

/**
* Convert a codeception request to a Jasny PSR-7 server request
* Get the request convertor
*
* @param BrowserKitRequest $request
* @return ServerRequest
* @return RequestConvertor
*/
protected function convertRequest(BrowserKitRequest $request)
public function getRequestConvertor()
{
list($uri, $queryParams) = $this->buildFullUri($request);

$stream = fopen('php://temp', 'r+');
fwrite($stream, $request->getContent());
fseek($stream, 0);

$baseRequest = $this->getBaseRequest();

if ($baseRequest instanceof ServerRequest) {
$serverParams = $this->determineServerParams($request, $uri, (array)$queryParams);
$baseRequest = $baseRequest->withServerParams($request->getServer() + $serverParams);
if (!isset($this->requestConvertor)) {
$this->requestConvertor = new RequestConvertor();
}

$psrRequest = $baseRequest
->withBody(new Stream($stream))
->withMethod($request->getMethod())
->withRequestTarget((string)($uri->withScheme('')->withHost('')->withPort('')->withUserInfo('')))
->withCookieParams($request->getCookies())
->withUri($uri)
->withQueryParams((array)$queryParams)
->withUploadedFiles($this->convertUploadedFiles($request->getFiles()));

if ($request->getMethod() !== 'GET' && !empty($request->getParameters())) {
$psrRequest = $psrRequest->withParsedBody($request->getParameters());
}

return $psrRequest;
return $this->requestConvertor;
}


/**
* Convert a Jasny PSR-7 response to a codeception response
* Set the response convertor
*
* @param ResponseInterface $psrResponse
* @return BrowserKitResponse
* @param ResponseConvertor $convertor
*/
protected function convertResponse(ResponseInterface $psrResponse)
public function setResponseConvertor(ResponseConvertor $convertor)
{
return new BrowserKitResponse(
(string)$psrResponse->getBody(),
$psrResponse->getStatusCode() ?: 200,
$psrResponse->getHeaders()
);
$this->responseConvertor = $convertor;
}

/**
* Convert a list of uploaded files to a Jasny PSR-7 uploaded files
* Get the response convertor
*
* @param array $files
* @return UploadedFile[]|array
* @return ResponseConvertor
*/
protected function convertUploadedFiles(array $files)
public function getResponseConvertor()
{
$fileObjects = [];

foreach ($files as $fieldName => $file) {
if ($file instanceof UploadedFileInterface) {
$fileObjects[$fieldName] = $file;
} elseif (!isset($file['tmp_name']) && !isset($file['name'])) {
$fileObjects[$fieldName] = $this->convertUploadedFiles($file);
} else {
$fileObjects[$fieldName] = new UploadedFile($file);
}
if (!isset($this->responseConvertor)) {
$this->responseConvertor = new ResponseConvertor();
}

return $fileObjects;
return $this->responseConvertor;
}


Expand All @@ -268,11 +226,11 @@ protected function doRequest($request)

$this->reset(); // Reset before each HTTP request

$psrRequest = $this->convertRequest($request);
$psrRequest = $this->getRequestConvertor()->convert($request, $this->getBaseRequest());

$router = $this->getRouter();
$psrResponse = $router->handle($psrRequest, $this->getBaseResponse());

return $this->convertResponse($psrResponse);
return $this->getResponseConvertor()->convert($psrResponse);
}
}
149 changes: 149 additions & 0 deletions src/RequestConvertor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<?php

namespace Jasny\Codeception;

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UploadedFileInterface;
use Psr\Http\Message\UriInterface;
use Jasny\HttpMessage\ServerRequest;
use Jasny\HttpMessage\UploadedFile;
use Jasny\HttpMessage\Uri;
use Jasny\HttpMessage\Stream;
use Symfony\Component\BrowserKit\Request as BrowserKitRequest;

/**
* Convert a codeception request to a Jasny PSR-7 server request
*/
class RequestConvertor
{
/**
* Create the output stream handle
*
* @param BrowserKitRequest $request
* @return resource
*/
protected function createStream(BrowserKitRequest $request)
{
$stream = fopen('php://temp', 'r+');
fwrite($stream, $request->getContent());
fseek($stream, 0);

return $stream;
}

/**
* Build a full URI from a request
*
* @param BrowserKitRequest $request
* @return array [Uri, queryParams]
*/
protected function buildFullUri(BrowserKitRequest $request)
{
$uri = new Uri($request->getUri());

$queryParams = [];
parse_str($uri->getQuery(), $queryParams);

if ($request->getMethod() === 'GET') {
$queryParams = array_merge($queryParams, $request->getParameters());
$uri = $uri->withQuery(http_build_query($queryParams));
}

return [$uri, $queryParams];
}

/**
* Get additional server params from request.
* @internal It would be nicer if this was solved by Jasny Http Message
*
* @param BrowserKitRequest $request
* @param UriInterface $uri
* @param array $queryParams
* @return array
*/
protected function determineServerParams(BrowserKitRequest $request, UriInterface $uri, array $queryParams)
{
return [
'REQUEST_METHOD' => $request->getMethod(),
'QUERY_STRING' => http_build_query($queryParams),
'REQUEST_URI' => (string)($uri->withScheme('')->withHost('')->withPort('')->withUserInfo(''))
];
}

/**
* Set the server request properties
*
* @param ServerRequestInterface $baseRequest
* @param BrowserKitRequest $request
* @param resource $stream
* @param UriInterface $uri
* @param array $queryParams
* @return ServerRequestInterface
*/
protected function setRequestProperties(
ServerRequestInterface $baseRequest,
BrowserKitRequest $request,
$stream,
UriInterface $uri,
array $queryParams
) {
$psrRequest = $baseRequest
->withBody(new Stream($stream))
->withMethod($request->getMethod())
->withRequestTarget((string)($uri->withScheme('')->withHost('')->withPort('')->withUserInfo('')))
->withCookieParams($request->getCookies())
->withUri($uri)
->withQueryParams((array)$queryParams)
->withUploadedFiles($this->convertUploadedFiles($request->getFiles()));

if ($request->getMethod() !== 'GET' && !empty($request->getParameters())) {
$psrRequest = $psrRequest->withParsedBody($request->getParameters());
}

return $psrRequest;
}

/**
* Convert a list of uploaded files to a Jasny PSR-7 uploaded files
*
* @param array $files
* @return UploadedFile[]|array
*/
protected function convertUploadedFiles(array $files)
{
$fileObjects = [];

foreach ($files as $fieldName => $file) {
if ($file instanceof UploadedFileInterface) {
$fileObjects[$fieldName] = $file;
} elseif (!isset($file['tmp_name']) && !isset($file['error'])) {
$fileObjects[$fieldName] = $this->convertUploadedFiles($file);
} else {
$fileObjects[$fieldName] = new UploadedFile($file);
}
}

return $fileObjects;
}


/**
* Convert a codeception request to a PSR-7 server request
*
* @param BrowserKitRequest $request
* @param ServerRequestInterface $baseRequest
* @return ServerRequest
*/
public function convert(BrowserKitRequest $request, ServerRequestInterface $baseRequest)
{
$stream = $this->createStream($request);
list($uri, $queryParams) = $this->buildFullUri($request);

if ($baseRequest instanceof ServerRequest) {
$serverParams = $this->determineServerParams($request, $uri, (array)$queryParams);
$baseRequest = $baseRequest->withServerParams($request->getServer() + $serverParams);
}

return $this->setRequestProperties($baseRequest, $request, $stream, $uri, (array)$queryParams);
}
}
Loading