diff --git a/src/Symfony/Component/BrowserKit/CHANGELOG.md b/src/Symfony/Component/BrowserKit/CHANGELOG.md index 41301b9258ad7..a730a86bf4e70 100644 --- a/src/Symfony/Component/BrowserKit/CHANGELOG.md +++ b/src/Symfony/Component/BrowserKit/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +6.1 +--- + + * Add `toArray` method to `Response` + 5.3 --- diff --git a/src/Symfony/Component/BrowserKit/Exception/JsonException.php b/src/Symfony/Component/BrowserKit/Exception/JsonException.php new file mode 100644 index 0000000000000..b62dbcbba3e54 --- /dev/null +++ b/src/Symfony/Component/BrowserKit/Exception/JsonException.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\BrowserKit\Exception; + +class JsonException extends \JsonException +{ +} diff --git a/src/Symfony/Component/BrowserKit/Response.php b/src/Symfony/Component/BrowserKit/Response.php index 3f669e423199a..5b0789d57c98b 100644 --- a/src/Symfony/Component/BrowserKit/Response.php +++ b/src/Symfony/Component/BrowserKit/Response.php @@ -11,6 +11,8 @@ namespace Symfony\Component\BrowserKit; +use Symfony\Component\BrowserKit\Exception\JsonException; + /** * @author Fabien Potencier */ @@ -19,6 +21,7 @@ final class Response private string $content; private int $status; private array $headers; + private array $jsonData; /** * The headers array is a set of key/value pairs. If a header is present multiple times @@ -87,4 +90,23 @@ public function getHeader(string $header, bool $first = true): string|array|null return $first ? null : []; } + + public function toArray(): array + { + if (isset($this->jsonData)) { + return $this->jsonData; + } + + try { + $content = json_decode($this->content, true, flags: \JSON_BIGINT_AS_STRING | \JSON_THROW_ON_ERROR); + } catch (\JsonException $e) { + throw new JsonException($e->getMessage(), $e->getCode(), $e); + } + + if (!\is_array($content)) { + throw new JsonException(sprintf('JSON content was expected to decode to an array, "%s" returned.', get_debug_type($content))); + } + + return $this->jsonData = $content; + } } diff --git a/src/Symfony/Component/BrowserKit/Tests/ResponseTest.php b/src/Symfony/Component/BrowserKit/Tests/ResponseTest.php index d70433549bec9..5abde5967dc3a 100644 --- a/src/Symfony/Component/BrowserKit/Tests/ResponseTest.php +++ b/src/Symfony/Component/BrowserKit/Tests/ResponseTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\BrowserKit\Tests; use PHPUnit\Framework\TestCase; +use Symfony\Component\BrowserKit\Exception\JsonException; use Symfony\Component\BrowserKit\Response; class ResponseTest extends TestCase @@ -74,4 +75,48 @@ public function testMagicToStringWithMultipleSetCookieHeader() $this->assertEquals($expected, $response->__toString(), '->__toString() returns the headers and the content as a string'); } + + public function testToArray() + { + $response = new Response('{"foo":"foo","bar":{"baz":"baz","qux":33,"quux":12345678901234567890}}'); + + $this->assertSame([ + 'foo' => 'foo', + 'bar' => [ + 'baz' => 'baz', + 'qux' => 33, + 'quux' => '12345678901234567890', + ], + ], $response->toArray(), '->toArray returns an array representation of json content'); + } + + /** + * @dataProvider provideInvalidJson + */ + public function testToArrayThrowsErrorOnInvalidJson(string $data) + { + $response = new Response($data); + + $this->expectException(JsonException::class); + $this->expectExceptionMessage('Syntax error'); + + $response->toArray(); + } + + public function provideInvalidJson(): iterable + { + yield 'Empty string' => ['']; + yield 'Not json' => ['freferfrefer']; + yield 'Malformed json' => ['{"foo", "bar", "baz"}']; + } + + public function testToArrayThrowsErrorOnNonArray() + { + $response = new Response('"foo"'); + + $this->expectException(JsonException::class); + $this->expectExceptionMessage('JSON content was expected to decode to an array'); + + $response->toArray(); + } }