merged branch fabpot/browserkit-client (PR #7835)
This PR was merged into the master branch. Discussion ---------- fixed Client implementation to return the right Response (closes #4475) | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | yes | Deprecations? | no | Tests pass? | yes | Fixed tickets | #4475 | License | MIT | Doc PR | symfony/symfony-docs#2549 This PR addresses #4475 by trying to minimize the BC break impact. Commits -------31cefc6
made some small tweaks84ca34b
alternate fix where we had accessor for the BrowerKit request/response instances1005fd1
fixed Client implementation to return the right Response (closes #4475)
This commit is contained in:
commit
7ceb6e5c99
@ -1,7 +1,8 @@
|
|||||||
UPGRADE FROM 2.2 to 2.3
|
UPGRADE FROM 2.2 to 2.3
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
### Form
|
Form
|
||||||
|
----
|
||||||
|
|
||||||
* Although this was not officially supported nor documented, it was possible to
|
* Although this was not officially supported nor documented, it was possible to
|
||||||
set the option "validation_groups" to false, resulting in the group "Default"
|
set the option "validation_groups" to false, resulting in the group "Default"
|
||||||
@ -109,7 +110,8 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### PropertyAccess
|
PropertyAccess
|
||||||
|
--------------
|
||||||
|
|
||||||
* PropertyAccessor was changed to continue its search for a property or method
|
* PropertyAccessor was changed to continue its search for a property or method
|
||||||
even if a non-public match was found. This means that the property "author"
|
even if a non-public match was found. This means that the property "author"
|
||||||
@ -161,7 +163,8 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### DomCrawler
|
DomCrawler
|
||||||
|
----------
|
||||||
|
|
||||||
* `Crawler::each()` and `Crawler::reduce()` now return Crawler instances
|
* `Crawler::each()` and `Crawler::reduce()` now return Crawler instances
|
||||||
instead of DomElement instances:
|
instead of DomElement instances:
|
||||||
|
@ -85,7 +85,7 @@ class Client extends BaseClient
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a request.
|
* {@inheritdoc}
|
||||||
*
|
*
|
||||||
* @param Request $request A Request instance
|
* @param Request $request A Request instance
|
||||||
*
|
*
|
||||||
@ -113,6 +113,10 @@ class Client extends BaseClient
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @param Request $request A Request instance
|
||||||
|
*
|
||||||
|
* @return Response A Response instance
|
||||||
*/
|
*/
|
||||||
protected function doRequestInProcess($request)
|
protected function doRequestInProcess($request)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
2.3.0
|
||||||
|
-----
|
||||||
|
|
||||||
|
* added `Client::getInternalRequest()` and `Client::getInternalResponse()` to
|
||||||
|
have access to the BrowserKit internal request and response objects
|
||||||
|
|
||||||
2.1.0
|
2.1.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -33,7 +33,9 @@ abstract class Client
|
|||||||
protected $history;
|
protected $history;
|
||||||
protected $cookieJar;
|
protected $cookieJar;
|
||||||
protected $server;
|
protected $server;
|
||||||
|
protected $internalRequest;
|
||||||
protected $request;
|
protected $request;
|
||||||
|
protected $internalResponse;
|
||||||
protected $response;
|
protected $response;
|
||||||
protected $crawler;
|
protected $crawler;
|
||||||
protected $insulated;
|
protected $insulated;
|
||||||
@ -156,7 +158,7 @@ abstract class Client
|
|||||||
/**
|
/**
|
||||||
* Returns the current Crawler instance.
|
* Returns the current Crawler instance.
|
||||||
*
|
*
|
||||||
* @return Crawler A Crawler instance
|
* @return Crawler|null A Crawler instance
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
@ -166,9 +168,26 @@ abstract class Client
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current Response instance.
|
* Returns the current BrowserKit Response instance.
|
||||||
*
|
*
|
||||||
* @return Response A Response instance
|
* @return Response|null A BrowserKit Response instance
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
public function getInternalResponse()
|
||||||
|
{
|
||||||
|
return $this->internalResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current origin response instance.
|
||||||
|
*
|
||||||
|
* The origin response is the response instance that is returned
|
||||||
|
* by the code that handles requests.
|
||||||
|
*
|
||||||
|
* @return object|null A response instance
|
||||||
|
*
|
||||||
|
* @see doRequest
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
@ -178,9 +197,26 @@ abstract class Client
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current Request instance.
|
* Returns the current BrowserKit Request instance.
|
||||||
*
|
*
|
||||||
* @return Request A Request instance
|
* @return Request|null A BrowserKit Request instance
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
public function getInternalRequest()
|
||||||
|
{
|
||||||
|
return $this->internalRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current origin Request instance.
|
||||||
|
*
|
||||||
|
* The origin request is the request instance that is sent
|
||||||
|
* to the code that handles requests.
|
||||||
|
*
|
||||||
|
* @return object|null A Request instance
|
||||||
|
*
|
||||||
|
* @see doRequest
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
@ -250,12 +286,12 @@ abstract class Client
|
|||||||
$server['HTTP_HOST'] = parse_url($uri, PHP_URL_HOST);
|
$server['HTTP_HOST'] = parse_url($uri, PHP_URL_HOST);
|
||||||
$server['HTTPS'] = 'https' == parse_url($uri, PHP_URL_SCHEME);
|
$server['HTTPS'] = 'https' == parse_url($uri, PHP_URL_SCHEME);
|
||||||
|
|
||||||
$request = new Request($uri, $method, $parameters, $files, $this->cookieJar->allValues($uri), $server, $content);
|
$this->internalRequest = new Request($uri, $method, $parameters, $files, $this->cookieJar->allValues($uri), $server, $content);
|
||||||
|
|
||||||
$this->request = $this->filterRequest($request);
|
$this->request = $this->filterRequest($this->internalRequest);
|
||||||
|
|
||||||
if (true === $changeHistory) {
|
if (true === $changeHistory) {
|
||||||
$this->history->add($request);
|
$this->history->add($this->internalRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->insulated) {
|
if ($this->insulated) {
|
||||||
@ -264,25 +300,25 @@ abstract class Client
|
|||||||
$this->response = $this->doRequest($this->request);
|
$this->response = $this->doRequest($this->request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->filterResponse($this->response);
|
$this->internalResponse = $this->filterResponse($this->response);
|
||||||
|
|
||||||
$this->cookieJar->updateFromResponse($response, $uri);
|
$this->cookieJar->updateFromResponse($this->internalResponse, $uri);
|
||||||
|
|
||||||
$this->redirect = $response->getHeader('Location');
|
$this->redirect = $this->internalResponse->getHeader('Location');
|
||||||
|
|
||||||
if ($this->followRedirects && $this->redirect) {
|
if ($this->followRedirects && $this->redirect) {
|
||||||
return $this->crawler = $this->followRedirect();
|
return $this->crawler = $this->followRedirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->crawler = $this->createCrawlerFromContent($request->getUri(), $response->getContent(), $response->getHeader('Content-Type'));
|
return $this->crawler = $this->createCrawlerFromContent($this->internalRequest->getUri(), $this->internalResponse->getContent(), $this->internalResponse->getHeader('Content-Type'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a request in another process.
|
* Makes a request in another process.
|
||||||
*
|
*
|
||||||
* @param Request $request A Request instance
|
* @param object $request An origin request instance
|
||||||
*
|
*
|
||||||
* @return Response A Response instance
|
* @return object An origin response instance
|
||||||
*
|
*
|
||||||
* @throws \RuntimeException When processing returns exit code
|
* @throws \RuntimeException When processing returns exit code
|
||||||
*/
|
*/
|
||||||
@ -302,16 +338,16 @@ abstract class Client
|
|||||||
/**
|
/**
|
||||||
* Makes a request.
|
* Makes a request.
|
||||||
*
|
*
|
||||||
* @param Request $request A Request instance
|
* @param object $request An origin request instance
|
||||||
*
|
*
|
||||||
* @return Response A Response instance
|
* @return object An origin response instance
|
||||||
*/
|
*/
|
||||||
abstract protected function doRequest($request);
|
abstract protected function doRequest($request);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the script to execute when the request must be insulated.
|
* Returns the script to execute when the request must be insulated.
|
||||||
*
|
*
|
||||||
* @param Request $request A Request instance
|
* @param object $request An origin request instance
|
||||||
*
|
*
|
||||||
* @throws \LogicException When this abstract class is not implemented
|
* @throws \LogicException When this abstract class is not implemented
|
||||||
*/
|
*/
|
||||||
@ -323,11 +359,11 @@ abstract class Client
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters the request.
|
* Filters the BrowserKit request to the origin one.
|
||||||
*
|
*
|
||||||
* @param Request $request The request to filter
|
* @param Request $request The BrowserKit Request to filter
|
||||||
*
|
*
|
||||||
* @return Request
|
* @return object An origin request instance
|
||||||
*/
|
*/
|
||||||
protected function filterRequest(Request $request)
|
protected function filterRequest(Request $request)
|
||||||
{
|
{
|
||||||
@ -335,11 +371,11 @@ abstract class Client
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters the Response.
|
* Filters the origin response to the BrowserKit one.
|
||||||
*
|
*
|
||||||
* @param Response $response The Response to filter
|
* @param object $response The origin response to filter
|
||||||
*
|
*
|
||||||
* @return Response
|
* @return Response An BrowserKit Response instance
|
||||||
*/
|
*/
|
||||||
protected function filterResponse($response)
|
protected function filterResponse($response)
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,10 @@ use Symfony\Component\BrowserKit\CookieJar;
|
|||||||
use Symfony\Component\BrowserKit\Request;
|
use Symfony\Component\BrowserKit\Request;
|
||||||
use Symfony\Component\BrowserKit\Response;
|
use Symfony\Component\BrowserKit\Response;
|
||||||
|
|
||||||
|
class SpecialResponse extends Response
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
class TestClient extends Client
|
class TestClient extends Client
|
||||||
{
|
{
|
||||||
protected $nextResponse = null;
|
protected $nextResponse = null;
|
||||||
@ -44,6 +48,15 @@ class TestClient extends Client
|
|||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function filterResponse($response)
|
||||||
|
{
|
||||||
|
if ($response instanceof SpecialResponse) {
|
||||||
|
return new Response($response->getContent(), $response->getStatus(), $response->getHeaders());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
protected function getScript($request)
|
protected function getScript($request)
|
||||||
{
|
{
|
||||||
$r = new \ReflectionClass('Symfony\Component\BrowserKit\Response');
|
$r = new \ReflectionClass('Symfony\Component\BrowserKit\Response');
|
||||||
@ -90,9 +103,6 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('http://example.com/', $client->getRequest()->getUri(), '->getCrawler() returns the Request of the last request');
|
$this->assertEquals('http://example.com/', $client->getRequest()->getUri(), '->getCrawler() returns the Request of the last request');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @covers Symfony\Component\BrowserKit\Client::getResponse
|
|
||||||
*/
|
|
||||||
public function testGetResponse()
|
public function testGetResponse()
|
||||||
{
|
{
|
||||||
$client = new TestClient();
|
$client = new TestClient();
|
||||||
@ -100,6 +110,18 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
|||||||
$client->request('GET', 'http://example.com/');
|
$client->request('GET', 'http://example.com/');
|
||||||
|
|
||||||
$this->assertEquals('foo', $client->getResponse()->getContent(), '->getCrawler() returns the Response of the last request');
|
$this->assertEquals('foo', $client->getResponse()->getContent(), '->getCrawler() returns the Response of the last request');
|
||||||
|
$this->assertInstanceOf('Symfony\Component\BrowserKit\Response', $client->getResponse(), '->getCrawler() returns the Response of the last request');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetInternalResponse()
|
||||||
|
{
|
||||||
|
$client = new TestClient();
|
||||||
|
$client->setNextResponse(new SpecialResponse('foo'));
|
||||||
|
$client->request('GET', 'http://example.com/');
|
||||||
|
|
||||||
|
$this->assertInstanceOf('Symfony\Component\BrowserKit\Response', $client->getInternalResponse());
|
||||||
|
$this->assertNotInstanceOf('Symfony\Component\BrowserKit\Tests\SpecialResponse', $client->getInternalResponse());
|
||||||
|
$this->assertInstanceOf('Symfony\Component\BrowserKit\Tests\SpecialResponse', $client->getResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetContent()
|
public function testGetContent()
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\HttpKernel;
|
|||||||
|
|
||||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\BrowserKit\Client as BaseClient;
|
use Symfony\Component\BrowserKit\Client as BaseClient;
|
||||||
use Symfony\Component\BrowserKit\Request as DomRequest;
|
use Symfony\Component\BrowserKit\Request as DomRequest;
|
||||||
use Symfony\Component\BrowserKit\Response as DomResponse;
|
use Symfony\Component\BrowserKit\Response as DomResponse;
|
||||||
@ -49,6 +50,26 @@ class Client extends BaseClient
|
|||||||
$this->followRedirects = false;
|
$this->followRedirects = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @return Request|null A Request instance
|
||||||
|
*/
|
||||||
|
public function getRequest()
|
||||||
|
{
|
||||||
|
return parent::getRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @return Response|null A Response instance
|
||||||
|
*/
|
||||||
|
public function getResponse()
|
||||||
|
{
|
||||||
|
return parent::getResponse();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a request.
|
* Makes a request.
|
||||||
*
|
*
|
||||||
@ -100,7 +121,7 @@ EOF;
|
|||||||
/**
|
/**
|
||||||
* Converts the BrowserKit request to a HttpKernel request.
|
* Converts the BrowserKit request to a HttpKernel request.
|
||||||
*
|
*
|
||||||
* @param DomRequest $request A Request instance
|
* @param DomRequest $request A DomRequest instance
|
||||||
*
|
*
|
||||||
* @return Request A Request instance
|
* @return Request A Request instance
|
||||||
*/
|
*/
|
||||||
@ -167,7 +188,7 @@ EOF;
|
|||||||
*
|
*
|
||||||
* @param Response $response A Response instance
|
* @param Response $response A Response instance
|
||||||
*
|
*
|
||||||
* @return Response A Response instance
|
* @return DomResponse A DomResponse instance
|
||||||
*/
|
*/
|
||||||
protected function filterResponse($response)
|
protected function filterResponse($response)
|
||||||
{
|
{
|
||||||
|
@ -35,6 +35,10 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$client->request('GET', '/');
|
$client->request('GET', '/');
|
||||||
$this->assertEquals('Request: /', $client->getResponse()->getContent(), '->doRequest() uses the request handler to make the request');
|
$this->assertEquals('Request: /', $client->getResponse()->getContent(), '->doRequest() uses the request handler to make the request');
|
||||||
|
$this->assertInstanceOf('Symfony\Component\BrowserKit\Request', $client->getInternalRequest());
|
||||||
|
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Request', $client->getRequest());
|
||||||
|
$this->assertInstanceOf('Symfony\Component\BrowserKit\Response', $client->getInternalResponse());
|
||||||
|
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $client->getResponse());
|
||||||
|
|
||||||
$client->request('GET', 'http://www.example.com/');
|
$client->request('GET', 'http://www.example.com/');
|
||||||
$this->assertEquals('Request: /', $client->getResponse()->getContent(), '->doRequest() uses the request handler to make the request');
|
$this->assertEquals('Request: /', $client->getResponse()->getContent(), '->doRequest() uses the request handler to make the request');
|
||||||
|
Reference in New Issue
Block a user