clusev/tests/Feature/ForgotPasswordSmtpAwareTest...

156 lines
5.8 KiB
PHP

<?php
namespace Tests\Feature;
use App\Livewire\Auth\ForgotPassword;
use App\Livewire\Settings\Security;
use App\Models\User;
use App\Notifications\QueuedResetPassword as ResetPasswordNotification;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Notification;
use Livewire\Livewire;
use PragmaRX\Google2FAQRCode\Google2FA;
use Tests\TestCase;
/**
* The forgot-password screen is mail-aware: with SMTP configured the e-mail reset link
* is the default path (with a secondary 2FA-fallback toggle); without SMTP only the
* inline 2FA-proof reset is shown. The public screen never advertises clusev:reset-admin
* — that last-resort recovery note lives in Settings → Security.
*/
class ForgotPasswordSmtpAwareTest extends TestCase
{
use RefreshDatabase;
// ── Token expiry ─────────────────────────────────────────────────────
public function test_reset_token_expires_in_15_minutes(): void
{
$this->assertSame(15, config('auth.passwords.users.expire'));
}
// ── SMTP configured: e-mail link is the default ──────────────────────
public function test_smtp_on_shows_send_link_button_and_hides_code_form_by_default(): void
{
config(['mail.default' => 'smtp']);
Livewire::test(ForgotPassword::class)
->assertSee(__('auth.forgot_send_email'))
->assertSee(__('auth.forgot_use_code_toggle'))
// the inline 2FA-proof form (new-password field) is hidden by default
->assertDontSee(__('auth.new_password'));
}
public function test_smtp_on_subtitle_advertises_the_email_link(): void
{
config(['mail.default' => 'smtp']);
Livewire::test(ForgotPassword::class)
->assertSee(__('auth.forgot_subtitle_mail'));
}
public function test_smtp_on_send_link_dispatches_reset_notification(): void
{
config(['mail.default' => 'smtp']);
Notification::fake();
$user = User::factory()->create(['email' => 'admin@clusev.local']);
Livewire::test(ForgotPassword::class)
->set('email', 'admin@clusev.local')
->call('sendResetLink')
->assertHasNoErrors();
Notification::assertSentTo($user, ResetPasswordNotification::class);
}
public function test_toggle_reveals_the_2fa_code_form(): void
{
config(['mail.default' => 'smtp']);
Livewire::test(ForgotPassword::class)
->assertDontSee(__('auth.new_password'))
->set('showCodeReset', true)
->assertSee(__('auth.new_password'))
->assertSee(__('auth.forgot_code'));
}
public function test_2fa_reset_still_works_with_smtp_on_via_toggle(): void
{
config(['mail.default' => 'smtp']);
$user = User::factory()->create([
'email' => 'admin@clusev.local',
'two_factor_secret' => (new Google2FA)->generateSecretKey(),
'two_factor_confirmed_at' => now(),
]);
$otp = (new Google2FA)->getCurrentOtp($user->two_factor_secret);
Livewire::test(ForgotPassword::class)
->set('showCodeReset', true)
->set('email', $user->email)->set('code', $otp)
->set('password', 'NewPassw0rd123')->set('password_confirmation', 'NewPassw0rd123')
->call('resetPassword')->assertHasNoErrors();
$this->assertTrue(Hash::check('NewPassw0rd123', $user->fresh()->password));
}
// ── No SMTP: inline 2FA-proof reset only ─────────────────────────────
public function test_smtp_off_shows_inline_2fa_form_and_no_send_link(): void
{
config(['mail.default' => 'log']);
Livewire::test(ForgotPassword::class)
->assertSee(__('auth.new_password'))
->assertSee(__('auth.forgot_code'))
->assertDontSee(__('auth.forgot_send_email'));
}
public function test_smtp_off_subtitle_keeps_the_2fa_copy(): void
{
config(['mail.default' => 'log']);
Livewire::test(ForgotPassword::class)
->assertSee(__('auth.forgot_subtitle'));
}
public function test_smtp_off_resets_with_a_valid_totp(): void
{
config(['mail.default' => 'log']);
$user = User::factory()->create([
'email' => 'admin@clusev.local',
'two_factor_secret' => (new Google2FA)->generateSecretKey(),
'two_factor_confirmed_at' => now(),
]);
$otp = (new Google2FA)->getCurrentOtp($user->two_factor_secret);
Livewire::test(ForgotPassword::class)
->set('email', $user->email)->set('code', $otp)
->set('password', 'NewPassw0rd123')->set('password_confirmation', 'NewPassw0rd123')
->call('resetPassword')->assertHasNoErrors();
$this->assertTrue(Hash::check('NewPassw0rd123', $user->fresh()->password));
}
// ── clusev:reset-admin recovery note placement ───────────────────────
public function test_public_forgot_view_does_not_advertise_reset_admin_command(): void
{
config(['mail.default' => 'log']);
Livewire::test(ForgotPassword::class)
->assertDontSee('clusev:reset-admin');
config(['mail.default' => 'smtp']);
Livewire::test(ForgotPassword::class)
->assertDontSee('clusev:reset-admin');
}
public function test_settings_security_shows_the_recovery_note_with_the_command(): void
{
$user = User::factory()->create();
Livewire::actingAs($user)->test(Security::class)
->assertSee(__('settings.recovery_note'))
->assertSee('clusev:reset-admin');
}
}