113 lines
3.9 KiB
PHP
113 lines
3.9 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Auth;
|
|
|
|
use App\Domains\Auth\Models\ResetPasswordAttempt;
|
|
use App\Domains\Auth\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Tests\TestCase;
|
|
|
|
class ResetPasswordControllerTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_it_resets_the_password_consumes_the_attempt_and_revokes_tokens(): void
|
|
{
|
|
$user = User::factory()->create([
|
|
'email' => 'ada@example.com',
|
|
'password' => 'OldSecret!123',
|
|
]);
|
|
$user->forceFill([
|
|
'failed_login_attempts' => 5,
|
|
'last_failed_login_at' => now(),
|
|
'locked_until' => now()->addMinutes(15),
|
|
])->save();
|
|
$user->createToken('existing-session');
|
|
$attempt = $user->resetPasswordAttempts()->create([
|
|
'codigo' => '0123',
|
|
'status' => ResetPasswordAttempt::STATUS_VALIDATED,
|
|
]);
|
|
|
|
$this->postJson('/api/password/reset', [
|
|
'email' => ' ADA@EXAMPLE.COM ',
|
|
'codigo' => '0123',
|
|
'password' => 'NewSecret!456',
|
|
'password_confirmation' => 'NewSecret!456',
|
|
])->assertOk()
|
|
->assertJsonPath('status', ResetPasswordAttempt::STATUS_USED);
|
|
|
|
$user->refresh();
|
|
|
|
$this->assertTrue(Hash::check('NewSecret!456', $user->password));
|
|
$this->assertFalse(Hash::check('OldSecret!123', $user->password));
|
|
$this->assertSame(ResetPasswordAttempt::STATUS_USED, $attempt->fresh()->status);
|
|
$this->assertDatabaseCount('personal_access_tokens', 0);
|
|
$this->assertSame(0, $user->failed_login_attempts);
|
|
$this->assertNull($user->last_failed_login_at);
|
|
$this->assertNull($user->locked_until);
|
|
}
|
|
|
|
public function test_it_rejects_a_pending_expired_or_used_attempt(): void
|
|
{
|
|
$user = User::factory()->create([
|
|
'email' => 'ada@example.com',
|
|
'password' => 'OldSecret!123',
|
|
]);
|
|
|
|
foreach ([
|
|
ResetPasswordAttempt::STATUS_PENDING,
|
|
ResetPasswordAttempt::STATUS_EXPIRED,
|
|
ResetPasswordAttempt::STATUS_USED,
|
|
] as $status) {
|
|
$user->resetPasswordAttempts()->create([
|
|
'codigo' => '1234',
|
|
'status' => $status,
|
|
]);
|
|
}
|
|
|
|
$this->postJson('/api/password/reset', [
|
|
'email' => 'ada@example.com',
|
|
'codigo' => '1234',
|
|
'password' => 'NewSecret!456',
|
|
'password_confirmation' => 'NewSecret!456',
|
|
])->assertUnprocessable()
|
|
->assertJsonValidationErrors('codigo');
|
|
|
|
$this->assertTrue(Hash::check('OldSecret!123', $user->fresh()->password));
|
|
}
|
|
|
|
public function test_a_used_attempt_cannot_be_reused(): void
|
|
{
|
|
$user = User::factory()->create(['email' => 'ada@example.com']);
|
|
$attempt = $user->resetPasswordAttempts()->create([
|
|
'codigo' => '1234',
|
|
'status' => ResetPasswordAttempt::STATUS_VALIDATED,
|
|
]);
|
|
$payload = [
|
|
'email' => 'ada@example.com',
|
|
'codigo' => '1234',
|
|
'password' => 'NewSecret!456',
|
|
'password_confirmation' => 'NewSecret!456',
|
|
];
|
|
|
|
$this->postJson('/api/password/reset', $payload)->assertOk();
|
|
$this->postJson('/api/password/reset', $payload)
|
|
->assertUnprocessable()
|
|
->assertJsonValidationErrors('codigo');
|
|
|
|
$this->assertSame(ResetPasswordAttempt::STATUS_USED, $attempt->fresh()->status);
|
|
}
|
|
|
|
public function test_it_validates_password_confirmation_and_strength(): void
|
|
{
|
|
$this->postJson('/api/password/reset', [
|
|
'email' => 'ada@example.com',
|
|
'codigo' => '1234',
|
|
'password' => 'weak',
|
|
'password_confirmation' => 'different',
|
|
])->assertUnprocessable()
|
|
->assertJsonValidationErrors('password');
|
|
}
|
|
}
|