QuickQuiz/tests/Feature/AuthFlowTest.php

87 lines
2.6 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Feature;
use App\Models\InviteCode;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
use Tests\TestCase;
final class AuthFlowTest extends TestCase
{
use RefreshDatabase;
protected bool $seed = true;
public function test_invite_register_login_refresh_me_and_logout_flow(): void
{
$invite = InviteCode::create([
'code' => 'JOIN2026',
'role' => 'user',
'max_uses' => 1,
'used_count' => 0,
'is_active' => true,
]);
$register = $this->postJson('/api/auth/register', [
'name' => '学生甲',
'email' => 'student@example.com',
'password' => 'secret123',
'password_confirmation' => 'secret123',
'invite_code' => $invite->code,
])->assertOk()
->assertJsonPath('data.user.email', 'student@example.com')
->assertJsonPath('data.user.role', 'user');
$this->assertSame(1, $invite->fresh()->used_count);
$token = $register->json('data.token');
$this->withToken($token)
->getJson('/api/auth/me')
->assertOk()
->assertJsonPath('data.email', 'student@example.com');
$login = $this->postJson('/api/auth/login', [
'email' => 'student@example.com',
'password' => 'secret123',
])->assertOk()
->assertJsonPath('data.user.email', 'student@example.com');
$refreshed = $this->withToken($login->json('data.token'))
->postJson('/api/auth/refresh')
->assertOk()
->json('data.token');
$this->withToken($refreshed)
->postJson('/api/auth/logout')
->assertOk()
->assertJsonPath('message', '已退出');
}
public function test_login_failures_require_captcha_after_limit(): void
{
$user = User::factory()->create([
'email' => 'limited@example.com',
'password' => Hash::make('correct-password'),
]);
for ($i = 0; $i < 5; $i++) {
$this->postJson('/api/auth/login', [
'email' => $user->email,
'password' => 'wrong-password',
])->assertStatus(422);
}
$this->assertSame(5, $user->fresh()->failed_login_count);
$this->postJson('/api/auth/login', [
'email' => $user->email,
'password' => 'correct-password',
])->assertStatus(429)
->assertJsonPath('data.captcha_required', true);
}
}