diff --git a/src/Symfony/Component/BrowserKit/AbstractBrowser.php b/src/Symfony/Component/BrowserKit/AbstractBrowser.php index a43f434c70337..41383c3a03517 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); + $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();