From 8408eede36071310455b29511ff17fca1da60c54 Mon Sep 17 00:00:00 2001 From: Nicolas Appriou Date: Wed, 1 Feb 2023 11:54:16 +0100 Subject: [PATCH] [HttpFoundation] Decrease response test constraint verbosity Feature #42948 --- .../Component/HttpFoundation/CHANGELOG.md | 1 + .../Component/HttpFoundation/Response.php | 10 +++++- .../Test/Constraint/ResponseIsRedirected.php | 9 +++++- .../Test/Constraint/ResponseIsSuccessful.php | 9 +++++- .../Constraint/ResponseIsUnprocessable.php | 14 ++++++--- .../Constraint/ResponseStatusCodeSame.php | 4 +-- .../Constraint/ResponseIsRedirectedTest.php | 22 +++++++++++-- .../Constraint/ResponseIsSuccessfulTest.php | 23 ++++++++++++-- .../ResponseIsUnprocessableTest.php | 31 +++++++++++++++++++ .../Constraint/ResponseStatusCodeSameTest.php | 19 +++++++++++- 10 files changed, 127 insertions(+), 15 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/CHANGELOG.md b/src/Symfony/Component/HttpFoundation/CHANGELOG.md index 8e70070fc8723..a2cf64e91eac2 100644 --- a/src/Symfony/Component/HttpFoundation/CHANGELOG.md +++ b/src/Symfony/Component/HttpFoundation/CHANGELOG.md @@ -7,6 +7,7 @@ CHANGELOG * Add `ParameterBag::getEnum()` * Create migration for session table when pdo handler is used * Add support for Relay PHP extension for Redis + * Add `verbose` argument to response test constraints 6.2 --- diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index d5c7129a5fa5a..72b6a730180b3 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -236,7 +236,7 @@ public function __construct(?string $content = '', int $status = 200, array $hea public function __toString(): string { return - sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n". + $this->getCommandString()."\r\n". $this->headers."\r\n". $this->getContent(); } @@ -249,6 +249,14 @@ public function __clone() $this->headers = clone $this->headers; } + /** + * @return string The first line of the actual HTTP request + */ + public function getCommandString(): string + { + return sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText); + } + /** * Prepares the Response before it is sent to the client. * diff --git a/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseIsRedirected.php b/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseIsRedirected.php index bb0e53d0e6cd8..d4e650e6fbc98 100644 --- a/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseIsRedirected.php +++ b/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseIsRedirected.php @@ -16,6 +16,13 @@ final class ResponseIsRedirected extends Constraint { + /** + * @param booll $verbose If true, the entire response is printed on failure. If false, the response body is omitted. + */ + public function __construct(private readonly bool $verbose = true) + { + } + public function toString(): string { return 'is redirected'; @@ -42,6 +49,6 @@ protected function failureDescription($response): string */ protected function additionalFailureDescription($response): string { - return (string) $response; + return $this->verbose ? (string) $response : $response->getCommandString()."\r\n".$response->headers; } } diff --git a/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseIsSuccessful.php b/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseIsSuccessful.php index 2c6b768061268..3ea8c69d2a523 100644 --- a/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseIsSuccessful.php +++ b/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseIsSuccessful.php @@ -16,6 +16,13 @@ final class ResponseIsSuccessful extends Constraint { + /** + * @param booll $verbose If true, the entire response is printed on failure. If false, the response body is omitted. + */ + public function __construct(private readonly bool $verbose = true) + { + } + public function toString(): string { return 'is successful'; @@ -42,6 +49,6 @@ protected function failureDescription($response): string */ protected function additionalFailureDescription($response): string { - return (string) $response; + return $this->verbose ? (string) $response : $response->getCommandString()."\r\n".$response->headers; } } diff --git a/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseIsUnprocessable.php b/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseIsUnprocessable.php index 52336a5b25dbc..1175f6ca9c416 100644 --- a/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseIsUnprocessable.php +++ b/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseIsUnprocessable.php @@ -16,6 +16,10 @@ final class ResponseIsUnprocessable extends Constraint { + public function __construct(private readonly bool $verbose = true) + { + } + public function toString(): string { return 'is unprocessable'; @@ -24,15 +28,15 @@ public function toString(): string /** * @param Response $other */ - protected function matches($other): bool + protected function matches($response): bool { - return Response::HTTP_UNPROCESSABLE_ENTITY === $other->getStatusCode(); + return Response::HTTP_UNPROCESSABLE_ENTITY === $response->getStatusCode(); } /** * @param Response $other */ - protected function failureDescription($other): string + protected function failureDescription($response): string { return 'the Response '.$this->toString(); } @@ -40,8 +44,8 @@ protected function failureDescription($other): string /** * @param Response $other */ - protected function additionalFailureDescription($other): string + protected function additionalFailureDescription($response): string { - return (string) $other; + return $this->verbose ? (string) $response : $response->getCommandString()."\r\n".$response->headers; } } diff --git a/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseStatusCodeSame.php b/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseStatusCodeSame.php index cd565ba987b64..9358fe3319b64 100644 --- a/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseStatusCodeSame.php +++ b/src/Symfony/Component/HttpFoundation/Test/Constraint/ResponseStatusCodeSame.php @@ -18,7 +18,7 @@ final class ResponseStatusCodeSame extends Constraint { private int $statusCode; - public function __construct(int $statusCode) + public function __construct(int $statusCode, private readonly bool $verbose = true) { $this->statusCode = $statusCode; } @@ -49,6 +49,6 @@ protected function failureDescription($response): string */ protected function additionalFailureDescription($response): string { - return (string) $response; + return $this->verbose ? (string) $response : $response->getCommandString()."\r\n".$response->headers; } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseIsRedirectedTest.php b/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseIsRedirectedTest.php index 60590346e2622..c4df3bc93a8c8 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseIsRedirectedTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseIsRedirectedTest.php @@ -27,9 +27,27 @@ public function testConstraint() $this->assertFalse($constraint->evaluate(new Response(), '', true)); try { - $constraint->evaluate(new Response()); + $constraint->evaluate(new Response('Body content')); } catch (ExpectationFailedException $e) { - $this->assertStringContainsString("Failed asserting that the Response is redirected.\nHTTP/1.0 200 OK", TestFailure::exceptionToString($e)); + $exceptionMessage = TestFailure::exceptionToString($e); + $this->assertStringContainsString("Failed asserting that the Response is redirected.\nHTTP/1.0 200 OK", $exceptionMessage); + $this->assertStringContainsString('Body content', $exceptionMessage); + + return; + } + + $this->fail(); + } + + public function testReducedVerbosity() + { + $constraint = new ResponseIsRedirected(verbose: false); + try { + $constraint->evaluate(new Response('Body content')); + } catch (ExpectationFailedException $e) { + $exceptionMessage = TestFailure::exceptionToString($e); + $this->assertStringContainsString("Failed asserting that the Response is redirected.\nHTTP/1.0 200 OK", $exceptionMessage); + $this->assertStringNotContainsString('Body content', $exceptionMessage); return; } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseIsSuccessfulTest.php b/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseIsSuccessfulTest.php index 89c3045f16dbf..9ecafae7e8880 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseIsSuccessfulTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseIsSuccessfulTest.php @@ -27,9 +27,28 @@ public function testConstraint() $this->assertFalse($constraint->evaluate(new Response('', 404), '', true)); try { - $constraint->evaluate(new Response('', 404)); + $constraint->evaluate(new Response('Response body', 404)); } catch (ExpectationFailedException $e) { - $this->assertStringContainsString("Failed asserting that the Response is successful.\nHTTP/1.0 404 Not Found", TestFailure::exceptionToString($e)); + $exceptionMessage = TestFailure::exceptionToString($e); + $this->assertStringContainsString("Failed asserting that the Response is successful.\nHTTP/1.0 404 Not Found", $exceptionMessage); + $this->assertStringContainsString('Response body', $exceptionMessage); + + return; + } + + $this->fail(); + } + + public function testReducedVerbosity() + { + $constraint = new ResponseIsSuccessful(verbose: false); + + try { + $constraint->evaluate(new Response('Response body', 404)); + } catch (ExpectationFailedException $e) { + $exceptionMessage = TestFailure::exceptionToString($e); + $this->assertStringContainsString("Failed asserting that the Response is successful.\nHTTP/1.0 404 Not Found", $exceptionMessage); + $this->assertStringNotContainsString('Response body', $exceptionMessage); return; } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseIsUnprocessableTest.php b/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseIsUnprocessableTest.php index 7f22bde345bf8..a142ec4b02c49 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseIsUnprocessableTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseIsUnprocessableTest.php @@ -11,7 +11,9 @@ namespace Symfony\Component\HttpFoundation\Tests\Test\Constraint; +use PHPUnit\Framework\ExpectationFailedException; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\TestFailure; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Test\Constraint\ResponseIsUnprocessable; @@ -23,5 +25,34 @@ public function testConstraint() $this->assertTrue($constraint->evaluate(new Response('', 422), '', true)); $this->assertFalse($constraint->evaluate(new Response(), '', true)); + + try { + $constraint->evaluate(new Response('Response body')); + } catch (ExpectationFailedException $e) { + $exceptionMessage = TestFailure::exceptionToString($e); + $this->assertStringContainsString("Failed asserting that the Response is unprocessable.\nHTTP/1.0 200 OK", $exceptionMessage); + $this->assertStringContainsString('Response body', $exceptionMessage); + + return; + } + + $this->fail(); + } + + public function testReducedVerbosity() + { + $constraint = new ResponseIsUnprocessable(verbose: false); + + try { + $constraint->evaluate(new Response('Response body')); + } catch (ExpectationFailedException $e) { + $exceptionMessage = TestFailure::exceptionToString($e); + $this->assertStringContainsString("Failed asserting that the Response is unprocessable.\nHTTP/1.0 200 OK", $exceptionMessage); + $this->assertStringNotContainsString('Response body', $exceptionMessage); + + return; + } + + $this->fail(); } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseStatusCodeSameTest.php b/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseStatusCodeSameTest.php index 80a4eebfc8611..df840f1a821cf 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseStatusCodeSameTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Test/Constraint/ResponseStatusCodeSameTest.php @@ -29,13 +29,30 @@ public function testConstraint() $constraint = new ResponseStatusCodeSame(200); try { - $constraint->evaluate(new Response('', 404)); + $constraint->evaluate(new Response('Response body', 404)); } catch (ExpectationFailedException $e) { + $exceptionMessage = TestFailure::exceptionToString($e); $this->assertStringContainsString("Failed asserting that the Response status code is 200.\nHTTP/1.0 404 Not Found", TestFailure::exceptionToString($e)); + $this->assertStringContainsString('Response body', $exceptionMessage); return; } $this->fail(); } + + public function testReducedVerbosity() + { + $constraint = new ResponseStatusCodeSame(200, verbose: false); + + try { + $constraint->evaluate(new Response('Response body', 404)); + } catch (ExpectationFailedException $e) { + $exceptionMessage = TestFailure::exceptionToString($e); + $this->assertStringContainsString("Failed asserting that the Response status code is 200.\nHTTP/1.0 404 Not Found", TestFailure::exceptionToString($e)); + $this->assertStringNotContainsString('Response body', $exceptionMessage); + + return; + } + } }