laravel-data/tests/Http/RequestTest.php
2026-02-27 11:14:42 -03:00

107 lines
3 KiB
PHP

<?php
namespace Tests\Http;
use Icefox\DTO\IDataObject;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Validator as ValidatorFacade;
use Illuminate\Validation\Validator;
readonly class Basic implements IDataObject
{
public string $reply;
public function __construct(string $message)
{
$this->reply = $message == 'ping' ? 'pong' : 'unknown';
}
}
test('injects data object', function () {
Route::post('/', fn(Basic $object) => ['reply' => $object->reply]);
/** @var \Tests\TestCase $this */
$this->postJson('/', ['message' => 'ping'])->assertJson(['reply' => 'pong']);
});
test('fails on validation error', function () {
Route::post('/', fn(Basic $object) => ['reply' => $object->reply]);
/** @var \Tests\TestCase $this */
$resp = $this->postJson('/', [])
->assertStatus(422)
->assertJson([
'message' => 'The message field is required.',
'errors' => ['message' => ['The message field is required.']],
]);
});
readonly class WithCustomValidator implements IDataObject
{
public string $reply;
public function __construct(string $message)
{
$this->reply = $message == 'ping' ? 'pong' : 'unknown';
}
/**
* @param array<string,mixed> $data
* @param array<string,mixed> $rules
*/
public static function withValidator(array $data, array $rules): Validator
{
return ValidatorFacade::make($data, $rules, $messages = [
'message.required' => 'the known message is pong',
]);
}
}
test('replies with custom validator', function () {
Route::post('/', fn(WithCustomValidator $object) => []);
/** @var \Tests\TestCase $this */
$this->postJson('/', [])
->assertStatus(422)
->assertJson([
'message' => 'the known message is pong',
'errors' => ['message' => ['the known message is pong']],
]);
});
readonly class WithCustomFailure implements IDataObject
{
public function __construct(public bool $flag) {}
public static function fails(Validator $validator): void
{
throw new HttpResponseException(
response(['result' => 'invalid, but that is ok' ], 202),
);
}
}
test('uses custom response', function () {
Route::post('/', fn(WithCustomFailure $object) => response('', 204));
/** @var \Tests\TestCase $this */
$this->postJson('/', [])
->assertStatus(202)
->assertJson(['result' => 'invalid, but that is ok']);
});
readonly class WithDefaultObjectOnFailure implements IDataObject
{
public function __construct(public bool $flag) {}
public static function fails(): self
{
return new self(false);
}
}
test('uses default object on failure', function () {
Route::post('/', fn(WithDefaultObjectOnFailure $object) => response(['flag' => $object->flag], 200));
/** @var \Tests\TestCase $this */
$this->postJson('/', [])
->assertStatus(200)
->assertJson(['flag' => false]);
});