123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- <?php
- namespace Illuminate\Tests\Foundation;
- use Exception;
- use Illuminate\Auth\Access\AuthorizationException;
- use Illuminate\Auth\Access\Response;
- use Illuminate\Container\Container;
- use Illuminate\Contracts\Translation\Translator;
- use Illuminate\Contracts\Validation\Factory as ValidationFactoryContract;
- use Illuminate\Contracts\Validation\Validator;
- use Illuminate\Foundation\Http\FormRequest;
- use Illuminate\Http\RedirectResponse;
- use Illuminate\Routing\Redirector;
- use Illuminate\Routing\UrlGenerator;
- use Illuminate\Validation\Factory as ValidationFactory;
- use Illuminate\Validation\ValidationException;
- use Mockery as m;
- use PHPUnit\Framework\TestCase;
- class FoundationFormRequestTest extends TestCase
- {
- protected $mocks = [];
- protected function tearDown(): void
- {
- m::close();
- $this->mocks = [];
- }
- public function testValidatedMethodReturnsTheValidatedData()
- {
- $request = $this->createRequest(['name' => 'specified', 'with' => 'extras']);
- $request->validateResolved();
- $this->assertEquals(['name' => 'specified'], $request->validated());
- }
- public function testValidatedMethodReturnsTheValidatedDataNestedRules()
- {
- $payload = ['nested' => ['foo' => 'bar', 'baz' => ''], 'array' => [1, 2]];
- $request = $this->createRequest($payload, FoundationTestFormRequestNestedStub::class);
- $request->validateResolved();
- $this->assertEquals(['nested' => ['foo' => 'bar'], 'array' => [1, 2]], $request->validated());
- }
- public function testValidatedMethodReturnsTheValidatedDataNestedChildRules()
- {
- $payload = ['nested' => ['foo' => 'bar', 'with' => 'extras']];
- $request = $this->createRequest($payload, FoundationTestFormRequestNestedChildStub::class);
- $request->validateResolved();
- $this->assertEquals(['nested' => ['foo' => 'bar']], $request->validated());
- }
- public function testValidatedMethodReturnsTheValidatedDataNestedArrayRules()
- {
- $payload = ['nested' => [['bar' => 'baz', 'with' => 'extras'], ['bar' => 'baz2', 'with' => 'extras']]];
- $request = $this->createRequest($payload, FoundationTestFormRequestNestedArrayStub::class);
- $request->validateResolved();
- $this->assertEquals(['nested' => [['bar' => 'baz'], ['bar' => 'baz2']]], $request->validated());
- }
- public function testValidatedMethodNotValidateTwice()
- {
- $payload = ['name' => 'specified', 'with' => 'extras'];
- $request = $this->createRequest($payload, FoundationTestFormRequestTwiceStub::class);
- $request->validateResolved();
- $request->validated();
- $this->assertEquals(1, FoundationTestFormRequestTwiceStub::$count);
- }
- public function testValidateThrowsWhenValidationFails()
- {
- $this->expectException(ValidationException::class);
- $request = $this->createRequest(['no' => 'name']);
- $this->mocks['redirect']->shouldReceive('withInput->withErrors');
- $request->validateResolved();
- }
- public function testValidateMethodThrowsWhenAuthorizationFails()
- {
- $this->expectException(AuthorizationException::class);
- $this->expectExceptionMessage('This action is unauthorized.');
- $this->createRequest([], FoundationTestFormRequestForbiddenStub::class)->validateResolved();
- }
- public function testValidateThrowsExceptionFromAuthorizationResponse()
- {
- $this->expectException(AuthorizationException::class);
- $this->expectExceptionMessage('foo');
- $this->createRequest([], FoundationTestFormRequestForbiddenWithResponseStub::class)->validateResolved();
- }
- public function testValidateDoesntThrowExceptionFromResponseAllowed()
- {
- $this->createRequest([], FoundationTestFormRequestPassesWithResponseStub::class)->validateResolved();
- }
- public function testPrepareForValidationRunsBeforeValidation()
- {
- $this->createRequest([], FoundationTestFormRequestHooks::class)->validateResolved();
- }
- public function test_after_validation_runs_after_validation()
- {
- $request = $this->createRequest([], FoundationTestFormRequestHooks::class);
- $request->validateResolved();
- $this->assertEquals(['name' => 'Adam'], $request->all());
- }
- /**
- * Catch the given exception thrown from the executor, and return it.
- *
- * @param string $class
- * @param \Closure $executor
- * @return \Exception
- *
- * @throws \Exception
- */
- protected function catchException($class, $executor)
- {
- try {
- $executor();
- } catch (Exception $e) {
- if (is_a($e, $class)) {
- return $e;
- }
- throw $e;
- }
- throw new Exception("No exception thrown. Expected exception {$class}.");
- }
- /**
- * Create a new request of the given type.
- *
- * @param array $payload
- * @param string $class
- * @return \Illuminate\Foundation\Http\FormRequest
- */
- protected function createRequest($payload = [], $class = FoundationTestFormRequestStub::class)
- {
- $container = tap(new Container, function ($container) {
- $container->instance(
- ValidationFactoryContract::class,
- $this->createValidationFactory($container)
- );
- });
- $request = $class::create('/', 'GET', $payload);
- return $request->setRedirector($this->createMockRedirector($request))
- ->setContainer($container);
- }
- /**
- * Create a new validation factory.
- *
- * @param \Illuminate\Container\Container $container
- * @return \Illuminate\Validation\Factory
- */
- protected function createValidationFactory($container)
- {
- $translator = m::mock(Translator::class)->shouldReceive('get')
- ->zeroOrMoreTimes()->andReturn('error')->getMock();
- return new ValidationFactory($translator, $container);
- }
- /**
- * Create a mock redirector.
- *
- * @param \Illuminate\Http\Request $request
- * @return \Illuminate\Routing\Redirector
- */
- protected function createMockRedirector($request)
- {
- $redirector = $this->mocks['redirector'] = m::mock(Redirector::class);
- $redirector->shouldReceive('getUrlGenerator')->zeroOrMoreTimes()
- ->andReturn($generator = $this->createMockUrlGenerator());
- $redirector->shouldReceive('to')->zeroOrMoreTimes()
- ->andReturn($this->createMockRedirectResponse());
- $generator->shouldReceive('previous')->zeroOrMoreTimes()
- ->andReturn('previous');
- return $redirector;
- }
- /**
- * Create a mock URL generator.
- *
- * @return \Illuminate\Routing\UrlGenerator
- */
- protected function createMockUrlGenerator()
- {
- return $this->mocks['generator'] = m::mock(UrlGenerator::class);
- }
- /**
- * Create a mock redirect response.
- *
- * @return \Illuminate\Http\RedirectResponse
- */
- protected function createMockRedirectResponse()
- {
- return $this->mocks['redirect'] = m::mock(RedirectResponse::class);
- }
- }
- class FoundationTestFormRequestStub extends FormRequest
- {
- public function rules()
- {
- return ['name' => 'required'];
- }
- public function authorize()
- {
- return true;
- }
- }
- class FoundationTestFormRequestNestedStub extends FormRequest
- {
- public function rules()
- {
- return ['nested.foo' => 'required', 'array.*' => 'integer'];
- }
- public function authorize()
- {
- return true;
- }
- }
- class FoundationTestFormRequestNestedChildStub extends FormRequest
- {
- public function rules()
- {
- return ['nested.foo' => 'required'];
- }
- public function authorize()
- {
- return true;
- }
- }
- class FoundationTestFormRequestNestedArrayStub extends FormRequest
- {
- public function rules()
- {
- return ['nested.*.bar' => 'required'];
- }
- public function authorize()
- {
- return true;
- }
- }
- class FoundationTestFormRequestTwiceStub extends FormRequest
- {
- public static $count = 0;
- public function rules()
- {
- return ['name' => 'required'];
- }
- public function withValidator(Validator $validator)
- {
- $validator->after(function ($validator) {
- self::$count++;
- });
- }
- public function authorize()
- {
- return true;
- }
- }
- class FoundationTestFormRequestForbiddenStub extends FormRequest
- {
- public function authorize()
- {
- return false;
- }
- }
- class FoundationTestFormRequestHooks extends FormRequest
- {
- public function rules()
- {
- return ['name' => 'required'];
- }
- public function authorize()
- {
- return true;
- }
- public function prepareForValidation()
- {
- $this->replace(['name' => 'Taylor']);
- }
- public function passedValidation()
- {
- $this->replace(['name' => 'Adam']);
- }
- }
- class FoundationTestFormRequestForbiddenWithResponseStub extends FormRequest
- {
- public function authorize()
- {
- return Response::deny('foo');
- }
- }
- class FoundationTestFormRequestPassesWithResponseStub extends FormRequest
- {
- public function rules()
- {
- return [];
- }
- public function authorize()
- {
- return Response::allow('baz');
- }
- }
|