Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ignaciodev's avatar

Testing presence channels in Laravel 11/Reverb?

I am using Laravel 11 and Reverb broadcasting.

I have a custom guard called 'video-call', which uses a Participant model.

Auth config:

'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'video-call' => [
            'driver' => 'session',
            'provider' => 'participants',
        ],
    ],
'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => env('AUTH_MODEL', App\Models\User::class),
    ],

    'participants' => [
        'driver' => 'eloquent',
        'model' => App\Models\Participant::class,
    ],
],

Model:

class Participant extends Authenticatable
{
    protected $guard = 'video-call';
}

Here is my Bradcast service provider:

public function boot(): void
{
    Broadcast::routes(['middleware' => ['auth:video-call']]);
}

The routes are added from the bootstrap like this:

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        channels: __DIR__.'/../routes/channels.php',
        health: '/up',
    )

I am trying to subscribe a Participant to a presence channel like this:

Broadcast::channel('videocalls.{video_call}', function (Participant $participant, VideoCall $video_call) {
    if ($participant->video_call_id === $video_call->id) {
        return [ 'id' => $participant->id ];
    }
}, ['guards' => ['video-call']]);

What's the best way to test this? I'm using the PHPUnit driver for my tests.

Here's what I have, but does not work (throws AccessDeniedHttpException) works fine from browser though:

use RefreshDatabase;

public function test_participants_can_join_video_call_presence_channel(): void
{
    $this->withoutExceptionHandling();

    $videoCall = VideoCall::factory()->create();
    
    $participant = Participant::factory()->for($videoCall)->create();

    $this->actingAs($participant, 'video-call');

    $response = $this->post('/broadcasting/auth', ['channel_name' => $videoCall->presence_channel_name]);

    $response->assertOk();
}
0 likes
2 replies
tisuchi's avatar
tisuchi
Best Answer
Level 70

@ignaciodev You should ensure that the channel name is correct!

/** @test */
    public function participants_can_join_video_call_presence_channel(): void
    {
        $this->withoutExceptionHandling();

        // Create a video call
        $videoCall = VideoCall::factory()->create();

        // Create a participant associated with the video call
        $participant = Participant::factory()->for($videoCall)->create();

        // Simulate acting as the participant using the video-call guard
        $this->actingAs($participant, 'video-call');

        // Generate the channel name, make sure it follows your channel naming pattern
        $channelName = 'videocalls.' . $videoCall->id;

        // Send the POST request to /broadcasting/auth
        $response = $this->post('/broadcasting/auth', ['channel_name' => $channelName]);

        // Assert the response is OK
        $response->assertOk();
    }
2 likes
ignaciodev's avatar

@tisuchi thank you, I was indeed passing the wrong channel name. One thing though, on Laravel 11 at least, you also need to pass a fake socket id - properly formatted (4 numbers, dot, 4 numbers):

$response = $this->post('/broadcasting/auth', [
    'channel_name' => 'videocalls.'.$videoCall->id,
    'socket_id' => '1234.5678'
]);
2 likes

Please or to participate in this conversation.