143 lines
4.1 KiB
PHP
143 lines
4.1 KiB
PHP
<?php
|
|
|
|
/**
|
|
* 文件功能:前台邮箱找回密码控制器功能测试
|
|
*
|
|
* 覆盖发送重置邮件、重复邮箱兜底、重置密码成功与无效令牌失败等关键场景。
|
|
*/
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Sysparam;
|
|
use App\Models\User;
|
|
use App\Notifications\ResetUserPasswordNotification;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Notification;
|
|
use Illuminate\Support\Facades\Password;
|
|
use Tests\TestCase;
|
|
|
|
/**
|
|
* 类功能:验证首页邮箱找回密码链路的核心行为。
|
|
*/
|
|
class PasswordResetControllerTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
/**
|
|
* 初始化系统参数,开启邮箱发信能力。
|
|
*/
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
Sysparam::updateOrCreate(
|
|
['alias' => 'smtp_enabled'],
|
|
['body' => '1']
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 验证独立找回密码页可以正常访问。
|
|
*/
|
|
public function test_can_view_password_recovery_page(): void
|
|
{
|
|
$this->get(route('password.request'))
|
|
->assertOk()
|
|
->assertSee('邮箱找回密码');
|
|
}
|
|
|
|
/**
|
|
* 验证唯一邮箱账号可以收到重置密码通知。
|
|
*/
|
|
public function test_can_send_password_reset_link_by_email(): void
|
|
{
|
|
Notification::fake();
|
|
|
|
$user = User::factory()->create([
|
|
'email' => 'recover@example.com',
|
|
]);
|
|
|
|
$this->postJson(route('password.email'), [
|
|
'email' => 'recover@example.com',
|
|
])->assertOk()
|
|
->assertJsonPath('status', 'success');
|
|
|
|
Notification::assertSentTo($user, ResetUserPasswordNotification::class);
|
|
$this->assertDatabaseHas('password_reset_tokens', [
|
|
'email' => 'recover@example.com',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 验证同一个邮箱绑定多个账号时会拒绝自助找回。
|
|
*/
|
|
public function test_cannot_send_reset_link_when_email_is_bound_to_multiple_users(): void
|
|
{
|
|
User::factory()->create([
|
|
'username' => 'recover-a',
|
|
'email' => 'shared@example.com',
|
|
]);
|
|
|
|
User::factory()->create([
|
|
'username' => 'recover-b',
|
|
'email' => 'shared@example.com',
|
|
]);
|
|
|
|
$this->postJson(route('password.email'), [
|
|
'email' => 'shared@example.com',
|
|
])->assertStatus(422)
|
|
->assertJsonPath('status', 'error');
|
|
}
|
|
|
|
/**
|
|
* 验证用户可以使用有效令牌成功重置密码。
|
|
*/
|
|
public function test_can_reset_password_with_valid_token(): void
|
|
{
|
|
$user = User::factory()->create([
|
|
'email' => 'reset@example.com',
|
|
'password' => Hash::make('old-password'),
|
|
]);
|
|
|
|
$token = Password::broker()->createToken($user);
|
|
|
|
$this->post(route('password.update'), [
|
|
'token' => $token,
|
|
'email' => 'reset@example.com',
|
|
'password' => 'new-password',
|
|
'password_confirmation' => 'new-password',
|
|
])->assertRedirect(route('home'));
|
|
|
|
$user->refresh();
|
|
|
|
$this->assertTrue(Hash::check('new-password', $user->password));
|
|
}
|
|
|
|
/**
|
|
* 验证无效令牌不会修改用户密码。
|
|
*/
|
|
public function test_cannot_reset_password_with_invalid_token(): void
|
|
{
|
|
$user = User::factory()->create([
|
|
'email' => 'broken@example.com',
|
|
'password' => Hash::make('old-password'),
|
|
]);
|
|
|
|
$response = $this->from(route('password.reset', ['token' => 'bad-token', 'email' => 'broken@example.com']))
|
|
->post(route('password.update'), [
|
|
'token' => 'bad-token',
|
|
'email' => 'broken@example.com',
|
|
'password' => 'new-password',
|
|
'password_confirmation' => 'new-password',
|
|
]);
|
|
|
|
$response->assertRedirect(route('password.reset', ['token' => 'bad-token', 'email' => 'broken@example.com']));
|
|
$response->assertSessionHasErrors('email');
|
|
|
|
$user->refresh();
|
|
|
|
$this->assertTrue(Hash::check('old-password', $user->password));
|
|
}
|
|
}
|