dingo_d's avatar

Test for user creation fails on validation

I have created a user creation screen and in my UserController I have a store method

    /**
     * Store a newly created users in a database.
     *
     * @param Request $request Incoming request
     *
     * @throws ValidationException
     *
     * @return mixed
     */
    public function store(Request $request)
    {
        $this->validate($request, [
            'name' => 'required',
            'email' => 'required|email|unique:users,email',
            'password' => ['required', 'same:confirm-password', $this->strongPassword],
            'roles' => 'required'
        ]);
            
        $input = $request->all();
        $input['password'] = Hash::make($input['password']);

        $user = User::create($input);
        $user->assignRole($request->input('roles'));

        return redirect()->route('users.index')
            ->with('success', 'User created successfully');
    }

The strong password validation is used from this package.

I've created the view for this and it works when I manually test it, but I want to create an automated test for this it failed for the wrong reasons.

I created

   public function testUserIsApprovedWhenCreated()
    {
        
        $name = $this->faker->name;
        $email = $this->faker->safeEmail;
        $password = $this->faker->password(13);
        
        $attributes = [
            'name' => $name,
            'email' => $email,
            'password' => $password,
            'password_confirmation' => $password,
            'roles' => ['support'],
        ];

        $response = $this->actingAs($this->adminUser)
            ->post('/users', $attributes);
            
        $this->assertDatabaseHas('users', [
            'name' => $name,
        ]);
    }

my test class extends a special abstract class (because I'm using laravel-permissions package from spatie)

<?php

namespace Tests;

use Spatie\Permission\Models\Role;
use Spatie\Permission\PermissionRegistrar;
use Spatie\Permission\Models\Permission;

abstract class UsersTestCase extends TestCase
{
    public function setUp(): void
    {
        // Include all the normal setUp operations.
        parent::setUp();

        // Re-register all the roles and permissions
        $this->app->make(PermissionRegistrar::class)->registerPermissions();

        // Create permissions.
        Permission::create(['name' => 'list users']);
        Permission::create(['name' => 'create users']);
        Permission::create(['name' => 'edit users']);
        Permission::create(['name' => 'delete users']);
        Permission::create(['name' => 'list roles']);
        Permission::create(['name' => 'create roles']);
        Permission::create(['name' => 'edit roles']);
        Permission::create(['name' => 'delete roles']);
        Permission::create(['name' => 'view dashboard']);

        // Create roles.
        Role::create(['name' => 'admin']);
        Role::create(['name' => 'management']);
        Role::create(['name' => 'staff']);
        Role::create(['name' => 'support']);
        Role::create(['name' => 'guest']);
    }
}

When I run this test, I can see that the validation fails because the test fails and I've error logged the request before and after validation, and it only shows before validation. If I remove the password validation (not only the strong PW, but all of it), then the request and test pass.

The passwords are there and same, and they are strong passwords (letters, numbers, symbols etc.)

The name of the test is such because I want to test that user is activated on creation which currently it's not (I'm doing TDD - write failing test, make it pass and then refactor).

0 likes
6 replies
tykus's avatar

Which validation rule is failing?

dingo_d's avatar

It looks like the password same:confirm-password fails, but I'm using the same password from faker.

tykus's avatar

Wait... is see it now; is the form input name confirm-password (validation rule) or password_confirmation (test form attributes)

dingo_d's avatar

The form input name is confirm-password (for password confirmation).

tykus's avatar
tykus
Best Answer
Level 104

Ok, so your test is sending the wrong key.

   public function testUserIsApprovedWhenCreated()
    {
        
        $name = $this->faker->name;
        $email = $this->faker->safeEmail;
        $password = $this->faker->password(13);
        
        $attributes = [
            'name' => $name,
            'email' => $email,
            'password' => $password,
            'confirm-password' => $password,
            'roles' => ['support'],
        ];

        $response = $this->actingAs($this->adminUser)
            ->post('/users', $attributes);
            
        $this->assertDatabaseHas('users', [
            'name' => $name,
        ]);
    }

This should fix the failing same validation

dingo_d's avatar

Oh I see! The attribute was wrong in my test 🤦🏼‍♂️

Thanks!

Please or to participate in this conversation.