diff --git a/app/Models/User.php b/app/Models/User.php index 70519e4..c728b9b 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -2,8 +2,8 @@ namespace App\Models; -// use Illuminate\Contracts\Auth\MustVerifyEmail; use Database\Factories\UserFactory; +use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\SoftDeletes; @@ -14,7 +14,7 @@ use Laravel\Jetstream\HasTeams; use Laravel\Sanctum\HasApiTokens; -class User extends Authenticatable +class User extends Authenticatable implements MustVerifyEmail { use HasApiTokens; diff --git a/config/fortify.php b/config/fortify.php index 726d83b..0551d1d 100644 --- a/config/fortify.php +++ b/config/fortify.php @@ -146,7 +146,7 @@ 'features' => [ Features::registration(), Features::resetPasswords(), - // Features::emailVerification(), + Features::emailVerification(), Features::updateProfileInformation(), Features::updatePasswords(), Features::twoFactorAuthentication([ diff --git a/database/factories/EventFactory.php b/database/factories/EventFactory.php index a529d95..8d8db4d 100644 --- a/database/factories/EventFactory.php +++ b/database/factories/EventFactory.php @@ -4,6 +4,7 @@ use App\Models\Event; use Illuminate\Database\Eloquent\Factories\Factory; +use Illuminate\Support\Str; /** * @extends Factory @@ -54,7 +55,10 @@ public function definition(): array $event = $this->faker->randomElement($eventTypes); return [ - 'name' => $event['name'], + // Append a random suffix so repeated factory calls for the same + // user can't collide against the (user_id, name) unique + // constraint (see #100). + 'name' => $event['name'].'_'.Str::random(6), 'description' => $event['description'], ]; } diff --git a/database/seeders/WebhookSeeder.php b/database/seeders/WebhookSeeder.php index 0b65bbd..a01bd0b 100644 --- a/database/seeders/WebhookSeeder.php +++ b/database/seeders/WebhookSeeder.php @@ -7,6 +7,7 @@ use App\Models\Event; use App\Models\User; use Illuminate\Database\Seeder; +use Illuminate\Support\Str; class WebhookSeeder extends Seeder { @@ -98,7 +99,7 @@ public function run(): void $event = Event::factory() ->for($user) ->create([ - 'name' => $eventType.'_'.time().'_'.rand(1000, 9999), + 'name' => $eventType.'_'.Str::ulid(), 'event_type' => $eventType, 'description' => 'Triggered when '.str_replace('.', ' ', $eventType).' occurs', ]); @@ -141,7 +142,7 @@ public function run(): void $event = Event::factory() ->for($user) ->create([ - 'name' => $eventType.'_recent_'.time().'_'.rand(1000, 9999), + 'name' => $eventType.'_recent_'.Str::ulid(), 'event_type' => $eventType, 'description' => 'Recent '.str_replace('.', ' ', $eventType).' event', 'created_at' => $createdAt, diff --git a/tests/Feature/EmailVerificationEnforcementTest.php b/tests/Feature/EmailVerificationEnforcementTest.php new file mode 100644 index 0000000..fd3ba5c --- /dev/null +++ b/tests/Feature/EmailVerificationEnforcementTest.php @@ -0,0 +1,30 @@ +unverified()->create(); + + $response = $this->actingAs($user)->get('/dashboard'); + + $response->assertRedirect(route('verification.notice')); + } + + public function test_verified_user_can_access_the_dashboard(): void + { + $user = User::factory()->create(); + + $response = $this->actingAs($user)->get('/dashboard'); + + $response->assertOk(); + } +}