vendredi 27 mars 2020

Laravel: Assert Email verification is sent with mail:fake() in a test

I'm making an SPA and using Laravel for the API. This requires making my own authentication structure. I've borrowed from Laravel's auth and I'm making it work for my REST API.

I have a registration test and I've added assertions to test if the email verification email gets sent to the user that just registered.

The docs explain you can fake email sends and assert that specific ones get sent: https://laravel.com/docs/6.x/mocking#mail-fake

I'm having trouble finding how I can assert that the email verification specifically was sent.

    /**
     * @test
     */
    public function a_user_can_register_and_receives_verification_email()
    {


        Mail::fake();

        $response = $this->json( 'POST', '/api/register', [
            'first_name' => 'User',
            'last_name' => 'Example',
            'email' => 'user@example.com',
            'password' => 'password'
        ])->assertStatus(201);

        $user = $response->getData();

        $this->assertDatabaseHas('users', [
            'email' => $user->email
        ]);

        // Assert a message was sent to the given users...
        Mail::assertSent(MailMessage::class, function ($mail) use ($user) {
            return $mail->hasTo($user->email);
        });


    }

I was trying to hunt down what sendEmailVerificationNotification() does, and it let me to Illuminate\Auth\Notifications\Verify

It is a little confusing to me, but seems to be sending a MailMessage, which is what I'm asserting. However, my test fails: The expected [Illuminate\Notifications\Messages\MailMessage] mailable was not sent

This is my register method on my controller:

    public function register(Request $request) {

        $request->validate([
            'first_name' => ['required', 'string', 'max:255'],
            'last_name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8'],
        ]);

        $user = User::create([
            'first_name' => $request->first_name,
            'last_name' => $request->last_name,
            'email' => $request->email,
            'password' => Hash::make($request->password)
        ]);

        event(new Registered($user));

        return $user;

    }

api routes

Route::post('register', 'Auth\RegisterController@register');
Route::get('email/resend', 'Auth\VerificationController@resend')
    ->name('verification.resend');

Route::get('email/verify/{id}/{hash}', 'Auth\VerificationController@verify')
    ->name('verification.verify');

If I hit my register route via Postman, the email does get sent with the appropriate link. I just cant pass the test to verify.

Aucun commentaire:

Enregistrer un commentaire