Test project for media files management.
<?php
namespace Illuminate\Testing;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Arr;
use PHPUnit\Framework\ExpectationFailedException;
use ReflectionProperty;
/**
* @internal
*
* @mixin Assert
*/
class TestResponseAssert
{
/**
* Create a new TestResponse assertion helper.
*/
private function __construct(protected TestResponse $response)
{
//
}
/**
* Create a new TestResponse assertion helper.
*/
public static function withResponse(TestResponse $response): self
{
return new static($response);
}
/**
* Pass method calls to the Assert class and decorate the exception message.
*
* @param string $name
* @param array $arguments
* @return void
*
* @throws \PHPUnit\Framework\ExpectationFailedException
*/
public function __call($name, $arguments)
{
try {
Assert::$name(...$arguments);
} catch (ExpectationFailedException $e) {
throw $this->injectResponseContext($e);
}
}
/**
* Pass static method calls to the Assert class.
*
* @param string $name
* @param array $arguments
* @return void
*
* @throws \PHPUnit\Framework\ExpectationFailedException
*/
public static function __callStatic($name, $arguments)
{
Assert::$name(...$arguments);
}
/**
* Inject additional context from the response into the exception message.
*
* @param \PHPUnit\Framework\ExpectationFailedException $exception
* @return \PHPUnit\Framework\ExpectationFailedException
*/
protected function injectResponseContext($exception)
{
if ($lastException = $this->response->exceptions->last()) {
return $this->appendExceptionToException($lastException, $exception);
}
if ($this->response->baseResponse instanceof RedirectResponse) {
$session = $this->response->baseResponse->getSession();
if (! is_null($session) && $session->has('errors')) {
return $this->appendErrorsToException($session->get('errors')->all(), $exception);
}
}
if ($this->response->baseResponse->headers->get('Content-Type') === 'application/json') {
$testJson = new AssertableJsonString($this->response->getContent());
if (isset($testJson['errors'])) {
return $this->appendErrorsToException($testJson->json(), $exception, true);
}
}
return $exception;
}
/**
* Append an exception to the message of another exception.
*
* @param \Throwable $exceptionToAppend
* @param \PHPUnit\Framework\ExpectationFailedException $exception
* @return \PHPUnit\Framework\ExpectationFailedException
*/
protected function appendExceptionToException($exceptionToAppend, $exception)
{
$exceptionMessage = is_string($exceptionToAppend) ? $exceptionToAppend : $exceptionToAppend->getMessage();
$exceptionToAppend = (string) $exceptionToAppend;
$message = <<<"EOF"
The following exception occurred during the last request:
$exceptionToAppend
----------------------------------------------------------------------------------
$exceptionMessage
EOF;
return $this->appendMessageToException($message, $exception);
}
/**
* Append errors to an exception message.
*
* @param array $errors
* @param \PHPUnit\Framework\ExpectationFailedException $exception
* @param bool $json
* @return \PHPUnit\Framework\ExpectationFailedException
*/
protected function appendErrorsToException($errors, $exception, $json = false)
{
$errors = $json
? json_encode($errors, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
: implode(PHP_EOL, Arr::flatten($errors));
// JSON error messages may already contain the errors, so we shouldn't duplicate them...
if (str_contains($exception->getMessage(), $errors)) {
return $exception;
}
$message = <<<"EOF"
The following errors occurred during the last request:
$errors
EOF;
return $this->appendMessageToException($message, $exception);
}
/**
* Append a message to an exception.
*
* @param string $message
* @param \PHPUnit\Framework\ExpectationFailedException $exception
* @return \PHPUnit\Framework\ExpectationFailedException
*/
protected function appendMessageToException($message, $exception)
{
$property = new ReflectionProperty($exception, 'message');
$property->setValue(
$exception,
$exception->getMessage().PHP_EOL.PHP_EOL.$message.PHP_EOL
);
return $exception;
}
}