feat(api): registration auth, account creation, check-email & email notifications
- Add POST /public/check-email endpoint with rate limiting (10/min)
- Create user accounts during volunteer registration (new or returning)
- Returning volunteers authenticate with existing password
- Add password validation to VolunteerRegistrationRequest
- Normalize emails to lowercase throughout registration flow
- Handle race condition on duplicate accounts gracefully
- Create RegistrationConfirmationMail, RegistrationApprovedMail, RegistrationRejectedMail
- Wire approval/rejection emails into PersonController
- Add POST persons/{person}/reject endpoint
- Trigger TagSyncService on registration and approval
- Add CheckEmailTest, PersonApprovalEmailTest, extend VolunteerRegistrationTest
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
81
api/tests/Feature/Api/V1/CheckEmailTest.php
Normal file
81
api/tests/Feature/Api/V1/CheckEmailTest.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature\Api\V1;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class CheckEmailTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_existing_email_returns_exists_true(): void
|
||||
{
|
||||
User::factory()->create(['email' => 'lisa@test.nl']);
|
||||
|
||||
$response = $this->postJson('/api/v1/public/check-email', [
|
||||
'email' => 'lisa@test.nl',
|
||||
]);
|
||||
|
||||
$response->assertOk();
|
||||
$response->assertJson(['exists' => true]);
|
||||
}
|
||||
|
||||
public function test_unknown_email_returns_exists_false(): void
|
||||
{
|
||||
$response = $this->postJson('/api/v1/public/check-email', [
|
||||
'email' => 'nobody@test.nl',
|
||||
]);
|
||||
|
||||
$response->assertOk();
|
||||
$response->assertJson(['exists' => false]);
|
||||
}
|
||||
|
||||
public function test_email_check_is_case_insensitive(): void
|
||||
{
|
||||
User::factory()->create(['email' => 'lisa@test.nl']);
|
||||
|
||||
$response = $this->postJson('/api/v1/public/check-email', [
|
||||
'email' => 'LISA@TEST.NL',
|
||||
]);
|
||||
|
||||
$response->assertOk();
|
||||
$response->assertJson(['exists' => true]);
|
||||
}
|
||||
|
||||
public function test_rate_limiting_returns_429(): void
|
||||
{
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$this->postJson('/api/v1/public/check-email', [
|
||||
'email' => 'test@test.nl',
|
||||
])->assertOk();
|
||||
}
|
||||
|
||||
$response = $this->postJson('/api/v1/public/check-email', [
|
||||
'email' => 'test@test.nl',
|
||||
]);
|
||||
|
||||
$response->assertStatus(429);
|
||||
}
|
||||
|
||||
public function test_invalid_email_returns_422(): void
|
||||
{
|
||||
$response = $this->postJson('/api/v1/public/check-email', [
|
||||
'email' => 'not-an-email',
|
||||
]);
|
||||
|
||||
$response->assertStatus(422);
|
||||
$response->assertJsonValidationErrors('email');
|
||||
}
|
||||
|
||||
public function test_missing_email_returns_422(): void
|
||||
{
|
||||
$response = $this->postJson('/api/v1/public/check-email', []);
|
||||
|
||||
$response->assertStatus(422);
|
||||
$response->assertJsonValidationErrors('email');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user