1

In laravel 9, breeze 1.11 app I want to make feature test for forgot-password functionality and in routes I found :

  GET|HEAD      
In laravel 9, breeze 1.11 app I want to make feature test for forgot-password functionality and in routes I found :

  GET|HEAD        forgot-password ... password.request › Auth\PasswordResetLinkController@create

  POST            forgot-password ........ password.email › Auth\PasswordResetLinkController@store

So I make :

test to check opened form : public function testAdminForgetPasswordFormOpened() { $response = $this->get(route('password.request'));

    $response->assertStatus(200); 
    $response->assertViewIs('auth.forgot-password');     
    $response->assertSessionHasNoErrors();
}

and it works ok. But I failed to check how token is sent when user submit form with email entered. I do :

public function testAdminGotPasswordResetLinkEmail()
{
    Notification::fake();

    $loggedAdmin = User::factory()->make();

    $response = $this->post(route('password.email'), [
        'email' => $loggedAdmin->email,
    ]);

    $token = DB::table('password_resets')->first();

    Notification::assertSentTo(       
        $loggedAdmin,
        SubscriptionEmailingNotification::class,// that is my my Notification class
        function ($notification) use ($token) {   // https://laravel.com/docs/9.x/mocking#notification-fake
            \Log::info(varDump($notification, ' -1 $notification::')); / I DO NOT SEE THESE LOG MESSAGES
            \Log::info(varDump($token, ' -12 $token::'));
            return Hash::check($notification->token, $token->token) === true;
        }
    );
}

But I got error :

1) Tests\Feature\AuthTest::testAdminGotPasswordResetLinkEmail 
The expected [App\Notifications\SubscriptionEmailingNotification] notification was not sent. 
Failed asserting that false is true. 
 
/mnt/_work_sdb8/wwwroot/lar/MngProducts/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/NotificationFake.php:83 
/mnt/_work_sdb8/wwwroot/lar/MngProducts/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:338 
/mnt/_work_sdb8/wwwroot/lar/MngProducts/tests/Feature/AuthTest.php:226
 

Looking how it works in breeze I see method :

  $status = Password::sendResetLink(
        $request->only('email')
    );

I did not find how method above is implemented and which notification it uses ? I suppose that some notification is used here, but not sure...

I found declaration of assertSentTo method as :

public static function assertSentTo($notifiable, $notification, $callback = null)
{

How that tests must be done ?

Thanks!

mstdmstd
  • 2,195
  • 17
  • 63
  • 140

1 Answers1

1

You shouldn't check the token in the email if you continue to use the Password::sendResetLink(...) method. Breeze already has its own tests for this. Proving the Password::sendResetLink(...) method is successfully called will be enough to confirm faultless integration. You can verify it by checking the "ResetPassword" notification:

Notification::assertSentTo($user, ResetPassword::class);

However, if you still want to check the token, you can use the sample code below, which took from Breeze's tests


use App\Models\User;
use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Support\Facades\Notification;

// ...

public function test_password_can_be_reset_with_valid_token()
{
     Notification::fake();
     
     $user = User::factory()->create();
     
     $this->post('/forgot-password', ['email' => $user->email]);
     
     Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user) {
        $response = $this->post('/reset-password', [
        'token' => $notification->token,
        'email' => $user->email,
        'password' => 'password',
        'password_confirmation' => 'password',
     ]);
     
     $response->assertSessionHasNoErrors();
     
     return true;
     });
}

Source: https://github.com/laravel/breeze/blob/v1.11.0/stubs/default/tests/Feature/PasswordResetTest.php#L50

Onur Uslu
  • 1,044
  • 1
  • 7
  • 11