diff --git a/src/Events/PresenceChannelSubscribe.php b/src/Events/PresenceChannelSubscribe.php new file mode 100644 index 00000000..4904fd44 --- /dev/null +++ b/src/Events/PresenceChannelSubscribe.php @@ -0,0 +1,18 @@ +name(),$connection); + parent::broadcastInternally( [ 'event' => 'pusher_internal:member_added', @@ -52,6 +56,8 @@ public function unsubscribe(Connection $connection): void return; } + PresenceChannelUnsubscribe::dispatch($this->name(), $connection); + parent::broadcast( [ 'event' => 'pusher_internal:member_removed', diff --git a/tests/Unit/Protocols/Pusher/Channels/PresenceChannelTest.php b/tests/Unit/Protocols/Pusher/Channels/PresenceChannelTest.php index 28c9fadf..2715d78a 100644 --- a/tests/Unit/Protocols/Pusher/Channels/PresenceChannelTest.php +++ b/tests/Unit/Protocols/Pusher/Channels/PresenceChannelTest.php @@ -5,6 +5,9 @@ use Laravel\Reverb\Protocols\Pusher\Contracts\ChannelConnectionManager; use Laravel\Reverb\Protocols\Pusher\Exceptions\ConnectionUnauthorized; use Laravel\Reverb\Tests\FakeConnection; +use Illuminate\Support\Facades\Event; +use Laravel\Reverb\Events\PresenceChannelSubscribe; +use Laravel\Reverb\Events\PresenceChannelUnsubscribe; beforeEach(function () { $this->connection = new FakeConnection; @@ -82,6 +85,58 @@ ]); }); + +it('dispatches PresenceChannelSubscribe event on first subscription', function () { + Event::fake([PresenceChannelSubscribe::class]); + + $channel = new PresenceChannel('presence-test-channel'); + $data = json_encode(['user_id' => 1, 'user_info' => ['name' => 'Joe']]); + + $this->channelConnectionManager->shouldReceive('add') + ->once() + ->with($this->connection, ['user_id' => 1, 'user_info' => ['name' => 'Joe']]); + + $this->channelConnectionManager->shouldReceive('all') + ->andReturn([]); + + $channel->subscribe( + $this->connection, + validAuth($this->connection->id(), 'presence-test-channel', $data), + $data + ); + + Event::assertDispatched(PresenceChannelSubscribe::class, function ($event) { + return $event->channel === 'presence-test-channel' && + $event->connection === $this->connection; + }); +}); + +it('dispatches PresenceChannelUnsubscribe event when last connection of user is removed', function () { + Event::fake([PresenceChannelUnsubscribe::class]); + + $channel = new PresenceChannel('presence-test-channel'); + + $this->channelConnectionManager->shouldReceive('find') + ->andReturn(new ChannelConnection($this->connection, [ + 'user_id' => 1, + 'user_info' => ['name' => 'Joe'], + ])); + + $this->channelConnectionManager->shouldReceive('all') + ->andReturn([]); + + $this->channelConnectionManager->shouldReceive('remove') + ->once() + ->with($this->connection); + + $channel->unsubscribe($this->connection); + + Event::assertDispatched(PresenceChannelUnsubscribe::class, function ($event) { + return $event->channel === 'presence-test-channel' && + $event->connection === $this->connection; + }); +}); + it('sends notification of subscription', function () { $channel = new PresenceChannel('presence-test-channel');