papa's avatar
Level 3

Test Validation Email Unique fails always

The Request

public function rules()
    {
        $id = (isset($this->id) ? $this->id : null) . ',id';

        return [
            'firstName' => ['required'],
            'lastName' => ['required'],
            'email' => ['required', 'email', 'unique:User,email,' . $id],
            'password' => ['required', 'min:6', 'confirmed'],
            'password_confirmation' => ['min:6'],
            'address' => ['required'],
            'zipcode' => ['required'],
            'city' => ['required'],
            'phone' => ['required'],
            'language' => ['required']
        ];
    }

The test Function

public function testUser()
{

$users = [
            [
                'firstName' => 'Name',
                'lastName' => 'Surname',
                'password' => 123456,
                'password_confirmation' => 123456,
                'address' => 'My address',
                'zipcode' => '84763',
                'city' => 'New York',
                'email' => '[email protected]',
                'phone' => '017654875674',
                'mobile' => '763636',
                'language' => 1
            ],
        ];


 foreach ($users as $user) {
            $response = $this->post(route('doRegister'), $user);

            $validator = Validator::make($user, $validation->rules());
            $this->assertEquals(false, $validator->fails());

            $this->assertDatabaseHas('User', ['email' => $user['email']]);
            $this->assertDatabaseHas('Member', [
                'firstName' => $user['firstName'],
                'lastName' => $user['lastName'],
                'address' => $user['address'],
                'zipcode' => $user['zipcode'],
                'city' => $user['city'],
                'phone' => $user['phone'],
                'mobile' => $user['mobile'],
                'langId' => 1
            ]);

            $response->assertRedirect(route('index', 200));
        }
}

The $validator gives me always error on Email Unique Rule and the test does not pass. Have someone an idea why that happens?

0 likes
8 replies
tykus's avatar

Is the database table really called User?

papa's avatar
Level 3

@TYKUS - Yes all my tables starts with capital letter

papa's avatar
Level 3

What I get in log file local.INFO: {"email":["validation.unique"]}

tykus's avatar

Your $id variable is this...

$id = (isset($this->id) ? $this->id : null) . ',id';

...how does that result reconcile with the identity column on your User table? What does $this->id evaluate to; if you are using Route-Model binding, then I suspect null?

You don't need to explicitly include the id column since it is the default. Consider using the Rule class to construct the validation rule, it can be clearer than that string construction

public function rules()
{
    return [
        'firstName' => ['required'],
        'lastName' => ['required'],
        'email' => ['required', 'email', Rule::unique('User')->ignore($this-id)],
        'password' => ['required', 'min:6', 'confirmed'],
        'password_confirmation' => ['min:6'],
        'address' => ['required'],
        'zipcode' => ['required'],
        'city' => ['required'],
        'phone' => ['required'],
        'language' => ['required']
    ];
}

EDIT, I have just re-read you test; what is going on there with the Validator? A feature test should be testing your application code, not the framework. In addition, there probably is no $this->id because there is not id segment in the URI usually for a store request.

papa's avatar
Level 3

@tykus Firstly: of course the $this->id is not set and is null and the rules() are

return [
            'firstName' => ['required'],
            'lastName' => ['required'],
            'email' => ['required', 'email', 'unique:User,email,null,id'],
            'password' => ['required', 'min:6', 'confirmed'],
            'password_confirmation' => ['min:6'],
            'address' => ['required'],
            'zipcode' => ['required'],
            'city' => ['required'],
            'phone' => ['required'],
            'language' => ['required']
        ];

Secondly: this Rule::unique('User')->ignore($this-id) is the same with this 'unique:User,email,null,id'. I have both tested.

Third: A feature test should be testing your application code, not the framework. Where I test the framework??

tykus's avatar

@papa you are not testing application code here:

$validator = Validator::make($user, $validation->rules());
$this->assertEquals(false, $validator->fails());

Beyond that I'm not helping someone with that attitude, so on your own...

munazzil's avatar

Simply use as like below and pass the $user->id

    'email' => ['sometimes', 'email', 'unique:user,email,' .$user->id],

else use only sometimes

'email' => ['sometimes', 'email', 'unique:user,email,' . $id],
papa's avatar
Level 3

@tykus found it

should change the sequence between the validation and the registration

foreach ($users as $user) {
            $validator = Validator::make($user, (new UserRequest())->rules();
            $this->assertEquals(false, $validator->fails()); // $this->assertTrue($validator->passes());

            $response = $this->post(route('doRegister'), $user);

I apologize if you have found my comment offensive, it was not like that. Thanks for your support.

Please or to participate in this conversation.