diff --git a/src/Symfony/Component/HttpClient/CHANGELOG.md b/src/Symfony/Component/HttpClient/CHANGELOG.md index c9417a88315e7..4e9e09ee263e3 100644 --- a/src/Symfony/Component/HttpClient/CHANGELOG.md +++ b/src/Symfony/Component/HttpClient/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG --- * Allow mocking `start_time` info in `MockResponse` + * Add `MockResponse::fromFile()` and `JsonMockResponse::fromFile()` methods to help using fixtures files 7.0 --- diff --git a/src/Symfony/Component/HttpClient/Response/JsonMockResponse.php b/src/Symfony/Component/HttpClient/Response/JsonMockResponse.php index 66372aa8a8149..a0ef7d28b471b 100644 --- a/src/Symfony/Component/HttpClient/Response/JsonMockResponse.php +++ b/src/Symfony/Component/HttpClient/Response/JsonMockResponse.php @@ -30,4 +30,18 @@ public function __construct(mixed $body = [], array $info = []) parent::__construct($json, $info); } + + public static function fromFile(string $path, array $info = []): static + { + if (!is_file($path)) { + throw new InvalidArgumentException(sprintf('File not found: "%s".', $path)); + } + + $json = file_get_contents($path); + if (!json_validate($json)) { + throw new \InvalidArgumentException(sprintf('File "%s" does not contain valid JSON.', $path)); + } + + return new static(json_decode($json, true, flags: \JSON_THROW_ON_ERROR), $info); + } } diff --git a/src/Symfony/Component/HttpClient/Response/MockResponse.php b/src/Symfony/Component/HttpClient/Response/MockResponse.php index ed2b2008f0c99..19041e3070ccd 100644 --- a/src/Symfony/Component/HttpClient/Response/MockResponse.php +++ b/src/Symfony/Component/HttpClient/Response/MockResponse.php @@ -64,6 +64,15 @@ public function __construct(string|iterable $body = '', array $info = []) self::addResponseHeaders($responseHeaders, $this->info, $this->headers); } + public static function fromFile(string $path, array $info = []): static + { + if (!is_file($path)) { + throw new \InvalidArgumentException(sprintf('File not found: "%s".', $path)); + } + + return new static(file_get_contents($path), $info); + } + /** * Returns the options used when doing the request. */ diff --git a/src/Symfony/Component/HttpClient/Tests/Response/Fixtures/invalid_json.json b/src/Symfony/Component/HttpClient/Tests/Response/Fixtures/invalid_json.json new file mode 100644 index 0000000000000..02ec6a9a01ade --- /dev/null +++ b/src/Symfony/Component/HttpClient/Tests/Response/Fixtures/invalid_json.json @@ -0,0 +1 @@ +foo ccc \ No newline at end of file diff --git a/src/Symfony/Component/HttpClient/Tests/Response/Fixtures/response.json b/src/Symfony/Component/HttpClient/Tests/Response/Fixtures/response.json new file mode 100644 index 0000000000000..c8c4105eb57cd --- /dev/null +++ b/src/Symfony/Component/HttpClient/Tests/Response/Fixtures/response.json @@ -0,0 +1,3 @@ +{ + "foo": "bar" +} diff --git a/src/Symfony/Component/HttpClient/Tests/Response/Fixtures/response.txt b/src/Symfony/Component/HttpClient/Tests/Response/Fixtures/response.txt new file mode 100644 index 0000000000000..b978efc508aee --- /dev/null +++ b/src/Symfony/Component/HttpClient/Tests/Response/Fixtures/response.txt @@ -0,0 +1 @@ +foo bar ccc \ No newline at end of file diff --git a/src/Symfony/Component/HttpClient/Tests/Response/JsonMockResponseTest.php b/src/Symfony/Component/HttpClient/Tests/Response/JsonMockResponseTest.php index b371c08cf4241..bd4c404fa61ca 100644 --- a/src/Symfony/Component/HttpClient/Tests/Response/JsonMockResponseTest.php +++ b/src/Symfony/Component/HttpClient/Tests/Response/JsonMockResponseTest.php @@ -85,4 +85,25 @@ public static function responseHeadersProvider(): array ['application/problem+json', ['x-foo' => 'ccc', 'content-type' => 'application/problem+json']], ]; } + + public function testFromFile() + { + $client = new MockHttpClient(JsonMockResponse::fromFile(__DIR__.'/Fixtures/response.json')); + $response = $client->request('GET', 'https://symfony.com'); + + $this->assertSame([ + 'foo' => 'bar', + ], $response->toArray()); + $this->assertSame('application/json', $response->getHeaders()['content-type'][0]); + } + + public function testFromFileWithInvalidJson() + { + $path = __DIR__.'/Fixtures/invalid_json.json'; + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage(sprintf('File "%s" does not contain valid JSON.', $path)); + + JsonMockResponse::fromFile($path); + } } diff --git a/src/Symfony/Component/HttpClient/Tests/Response/MockResponseTest.php b/src/Symfony/Component/HttpClient/Tests/Response/MockResponseTest.php index 3051e29b4f03b..909b3dec8da0d 100644 --- a/src/Symfony/Component/HttpClient/Tests/Response/MockResponseTest.php +++ b/src/Symfony/Component/HttpClient/Tests/Response/MockResponseTest.php @@ -15,11 +15,9 @@ use Symfony\Component\HttpClient\Exception\InvalidArgumentException; use Symfony\Component\HttpClient\Exception\JsonException; use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\MockHttpClient; use Symfony\Component\HttpClient\Response\MockResponse; -/** - * Test methods from Symfony\Component\HttpClient\Response\*ResponseTrait. - */ class MockResponseTest extends TestCase { public function testTotalTimeShouldBeSimulatedWhenNotProvided() @@ -133,4 +131,12 @@ public function testMustBeIssuedByMockHttpClient() (new MockResponse())->getContent(); } + + public function testFromFile() + { + $client = new MockHttpClient(MockResponse::fromFile(__DIR__.'/Fixtures/response.txt')); + $response = $client->request('GET', 'https://symfony.com'); + + $this->assertSame('foo bar ccc', $response->getContent()); + } }