seed([RoleSeeder::class, SamplePsgcSeeder::class]); $this->app->instance(SmsService::class, new FakeSmsService); } public function test_register_sends_verification_email(): void { Notification::fake(); $barangay = Barangay::firstOrFail(); $this->postJson('/api/v1/auth/register', [ 'first_name' => 'Em', 'last_name' => 'Ail', 'email' => 'verify@example.com', 'phone' => '+639170000200', 'password' => 'Password123', 'password_confirmation' => 'Password123', 'role' => User::ROLE_RESIDENT, 'address_line' => '123 Street', 'barangay_id' => $barangay->id, 'lat' => 14.5995, 'lng' => 120.9842, 'household_size' => 4, ])->assertCreated(); $user = User::where('email', 'verify@example.com')->firstOrFail(); Notification::assertSentTo($user, VerifyEmailNotification::class); } public function test_signed_link_marks_email_verified(): void { $user = User::factory()->create(['email' => 'pending@example.com', 'email_verified_at' => null]); $url = URL::temporarySignedRoute( 'api.v1.auth.verification.verify', now()->addMinutes(60), ['id' => $user->id, 'hash' => sha1($user->email)], ); // Strip the absolute URL prefix to get the path the test client expects. $path = parse_url($url, PHP_URL_PATH).'?'.parse_url($url, PHP_URL_QUERY); $this->getJson($path)->assertOk()->assertJsonPath('data.verified', true); $this->assertNotNull($user->fresh()->email_verified_at); } public function test_tampered_signature_rejected(): void { $user = User::factory()->create(['email_verified_at' => null]); $path = "/api/v1/auth/email/verify/{$user->id}/badhash?signature=tampered"; $this->getJson($path)->assertStatus(403); } public function test_authed_user_can_resend_email(): void { Notification::fake(); $user = User::factory()->create(['email_verified_at' => null]); Sanctum::actingAs($user); $this->postJson('/api/v1/auth/email/resend') ->assertOk() ->assertJsonPath('data.sent', true); Notification::assertSentTo($user, VerifyEmailNotification::class); } public function test_already_verified_user_resend_is_noop(): void { $user = User::factory()->create(['email_verified_at' => now()]); Sanctum::actingAs($user); $this->postJson('/api/v1/auth/email/resend') ->assertOk() ->assertJsonPath('data.already_verified', true); } }