From 8fffa2c6f87b7dbaf790ef2d542e3def4acb0801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 31 Dec 2020 01:14:53 +0100 Subject: [PATCH] [FrameworkBundle][HttpFoundation] add assertResponseFormatSame() --- .../Bundle/FrameworkBundle/CHANGELOG.md | 1 + .../Test/BrowserKitAssertionsTrait.php | 5 ++ .../Tests/Test/WebTestCaseTest.php | 19 +++++ .../Component/HttpFoundation/CHANGELOG.md | 5 ++ .../Test/Constraint/ResponseFormatSame.php | 71 +++++++++++++++++++ .../Constraint/ResponseFormatSameTest.php | 61 ++++++++++++++++ 6 files changed, 162 insertions(+) create mode 100644 src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseFormatSame.php create mode 100644 src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseFormatSameTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index bc5ca7f27d..66710663e5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -7,6 +7,7 @@ CHANGELOG * Added support for configuring PHP error level to log levels * Added the `dispatcher` option to `debug:event-dispatcher` * Added the `event_dispatcher.dispatcher` tag + * Added `assertResponseFormatSame()` in `BrowserKitAssertionsTrait` 5.2.0 ----- diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/BrowserKitAssertionsTrait.php b/src/Symfony/Bundle/FrameworkBundle/Test/BrowserKitAssertionsTrait.php index 48f2b68e11..8caa19fa1f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/BrowserKitAssertionsTrait.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/BrowserKitAssertionsTrait.php @@ -38,6 +38,11 @@ trait BrowserKitAssertionsTrait self::assertThatForResponse(new ResponseConstraint\ResponseStatusCodeSame($expectedCode), $message); } + public static function assertResponseFormatSame(?string $expectedFormat, string $message = ''): void + { + self::assertThatForResponse(new ResponseConstraint\ResponseFormatSame(self::getRequest(), $expectedFormat), $message); + } + public static function assertResponseRedirects(string $expectedLocation = null, int $expectedCode = null, string $message = ''): void { $constraint = new ResponseConstraint\ResponseIsRedirected(); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Test/WebTestCaseTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Test/WebTestCaseTest.php index 96e1d8779b..0e1ed19e41 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Test/WebTestCaseTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Test/WebTestCaseTest.php @@ -23,6 +23,7 @@ use Symfony\Component\DomCrawler\Crawler; use Symfony\Component\HttpFoundation\Cookie as HttpFoundationCookie; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Test\Constraint\ResponseFormatSame; class WebTestCaseTest extends TestCase { @@ -75,6 +76,20 @@ class WebTestCaseTest extends TestCase $this->getResponseTester(new Response('', 302))->assertResponseRedirects('https://example.com/', 301); } + public function testAssertResponseFormat() + { + if (!class_exists(ResponseFormatSame::class)) { + $this->markTestSkipped('Too old version of HttpFoundation.'); + } + + $this->getResponseTester(new Response('', 200, ['Content-Type' => 'application/vnd.myformat']))->assertResponseFormatSame('custom'); + $this->getResponseTester(new Response('', 200, ['Content-Type' => 'application/ld+json']))->assertResponseFormatSame('jsonld'); + $this->getResponseTester(new Response())->assertResponseFormatSame(null); + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage("Failed asserting that the Response format is jsonld.\nHTTP/1.0 200 OK"); + $this->getResponseTester(new Response())->assertResponseFormatSame('jsonld'); + } + public function testAssertResponseHasHeader() { $this->getResponseTester(new Response())->assertResponseHasHeader('Date'); @@ -284,6 +299,10 @@ class WebTestCaseTest extends TestCase $client = $this->createMock(KernelBrowser::class); $client->expects($this->any())->method('getResponse')->willReturn($response); + $request = new Request(); + $request->setFormat('custom', ['application/vnd.myformat']); + $client->expects($this->any())->method('getRequest')->willReturn($request); + return $this->getTester($client); } diff --git a/src/Symfony/Component/HttpFoundation/CHANGELOG.md b/src/Symfony/Component/HttpFoundation/CHANGELOG.md index 472fef05a5..b6b90cb855 100644 --- a/src/Symfony/Component/HttpFoundation/CHANGELOG.md +++ b/src/Symfony/Component/HttpFoundation/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +5.3.0 +----- + + * added `ResponseFormatSame` PHPUnit constraint + 5.2.0 ----- diff --git a/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseFormatSame.php b/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseFormatSame.php new file mode 100644 index 0000000000..f73aedfa11 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseFormatSame.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * Asserts that the response is in the given format. + * + * @author Kévin Dunglas + */ +final class ResponseFormatSame extends Constraint +{ + private $request; + private $format; + + public function __construct(Request $request, ?string $format) + { + $this->request = $request; + $this->format = $format; + } + + /** + * {@inheritdoc} + */ + public function toString(): string + { + return 'format is '.($this->format ?? 'null'); + } + + /** + * @param Response $response + * + * {@inheritdoc} + */ + protected function matches($response): bool + { + return $this->format === $this->request->getFormat($response->headers->get('Content-Type')); + } + + /** + * @param Response $response + * + * {@inheritdoc} + */ + protected function failureDescription($response): string + { + return 'the Response '.$this->toString(); + } + + /** + * @param Response $response + * + * {@inheritdoc} + */ + protected function additionalFailureDescription($response): string + { + return (string) $response; + } +} diff --git a/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseFormatSameTest.php b/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseFormatSameTest.php new file mode 100644 index 0000000000..aed9285f24 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseFormatSameTest.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Tests\Test\Constraint; + +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\TestFailure; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Test\Constraint\ResponseFormatSame; + +/** + * @author Kévin Dunglas + */ +class ResponseFormatSameTest extends TestCase +{ + public function testConstraint() + { + $request = new Request(); + $request->setFormat('custom', ['application/vnd.myformat']); + + $constraint = new ResponseFormatSame($request, 'custom'); + $this->assertTrue($constraint->evaluate(new Response('', 200, ['Content-Type' => 'application/vnd.myformat']), '', true)); + $this->assertFalse($constraint->evaluate(new Response(), '', true)); + + try { + $constraint->evaluate(new Response('', 200, ['Content-Type' => 'application/ld+json'])); + } catch (ExpectationFailedException $e) { + $this->assertStringContainsString("Failed asserting that the Response format is custom.\nHTTP/1.0 200 OK", TestFailure::exceptionToString($e)); + + return; + } + + $this->fail(); + } + + public function testNullFormat() + { + $constraint = new ResponseFormatSame(new Request(), null); + $this->assertTrue($constraint->evaluate(new Response(), '', true)); + + try { + $constraint->evaluate(new Response('', 200, ['Content-Type' => 'application/ld+json'])); + } catch (ExpectationFailedException $e) { + $this->assertStringContainsString("Failed asserting that the Response format is null.\nHTTP/1.0 200 OK", TestFailure::exceptionToString($e)); + + return; + } + + $this->fail(); + } +}