59 lines
1.9 KiB
PHP
59 lines
1.9 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\User;
|
|
use App\Models\WebauthnCredential;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class UserFactorSemanticsTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
private function totpUser(): User
|
|
{
|
|
return User::factory()->create(['two_factor_secret' => 'S', 'two_factor_confirmed_at' => now()]);
|
|
}
|
|
|
|
private function keyUser(): 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_has_totp_only_reflects_totp(): void
|
|
{
|
|
$this->assertTrue($this->totpUser()->hasTotp());
|
|
$this->assertFalse($this->keyUser()->hasTotp());
|
|
}
|
|
|
|
public function test_has_two_factor_enabled_is_either_factor(): void
|
|
{
|
|
$this->assertTrue($this->totpUser()->hasTwoFactorEnabled());
|
|
$this->assertTrue($this->keyUser()->hasTwoFactorEnabled());
|
|
$this->assertFalse(User::factory()->create()->hasTwoFactorEnabled());
|
|
}
|
|
|
|
public function test_security_onboarded_is_password_rotation_only(): void
|
|
{
|
|
$this->assertTrue(User::factory()->create(['must_change_password' => false])->securityOnboarded());
|
|
$this->assertFalse(User::factory()->create(['must_change_password' => true])->securityOnboarded());
|
|
}
|
|
|
|
public function test_reset_if_no_factor_clears_codes_only_when_no_factor_remains(): void
|
|
{
|
|
$totp = $this->totpUser();
|
|
$totp->replaceRecoveryCodes();
|
|
$totp->resetIfNoFactor();
|
|
$this->assertTrue($totp->fresh()->hasRecoveryCodes(), 'codes kept while a factor remains');
|
|
|
|
$none = User::factory()->create();
|
|
$none->replaceRecoveryCodes();
|
|
$none->resetIfNoFactor();
|
|
$this->assertFalse($none->fresh()->hasRecoveryCodes(), 'codes cleared when no factor remains');
|
|
}
|
|
}
|