Skip to content

Instantly share code, notes, and snippets.

@decodedmrq
Forked from tuanpht/RegisterRequest.php
Created August 10, 2021 17:01
Show Gist options
  • Save decodedmrq/80fadd4ddef15f5fd07b60e20e23a251 to your computer and use it in GitHub Desktop.
Save decodedmrq/80fadd4ddef15f5fd07b60e20e23a251 to your computer and use it in GitHub Desktop.

Revisions

  1. @tuanpht tuanpht revised this gist Jul 24, 2019. 2 changed files with 4 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions RegisterRequest.php
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    <?php

    use Illuminate\Foundation\Http\FormRequest;
    use Illuminate\Validation\Rules\Unique;

    2 changes: 2 additions & 0 deletions RegisterRequestTest1.php
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    <?php

    use Tests\TestCase;
    use App\Http\Requests\Web\RegisterRequest;
    use Illuminate\Support\Facades\Validator;
  2. @tuanpht tuanpht created this gist Jul 24, 2019.
    21 changes: 21 additions & 0 deletions RegisterRequest.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,21 @@
    use Illuminate\Foundation\Http\FormRequest;
    use Illuminate\Validation\Rules\Unique;

    class RegisterRequest extends FormRequest
    {
    const NAME_MAX_LENGTH = 255;
    const EMAIL_MAX_LENGTH = 255;
    const PASSWORD_MIN_LENGTH = 8;

    /**
    * @return array
    */
    public function rules()
    {
    return [
    'name' => ['required', 'string', 'max:' . self::NAME_MAX_LENGTH],
    'email' => ['required', 'string', 'email', 'max:' . self::EMAIL_MAX_LENGTH, new Unique('users', 'email')],
    'password' => ['required', 'string', 'min:' . self::PASSWORD_MIN_LENGTH, 'confirmed'],
    ];
    }
    }
    18 changes: 18 additions & 0 deletions RegisterRequestTest1.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    use Tests\TestCase;
    use App\Http\Requests\Web\RegisterRequest;
    use Illuminate\Support\Facades\Validator;
    use Illuminate\Validation\PresenceVerifierInterface;

    class RegisterRequestTest extends TestCase
    {
    public function test_it_contains_valid_rules()
    {
    $request = new RegisterRequest;

    $this->assertEquals([
    'name' => ['required', 'string', 'max:' . RegisterRequest::NAME_MAX_LENGTH],
    'email' => ['required', 'string', 'email', 'max:' . RegisterRequest::EMAIL_MAX_LENGTH, new Unique('users', 'email')],
    'password' => ['required', 'string', 'min:' . RegisterRequest::PASSWORD_MIN_LENGTH, 'confirmed'],
    ], $request->rules());
    }
    }
    236 changes: 236 additions & 0 deletions RegisterRequestTest2.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,236 @@
    <?php

    namespace Tests\Unit\Http\Requests\Web;

    use Tests\TestCase;
    use App\Http\Requests\Web\RegisterRequest;
    use Illuminate\Support\Facades\Validator;
    use Mockery;
    use Illuminate\Validation\PresenceVerifierInterface;

    class RegisterRequestTest extends TestCase
    {
    /**
    * @param array $data Request data
    *
    * @dataProvider provideDataValidateNameSuccess
    */
    public function testValidateNameSuccess($data)
    {
    $request = new RegisterRequest;
    $rules = array_only($request->rules(), 'name');

    $validator = Validator::make($data, $rules);
    $passed = $validator->passes();

    // Can be debug with
    // dd($validator->failed());

    $this->assertTrue($passed);
    }

    public function provideDataValidateNameSuccess()
    {
    return [
    [['name' => 'Valid name']],
    [['name' => str_repeat('a', RegisterRequest::NAME_MAX_LENGTH)]],
    ];
    }

    /**
    * @param array $data Request data
    *
    * @dataProvider provideDataValidateNameFailed
    */
    public function testValidateNameFailedWhenMissingInput($data)
    {
    $request = new RegisterRequest;
    $rules = array_only($request->rules(), 'name');

    $validator = Validator::make($data, $rules);
    $passed = $validator->passes();

    $this->assertFalse($passed);
    }

    public function provideDataValidateNameFailed()
    {
    return [
    [[]],
    [['name' => ' ']],
    [['name' => '']],
    ];
    }

    public function testValidateNameFailedWhenExceedingMaxlength()
    {
    $request = new RegisterRequest;
    $rules = array_only($request->rules(), 'name');

    $validator = Validator::make([
    'name' => str_repeat('a', RegisterRequest::NAME_MAX_LENGTH + 1),
    ], $rules);

    $passed = $validator->passes();

    $this->assertFalse($passed);
    }

    /**
    * Fake database connection when using some db rules, e.g. unique, exists...
    */
    private function fakeDatabaseRuleVerifier($validator)
    {
    $presenceVerifier = Mockery::mock(PresenceVerifierInterface::class);
    /*
    * Interface PresenceVerifierInterface does not have method setConnection,
    * but validator call that method somewhere, so we need to mock that method also.
    *
    * It's a hack, not good
    * https://github.com/laravel/framework/issues/12250
    */
    $presenceVerifier->shouldReceive('setConnection');
    $validator->setPresenceVerifier($presenceVerifier);

    return $presenceVerifier;
    }

    /**
    * @param array $data Request data
    *
    * @dataProvider provideDataValidateEmailSuccess
    */
    public function testValidateEmailSuccess($data)
    {
    $request = new RegisterRequest;
    $rules = array_only($request->rules(), 'email');

    $validator = Validator::make($data, $rules);
    $presenceVerifier = $this->fakeDatabaseRuleVerifier($validator);
    $presenceVerifier->shouldReceive('getCount')->andReturn(0);

    $passed = $validator->passes();

    $this->assertTrue($passed);
    }

    public function provideDataValidateEmailSuccess()
    {
    return [
    [['email' => '[email protected]']],
    ];
    }

    /**
    * @param array $data Request data
    *
    * @dataProvider provideDataValidateEmailFailedWhenEmailInvalid
    */
    public function testValidateEmailFailedWhenEmailInvalid($data)
    {
    $request = new RegisterRequest;
    $rules = array_only($request->rules(), 'email');

    $validator = Validator::make($data, $rules);
    $presenceVerifier = $this->fakeDatabaseRuleVerifier($validator);
    // We are testing email format
    // so we make getCount return 0, meaning email had not existed in db
    $presenceVerifier->shouldReceive('getCount')->andReturn(0);

    $passed = $validator->passes();

    $this->assertFalse($passed);
    }

    public function provideDataValidateEmailFailedWhenEmailInvalid()
    {
    return [
    [[]],
    [['email' => '']],
    [['email' => ' ']],
    [['email' => 'missingdomain']],
    [['email' => '@missinguser.com']],
    [['email' => 'invalidchar &*@example.com']],
    [['email' => 'exceedlength' . str_repeat('a', RegisterRequest::EMAIL_MAX_LENGTH + 1) . '@example.com']],
    ];
    }

    public function testValidateEmailFailedWhenEmailExisted()
    {
    $request = new RegisterRequest;
    $rules = array_only($request->rules(), 'email');

    $validator = Validator::make([
    'email' => '[email protected]',
    ], $rules);
    $presenceVerifier = $this->fakeDatabaseRuleVerifier($validator);
    $presenceVerifier->shouldReceive('getCount')->andReturn(1);

    $passed = $validator->passes();

    $this->assertFalse($passed);
    }

    /**
    * @param array $data Request data
    *
    * @dataProvider provideDataValidatePasswordFailedWhenInputInvalid
    */
    public function testValidatePasswordFailedWhenInputInvalid($data)
    {
    $request = new RegisterRequest;
    $rules = array_only($request->rules(), 'password');

    $validator = Validator::make($data, $rules);

    $passed = $validator->passes();

    $this->assertFalse($passed);
    }

    public function provideDataValidatePasswordFailedWhenInputInvalid()
    {
    return [
    [[]],
    [['password' => '']],
    [['password' => ' ']],
    [['password' => str_repeat('a', RegisterRequest::PASSWORD_MIN_LENGTH - 1)]],
    ];
    }

    /**
    * @param array $data Request data
    *
    * @dataProvider provideDataValidatePasswordSuccess
    */
    public function testValidatePasswordSuccess($data)
    {
    $request = new RegisterRequest;
    $rules = array_only($request->rules(), 'password');

    $validator = Validator::make($data, $rules);

    $passed = $validator->passes();

    $this->assertTrue($passed);
    }

    public function provideDataValidatePasswordSuccess()
    {
    return [
    [['password' => ' 12345678 ', 'password_confirmation' => ' 12345678 ']],
    [
    [
    'password' => str_repeat('a', RegisterRequest::PASSWORD_MIN_LENGTH),
    'password_confirmation' => str_repeat('a', RegisterRequest::PASSWORD_MIN_LENGTH),
    ],
    ],
    [
    [
    'password' => str_repeat('a', RegisterRequest::PASSWORD_MIN_LENGTH + 1),
    'password_confirmation' => str_repeat('a', RegisterRequest::PASSWORD_MIN_LENGTH + 1),
    ],
    ],
    ];
    }
    }