create(); $participant = User::factory()->create(); $hunt = Hunts::withoutSyncingToSearch(fn () => Hunts::factory()->create([ 'creator_id' => $creator->id, ])); $response = $this ->actingAs($participant, 'sanctum') ->postJson("/api/hunts/{$hunt->id}/participate"); $response ->assertOk() ->assertJson([ 'message' => 'Successfully joined the hunt', ]); Notification::assertSentTo( $creator, HuntParticipantJoinedNotification::class, fn (HuntParticipantJoinedNotification $notification): bool => $notification->hunt->is($hunt) && $notification->participant->is($participant) && $notification instanceof ShouldQueue, ); }); it('does not notify the hunt creator when the user already participates', function () { Notification::fake(); $creator = User::factory()->create(); $participant = User::factory()->create(); $hunt = Hunts::withoutSyncingToSearch(fn () => Hunts::factory()->create([ 'creator_id' => $creator->id, ])); $hunt->participants()->attach($participant->id, [ 'current_step_number' => 0, 'status' => 'in_progress', ]); $response = $this ->actingAs($participant, 'sanctum') ->postJson("/api/hunts/{$hunt->id}/participate"); $response->assertConflict(); Notification::assertNotSentTo($creator, HuntParticipantJoinedNotification::class); }); it('uses the personalized joined hunt email view', function () { $creator = User::factory()->create([ 'username' => 'creator-test', ]); $participant = User::factory()->create([ 'username' => 'participant-test', ]); $hunt = Hunts::withoutSyncingToSearch(fn () => Hunts::factory()->create([ 'creator_id' => $creator->id, 'title' => 'La quête des lanternes', 'city' => 'Lyon', ])); $hunt->participants()->attach($participant->id, [ 'current_step_number' => 0, 'status' => 'in_progress', ]); $notification = new HuntParticipantJoinedNotification($hunt, $participant); $mailMessage = $notification->toMail($creator); expect($mailMessage->subject)->toBe('Nouveau participant sur La quête des lanternes') ->and($mailMessage->view)->toBe('mail.hunts.joined-hunt') ->and($mailMessage->viewData) ->toMatchArray([ 'notifiable' => $creator, 'hunt' => $hunt, 'participant' => $participant, 'participantsCount' => 1, ]); $renderedView = view($mailMessage->view, $mailMessage->viewData)->render(); expect($renderedView) ->toContain('Bonjour creator-test') ->toContain('participant-test') ->toContain('La quête des lanternes') ->toContain('Lyon'); }); it('queues email verification notifications', function () { expect(new VerifyEmailNotification)->toBeInstanceOf(ShouldQueue::class); });