ValidationFailure tests

This commit is contained in:
icefox 2026-02-19 08:44:49 -03:00
parent 709201547c
commit f1d46dacb6
No known key found for this signature in database
7 changed files with 264 additions and 5 deletions

View file

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace Tests\Classes;
use Icefox\DTO\DataObject;
use Illuminate\Validation\Validator;
readonly class FailsReturnsDefault
{
use DataObject;
public function __construct(
public string $string,
public int $int = 42,
) {}
public static function fails(Validator $validator): ?static
{
return new self(string: 'default_value');
}
}

View file

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace Tests\Classes;
use Icefox\DTO\DataObject;
use Illuminate\Validation\Validator;
readonly class FailsReturnsNull
{
use DataObject;
public function __construct(
public string $string,
public int $int,
) {}
public static function fails(Validator $validator): ?static
{
return null;
}
}

View file

@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace Tests\Classes;
use Icefox\DTO\DataObject;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Validation\Validator;
readonly class FailsWithHttpResponse
{
use DataObject;
public function __construct(
public string $string,
public int $int,
) {}
public static function fails(Validator $validator): ?static
{
throw new HttpResponseException(
response()->json(['errors' => $validator->errors()], 422)
);
}
}

View file

@ -0,0 +1,108 @@
<?php
namespace Tests\FailedValidation;
use Illuminate\Validation\ValidationException;
use Tests\Classes\FailsReturnsDefault;
use Tests\Classes\FailsReturnsNull;
use Tests\Classes\FailsWithHttpResponse;
use Tests\Classes\PrimitiveData;
describe('fails method behavior', function () {
it('throws ValidationException when class does not implement fails()', function () {
expect(function () {
PrimitiveData::fromArray([
'int' => 0,
'float' => 3.14,
'bool' => true,
]);
})->toThrow(ValidationException::class);
});
it('returns null when fails() returns null', function () {
$result = FailsReturnsNull::fromArray([
'int' => 0,
]);
expect($result)->toBeNull();
});
it('returns static instance when fails() returns an object', function () {
$result = FailsReturnsDefault::fromArray([
'int' => 0,
]);
expect($result)->toBeInstanceOf(FailsReturnsDefault::class);
expect($result->string)->toBe('default_value');
expect($result->int)->toBe(42);
});
});
describe('HTTP request handling', function () {
beforeEach(function () {
\Illuminate\Support\Facades\Route::post('/test-validation-exception', function () {
PrimitiveData::fromArray([
'int' => 0,
'float' => 3.14,
'bool' => true,
]);
return response()->json(['success' => true]);
});
\Illuminate\Support\Facades\Route::post('/test-http-response-exception', function () {
FailsWithHttpResponse::fromArray([
'int' => 0,
]);
return response()->json(['success' => true]);
});
\Illuminate\Support\Facades\Route::post('/test-validation-exception-html', function () {
PrimitiveData::fromArray([
'int' => 0,
'float' => 3.14,
'bool' => true,
]);
return response('success');
});
});
it('returns 422 with errors when ValidationException is thrown in JSON request', function () {
$response = $this->postJson('/test-validation-exception', [
'int' => 0,
'float' => 3.14,
'bool' => true,
]);
$response->assertStatus(422);
$response->assertJsonValidationErrors(['string']);
});
it('returns custom JSON response when HttpResponseException is thrown', function () {
$response = $this->postJson('/test-http-response-exception', [
'int' => 0,
]);
$response->assertStatus(422);
$response->assertJsonStructure(['errors']);
$response->assertJsonFragment([
'errors' => [
'string' => ['The string field is required.'],
],
]);
});
it('redirects back with session errors when ValidationException is thrown in text/html request', function () {
$response = $this->post('/test-validation-exception-html', [
'int' => 0,
'float' => 3.14,
'bool' => true,
], [
'Accept' => 'text/html',
]);
$response->assertRedirect();
$response->assertSessionHasErrors(['string']);
});
});