'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)); } }