Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] Assert invalid #38384

Merged
merged 7 commits into from
Aug 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions src/Illuminate/Testing/TestResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,105 @@ protected function responseHasView()
return isset($this->original) && $this->original instanceof View;
}

/**
* Assert that the given keys do not have validation errors.
*
* @param array|null $keys
* @param string $errorBag
* @param string $responseKey
* @return $this
*/
public function assertValid($keys = null, $errorBag = 'default', $responseKey = 'errors')
{
if ($this->baseResponse->headers->get('Content-Type') === 'application/json') {
return $this->assertJsonMissingValidationErrors($keys, $responseKey);
}

if ($this->session()->get('errors')) {
$errors = $this->session()->get('errors')->getBag($errorBag)->getMessages();
} else {
$errors = [];
}

if (empty($errors)) {
PHPUnit::assertTrue(true);

return $this;
}

if (is_null($keys) && count($errors) > 0) {
PHPUnit::fail(
'Response has unexpected validation errors: '.PHP_EOL.PHP_EOL.
json_encode($errors, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
);
}

foreach (Arr::wrap($keys) as $key) {
PHPUnit::assertFalse(
isset($errors[$key]),
"Found unexpected validation error for key: '{$key}'"
);
}

return $this;
}

/**
* Assert that the response has the given validation errors.
*
* @param array $errors
* @param string $errorBag
* @param string $responseKey
* @return $this
*/
public function assertInvalid($errors,
$errorBag = 'default',
$responseKey = 'errors')
{
if ($this->baseResponse->headers->get('Content-Type') === 'application/json') {
return $this->assertJsonValidationErrors($errors, $responseKey);
}

$this->assertSessionHas('errors');

$keys = (array) $errors;

$sessionErrors = $this->session()->get('errors')->getBag($errorBag)->getMessages();

$errorMessage = $sessionErrors
? 'Response has the following validation errors in the session:'.
PHP_EOL.PHP_EOL.json_encode($sessionErrors, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE).PHP_EOL
: 'Response does not have validation errors in the session.';

foreach ($errors as $key => $value) {
PHPUnit::assertArrayHasKey(
(is_int($key)) ? $value : $key,
$sessionErrors,
"Failed to find a validation error in session for key: '{$value}'".PHP_EOL.PHP_EOL.$errorMessage
);

if (! is_int($key)) {
$hasError = false;

foreach (Arr::wrap($sessionErrors[$key]) as $sessionErrorMessage) {
if (Str::contains($sessionErrorMessage, $value)) {
$hasError = true;

break;
}
}

if (! $hasError) {
PHPUnit::fail(
"Failed to find a validation error for key and message: '$key' => '$value'".PHP_EOL.PHP_EOL.$errorMessage
);
}
}
}

return $this;
}

/**
* Assert that the session has a given value.
*
Expand Down
51 changes: 51 additions & 0 deletions tests/Testing/TestResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
use Illuminate\Http\Response;
use Illuminate\Session\ArraySessionHandler;
use Illuminate\Session\Store;
use Illuminate\Support\MessageBag;
use Illuminate\Support\ViewErrorBag;
use Illuminate\Testing\Fluent\AssertableJson;
use Illuminate\Testing\TestResponse;
use JsonSerializable;
Expand Down Expand Up @@ -916,6 +918,55 @@ public function testAssertJsonValidationErrors()
$testResponse->assertJsonValidationErrors('foo');
}

public function testAssertJsonValidationErrorsUsingAssertInvalid()
{
$data = [
'status' => 'ok',
'errors' => ['foo' => 'oops'],
];

$testResponse = TestResponse::fromBaseResponse(
(new Response('', 200, ['Content-Type' => 'application/json']))->setContent(json_encode($data))
);

$testResponse->assertInvalid('foo');
}

public function testAssertSessionValidationErrorsUsingAssertInvalid()
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));

$store->put('errors', $errorBag = new ViewErrorBag);

$errorBag->put('default', new MessageBag([
'first_name' => [
'Your first name is required',
'Your first name must be at least 1 character',
],
]));

$testResponse = TestResponse::fromBaseResponse(new Response);

$testResponse->assertValid(['last_name']);
$testResponse->assertInvalid(['first_name']);
$testResponse->assertInvalid(['first_name' => 'required']);
$testResponse->assertInvalid(['first_name' => 'character']);
Comment on lines +950 to +953

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lovely API ❤️

}

public function testAssertSessionValidationErrorsUsingAssertValid()
{
app()->instance('session.store', $store = new Store('test-session', new ArraySessionHandler(1)));

$store->put('errors', $errorBag = new ViewErrorBag);

$errorBag->put('default', new MessageBag([
]));

$testResponse = TestResponse::fromBaseResponse(new Response);

$testResponse->assertValid();
}

public function testAssertJsonValidationErrorsCustomErrorsName()
{
$data = [
Expand Down