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 IData { public string $reply; public function __construct(string $message) { $this->reply = $message == 'ping' ? 'pong' : 'unknown'; } /** * @param array $data * @param array $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 IData { 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 IData { 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]); });