107 lines
3 KiB
PHP
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]);
|
|
});
|