142 lines
4.6 KiB
PHP
142 lines
4.6 KiB
PHP
<?php
|
|
|
|
use App\Mail\ResetPassword;
|
|
use App\Models\User;
|
|
use Illuminate\Auth\Events\PasswordReset;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Event;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use Illuminate\Support\Facades\Password;
|
|
use Inertia\Testing\AssertableInertia as Assert;
|
|
use Tests\UpdatesSettings;
|
|
|
|
uses(RefreshDatabase::class);
|
|
uses(UpdatesSettings::class);
|
|
|
|
beforeEach(function () {
|
|
$this->setSettings(['forgot_password' => true]);
|
|
});
|
|
|
|
test('password request form is displayed', function () {
|
|
$this->get('password/reset')
|
|
->assertOk()
|
|
->assertInertia(fn (Assert $page) => $page->component('auth/ForgotPassword'));
|
|
});
|
|
|
|
test('reset link is sent for existing email', function () {
|
|
Mail::fake();
|
|
|
|
$user = User::factory()->create(['email' => 'foo@bar.com']);
|
|
|
|
$this->from('password/reset')
|
|
->post('password/email', ['email' => $user->email])
|
|
->assertRedirect('password/reset');
|
|
|
|
Mail::assertQueued(ResetPassword::class, fn ($mail) => $mail->hasTo($user->email));
|
|
});
|
|
|
|
test('reset link request with unknown email does not leak existence', function () {
|
|
Mail::fake();
|
|
|
|
$this->from('password/reset')
|
|
->post('password/email', ['email' => 'nobody@example.com'])
|
|
->assertRedirect('password/reset')
|
|
->assertSessionHasNoErrors()
|
|
->assertSessionHas('success', trans('passwords.sent'));
|
|
|
|
Mail::assertNothingQueued();
|
|
});
|
|
|
|
test('unknown email flashes a string the toast can render', function () {
|
|
Mail::fake();
|
|
|
|
$this->from('password/reset')
|
|
->post('password/email', ['email' => 'nobody@example.com'])
|
|
->assertSessionHas('success', fn ($success) => is_string($success));
|
|
|
|
$this->get('password/reset')
|
|
->assertInertia(fn (Assert $page) => $page->where('flash.success', trans('passwords.sent')));
|
|
});
|
|
|
|
test('a throttled reset link request reports the failure against the email field', function () {
|
|
Mail::fake();
|
|
|
|
$user = User::factory()->create(['email' => 'foo@bar.com']);
|
|
|
|
$this->post('password/email', ['email' => $user->email]);
|
|
|
|
$this->from('password/reset')
|
|
->post('password/email', ['email' => $user->email])
|
|
->assertRedirect('password/reset')
|
|
->assertSessionHasErrors(['email' => trans('passwords.throttled')]);
|
|
});
|
|
|
|
test('reset form is displayed with token', function () {
|
|
$this->get('password/reset/sometoken?email=foo@bar.com')
|
|
->assertOk()
|
|
->assertInertia(fn (Assert $page) => $page
|
|
->component('auth/ResetPassword')
|
|
->where('token', 'sometoken')
|
|
->where('email', 'foo@bar.com')
|
|
);
|
|
});
|
|
|
|
test('password can be reset with valid token', function () {
|
|
Event::fake([PasswordReset::class]);
|
|
|
|
$user = User::factory()->create(['email' => 'foo@bar.com']);
|
|
$token = Password::broker()->createToken($user);
|
|
|
|
$this->post('password/reset', [
|
|
'email' => $user->email,
|
|
'token' => $token,
|
|
'password' => 'new-password',
|
|
'password_confirmation' => 'new-password',
|
|
])->assertRedirect('/');
|
|
|
|
$this->assertTrue(Hash::check('new-password', $user->fresh()->password));
|
|
$this->assertTrue(auth()->check());
|
|
$this->assertTrue($user->is(auth()->user()));
|
|
|
|
Event::assertDispatched(PasswordReset::class);
|
|
});
|
|
|
|
test('password cannot be reset with invalid token', function () {
|
|
$user = User::factory()->create(['email' => 'foo@bar.com']);
|
|
$originalHash = $user->password;
|
|
|
|
$this->from('password/reset/invalid-token')
|
|
->post('password/reset', [
|
|
'email' => $user->email,
|
|
'token' => 'invalid-token',
|
|
'password' => 'new-password',
|
|
'password_confirmation' => 'new-password',
|
|
])
|
|
->assertRedirect('password/reset/invalid-token');
|
|
|
|
$this->assertSame($originalHash, $user->fresh()->password);
|
|
$this->assertFalse(auth()->check());
|
|
});
|
|
|
|
test('password reset requires password confirmation', function () {
|
|
$user = User::factory()->create();
|
|
$token = Password::broker()->createToken($user);
|
|
|
|
$this->from('password/reset/'.$token)
|
|
->post('password/reset', [
|
|
'email' => $user->email,
|
|
'token' => $token,
|
|
'password' => 'new-password',
|
|
'password_confirmation' => 'different',
|
|
])
|
|
->assertSessionHasErrors('password');
|
|
});
|
|
|
|
test('password reset routes unavailable when disabled', function () {
|
|
$this->setSettings(['forgot_password' => false]);
|
|
|
|
$this->get('password/reset')->assertStatus(404);
|
|
$this->post('password/email', ['email' => 'foo@bar.com'])->assertStatus(404);
|
|
});
|