clusev/tests/Feature/ChallengeFactorAdaptTest.php

87 lines
3.6 KiB
PHP

<?php
namespace Tests\Feature;
use App\Livewire\Auth\TwoFactorChallenge;
use App\Models\User;
use App\Models\WebauthnCredential;
use App\Services\WebauthnService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Tests\TestCase;
class ChallengeFactorAdaptTest extends TestCase
{
use RefreshDatabase;
private function keyOnlyUser(): User
{
$u = User::factory()->create();
WebauthnCredential::create(['user_id' => $u->id, 'name' => 'k', 'credential_id' => 'cid', 'public_key' => '{}', 'sign_count' => 0]);
return $u->fresh();
}
public function test_totp_user_sees_the_field(): void
{
$user = User::factory()->create(['two_factor_secret' => 'S', 'two_factor_confirmed_at' => now()]);
session(['2fa.user' => $user->id, '2fa.remember' => false]);
Livewire::test(TwoFactorChallenge::class)->assertSet('pendingHasTotp', true);
}
public function test_totp_user_sees_the_backup_link_but_not_the_backup_field(): void
{
$user = User::factory()->create(['two_factor_secret' => 'S', 'two_factor_confirmed_at' => now()]);
session(['2fa.user' => $user->id, '2fa.remember' => false]);
Livewire::test(TwoFactorChallenge::class)
->assertSee('000000') // TOTP field present
->assertSee(__('auth.challenge_use_backup')) // backup link present
->assertDontSee(__('auth.challenge_backup_placeholder')); // no backup field here
}
public function test_key_only_user_without_secure_context_is_redirected_to_the_backup_view(): void
{
// No domain configured → webauthnAvailable() false, pendingHasTotp false: the backup code
// is the only usable path, so mount() sends the user straight to the dedicated view.
$user = $this->keyOnlyUser();
session(['2fa.user' => $user->id, '2fa.remember' => false]);
Livewire::test(TwoFactorChallenge::class)
->assertRedirect(route('two-factor.challenge.backup'));
}
public function test_key_only_user_with_secure_context_stays_and_shows_key_plus_backup(): void
{
$svc = $this->mock(WebauthnService::class);
$svc->shouldReceive('available')->andReturn(true);
$user = $this->keyOnlyUser();
session(['2fa.user' => $user->id, '2fa.remember' => false]);
Livewire::test(TwoFactorChallenge::class)
->assertNoRedirect()
->assertSee(__('auth.webauthn_login')) // security-key button
->assertSee(__('auth.challenge_use_backup')) // backup link
->assertDontSee('000000') // no TOTP field
->assertDontSee(__('auth.challenge_backup_placeholder')); // no inline backup field
}
public function test_totp_and_key_user_with_secure_context_sees_field_key_alt_and_backup(): void
{
$svc = $this->mock(WebauthnService::class);
$svc->shouldReceive('available')->andReturn(true);
$user = User::factory()->create(['two_factor_secret' => 'S', 'two_factor_confirmed_at' => now()]);
WebauthnCredential::create(['user_id' => $user->id, 'name' => 'k', 'credential_id' => 'cid', 'public_key' => '{}', 'sign_count' => 0]);
session(['2fa.user' => $user->id, '2fa.remember' => false]);
Livewire::test(TwoFactorChallenge::class)
->assertNoRedirect()
->assertSee('000000') // TOTP field
->assertSee(__('auth.webauthn_login')) // secondary security-key button (nested branch)
->assertSee(__('auth.challenge_use_backup')); // backup link
}
}