From 589d06f19683c1b282d45774572d7dfaf2e85ac8 Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Wed, 2 Dec 2020 11:07:44 +0100 Subject: [PATCH 1/2] Fix jsonRequest in AbstractBrowser for GET Methods --- .../Component/BrowserKit/AbstractBrowser.php | 34 ++++++++++++++++--- .../BrowserKit/Tests/AbstractBrowserTest.php | 24 ++++++++++++- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/BrowserKit/AbstractBrowser.php b/src/Symfony/Component/BrowserKit/AbstractBrowser.php index a43f434c70337..6b748717ebc52 100644 --- a/src/Symfony/Component/BrowserKit/AbstractBrowser.php +++ b/src/Symfony/Component/BrowserKit/AbstractBrowser.php @@ -166,16 +166,42 @@ public function xmlHttpRequest(string $method, string $uri, array $parameters = */ public function jsonRequest(string $method, string $uri, array $parameters = [], array $server = [], bool $changeHistory = true): Crawler { - $content = json_encode($parameters); + // Based on https://github.com/symfony/symfony/blob/v5.2.0/src/Symfony/Component/HttpFoundation/Request.php#L388-L404 + // the logic in symfony/http-foundation we convert parameters to json content. + switch (strtoupper($method)) { + case 'POST': + case 'PUT': + case 'DELETE': + case 'PATCH': + $content = json_encode($parameters, \defined('JSON_THROW_ON_ERROR') ? \JSON_THROW_ON_ERROR : 0); + $query = []; + break; + default: + $content = null; + $query = $parameters; + break; + } + + $serverContentType = $this->getServerParameter('CONTENT_TYPE', null); + $serverHttpAccept = $this->getServerParameter('HTTP_ACCEPT', null); $this->setServerParameter('CONTENT_TYPE', 'application/json'); $this->setServerParameter('HTTP_ACCEPT', 'application/json'); try { - return $this->request($method, $uri, [], [], $server, $content, $changeHistory); + return $this->request($method, $uri, $query, [], $server, $content, $changeHistory); } finally { - unset($this->server['CONTENT_TYPE']); - unset($this->server['HTTP_ACCEPT']); + if (null === $serverContentType) { + unset($this->server['CONTENT_TYPE']); + } else { + $this->setServerParameter('CONTENT_TYPE', $serverContentType); + } + + if (null === $serverHttpAccept) { + unset($this->server['HTTP_ACCEPT']); + } else { + $this->setServerParameter('HTTP_ACCEPT', $serverHttpAccept); + } } } diff --git a/src/Symfony/Component/BrowserKit/Tests/AbstractBrowserTest.php b/src/Symfony/Component/BrowserKit/Tests/AbstractBrowserTest.php index 120286cf0ddab..effca8ed8dec9 100644 --- a/src/Symfony/Component/BrowserKit/Tests/AbstractBrowserTest.php +++ b/src/Symfony/Component/BrowserKit/Tests/AbstractBrowserTest.php @@ -63,7 +63,7 @@ public function testXmlHttpRequest() public function testJsonRequest() { $client = $this->getBrowser(); - $client->jsonRequest('GET', 'http://example.com/', ['param' => 1], [], true); + $client->jsonRequest('POST', 'http://example.com/', ['param' => 1], [], true); $this->assertSame('application/json', $client->getRequest()->getServer()['CONTENT_TYPE']); $this->assertSame('application/json', $client->getRequest()->getServer()['HTTP_ACCEPT']); $this->assertFalse($client->getServerParameter('CONTENT_TYPE', false)); @@ -71,6 +71,28 @@ public function testJsonRequest() $this->assertSame('{"param":1}', $client->getRequest()->getContent()); } + public function testJsonRequestPredefinedServerVariables() + { + $client = $this->getBrowser(['HTTP_ACCEPT' => 'application/xml', 'CONTENT_TYPE' => 'application/xml']); + $client->jsonRequest('POST', 'http://example.com/', ['param' => 1], [], true); + $this->assertSame('application/json', $client->getRequest()->getServer()['CONTENT_TYPE']); + $this->assertSame('application/json', $client->getRequest()->getServer()['HTTP_ACCEPT']); + $this->assertSame('application/xml', $client->getServerParameter('HTTP_ACCEPT')); + $this->assertSame('application/xml', $client->getServerParameter('CONTENT_TYPE')); + } + + public function testJsonRequestGet() + { + $client = $this->getBrowser(); + $client->jsonRequest('GET', 'http://example.com/', ['param' => 1], [], true); + $this->assertSame('application/json', $client->getRequest()->getServer()['CONTENT_TYPE']); + $this->assertSame('application/json', $client->getRequest()->getServer()['HTTP_ACCEPT']); + $this->assertFalse($client->getServerParameter('CONTENT_TYPE', false)); + $this->assertFalse($client->getServerParameter('HTTP_ACCEPT', false)); + $this->assertNull($client->getRequest()->getContent()); + $this->assertSame(['param' => '1'], $client->getRequest()->getParameters()); + } + public function testGetRequestWithIpAsHttpHost() { $client = $this->getBrowser(); From 0411c79f39539690072f54d450e4ddd514348efd Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Thu, 10 Dec 2020 10:33:14 +0100 Subject: [PATCH 2/2] Remove JSON_THROW_ERROR conditional to behave the same in all PHP Versions --- src/Symfony/Component/BrowserKit/AbstractBrowser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/BrowserKit/AbstractBrowser.php b/src/Symfony/Component/BrowserKit/AbstractBrowser.php index 6b748717ebc52..41383c3a03517 100644 --- a/src/Symfony/Component/BrowserKit/AbstractBrowser.php +++ b/src/Symfony/Component/BrowserKit/AbstractBrowser.php @@ -173,7 +173,7 @@ public function jsonRequest(string $method, string $uri, array $parameters = [], case 'PUT': case 'DELETE': case 'PATCH': - $content = json_encode($parameters, \defined('JSON_THROW_ON_ERROR') ? \JSON_THROW_ON_ERROR : 0); + $content = json_encode($parameters); $query = []; break; default: