From d7c50f7fb0eccc29333dfda3d41d268f67abe478 Mon Sep 17 00:00:00 2001 From: Joe Dixon Date: Mon, 4 Dec 2023 11:34:42 +0000 Subject: [PATCH 01/10] wip --- tests/Feature/Reverb/ServerTest.php | 13 ++-- tests/Helpers/Reverb.php | 97 +++++++++++++++++++++++++++++ tests/ReverbTestCase.php | 37 ----------- 3 files changed, 103 insertions(+), 44 deletions(-) create mode 100644 tests/Helpers/Reverb.php diff --git a/tests/Feature/Reverb/ServerTest.php b/tests/Feature/Reverb/ServerTest.php index 61f88771..a0fbf183 100644 --- a/tests/Feature/Reverb/ServerTest.php +++ b/tests/Feature/Reverb/ServerTest.php @@ -8,16 +8,15 @@ use Laravel\Reverb\Tests\ReverbTestCase; use React\Promise\Deferred; -use function Ratchet\Client\connect; use function React\Async\await; use function React\Promise\all; uses(ReverbTestCase::class); it('can handle connections to different applications', function () { - $this->connect(); - $this->connect(key: 'pusher-key-2'); - $this->connect(key: 'pusher-key-3', headers: ['Origin' => 'http://laravel.com']); + connect(); + connect(key: 'pusher-key-2'); + connect(key: 'pusher-key-3', headers: ['Origin' => 'http://laravel.com']); }); it('can subscribe to a channel', function () { @@ -29,7 +28,7 @@ }); it('can subscribe to a private channel', function () { - $response = $this->subscribe('private-test-channel'); + $response = subscribe('private-test-channel'); expect($response)->toBe('{"event":"pusher_internal:subscription_succeeded","channel":"private-test-channel"}'); }); @@ -202,8 +201,8 @@ }); it('can handle an event', function () { - $connection = $this->connect(); - $this->subscribe('presence-test-channel', connection: $connection, data: ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]); + $connection = connect(); + subscribe('presence-test-channel', connection: $connection, data: ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]); $promise = $this->messagePromise($connection); $this->triggerEvent( diff --git a/tests/Helpers/Reverb.php b/tests/Helpers/Reverb.php new file mode 100644 index 00000000..d5d2bd48 --- /dev/null +++ b/tests/Helpers/Reverb.php @@ -0,0 +1,97 @@ +on('message', function ($message) use ($promise) { + $promise->resolve((string) $message); + }); + + $message = await($promise->promise()); + + expect($message)->toContain('connection_established'); + + return $connection; +} + +/** + * Send a message to the connected client. + */ +function send(array $message, WebSocket $connection = null): string +{ + $promise = new Deferred; + + $connection = $connection ?: connect(); + + $connection->on('message', function ($message) use ($promise) { + $promise->resolve((string) $message); + }); + + $connection->on('close', function ($code, $message) use ($promise) { + $promise->resolve((string) $message); + }); + + $connection->send(json_encode($message)); + + return await($promise->promise()); +} + +/** + * Subscribe to a channel. + */ +function subscribe(string $channel, ?array $data = [], string $auth = null, WebSocket $connection = null): string +{ + $data = ! empty($data) ? json_encode($data) : null; + + if (! $auth && Str::startsWith($channel, ['private-', 'presence-'])) { + $connection = $connection ?: connect(); + $auth = validAuth(socketId($connection), $channel, $data); + } + + return send([ + 'event' => 'pusher:subscribe', + 'data' => array_filter([ + 'channel' => $channel, + 'channel_data' => $data, + 'auth' => $auth, + ]), + ], $connection); +} + +/** + * Disconnect the connected client. + */ +function disconnect(WebSocket $connection): string +{ + $promise = new Deferred; + + $connection->on('close', function () use ($promise) { + $promise->resolve('Connection Closed.'); + }); + + $connection->close(); + + return await($promise->promise()); +} + +function socketId(WebSocket $connection) +{ + $connections = channelManager()->connections(); + + dd($connections); +} diff --git a/tests/ReverbTestCase.php b/tests/ReverbTestCase.php index 00ae1d52..580333cf 100644 --- a/tests/ReverbTestCase.php +++ b/tests/ReverbTestCase.php @@ -126,43 +126,6 @@ public function stopServer() } } - /** - * Connect to the WebSocket server. - * - * @param string $host - * @param string $port - * @param string $key - * @return \Ratchet\Client\WebSocket - */ - public function connect($host = '0.0.0.0', $port = '8080', $key = 'pusher-key', $headers = []) - { - $promise = new Deferred; - - $connection = await( - connect("ws://{$host}:{$port}/app/{$key}", headers: $headers) - ); - - $connection->on('message', function ($message) use ($promise) { - $promise->resolve((string) $message); - }); - - $message = await($promise->promise()); - - $this->assertTrue( - Str::contains( - $message, - 'connection_established' - ) - ); - - $message = json_decode($message, true); - $data = json_decode($message['data'], true); - - $this->connectionId = $data['socket_id'] ?? null; - - return $connection; - } - /** * Send a message to the connected client. */ From 8c958bdc2bc2b472efc095a47e4a5e0dcfdf9083 Mon Sep 17 00:00:00 2001 From: Joe Dixon Date: Wed, 6 Dec 2023 11:40:16 +0000 Subject: [PATCH 02/10] wip --- tests/ApiGatewayTestCase.php | 4 +-- tests/{Connection.php => FakeConnection.php} | 4 +-- tests/Feature/ApiGateway/ServerTest.php | 28 ++++++++-------- .../Reverb/ChannelUsersControllerTest.php | 8 ++--- tests/Feature/ServerTest.php | 32 +++++++++---------- tests/Helpers/ApiGateway.php | 11 +++++++ tests/Helpers/Reverb.php | 5 +-- tests/Pest.php | 14 ++------ tests/SerializableConnection.php | 2 +- tests/Unit/Channels/CacheChannelTest.php | 4 +-- tests/Unit/Channels/ChannelTest.php | 8 ++--- .../Channels/PresenceCacheChannelTest.php | 16 +++++----- tests/Unit/Channels/PresenceChannelTest.php | 16 +++++----- .../Unit/Channels/PrivateCacheChannelTest.php | 6 ++-- tests/Unit/Channels/PrivateChannelTest.php | 6 ++-- tests/Unit/ClientEventTest.php | 6 ++-- .../Unit/Jobs/PingInactiveConnectionsTest.php | 2 +- tests/Unit/Jobs/PruneStaleConnectionsTest.php | 2 +- tests/Unit/Managers/ChannelManagerTest.php | 14 ++++---- tests/Unit/Pusher/EventTest.php | 4 +-- 20 files changed, 98 insertions(+), 94 deletions(-) rename tests/{Connection.php => FakeConnection.php} (94%) create mode 100644 tests/Helpers/ApiGateway.php diff --git a/tests/ApiGatewayTestCase.php b/tests/ApiGatewayTestCase.php index 02081504..a6abb9b5 100644 --- a/tests/ApiGatewayTestCase.php +++ b/tests/ApiGatewayTestCase.php @@ -180,8 +180,8 @@ public function assertSent(?string $connectionId = null, mixed $message = null, */ public function managedConnection(): ?Connection { - $connection = Arr::last(connectionManager()->all()); + $connection = Arr::last(connections()->all()); - return connectionManager()->find($connection->identifier()); + return connections()->find($connection->identifier()); } } diff --git a/tests/Connection.php b/tests/FakeConnection.php similarity index 94% rename from tests/Connection.php rename to tests/FakeConnection.php index aed0259b..3231fa38 100644 --- a/tests/Connection.php +++ b/tests/FakeConnection.php @@ -8,7 +8,7 @@ use Laravel\Reverb\Contracts\ApplicationProvider; use Laravel\Reverb\Contracts\Connection as BaseConnection; -class Connection extends BaseConnection +class FakeConnection extends BaseConnection { use GeneratesPusherIdentifiers; @@ -49,7 +49,7 @@ public function origin(): string return 'http://localhost'; } - public function setLastSeenAt(int $time): Connection + public function setLastSeenAt(int $time): FakeConnection { $this->lastSeenAt = $time; diff --git a/tests/Feature/ApiGateway/ServerTest.php b/tests/Feature/ApiGateway/ServerTest.php index 09d795e9..d83466fc 100644 --- a/tests/Feature/ApiGateway/ServerTest.php +++ b/tests/Feature/ApiGateway/ServerTest.php @@ -18,27 +18,27 @@ afterEach(function () { channelManager()->flush(); - connectionManager()->flush(); + connections()->flush(); }); it('can handle a new connection', function () { $this->connect(); - $this->assertCount(1, connectionManager()->all()); + $this->assertCount(1, connections()->all()); }); it('can handle multiple new connections', function () { $this->connect(); $this->connect('def-456'); - $this->assertCount(2, connectionManager()->all()); + $this->assertCount(2, connections()->all()); }); it('can handle connections to different applications', function () { $this->connect(); $this->connect('def-456', appKey: 'pusher-key-2'); - $connections = connectionManager()->all(); + $connections = connections()->all(); expect(Arr::first($connections)->identifier())->toBe('abc-123'); expect(Arr::first($connections)->app()->id())->toBe('123456'); @@ -49,7 +49,7 @@ it('can subscribe to a channel', function () { $this->subscribe('test-channel'); - expect(connectionManager()->all())->toHaveCount(1); + expect(connections()->all())->toHaveCount(1); expect(channelManager()->find('test-channel')->connections())->toHaveCount(1); @@ -97,11 +97,11 @@ $this->subscribe('presence-test-channel', data: $data, connectionId: 'ghi-789'); $this->assertSent('def-456', '{"event":"pusher_internal:member_added","data":{"user_id":3,"user_info":{"name":"Test User 3"}},"channel":"presence-test-channel"}'); - expect(connectionManager()->all())->toHaveCount(3); + expect(connections()->all())->toHaveCount(3); $this->disconnect('ghi-789'); - expect(connectionManager()->all())->toHaveCount(2); + expect(connections()->all())->toHaveCount(2); $this->assertSent( message: '{"event":"pusher_internal:member_removed","data":{"user_id":3},"channel":"presence-test-channel"}', @@ -146,9 +146,9 @@ $this->subscribe('test-channel'); $this->assertSent('abc-123', 'subscription_succeeded', 1); - $connection = Arr::first(connectionManager()->all()); + $connection = Arr::first(connections()->all()); $connection->setLastSeenAt(time() - 60 * 10); - connectionManager()->connect($connection); + connections()->connect($connection); (new PingInactiveConnections)->handle( channelManager() @@ -160,9 +160,9 @@ it('it can disconnect inactive subscribers', function () { $this->subscribe('test-channel'); - $connection = Arr::first(connectionManager()->all()); + $connection = Arr::first(connections()->all()); $connection->setLastSeenAt(time() - 60 * 10); - connectionManager()->connect($connection); + connections()->connect($connection); (new PingInactiveConnections)->handle( channelManager() @@ -173,7 +173,7 @@ channelManager() ); - // expect(connectionManager()->all())->toHaveCount(0); + // expect(connections()->all())->toHaveCount(0); expect(channelManager()->find('test-channel')->connections())->toHaveCount(0); $this->assertSent('abc-123', '{"event":"pusher:error","data":"{\"code\":4201,\"message\":\"Pong reply not received in time\"}"}', 1); @@ -202,7 +202,7 @@ $this->subscribe('private-test-channel-3', data: ['foo' => 'bar']); $this->subscribe('presence-test-channel-4', data: ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]); - expect(connectionManager()->all())->toHaveCount(1); + expect(connections()->all())->toHaveCount(1); expect(channelManager()->all())->toHaveCount(4); $connection = $this->managedConnection(); @@ -223,7 +223,7 @@ $this->subscribe('test-channel', connectionId: 'def-456'); $this->subscribe('private-test-channel-3', connectionId: 'def-456', data: ['foo' => 'bar']); - expect(connectionManager()->all())->toHaveCount(2); + expect(connections()->all())->toHaveCount(2); expect(channelManager()->all())->toHaveCount(4); expect(channelManager()->find('test-channel')->connections())->toHaveCount(2); diff --git a/tests/Feature/Reverb/ChannelUsersControllerTest.php b/tests/Feature/Reverb/ChannelUsersControllerTest.php index af53642b..d9cbbc56 100644 --- a/tests/Feature/Reverb/ChannelUsersControllerTest.php +++ b/tests/Feature/Reverb/ChannelUsersControllerTest.php @@ -2,7 +2,7 @@ use Laravel\Reverb\Contracts\ApplicationProvider; use Laravel\Reverb\Contracts\ChannelManager; -use Laravel\Reverb\Tests\Connection; +use Laravel\Reverb\Tests\FakeConnection; use Laravel\Reverb\Tests\ReverbTestCase; use React\Http\Message\ResponseException; @@ -18,9 +18,9 @@ $channel = app(ChannelManager::class) ->for(app()->make(ApplicationProvider::class)->findByKey('pusher-key')) ->find('presence-test-channel'); - $channel->subscribe($connection = new Connection('test-connection-one'), validAuth($connection->id(), 'presence-test-channel', $data = json_encode(['user_id' => 1, 'user_info' => ['name' => 'Taylor']])), $data); - $channel->subscribe($connection = new Connection('test-connection-two'), validAuth($connection->id(), 'presence-test-channel', $data = json_encode(['user_id' => 2, 'user_info' => ['name' => 'Joe']])), $data); - $channel->subscribe($connection = new Connection('test-connection-three'), validAuth($connection->id(), 'presence-test-channel', $data = json_encode(['user_id' => 3, 'user_info' => ['name' => 'Jess']])), $data); + $channel->subscribe($connection = new FakeConnection('test-connection-one'), validAuth($connection->id(), 'presence-test-channel', $data = json_encode(['user_id' => 1, 'user_info' => ['name' => 'Taylor']])), $data); + $channel->subscribe($connection = new FakeConnection('test-connection-two'), validAuth($connection->id(), 'presence-test-channel', $data = json_encode(['user_id' => 2, 'user_info' => ['name' => 'Joe']])), $data); + $channel->subscribe($connection = new FakeConnection('test-connection-three'), validAuth($connection->id(), 'presence-test-channel', $data = json_encode(['user_id' => 3, 'user_info' => ['name' => 'Jess']])), $data); $response = await($this->signedRequest('channels/presence-test-channel/users')); diff --git a/tests/Feature/ServerTest.php b/tests/Feature/ServerTest.php index 51bba291..1c364aa7 100644 --- a/tests/Feature/ServerTest.php +++ b/tests/Feature/ServerTest.php @@ -2,7 +2,7 @@ use Laravel\Reverb\Contracts\ChannelManager; use Laravel\Reverb\Pusher\Server; -use Laravel\Reverb\Tests\Connection; +use Laravel\Reverb\Tests\FakeConnection; use Laravel\Reverb\Tests\TestCase; uses(TestCase::class); @@ -12,7 +12,7 @@ }); it('can handle a connection', function () { - $this->server->open($connection = new Connection); + $this->server->open($connection = new FakeConnection); expect($connection->lastSeenAt())->not->toBeNull(); @@ -32,13 +32,13 @@ $this->app->singleton(ChannelManager::class, fn () => $channelManager); $server = $this->app->make(Server::class); - $server->close(new Connection); + $server->close(new FakeConnection); $channelManager->shouldHaveReceived('unsubscribeFromAll'); }); it('can handle a new message', function () { - $this->server->open($connection = new Connection); + $this->server->open($connection = new FakeConnection); $this->server->message( $connection, json_encode([ @@ -65,7 +65,7 @@ it('sends an error if something fails', function () { $this->server->message( - $connection = new Connection, + $connection = new FakeConnection, 'Hi' ); @@ -98,7 +98,7 @@ it('can subscribe a user to a channel', function () { $this->server->message( - $connection = new Connection, + $connection = new FakeConnection, json_encode([ 'event' => 'pusher:subscribe', 'data' => [ @@ -117,7 +117,7 @@ it('can subscribe a user to a private channel', function () { $this->server->message( - $connection = new Connection, + $connection = new FakeConnection, json_encode([ 'event' => 'pusher:subscribe', 'data' => [ @@ -134,7 +134,7 @@ it('can subscribe a user to a presence channel', function () { $this->server->message( - $connection = new Connection, + $connection = new FakeConnection, json_encode([ 'event' => 'pusher:subscribe', 'data' => [ @@ -158,7 +158,7 @@ it('receives no data when no previous event triggered when joining a cache channel', function () { $this->server->message( - $connection = new Connection, + $connection = new FakeConnection, json_encode([ 'event' => 'pusher:subscribe', 'data' => [ @@ -179,7 +179,7 @@ it('receives last triggered event when joining a cache channel', function () { $this->server->message( - $connection = new Connection, + $connection = new FakeConnection, json_encode([ 'event' => 'pusher:subscribe', 'data' => [ @@ -192,7 +192,7 @@ $channel->broadcast(['foo' => 'bar']); $this->server->message( - $connection = new Connection, + $connection = new FakeConnection, json_encode([ 'event' => 'pusher:subscribe', 'data' => [ @@ -216,7 +216,7 @@ $server = $this->app->make(Server::class); $server->message( - $connection = new Connection, + $connection = new FakeConnection, json_encode([ 'event' => 'pusher:subscribe', 'data' => [ @@ -240,7 +240,7 @@ $server = $this->app->make(Server::class); $server->message( - $connection = new Connection, + $connection = new FakeConnection, json_encode([ 'event' => 'pusher:subscribe', 'data' => [ @@ -264,7 +264,7 @@ $server = $this->app->make(Server::class); $server->message( - $connection = new Connection, + $connection = new FakeConnection, json_encode([ 'event' => 'pusher:subscribe', 'data' => [ @@ -282,7 +282,7 @@ it('it rejects a connection from an invalid origin', function () { $this->app['config']->set('reverb.apps.apps.0.allowed_origins', ['laravel.com']); - $this->server->open($connection = new Connection); + $this->server->open($connection = new FakeConnection); $connection->assertSent([ 'event' => 'pusher:error', @@ -295,7 +295,7 @@ it('it accepts a connection from an valid origin', function () { $this->app['config']->set('reverb.apps.0.allowed_origins', ['localhost']); - $this->server->open($connection = new Connection); + $this->server->open($connection = new FakeConnection); $connection->assertSent([ 'event' => 'pusher:connection_established', diff --git a/tests/Helpers/ApiGateway.php b/tests/Helpers/ApiGateway.php new file mode 100644 index 00000000..3fe1c178 --- /dev/null +++ b/tests/Helpers/ApiGateway.php @@ -0,0 +1,11 @@ +connections(); - dd($connections); + // dd($connections); } diff --git a/tests/Pest.php b/tests/Pest.php index c3fa2ef5..6286cd4e 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -7,7 +7,7 @@ use Laravel\Reverb\Contracts\ConnectionManager; use Laravel\Reverb\Managers\Connections; use Laravel\Reverb\Servers\Reverb\ChannelConnection; -use Laravel\Reverb\Tests\Connection; +use Laravel\Reverb\Tests\FakeConnection; use Laravel\Reverb\Tests\SerializableConnection; use Laravel\Reverb\Tests\TestCase; use Ramsey\Uuid\Uuid; @@ -20,13 +20,13 @@ * @param bool $serializable * @return array */ -function connections(int $count = 1, array $data = [], $serializable = false): array +function factory(int $count = 1, array $data = [], $serializable = false): array { return Collection::make(range(1, $count))->map(function () use ($data, $serializable) { return new ChannelConnection( $serializable ? new SerializableConnection(Uuid::uuid4()) - : new Connection(Uuid::uuid4()), + : new FakeConnection(Uuid::uuid4()), $data ); })->all(); @@ -46,14 +46,6 @@ function validAuth(string $connectionId, string $channel, ?string $data = null): return 'app-key:'.hash_hmac('sha256', $signature, 'pusher-secret'); } -/** - * Return the connection manager. - */ -function connectionManager(): ConnectionManager -{ - return app(ConnectionManager::class); -} - /** * Return the channel manager. */ diff --git a/tests/SerializableConnection.php b/tests/SerializableConnection.php index 4f16052e..f7e32e7e 100644 --- a/tests/SerializableConnection.php +++ b/tests/SerializableConnection.php @@ -4,7 +4,7 @@ use Laravel\Reverb\Concerns\SerializesConnections; use Laravel\Reverb\Contracts\SerializableConnection as ContractsSerializableConnection; -use Laravel\Reverb\Tests\Connection as BaseConnection; +use Laravel\Reverb\Tests\FakeConnection as BaseConnection; class SerializableConnection extends BaseConnection implements ContractsSerializableConnection { diff --git a/tests/Unit/Channels/CacheChannelTest.php b/tests/Unit/Channels/CacheChannelTest.php index 31d949bf..3e39d751 100644 --- a/tests/Unit/Channels/CacheChannelTest.php +++ b/tests/Unit/Channels/CacheChannelTest.php @@ -3,10 +3,10 @@ use Laravel\Reverb\Channels\CacheChannel; use Laravel\Reverb\Channels\ChannelBroker; use Laravel\Reverb\Contracts\ChannelConnectionManager; -use Laravel\Reverb\Tests\Connection; +use Laravel\Reverb\Tests\FakeConnection; beforeEach(function () { - $this->connection = new Connection(); + $this->connection = new FakeConnection(); $this->channelConnectionManager = Mockery::spy(ChannelConnectionManager::class); $this->channelConnectionManager->shouldReceive('for') ->andReturn($this->channelConnectionManager); diff --git a/tests/Unit/Channels/ChannelTest.php b/tests/Unit/Channels/ChannelTest.php index ceeaeed2..046360ff 100644 --- a/tests/Unit/Channels/ChannelTest.php +++ b/tests/Unit/Channels/ChannelTest.php @@ -3,10 +3,10 @@ use Laravel\Reverb\Channels\Channel; use Laravel\Reverb\Contracts\ChannelConnectionManager; use Laravel\Reverb\Contracts\ChannelManager; -use Laravel\Reverb\Tests\Connection; +use Laravel\Reverb\Tests\FakeConnection; beforeEach(function () { - $this->connection = new Connection(); + $this->connection = new FakeConnection(); $this->channelConnectionManager = Mockery::spy(ChannelConnectionManager::class); $this->channelConnectionManager->shouldReceive('for') ->andReturn($this->channelConnectionManager); @@ -66,7 +66,7 @@ $this->channelConnectionManager->shouldReceive('all') ->once() - ->andReturn($connections = connections(3)); + ->andReturn($connections = factory(3)); $channel->broadcast(['foo' => 'bar']); @@ -80,7 +80,7 @@ $this->channelConnectionManager->shouldReceive('all') ->once() - ->andReturn($connections = connections(3)); + ->andReturn($connections = factory(3)); $channel->broadcast(['foo' => 'bar'], $connections[0]->connection()); diff --git a/tests/Unit/Channels/PresenceCacheChannelTest.php b/tests/Unit/Channels/PresenceCacheChannelTest.php index 845bc735..de24d66a 100644 --- a/tests/Unit/Channels/PresenceCacheChannelTest.php +++ b/tests/Unit/Channels/PresenceCacheChannelTest.php @@ -4,10 +4,10 @@ use Laravel\Reverb\Contracts\ChannelConnectionManager; use Laravel\Reverb\Exceptions\ConnectionUnauthorized; use Laravel\Reverb\Servers\Reverb\ChannelConnection; -use Laravel\Reverb\Tests\Connection; +use Laravel\Reverb\Tests\FakeConnection; beforeEach(function () { - $this->connection = new Connection(); + $this->connection = new FakeConnection(); $this->channelConnectionManager = Mockery::spy(ChannelConnectionManager::class); $this->channelConnectionManager->shouldReceive('for') ->andReturn($this->channelConnectionManager); @@ -43,7 +43,7 @@ $this->channelConnectionManager->shouldReceive('all') ->once() - ->andReturn($connections = connections(3)); + ->andReturn($connections = factory(3)); $channel->broadcast(['foo' => 'bar']); @@ -62,8 +62,8 @@ $channel = new PresenceCacheChannel('presence-cache-test-channel'); $connections = [ - connections(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 1])[0], - connections(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 2])[0], + factory(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 1])[0], + factory(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 2])[0], ]; $this->channelConnectionManager->shouldReceive('all') @@ -90,7 +90,7 @@ ->with($this->connection, []); $this->channelConnectionManager->shouldReceive('all') - ->andReturn($connections = connections(3)); + ->andReturn($connections = factory(3)); $channel->subscribe($this->connection, validAuth($this->connection->id(), 'presence-cache-test-channel')); @@ -110,7 +110,7 @@ ->with($this->connection, ['name' => 'Joe']); $this->channelConnectionManager->shouldReceive('all') - ->andReturn($connections = connections(3)); + ->andReturn($connections = factory(3)); $channel->subscribe( $this->connection, @@ -147,7 +147,7 @@ ->andReturn(new ChannelConnection($this->connection, ['user_info' => ['name' => 'Joe'], 'user_id' => 1])); $this->channelConnectionManager->shouldReceive('all') - ->andReturn($connections = connections(3)); + ->andReturn($connections = factory(3)); $this->channelConnectionManager->shouldReceive('remove') ->once() diff --git a/tests/Unit/Channels/PresenceChannelTest.php b/tests/Unit/Channels/PresenceChannelTest.php index c2cf7e10..0c8afff0 100644 --- a/tests/Unit/Channels/PresenceChannelTest.php +++ b/tests/Unit/Channels/PresenceChannelTest.php @@ -4,10 +4,10 @@ use Laravel\Reverb\Contracts\ChannelConnectionManager; use Laravel\Reverb\Exceptions\ConnectionUnauthorized; use Laravel\Reverb\Servers\Reverb\ChannelConnection; -use Laravel\Reverb\Tests\Connection; +use Laravel\Reverb\Tests\FakeConnection; beforeEach(function () { - $this->connection = new Connection(); + $this->connection = new FakeConnection(); $this->channelConnectionManager = Mockery::spy(ChannelConnectionManager::class); $this->channelConnectionManager->shouldReceive('for') ->andReturn($this->channelConnectionManager); @@ -43,7 +43,7 @@ $this->channelConnectionManager->shouldReceive('all') ->once() - ->andReturn($connections = connections(3)); + ->andReturn($connections = factory(3)); $channel->broadcast(['foo' => 'bar']); @@ -62,8 +62,8 @@ $channel = new PresenceChannel('presence-test-channel'); $connections = [ - connections(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 1])[0], - connections(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 2])[0], + factory(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 1])[0], + factory(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 2])[0], ]; $this->channelConnectionManager->shouldReceive('all') @@ -90,7 +90,7 @@ ->with($this->connection, []); $this->channelConnectionManager->shouldReceive('all') - ->andReturn($connections = connections(3)); + ->andReturn($connections = factory(3)); $channel->subscribe($this->connection, validAuth($this->connection->id(), 'presence-test-channel')); @@ -110,7 +110,7 @@ ->with($this->connection, ['name' => 'Joe']); $this->channelConnectionManager->shouldReceive('all') - ->andReturn($connections = connections(3)); + ->andReturn($connections = factory(3)); $channel->subscribe( $this->connection, @@ -147,7 +147,7 @@ ->andReturn(new ChannelConnection($this->connection, ['user_info' => ['name' => 'Joe'], 'user_id' => 1])); $this->channelConnectionManager->shouldReceive('all') - ->andReturn($connections = connections(3)); + ->andReturn($connections = factory(3)); $this->channelConnectionManager->shouldReceive('remove') ->once() diff --git a/tests/Unit/Channels/PrivateCacheChannelTest.php b/tests/Unit/Channels/PrivateCacheChannelTest.php index ee491c93..abb91e99 100644 --- a/tests/Unit/Channels/PrivateCacheChannelTest.php +++ b/tests/Unit/Channels/PrivateCacheChannelTest.php @@ -3,10 +3,10 @@ use Laravel\Reverb\Channels\PrivateCacheChannel; use Laravel\Reverb\Contracts\ChannelConnectionManager; use Laravel\Reverb\Exceptions\ConnectionUnauthorized; -use Laravel\Reverb\Tests\Connection; +use Laravel\Reverb\Tests\FakeConnection; beforeEach(function () { - $this->connection = new Connection(); + $this->connection = new FakeConnection(); $this->channelConnectionManager = Mockery::spy(ChannelConnectionManager::class); $this->channelConnectionManager->shouldReceive('for') ->andReturn($this->channelConnectionManager); @@ -40,7 +40,7 @@ $this->channelConnectionManager->shouldReceive('all') ->once() - ->andReturn($connections = connections(3)); + ->andReturn($connections = factory(3)); $channel->broadcast(['foo' => 'bar']); diff --git a/tests/Unit/Channels/PrivateChannelTest.php b/tests/Unit/Channels/PrivateChannelTest.php index 5720ab9b..4b4a8c73 100644 --- a/tests/Unit/Channels/PrivateChannelTest.php +++ b/tests/Unit/Channels/PrivateChannelTest.php @@ -3,10 +3,10 @@ use Laravel\Reverb\Channels\PrivateChannel; use Laravel\Reverb\Contracts\ChannelConnectionManager; use Laravel\Reverb\Exceptions\ConnectionUnauthorized; -use Laravel\Reverb\Tests\Connection; +use Laravel\Reverb\Tests\FakeConnection; beforeEach(function () { - $this->connection = new Connection(); + $this->connection = new FakeConnection(); $this->channelConnectionManager = Mockery::spy(ChannelConnectionManager::class); $this->channelConnectionManager->shouldReceive('for') ->andReturn($this->channelConnectionManager); @@ -40,7 +40,7 @@ $this->channelConnectionManager->shouldReceive('all') ->once() - ->andReturn($connections = connections(3)); + ->andReturn($connections = factory(3)); $channel->broadcast(['foo' => 'bar']); diff --git a/tests/Unit/ClientEventTest.php b/tests/Unit/ClientEventTest.php index d3c2b80f..b61e6153 100644 --- a/tests/Unit/ClientEventTest.php +++ b/tests/Unit/ClientEventTest.php @@ -3,10 +3,10 @@ use Laravel\Reverb\ClientEvent; use Laravel\Reverb\Contracts\ChannelConnectionManager; use Laravel\Reverb\Servers\Reverb\ChannelConnection; -use Laravel\Reverb\Tests\Connection; +use Laravel\Reverb\Tests\FakeConnection; beforeEach(function () { - $this->connection = new Connection; + $this->connection = new FakeConnection; $this->channelConnectionManager = Mockery::spy(ChannelConnectionManager::class); $this->channelConnectionManager->shouldReceive('for') ->andReturn($this->channelConnectionManager); @@ -16,7 +16,7 @@ it('can forward a client message', function () { $this->channelConnectionManager->shouldReceive('all') ->once() - ->andReturn($connections = connections()); + ->andReturn($connections = factory()); ClientEvent::handle( $this->connection, [ diff --git a/tests/Unit/Jobs/PingInactiveConnectionsTest.php b/tests/Unit/Jobs/PingInactiveConnectionsTest.php index 3f6f2c8f..e2364d8d 100644 --- a/tests/Unit/Jobs/PingInactiveConnectionsTest.php +++ b/tests/Unit/Jobs/PingInactiveConnectionsTest.php @@ -12,7 +12,7 @@ }); it('pings inactive connections', function () { - $connections = connections(5); + $connections = factory(5); $channel = ChannelBroker::create('test-channel'); $this->channelManager->shouldReceive('connections') diff --git a/tests/Unit/Jobs/PruneStaleConnectionsTest.php b/tests/Unit/Jobs/PruneStaleConnectionsTest.php index 22af7579..db03dd30 100644 --- a/tests/Unit/Jobs/PruneStaleConnectionsTest.php +++ b/tests/Unit/Jobs/PruneStaleConnectionsTest.php @@ -12,7 +12,7 @@ }); it('cleans up stale connections', function () { - $connections = connections(5); + $connections = factory(5); $channel = ChannelBroker::create('test-channel'); $this->channelManager->shouldReceive('connections') diff --git a/tests/Unit/Managers/ChannelManagerTest.php b/tests/Unit/Managers/ChannelManagerTest.php index 3d03baa3..8b7642a6 100644 --- a/tests/Unit/Managers/ChannelManagerTest.php +++ b/tests/Unit/Managers/ChannelManagerTest.php @@ -1,24 +1,24 @@ connection = new Connection; + $this->connection = new FakeConnection; $this->channelManager = $this->app->make(ChannelManager::class) ->for($this->connection->app()); $this->channel = $this->channelManager->find('test-channel-0'); }); it('can subscribe to a channel', function () { - collect(connections(5)) + collect(factory(5)) ->each(fn ($connection) => $this->channel->subscribe($connection->connection())); expect($this->channel->connections())->toHaveCount(5); }); it('can unsubscribe from a channel', function () { - $connections = collect(connections(5)) + $connections = collect(factory(5)) ->each(fn ($connection) => $this->channel->subscribe($connection->connection())); $this->channel->unsubscribe($connections->first()->connection()); @@ -39,7 +39,7 @@ }); it('can get all connections subscribed to a channel', function () { - $connections = collect(connections(5)) + $connections = collect(factory(5)) ->each(fn ($connection) => $this->channel->subscribe($connection->connection())); $connections->each(fn ($connection) => expect($connection->id()) @@ -59,7 +59,7 @@ }); it('can get the data for a connection subscribed to a channel', function () { - collect(connections(5))->each(fn ($connection) => $this->channel->subscribe( + collect(factory(5))->each(fn ($connection) => $this->channel->subscribe( $connection->connection(), data: json_encode(['name' => 'Joe']) )); @@ -70,7 +70,7 @@ }); it('can get all connections for all channels', function () { - $connections = connections(12); + $connections = factory(12); $channelOne = $this->channelManager->find('test-channel-0'); $channelTwo = $this->channelManager->find('test-channel-1'); diff --git a/tests/Unit/Pusher/EventTest.php b/tests/Unit/Pusher/EventTest.php index 61a95b5e..fedceac8 100644 --- a/tests/Unit/Pusher/EventTest.php +++ b/tests/Unit/Pusher/EventTest.php @@ -2,10 +2,10 @@ use Laravel\Reverb\Contracts\ChannelManager; use Laravel\Reverb\Pusher\Event as PusherEvent; -use Laravel\Reverb\Tests\Connection; +use Laravel\Reverb\Tests\FakeConnection; beforeEach(function () { - $this->connection = new Connection; + $this->connection = new FakeConnection; $this->pusher = new PusherEvent(app(ChannelManager::class)); }); From d49a3b8aeaaeaf74193d25c19724804136a76c8b Mon Sep 17 00:00:00 2001 From: Joe Dixon Date: Wed, 6 Dec 2023 13:04:13 +0000 Subject: [PATCH 03/10] refactor tests --- tests/Feature/ApiGateway/ServerTest.php | 26 +- tests/Feature/Reverb/ServerTest.php | 295 ++++++++---------- .../Reverb/UsersTerminateControllerTest.php | 4 + tests/Helpers/Reverb.php | 56 ++-- tests/Pest.php | 2 +- tests/ReverbTestCase.php | 111 ------- tests/TestConnection.php | 68 ++++ 7 files changed, 258 insertions(+), 304 deletions(-) create mode 100644 tests/TestConnection.php diff --git a/tests/Feature/ApiGateway/ServerTest.php b/tests/Feature/ApiGateway/ServerTest.php index d83466fc..f47b2837 100644 --- a/tests/Feature/ApiGateway/ServerTest.php +++ b/tests/Feature/ApiGateway/ServerTest.php @@ -17,7 +17,7 @@ }); afterEach(function () { - channelManager()->flush(); + channels()->flush(); connections()->flush(); }); @@ -51,7 +51,7 @@ expect(connections()->all())->toHaveCount(1); - expect(channelManager()->find('test-channel')->connections())->toHaveCount(1); + expect(channels()->find('test-channel')->connections())->toHaveCount(1); $this->assertSent('abc-123', '{"event":"pusher_internal:subscription_succeeded","channel":"test-channel"}'); }); @@ -151,7 +151,7 @@ connections()->connect($connection); (new PingInactiveConnections)->handle( - channelManager() + channels() ); $this->assertSent('abc-123', '{"event":"pusher:ping"}', 1); @@ -165,16 +165,16 @@ connections()->connect($connection); (new PingInactiveConnections)->handle( - channelManager() + channels() ); $this->assertSent('abc-123', '{"event":"pusher:ping"}'); (new PruneStaleConnections)->handle( - channelManager() + channels() ); // expect(connections()->all())->toHaveCount(0); - expect(channelManager()->find('test-channel')->connections())->toHaveCount(0); + expect(channels()->find('test-channel')->connections())->toHaveCount(0); $this->assertSent('abc-123', '{"event":"pusher:error","data":"{\"code\":4201,\"message\":\"Pong reply not received in time\"}"}', 1); }); @@ -203,11 +203,11 @@ $this->subscribe('presence-test-channel-4', data: ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]); expect(connections()->all())->toHaveCount(1); - expect(channelManager()->all())->toHaveCount(4); + expect(channels()->all())->toHaveCount(4); $connection = $this->managedConnection(); - collect(channelManager()->all())->each(function ($channel) use ($connection) { + collect(channels()->all())->each(function ($channel) use ($connection) { expect($channel->connections())->toHaveCount(1); expect(collect($channel->connections())->map(fn ($conn, $index) => (string) $index))->toContain($connection->identifier()); }); @@ -224,12 +224,12 @@ $this->subscribe('private-test-channel-3', connectionId: 'def-456', data: ['foo' => 'bar']); expect(connections()->all())->toHaveCount(2); - expect(channelManager()->all())->toHaveCount(4); + expect(channels()->all())->toHaveCount(4); - expect(channelManager()->find('test-channel')->connections())->toHaveCount(2); - expect(channelManager()->find('test-channel-2')->connections())->toHaveCount(1); - expect(channelManager()->find('private-test-channel-3')->connections())->toHaveCount(2); - expect(channelManager()->find('presence-test-channel-4')->connections())->toHaveCount(1); + expect(channels()->find('test-channel')->connections())->toHaveCount(2); + expect(channels()->find('test-channel-2')->connections())->toHaveCount(1); + expect(channels()->find('private-test-channel-3')->connections())->toHaveCount(2); + expect(channels()->find('presence-test-channel-4')->connections())->toHaveCount(1); }); it('fails to subscribe to a private channel with invalid auth signature', function () { diff --git a/tests/Feature/Reverb/ServerTest.php b/tests/Feature/Reverb/ServerTest.php index a0fbf183..09115e62 100644 --- a/tests/Feature/Reverb/ServerTest.php +++ b/tests/Feature/Reverb/ServerTest.php @@ -8,8 +8,8 @@ use Laravel\Reverb\Tests\ReverbTestCase; use React\Promise\Deferred; +use function Ratchet\Client\connect as wsConnect; use function React\Async\await; -use function React\Promise\all; uses(ReverbTestCase::class); @@ -20,10 +20,9 @@ }); it('can subscribe to a channel', function () { - $response = $this->subscribe('test-channel'); - - $this->assertCount(1, channelManager()->find('test-channel')->connections()); + $response = subscribe('test-channel'); + expect(channels()->find('test-channel')->connections())->toHaveCount(1); expect($response)->toBe('{"event":"pusher_internal:subscription_succeeded","channel":"test-channel"}'); }); @@ -35,80 +34,72 @@ it('can subscribe to a presence channel', function () { $data = ['user_id' => 1, 'user_info' => ['name' => 'Test User']]; - $response = $this->subscribe('presence-test-channel', data: $data); + $response = subscribe('presence-test-channel', data: $data); - expect(Str::contains($response, 'pusher_internal:subscription_succeeded'))->toBeTrue(); - expect(Str::contains($response, '"hash\":{\"1\":{\"name\":\"Test User\"}}'))->toBeTrue(); + expect($response)->toContain('pusher_internal:subscription_succeeded'); + expect($response)->toContain('"hash\":{\"1\":{\"name\":\"Test User\"}}'); }); it('can subscribe to a cache channel', function () { - $response = $this->subscribe('cache-test-channel'); + $response = subscribe('cache-test-channel'); expect($response)->toBe('{"event":"pusher_internal:subscription_succeeded","channel":"cache-test-channel"}'); }); it('can subscribe to a private cache channel', function () { - $response = $this->subscribe('private-cache-test-channel'); + $response = subscribe('private-cache-test-channel'); expect($response)->toBe('{"event":"pusher_internal:subscription_succeeded","channel":"private-cache-test-channel"}'); }); it('can subscribe to a presence cache channel', function () { $data = ['user_id' => 1, 'user_info' => ['name' => 'Test User']]; - $response = $this->subscribe('presence-cache-test-channel', data: $data); + $response = subscribe('presence-cache-test-channel', data: $data); - expect(Str::contains($response, 'pusher_internal:subscription_succeeded'))->toBeTrue(); - expect(Str::contains($response, '"hash\":{\"1\":{\"name\":\"Test User\"}}'))->toBeTrue(); + expect($response)->toContain('pusher_internal:subscription_succeeded'); + expect($response)->toContain('"hash\":{\"1\":{\"name\":\"Test User\"}}'); }); it('can notify other subscribers of a presence channel when a new member joins', function () { - $connectionOne = $this->connect(); + $connectionOne = connect(); $data = ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]; - $this->subscribe('presence-test-channel', data: $data, connection: $connectionOne); - $promiseOne = $this->messagePromise($connectionOne); + subscribe('presence-test-channel', data: $data, connection: $connectionOne); - $connectionTwo = $this->connect(); + $connectionTwo = connect(); $data = ['user_id' => 2, 'user_info' => ['name' => 'Test User 2']]; - $this->subscribe('presence-test-channel', data: $data, connection: $connectionTwo); - $promiseTwo = $this->messagePromise($connectionTwo); + subscribe('presence-test-channel', data: $data, connection: $connectionTwo); - $connectionThree = $this->connect(); $data = ['user_id' => 3, 'user_info' => ['name' => 'Test User 3']]; - $this->subscribe('presence-test-channel', data: $data, connection: $connectionThree); + subscribe('presence-test-channel', data: $data); - expect(await($promiseOne))->toBe('{"event":"pusher_internal:member_added","data":{"user_id":2,"user_info":{"name":"Test User 2"}},"channel":"presence-test-channel"}'); - expect(await($promiseTwo))->toBe('{"event":"pusher_internal:member_added","data":{"user_id":3,"user_info":{"name":"Test User 3"}},"channel":"presence-test-channel"}'); + $connectionOne->assertReceived('{"event":"pusher_internal:member_added","data":{"user_id":2,"user_info":{"name":"Test User 2"}},"channel":"presence-test-channel"}'); + $connectionTwo->assertReceived('{"event":"pusher_internal:member_added","data":{"user_id":3,"user_info":{"name":"Test User 3"}},"channel":"presence-test-channel"}'); }); it('can notify other subscribers of a presence channel when a member leaves', function () { - $connectionOne = $this->connect(); + $connectionOne = connect(); $data = ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]; - $this->subscribe('presence-test-channel', data: $data, connection: $connectionOne); - $promiseOne = $this->messagePromise($connectionOne); + subscribe('presence-test-channel', data: $data, connection: $connectionOne); - $connectionTwo = $this->connect(); + $connectionTwo = connect(); $data = ['user_id' => 2, 'user_info' => ['name' => 'Test User 2']]; - $this->subscribe('presence-test-channel', data: $data, connection: $connectionTwo); - $promiseTwo = $this->messagePromise($connectionTwo); + subscribe('presence-test-channel', data: $data, connection: $connectionTwo); - $connectionThree = $this->connect(); + $connectionThree = connect(); $data = ['user_id' => 3, 'user_info' => ['name' => 'Test User 3']]; - $this->subscribe('presence-test-channel', data: $data, connection: $connectionThree); - - expect(await($promiseOne))->toBe('{"event":"pusher_internal:member_added","data":{"user_id":2,"user_info":{"name":"Test User 2"}},"channel":"presence-test-channel"}'); - expect(await($promiseTwo))->toBe('{"event":"pusher_internal:member_added","data":{"user_id":3,"user_info":{"name":"Test User 3"}},"channel":"presence-test-channel"}'); + subscribe('presence-test-channel', data: $data, connection: $connectionThree); - $promiseThree = $this->messagePromise($connectionOne); - $promiseFour = $this->messagePromise($connectionOne); + $connectionOne->assertReceived('{"event":"pusher_internal:member_added","data":{"user_id":2,"user_info":{"name":"Test User 2"}},"channel":"presence-test-channel"}'); + $connectionTwo->assertReceived('{"event":"pusher_internal:member_added","data":{"user_id":3,"user_info":{"name":"Test User 3"}},"channel":"presence-test-channel"}'); - $connectionThree->close(); + disconnect($connectionThree); - expect(await($promiseThree))->toBe('{"event":"pusher_internal:member_removed","data":{"user_id":3},"channel":"presence-test-channel"}'); - expect(await($promiseFour))->toBe('{"event":"pusher_internal:member_removed","data":{"user_id":3},"channel":"presence-test-channel"}'); + $connectionOne->assertReceived('{"event":"pusher_internal:member_removed","data":{"user_id":3},"channel":"presence-test-channel"}'); + $connectionTwo->assertReceived('{"event":"pusher_internal:member_removed","data":{"user_id":3},"channel":"presence-test-channel"}'); }); it('can receive a cached message when joining a cache channel', function () { - $connection = $this->connect(); + $connection = connect(); $this->triggerEvent( 'cache-test-channel', @@ -116,14 +107,13 @@ ['foo' => 'bar'] ); - $this->subscribe('cache-test-channel', connection: $connection); - $promise = $this->messagePromise($connection); + subscribe('cache-test-channel', connection: $connection); - expect(await($promise))->toBe('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"cache-test-channel"}'); + $connection->assertReceived('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"cache-test-channel"}'); }); it('can receive a cached message when joining a private cache channel', function () { - $connection = $this->connect(); + $connection = connect(); $this->triggerEvent( 'private-cache-test-channel', @@ -131,14 +121,13 @@ ['foo' => 'bar'] ); - $this->subscribe('private-cache-test-channel', connection: $connection); - $promise = $this->messagePromise($connection); + subscribe('private-cache-test-channel', connection: $connection); - expect(await($promise))->toBe('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"private-cache-test-channel"}'); + $connection->assertReceived('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"private-cache-test-channel"}'); }); it('can receive a cached message when joining a presence cache channel', function () { - $connection = $this->connect(); + $connection = connect(); $this->triggerEvent( 'presence-cache-test-channel', @@ -146,48 +135,41 @@ ['foo' => 'bar'] ); - $this->subscribe('presence-cache-test-channel', connection: $connection); - $promise = $this->messagePromise($connection); + subscribe('presence-cache-test-channel', connection: $connection); - expect(await($promise))->toBe('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"presence-cache-test-channel"}'); + $connection->assertReceived('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"presence-cache-test-channel"}'); }); it('can receive a cach missed message when joining a cache channel with an empty cache', function () { - $connection = $this->connect(); - $this->subscribe('cache-test-channel', connection: $connection); - $promise = $this->messagePromise($connection); + $connection = connect(); + subscribe('cache-test-channel', connection: $connection); - expect(await($promise))->toBe('{"event":"pusher:cache_miss","channel":"cache-test-channel"}'); + $connection->assertReceived('{"event":"pusher:cache_miss","channel":"cache-test-channel"}'); }); it('can receive a cach missed message when joining a private cache channel with an empty cache', function () { - $connection = $this->connect(); - $this->subscribe('private-cache-test-channel', connection: $connection); - $promise = $this->messagePromise($connection); + $connection = connect(); + subscribe('private-cache-test-channel', connection: $connection); - expect(await($promise))->toBe('{"event":"pusher:cache_miss","channel":"private-cache-test-channel"}'); + $connection->assertReceived('{"event":"pusher:cache_miss","channel":"private-cache-test-channel"}'); }); it('can receive a cach missed message when joining a presence cache channel with an empty cache', function () { - $connection = $this->connect(); - $this->subscribe('presence-cache-test-channel', connection: $connection); - $promise = $this->messagePromise($connection); + $connection = connect(); + subscribe('presence-cache-test-channel', connection: $connection); - expect(await($promise))->toBe('{"event":"pusher:cache_miss","channel":"presence-cache-test-channel"}'); + $connection->assertReceived('{"event":"pusher:cache_miss","channel":"presence-cache-test-channel"}'); }); it('can receive a message broadcast from the server', function () { - $connectionOne = $this->connect(); - $this->subscribe('test-channel', connection: $connectionOne); - $promiseOne = $this->messagePromise($connectionOne); + $connectionOne = connect(); + subscribe('test-channel', connection: $connectionOne); - $connectionTwo = $this->connect(); - $this->subscribe('test-channel', connection: $connectionTwo); - $promiseTwo = $this->messagePromise($connectionTwo); + $connectionTwo = connect(); + subscribe('test-channel', connection: $connectionTwo); - $connectionThree = $this->connect(); - $this->subscribe('test-channel', connection: $connectionThree); - $promiseThree = $this->messagePromise($connectionThree); + $connectionThree = connect(); + subscribe('test-channel', connection: $connectionThree); $this->triggerEvent( 'test-channel', @@ -195,15 +177,14 @@ ['foo' => 'bar'] ); - foreach (await(all([$promiseOne, $promiseTwo, $promiseThree])) as $response) { - expect($response)->toBe('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"test-channel"}'); - } + $connectionOne->assertReceived('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"test-channel"}'); + $connectionTwo->assertReceived('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"test-channel"}'); + $connectionThree->assertReceived('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"test-channel"}'); }); it('can handle an event', function () { $connection = connect(); subscribe('presence-test-channel', connection: $connection, data: ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]); - $promise = $this->messagePromise($connection); $this->triggerEvent( 'presence-test-channel', @@ -211,63 +192,52 @@ ['foo' => 'bar'] ); - expect(await($promise))->toBe('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"presence-test-channel"}'); + $connection->assertReceived('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"presence-test-channel"}'); }); it('can respond to a ping', function () { - $connection = $this->connect(); - $promise = $this->messagePromise($connection); + $connection = connect(); - $this->send(['event' => 'pusher:ping'], $connection); + send(['event' => 'pusher:ping'], $connection); - expect(await($promise))->toBe('{"event":"pusher:pong"}'); + $connection->assertReceived('{"event":"pusher:pong"}'); }); it('it can ping inactive subscribers', function () { - $connection = $this->connect(); - $this->subscribe('test-channel', connection: $connection); - $promise = $this->messagePromise($connection); + $connection = connect(); + subscribe('test-channel', connection: $connection); - Arr::first(channelManager()->connections())->setLastSeenAt(time() - 60 * 10); + Arr::first(channels()->connections())->setLastSeenAt(time() - 60 * 10); - (new PingInactiveConnections)->handle(channelManager()); + (new PingInactiveConnections)->handle(channels()); - expect(await($promise))->toBe('{"event":"pusher:ping"}'); + $connection->assertReceived('{"event":"pusher:ping"}'); }); it('it can disconnect inactive subscribers', function () { - $connection = $this->connect(); - $this->subscribe('test-channel', connection: $connection); - $promise = $this->disconnectPromise($connection); + $connection = connect(); + subscribe('test-channel', connection: $connection); - expect(channelManager()->find('test-channel')->connections())->toHaveCount(1); + expect(channels()->find('test-channel')->connections())->toHaveCount(1); - Arr::first(channelManager()->connections())->setLastSeenAt(time() - 60 * 10); + Arr::first(channels()->connections())->setLastSeenAt(time() - 60 * 10); - $promiseTwo = $this->messagePromise($connection); - (new PingInactiveConnections)->handle( - channelManager() - ); - expect(await($promiseTwo))->toBe('{"event":"pusher:ping"}'); + (new PingInactiveConnections)->handle(channels()); - $promiseThree = $this->messagePromise($connection); - (new PruneStaleConnections)->handle( - channelManager() - ); + (new PruneStaleConnections)->handle(channels()); - expect(channelManager()->find('test-channel')->connections())->toHaveCount(0); + expect(channels()->find('test-channel')->connections())->toHaveCount(0); - expect(await($promiseThree))->toBe('{"event":"pusher:error","data":"{\"code\":4201,\"message\":\"Pong reply not received in time\"}"}'); - expect(await($promise))->toBe('Connection Closed.'); + $connection->assertReceived('{"event":"pusher:ping"}'); + $connection->assertReceived('{"event":"pusher:error","data":"{\"code\":4201,\"message\":\"Pong reply not received in time\"}"}'); }); it('can handle a client whisper', function () { - $connection = $this->connect(); - $this->subscribe('test-channel', connection: $connection); + $connection = connect(); + subscribe('test-channel', connection: $connection); - $newConnection = $this->connect(); - $this->subscribe('test-channel', connection: $newConnection); - $promise = $this->messagePromise($newConnection); + $newConnection = connect(); + subscribe('test-channel', connection: $newConnection); $connection->send( json_encode([ @@ -280,62 +250,62 @@ ]) ); - expect(await($promise))->toBe('{"event":"client-start-typing","channel":"test-channel","data":{"id":123,"name":"Joe Dixon"}}'); + $newConnection->assertReceived('{"event":"client-start-typing","channel":"test-channel","data":{"id":123,"name":"Joe Dixon"}}'); }); it('can subscribe a connection to multiple channels', function () { - $connection = $this->connect(); - $this->subscribe('test-channel', connection: $connection); - $this->subscribe('test-channel-2', connection: $connection); - $this->subscribe('private-test-channel-3', connection: $connection, data: ['foo' => 'bar']); - $this->subscribe('presence-test-channel-4', connection: $connection, data: ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]); - - expect(channelManager()->all())->toHaveCount(4); - collect(channelManager()->all())->each(function ($channel) use ($connection) { + $connection = connect(); + subscribe('test-channel', connection: $connection); + subscribe('test-channel-2', connection: $connection); + subscribe('private-test-channel-3', connection: $connection, data: ['foo' => 'bar']); + subscribe('presence-test-channel-4', connection: $connection, data: ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]); + + expect(channels()->all())->toHaveCount(4); + collect(channels()->all())->each(function ($channel) use ($connection) { expect($channel->connections())->toHaveCount(1); - expect(collect($channel->connections())->map(fn ($connection) => $connection->id()))->toContain($this->connectionId); + expect(collect($channel->connections())->map(fn ($conn) => $conn->id()))->toContain($connection->socketId()); }); }); it('can subscribe multiple connections to multiple channels', function () { - $connection = $this->connect(); - $this->subscribe('test-channel', connection: $connection); - $this->subscribe('test-channel-2', connection: $connection); - $this->subscribe('private-test-channel-3', connection: $connection, data: ['foo' => 'bar']); - $this->subscribe('presence-test-channel-4', connection: $connection, data: ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]); + $connection = connect(); + subscribe('test-channel', connection: $connection); + subscribe('test-channel-2', connection: $connection); + subscribe('private-test-channel-3', connection: $connection, data: ['foo' => 'bar']); + subscribe('presence-test-channel-4', connection: $connection, data: ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]); - $connection = $this->connect(); - $this->subscribe('test-channel', connection: $connection); - $this->subscribe('private-test-channel-3', connection: $connection, data: ['foo' => 'bar']); + $connection = connect(); + subscribe('test-channel', connection: $connection); + subscribe('private-test-channel-3', connection: $connection, data: ['foo' => 'bar']); - expect(channelManager()->all())->toHaveCount(4); + expect(channels()->all())->toHaveCount(4); - expect(channelManager()->find('test-channel')->connections())->toHaveCount(2); - expect(channelManager()->find('test-channel-2')->connections())->toHaveCount(1); - expect(channelManager()->find('private-test-channel-3')->connections())->toHaveCount(2); - expect(channelManager()->find('presence-test-channel-4')->connections())->toHaveCount(1); + expect(channels()->find('test-channel')->connections())->toHaveCount(2); + expect(channels()->find('test-channel-2')->connections())->toHaveCount(1); + expect(channels()->find('private-test-channel-3')->connections())->toHaveCount(2); + expect(channels()->find('presence-test-channel-4')->connections())->toHaveCount(1); }); it('fails to subscribe to a private channel with invalid auth signature', function () { - $response = $this->subscribe('private-test-channel', auth: 'invalid-signature'); + $response = subscribe('private-test-channel', auth: 'invalid-signature'); expect($response)->toBe('{"event":"pusher:error","data":"{\"code\":4009,\"message\":\"Connection is unauthorized\"}"}'); }); it('fails to subscribe to a presence channel with invalid auth signature', function () { - $response = $this->subscribe('presence-test-channel', auth: 'invalid-signature'); + $response = subscribe('presence-test-channel', auth: 'invalid-signature'); expect($response)->toBe('{"event":"pusher:error","data":"{\"code\":4009,\"message\":\"Connection is unauthorized\"}"}'); }); it('fails to subscribe to a private cache channel with invalid auth signature', function () { - $response = $this->subscribe('private-cache-test-channel', auth: 'invalid-signature'); + $response = subscribe('private-cache-test-channel', auth: 'invalid-signature'); expect($response)->toBe('{"event":"pusher:error","data":"{\"code\":4009,\"message\":\"Connection is unauthorized\"}"}'); }); it('fails to subscribe to a presence cache channel with invalid auth signature', function () { - $response = $this->subscribe('presence-cache-test-channel', auth: 'invalid-signature'); + $response = subscribe('presence-cache-test-channel', auth: 'invalid-signature'); expect($response)->toBe('{"event":"pusher:error","data":"{\"code\":4009,\"message\":\"Connection is unauthorized\"}"}'); }); @@ -344,7 +314,7 @@ $promise = new Deferred(); $connection = await( - connect('ws://0.0.0.0:8080/app/invalid-key') + wsConnect('ws://0.0.0.0:8080/app/invalid-key') ); $connection->on('message', function ($message) use ($promise) { @@ -362,9 +332,8 @@ it('can publish and subscribe to a triggered event', function () { $this->usingRedis(); - $connection = $this->connect(); - $this->subscribe('presence-test-channel', connection: $connection, data: ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]); - $promise = $this->messagePromise($connection); + $connection = connect(); + subscribe('presence-test-channel', connection: $connection, data: ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]); $this->triggerEvent( 'presence-test-channel', @@ -372,18 +341,17 @@ ['foo' => 'bar'] ); - expect(await($promise))->toBe('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"presence-test-channel"}'); + $connection->assertReceived('{"event":"App\\\\Events\\\\TestEvent","data":{"foo":"bar"},"channel":"presence-test-channel"}'); }); it('can publish and subscribe to a client whisper', function () { $this->usingRedis(); - $connection = $this->connect(); - $this->subscribe('test-channel', connection: $connection); + $connection = connect(); + subscribe('test-channel', connection: $connection); - $newConnection = $this->connect(); - $this->subscribe('test-channel', connection: $newConnection); - $promise = $this->messagePromise($newConnection); + $newConnection = connect(); + subscribe('test-channel', connection: $newConnection); $connection->send( json_encode([ @@ -396,44 +364,53 @@ ]) ); - expect(await($promise))->toBe('{"event":"client-start-typing","channel":"test-channel","data":{"id":123,"name":"Joe Dixon"}}'); + $newConnection->assertReceived('{"event":"client-start-typing","channel":"test-channel","data":{"id":123,"name":"Joe Dixon"}}'); }); it('cannot connect from an invalid origin', function () { $connection = await( - connect('ws://0.0.0.0:8080/app/pusher-key-3') + wsConnect('ws://0.0.0.0:8080/app/pusher-key-3') ); - $promise = $this->messagePromise($connection); - expect(await($promise))->toBe('{"event":"pusher:error","data":"{\"code\":4009,\"message\":\"Origin not allowed\"}"}'); + $promise = new Deferred(); + + $connection->on('message', function ($message) use ($promise) { + $promise->resolve((string) $message); + }); + + $message = await($promise->promise()); + + expect($message)->toBe('{"event":"pusher:error","data":"{\"code\":4009,\"message\":\"Origin not allowed\"}"}'); }); it('can connect from a valid origin', function () { $this->app['config']->set('reverb.apps.0.allowed_origins', ['0.0.0.0']); - $this->connect(); + connect(); }); it('limits the size of messages', function () { - $connection = $this->connect(key: 'pusher-key-3', headers: ['Origin' => 'http://laravel.com']); - $message = $this->send(['This message is waaaaaay longer than the 1 byte limit'], $connection); + $connection = connect(key: 'pusher-key-3', headers: ['Origin' => 'http://laravel.com']); + send(['This message is waaaaaay longer than the 1 byte limit'], $connection); - expect($message)->toBe('Maximum message size exceeded'); + $connection->assertReceived('Maximum message size exceeded'); }); it('removes a channel when no subscribers remain', function () { - $connection = $this->connect(); - $this->subscribe('test-channel', connection: $connection); + $connection = connect(); + subscribe('test-channel', connection: $connection); + + expect(channels()->all())->toHaveCount(1); - expect(channelManager()->all())->toHaveCount(1); + unsubscribe('test-channel', $connection); - $this->unsubscribe('test-channel', $connection); + $connection->await(); - expect(channelManager()->all())->toHaveCount(0); + expect(channels()->all())->toHaveCount(0); }); it('clears application state between requests', function () { - $this->subscribe('test-channel'); + subscribe('test-channel'); expect($this->app->make(ChannelManager::class)->app())->toBeNull(); })->todo(); diff --git a/tests/Feature/Reverb/UsersTerminateControllerTest.php b/tests/Feature/Reverb/UsersTerminateControllerTest.php index 57165b0b..05724c97 100644 --- a/tests/Feature/Reverb/UsersTerminateControllerTest.php +++ b/tests/Feature/Reverb/UsersTerminateControllerTest.php @@ -22,6 +22,8 @@ expect(collect(channelManager()->find('presence-test-channel-one')->connections()))->toHaveCount(2); expect(collect(channelManager()->find('test-channel-two')->connections()))->toHaveCount(2); + expect(collect(channels()->all())->get('test-channel-one')->connections())->toHaveCount(2); + expect(collect(channels()->all())->get('test-channel-two')->connections())->toHaveCount(2); $response = await($this->signedPostRequest('users/456/terminate_connections')); @@ -29,4 +31,6 @@ $this->assertSame('{}', $response->getBody()->getContents()); expect(collect(channelManager()->find('presence-test-channel-one')->connections()))->toHaveCount(1); expect(collect(channelManager()->find('test-channel-two')->connections()))->toHaveCount(1); + expect(collect(channels()->all())->get('test-channel-one')->connections())->toHaveCount(1); + expect(collect(channels()->all())->get('test-channel-two')->connections())->toHaveCount(1); }); diff --git a/tests/Helpers/Reverb.php b/tests/Helpers/Reverb.php index 34b4164b..792b47c0 100644 --- a/tests/Helpers/Reverb.php +++ b/tests/Helpers/Reverb.php @@ -1,17 +1,19 @@ on('message', function ($message) use ($promise) { $promise->resolve((string) $message); }); @@ -27,41 +31,33 @@ function connect(string $host = '0.0.0.0', string $port = '8080', string $key = expect($message)->toContain('connection_established'); + $connection->socketId = json_decode(json_decode($message)->data)->socket_id; + return $connection; } /** * Send a message to the connected client. */ -function send(array $message, WebSocket $connection = null): string +function send(array $message, ?TestConnection $connection = null) { - $promise = new Deferred; - $connection = $connection ?: connect(); - $connection->on('message', function ($message) use ($promise) { - $promise->resolve((string) $message); - }); - - $connection->on('close', function ($code, $message) use ($promise) { - $promise->resolve((string) $message); - }); - $connection->send(json_encode($message)); - return await($promise->promise()); + return $connection->await(); } /** * Subscribe to a channel. */ -function subscribe(string $channel, ?array $data = [], string $auth = null, WebSocket $connection = null): string +function subscribe(string $channel, ?array $data = [], ?string $auth = null, ?TestConnection $connection = null): string { $data = ! empty($data) ? json_encode($data) : null; if (! $auth && Str::startsWith($channel, ['private-', 'presence-'])) { $connection = $connection ?: connect(); - $auth = validAuth(socketId($connection), $channel, $data); + $auth = validAuth($connection->socketId(), $channel, $data); } return send([ @@ -74,10 +70,21 @@ function subscribe(string $channel, ?array $data = [], string $auth = null, WebS ], $connection); } +/** + * Unsubscribe to a channel. + */ +function unsubscribe(string $channel, ?TestConnection $connection = null): ?string +{ + return send([ + 'event' => 'pusher:unsubscribe', + 'data' => ['channel' => $channel], + ], $connection); +} + /** * Disconnect the connected client. */ -function disconnect(WebSocket $connection): string +function disconnect(TestConnection $connection): string { $promise = new Deferred; @@ -90,9 +97,18 @@ function disconnect(WebSocket $connection): string return await($promise->promise()); } -function socketId(WebSocket $connection) +/** + * Return a promise when a given connection is disconnected. + * + * @param \Ratchet\Client\WebSocketWebSocket $connection + */ +function disconnectPromise(WebSocket $connection): PromiseInterface { - $connections = channelManager()->connections(); + $promise = new Deferred; + + $connection->on('close', function ($message) use ($promise) { + $promise->resolve('Connection Closed.'); + }); - // dd($connections); + return $promise->promise(); } diff --git a/tests/Pest.php b/tests/Pest.php index 6286cd4e..3dc0bbcd 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -49,7 +49,7 @@ function validAuth(string $connectionId, string $channel, ?string $data = null): /** * Return the channel manager. */ -function channelManager(?Application $app = null): ChannelManager +function channels(?Application $app = null): ChannelManager { return app(ChannelManager::class) ->for($app ?: app(ApplicationProvider::class)->all()->first()); diff --git a/tests/ReverbTestCase.php b/tests/ReverbTestCase.php index 580333cf..01505073 100644 --- a/tests/ReverbTestCase.php +++ b/tests/ReverbTestCase.php @@ -126,117 +126,6 @@ public function stopServer() } } - /** - * Send a message to the connected client. - */ - public function send(array $message, ?WebSocket $connection = null): ?string - { - $promise = new Deferred; - - $connection = $connection ?: $this->connect(); - - $connection->on('message', function ($message) use ($promise) { - $promise->resolve((string) $message); - }); - - $connection->on('close', function ($code, $message) use ($promise) { - $promise->resolve((string) $message); - }); - - $connection->send(json_encode($message)); - - return await(timeout($promise->promise(), 2, $this->loop) - ->then( - fn ($message) => $message, - fn (TimeoutException $error) => null - )); - } - - /** - * Disconnect the connected client. - */ - public function disconnect(WebSocket $connection): string - { - $promise = new Deferred; - - $connection->on('close', function () use ($promise) { - $promise->resolve('Connection Closed.'); - }); - - $connection->close(); - - return await($promise->promise()); - } - - /** - * Subscribe to a channel. - */ - public function subscribe(string $channel, ?array $data = [], ?string $auth = null, ?WebSocket $connection = null): string - { - $data = ! empty($data) ? json_encode($data) : null; - - if (! $auth && Str::startsWith($channel, ['private-', 'presence-'])) { - $connection = $connection ?: $this->connect(); - $auth = validAuth($this->connectionId, $channel, $data); - } - - return $this->send([ - 'event' => 'pusher:subscribe', - 'data' => array_filter([ - 'channel' => $channel, - 'channel_data' => $data, - 'auth' => $auth, - ]), - ], $connection); - } - - /** - * Unsubscribe to a channel. - */ - public function unsubscribe(string $channel, ?WebSocket $connection = null): ?string - { - return $this->send([ - 'event' => 'pusher:unsubscribe', - 'data' => ['channel' => $channel], - ], $connection); - } - - /** - * Return a promise for the next message received to the given connection. - * - * @param \Ratchet\Client\WebSocketWebSocket $connection - */ - public function messagePromise(WebSocket $connection) - { - $promise = new Deferred; - - $connection->on('message', function ($message) use ($promise) { - $promise->resolve((string) $message); - }); - - return timeout($promise->promise(), 2, $this->loop) - ->then( - fn ($message) => $message, - fn (TimeoutException $error) => false - ); - } - - /** - * Return a promise when a given connection is disconnected. - * - * @param \Ratchet\Client\WebSocketWebSocket $connection - */ - public function disconnectPromise(WebSocket $connection): PromiseInterface - { - $promise = new Deferred; - - $connection->on('close', function ($message) use ($promise) { - $promise->resolve('Connection Closed.'); - }); - - return $promise->promise(); - } - /** * Send an event to the server. */ diff --git a/tests/TestConnection.php b/tests/TestConnection.php new file mode 100644 index 00000000..6d6cb7c0 --- /dev/null +++ b/tests/TestConnection.php @@ -0,0 +1,68 @@ +on('message', function ($message) { + $this->receivedMessages[] = (string) $message; + }); + + $connection->on('close', function ($code, $message) { + $this->receivedMessages[] = (string) $message; + }); + } + + public function socketId(): string + { + return $this->socketId; + } + + public function __call($method, $arguments) + { + return $this->connection->{$method}(...$arguments); + } + + public function await() + { + $promise = new Deferred(); + + $this->connection->on('message', function ($message) use ($promise) { + $promise->resolve((string) $message); + }); + + $this->connection->on('close', function ($code, $message) use ($promise) { + $promise->resolve((string) $message); + }); + + return await( + timeout($promise->promise(), 2) + ->then( + fn ($message) => $message, + fn (TimeoutException $error) => false + ) + ); + } + + public function assertReceived(string $message) + { + if (! in_array($message, $this->receivedMessages)) { + $this->await(); + } + + return expect($this->receivedMessages)->toContain($message); + } +} From 10d820d7c623edd7947a5f83a60af123262addff Mon Sep 17 00:00:00 2001 From: Joe Dixon Date: Wed, 6 Dec 2023 13:14:15 +0000 Subject: [PATCH 04/10] wip --- .../Feature/Reverb/ChannelControllerTest.php | 33 ++++++++++++++----- .../Feature/Reverb/ChannelsControllerTest.php | 18 ++++++---- .../Reverb/UsersTerminateControllerTest.php | 11 +++++++ 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/tests/Feature/Reverb/ChannelControllerTest.php b/tests/Feature/Reverb/ChannelControllerTest.php index 7f230bb1..8d14b22a 100644 --- a/tests/Feature/Reverb/ChannelControllerTest.php +++ b/tests/Feature/Reverb/ChannelControllerTest.php @@ -7,13 +7,13 @@ uses(ReverbTestCase::class); it('can return data for a single channel', function () { - $this->subscribe('test-channel-one'); - $this->subscribe('test-channel-one'); + subscribe('test-channel-one'); + subscribe('test-channel-one'); $response = await($this->signedRequest('channels/test-channel-one?info=user_count,subscription_count,cache')); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('{"occupied":true,"subscription_count":2}', $response->getBody()->getContents()); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{"occupied":true,"subscription_count":2}'); }); it('returns unoccupied when no connections', function () { @@ -24,10 +24,27 @@ }); it('can return cache channel attributes', function () { - $this->subscribe('cache-test-channel-one'); - channelManager()->find('cache-test-channel-one')->broadcast(['some' => 'data']); + subscribe('cache-test-channel-one'); + channels()->find('cache-test-channel-one')->broadcast(['some' => 'data']); $response = await($this->signedRequest('channels/cache-test-channel-one?info=subscription_count,cache')); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('{"occupied":true,"subscription_count":1,"cache":{"some":"data"}}', $response->getBody()->getContents()); + + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{"occupied":true,"subscription_count":1,"cache":{"some":"data"}}'); +}); + +it('can return only the requested attributes', function () { + subscribe('test-channel-one'); + + $response = await($this->signedRequest('channels/test-channel-one?info=user_count,subscription_count,cache')); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{"occupied":true,"subscription_count":1}'); + + $response = await($this->signedRequest('channels/test-channel-one?info=cache')); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{"occupied":true}'); + + $response = await($this->signedRequest('channels/test-channel-one?info=subscription_count,user_count')); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{"occupied":true,"subscription_count":1}'); }); diff --git a/tests/Feature/Reverb/ChannelsControllerTest.php b/tests/Feature/Reverb/ChannelsControllerTest.php index c11ee27c..2195e1fb 100644 --- a/tests/Feature/Reverb/ChannelsControllerTest.php +++ b/tests/Feature/Reverb/ChannelsControllerTest.php @@ -8,8 +8,8 @@ uses(ReverbTestCase::class); it('can return all channel information', function () { - $this->subscribe('test-channel-one'); - $this->subscribe('presence-test-channel-two'); + subscribe('test-channel-one'); + subscribe('presence-test-channel-two'); $response = await($this->signedRequest('channels?info=user_count')); @@ -20,16 +20,18 @@ it('can return filtered channels', function () { $this->subscribe('test-channel-one'); $this->subscribe('presence-test-channel-two'); + subscribe('test-channel-one'); + subscribe('test-channel-two'); - $response = await($this->signedRequest('channels?filter_by_prefix=presence-test-channel-t&info=user_count')); + $response = await($this->signedRequest('channels?info=user_count')); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('{"channels":{"presence-test-channel-two":{"user_count":1}}}', $response->getBody()->getContents()); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{"channels":{"test-channel-one":{"user_count":1},"test-channel-two":{"user_count":1}}}'); }); it('returns empty results if no metrics requested', function () { - $this->subscribe('test-channel-one'); - $this->subscribe('test-channel-two'); + subscribe('test-channel-one'); + subscribe('test-channel-two'); $response = await($this->signedRequest('channels')); @@ -49,4 +51,6 @@ $this->assertSame(200, $response->getStatusCode()); $this->assertSame('{"channels":{"test-channel-two":{}}}', $response->getBody()->getContents()); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{"channels":{"test-channel-one":[],"test-channel-two":[]}}'); }); diff --git a/tests/Feature/Reverb/UsersTerminateControllerTest.php b/tests/Feature/Reverb/UsersTerminateControllerTest.php index 05724c97..30ee36a5 100644 --- a/tests/Feature/Reverb/UsersTerminateControllerTest.php +++ b/tests/Feature/Reverb/UsersTerminateControllerTest.php @@ -19,6 +19,13 @@ $connection = $this->connect(); $this->subscribe('presence-test-channel-one', ['user_id' => '456'], connection: $connection); $this->subscribe('test-channel-two', connection: $connection); + $connection = connect(); + subscribe('test-channel-one', connection: $connection); + subscribe('test-channel-two', connection: $connection); + + $connection = connect(); + subscribe('test-channel-one', connection: $connection); + subscribe('test-channel-two', connection: $connection); expect(collect(channelManager()->find('presence-test-channel-one')->connections()))->toHaveCount(2); expect(collect(channelManager()->find('test-channel-two')->connections()))->toHaveCount(2); @@ -31,6 +38,10 @@ $this->assertSame('{}', $response->getBody()->getContents()); expect(collect(channelManager()->find('presence-test-channel-one')->connections()))->toHaveCount(1); expect(collect(channelManager()->find('test-channel-two')->connections()))->toHaveCount(1); + $response = await($this->signedPostRequest("users/{$connection->socketId()}/terminate_connections")); + + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{}'); expect(collect(channels()->all())->get('test-channel-one')->connections())->toHaveCount(1); expect(collect(channels()->all())->get('test-channel-two')->connections())->toHaveCount(1); }); From 6d408b6fa8a6191032243d1c990c6588c115bfa2 Mon Sep 17 00:00:00 2001 From: joedixon Date: Wed, 6 Dec 2023 13:14:46 +0000 Subject: [PATCH 05/10] Fix code styling --- tests/Feature/ApiGateway/ServerTest.php | 1 - tests/Helpers/ApiGateway.php | 2 +- tests/Helpers/Reverb.php | 2 -- tests/Pest.php | 1 - tests/ReverbTestCase.php | 7 +------ 5 files changed, 2 insertions(+), 11 deletions(-) diff --git a/tests/Feature/ApiGateway/ServerTest.php b/tests/Feature/ApiGateway/ServerTest.php index f47b2837..4a73d8cc 100644 --- a/tests/Feature/ApiGateway/ServerTest.php +++ b/tests/Feature/ApiGateway/ServerTest.php @@ -3,7 +3,6 @@ use Illuminate\Support\Arr; use Illuminate\Support\Facades\Bus; use Laravel\Reverb\Contracts\ChannelManager; -use Laravel\Reverb\Contracts\ConnectionManager; use Laravel\Reverb\Jobs\PingInactiveConnections; use Laravel\Reverb\Jobs\PruneStaleConnections; use Laravel\Reverb\Servers\ApiGateway\Request; diff --git a/tests/Helpers/ApiGateway.php b/tests/Helpers/ApiGateway.php index 3fe1c178..f93968cd 100644 --- a/tests/Helpers/ApiGateway.php +++ b/tests/Helpers/ApiGateway.php @@ -8,4 +8,4 @@ function connections(): ConnectionManager { return app(ConnectionManager::class); -} \ No newline at end of file +} diff --git a/tests/Helpers/Reverb.php b/tests/Helpers/Reverb.php index 792b47c0..6592616e 100644 --- a/tests/Helpers/Reverb.php +++ b/tests/Helpers/Reverb.php @@ -4,11 +4,9 @@ use Laravel\Reverb\Tests\TestConnection; use Ratchet\Client\WebSocket; use React\Promise\Deferred; -use React\Promise\Timer\TimeoutException; use function Ratchet\Client\connect as connector; use function React\Async\await; -use function React\Promise\Timer\timeout; /** * Connect to the WebSocket server. diff --git a/tests/Pest.php b/tests/Pest.php index 3dc0bbcd..0d58b29d 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -4,7 +4,6 @@ use Laravel\Reverb\Application; use Laravel\Reverb\Contracts\ApplicationProvider; use Laravel\Reverb\Contracts\ChannelManager; -use Laravel\Reverb\Contracts\ConnectionManager; use Laravel\Reverb\Managers\Connections; use Laravel\Reverb\Servers\Reverb\ChannelConnection; use Laravel\Reverb\Tests\FakeConnection; diff --git a/tests/ReverbTestCase.php b/tests/ReverbTestCase.php index 01505073..a34a5895 100644 --- a/tests/ReverbTestCase.php +++ b/tests/ReverbTestCase.php @@ -2,10 +2,9 @@ namespace Laravel\Reverb\Tests; -use Clue\React\Redis\Client; use Illuminate\Support\Str; use Laravel\Reverb\Concerns\InteractsWithAsyncRedis; -use Laravel\Reverb\Contracts\Connection; +use Laravel\Reverb\Contracts\Logger; use Laravel\Reverb\Event; use Laravel\Reverb\ServerManager; use Laravel\Reverb\Servers\Reverb\Factory; @@ -13,14 +12,10 @@ use React\Async\SimpleFiber; use React\EventLoop\Loop; use React\Http\Browser; -use React\Promise\Deferred; use React\Promise\PromiseInterface; -use React\Promise\Timer\TimeoutException; use ReflectionObject; -use function Ratchet\Client\connect; use function React\Async\await; -use function React\Promise\Timer\timeout; class ReverbTestCase extends TestCase { From 8fa629071810e6ef2e027607460dff25310f6de6 Mon Sep 17 00:00:00 2001 From: Joe Dixon Date: Wed, 6 Dec 2023 13:25:16 +0000 Subject: [PATCH 06/10] fix tests --- .../Reverb/UsersTerminateControllerTest.php | 25 ++++--------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/tests/Feature/Reverb/UsersTerminateControllerTest.php b/tests/Feature/Reverb/UsersTerminateControllerTest.php index 30ee36a5..ce934a00 100644 --- a/tests/Feature/Reverb/UsersTerminateControllerTest.php +++ b/tests/Feature/Reverb/UsersTerminateControllerTest.php @@ -12,36 +12,21 @@ })->throws(ResponseException::class); it('unsubscribes from all channels and terminates a user', function () { - $connection = $this->connect(); - $this->subscribe('presence-test-channel-one', ['user_id' => '123'], connection: $connection); - $this->subscribe('test-channel-two', connection: $connection); - - $connection = $this->connect(); - $this->subscribe('presence-test-channel-one', ['user_id' => '456'], connection: $connection); - $this->subscribe('test-channel-two', connection: $connection); $connection = connect(); - subscribe('test-channel-one', connection: $connection); + subscribe('presence-test-channel-one', ['user_id' => '123'], connection: $connection); subscribe('test-channel-two', connection: $connection); $connection = connect(); - subscribe('test-channel-one', connection: $connection); + subscribe('presence-test-channel-one', ['user_id' => '456'], connection: $connection); subscribe('test-channel-two', connection: $connection); - expect(collect(channelManager()->find('presence-test-channel-one')->connections()))->toHaveCount(2); - expect(collect(channelManager()->find('test-channel-two')->connections()))->toHaveCount(2); - expect(collect(channels()->all())->get('test-channel-one')->connections())->toHaveCount(2); - expect(collect(channels()->all())->get('test-channel-two')->connections())->toHaveCount(2); + expect(collect(channels()->find('presence-test-channel-one')->connections()))->toHaveCount(2); + expect(collect(channels()->find('test-channel-two')->connections()))->toHaveCount(2); $response = await($this->signedPostRequest('users/456/terminate_connections')); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('{}', $response->getBody()->getContents()); - expect(collect(channelManager()->find('presence-test-channel-one')->connections()))->toHaveCount(1); - expect(collect(channelManager()->find('test-channel-two')->connections()))->toHaveCount(1); - $response = await($this->signedPostRequest("users/{$connection->socketId()}/terminate_connections")); - expect($response->getStatusCode())->toBe(200); expect($response->getBody()->getContents())->toBe('{}'); - expect(collect(channels()->all())->get('test-channel-one')->connections())->toHaveCount(1); + expect(collect(channels()->all())->get('presence-test-channel-one')->connections())->toHaveCount(1); expect(collect(channels()->all())->get('test-channel-two')->connections())->toHaveCount(1); }); From d0e026fac09f6069d8b01ecaf5e88539c1fa640a Mon Sep 17 00:00:00 2001 From: Joe Dixon Date: Wed, 6 Dec 2023 13:37:16 +0000 Subject: [PATCH 07/10] wip --- tests/Feature/Reverb/EventsControllerTest.php | 35 +++++++++---------- tests/TestConnection.php | 10 ++++-- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/tests/Feature/Reverb/EventsControllerTest.php b/tests/Feature/Reverb/EventsControllerTest.php index f59fed45..947cc681 100644 --- a/tests/Feature/Reverb/EventsControllerTest.php +++ b/tests/Feature/Reverb/EventsControllerTest.php @@ -14,8 +14,8 @@ 'data' => ['some' => 'data'], ])); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('{}', $response->getBody()->getContents()); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{}'); }); it('can receive and event trigger for multiple channels', function () { @@ -25,12 +25,12 @@ 'data' => ['some' => 'data'], ])); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('{}', $response->getBody()->getContents()); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{}'); }); it('can return user counts when requested', function () { - $this->subscribe('presence-test-channel-one'); + subscribe('presence-test-channel-one'); $response = await($this->signedPostRequest('events', [ 'name' => 'NewEvent', @@ -39,12 +39,12 @@ 'info' => 'user_count', ])); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('{"channels":{"presence-test-channel-one":{"user_count":1},"test-channel-two":{}}}', $response->getBody()->getContents()); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{"channels":{"presence-test-channel-one":{"user_count":1},"test-channel-two":{}}}'); }); it('can return subscription counts when requested', function () { - $this->subscribe('test-channel-two'); + subscribe('test-channel-two'); $response = await($this->signedPostRequest('events', [ 'name' => 'NewEvent', @@ -53,32 +53,29 @@ 'info' => 'subscription_count', ])); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('{"channels":{"presence-test-channel-one":{},"test-channel-two":{"subscription_count":1}}}', $response->getBody()->getContents()); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{"channels":{"presence-test-channel-one":{},"test-channel-two":{"subscription_count":1}}}'); }); it('can ignore a subscriber', function () { - $connection = $this->connect(); - $this->subscribe('test-channel-two', connection: $connection); - $promiseOne = $this->messagePromise($connection); + $connection = connect(); + subscribe('test-channel-two', connection: $connection); $response = await($this->signedPostRequest('events', [ 'name' => 'NewEvent', 'channels' => ['test-channel-one', 'test-channel-two'], 'data' => ['some' => 'data'], ])); - expect(await($promiseOne))->toBe('{"event":"NewEvent","data":{"some":"data"},"channel":"test-channel-two"}'); - $promiseTwo = $this->messagePromise($connection); $response = await($this->signedPostRequest('events', [ 'name' => 'NewEvent', 'channels' => ['test-channel-one', 'test-channel-two'], 'data' => ['some' => 'data'], - 'socket_id' => $this->connectionId, + 'socket_id' => $connection->socketId(), ])); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('{}', $response->getBody()->getContents()); - expect(await($promiseTwo))->toBeFalse(); + $connection->assertReceived('{"event":"NewEvent","data":{"some":"data"},"channel":"test-channel-two"}', 1); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{}'); }); it('validates invalid data', function ($payload) { diff --git a/tests/TestConnection.php b/tests/TestConnection.php index 6d6cb7c0..5677cbcd 100644 --- a/tests/TestConnection.php +++ b/tests/TestConnection.php @@ -57,12 +57,18 @@ public function await() ); } - public function assertReceived(string $message) + public function assertReceived(string $message, ?int $count = null) { - if (! in_array($message, $this->receivedMessages)) { + if (! in_array($message, $this->receivedMessages) || $count !== null) { $this->await(); } + if ($count) { + $matches = array_filter($this->receivedMessages, fn ($m) => $m === $message); + + expect($matches)->toHaveCount($count); + } + return expect($this->receivedMessages)->toContain($message); } } From 81dcdc810b02b60fe48ed759f7622c30fbeae189 Mon Sep 17 00:00:00 2001 From: Joe Dixon Date: Wed, 6 Dec 2023 13:41:56 +0000 Subject: [PATCH 08/10] wip --- tests/Feature/ApiGateway/ServerTest.php | 7 ------ .../Feature/Reverb/ChannelsControllerTest.php | 22 ++++++++----------- tests/Feature/Reverb/ServerTest.php | 7 ------ tests/ReverbTestCase.php | 1 - 4 files changed, 9 insertions(+), 28 deletions(-) diff --git a/tests/Feature/ApiGateway/ServerTest.php b/tests/Feature/ApiGateway/ServerTest.php index 4a73d8cc..eb26ade8 100644 --- a/tests/Feature/ApiGateway/ServerTest.php +++ b/tests/Feature/ApiGateway/ServerTest.php @@ -2,7 +2,6 @@ use Illuminate\Support\Arr; use Illuminate\Support\Facades\Bus; -use Laravel\Reverb\Contracts\ChannelManager; use Laravel\Reverb\Jobs\PingInactiveConnections; use Laravel\Reverb\Jobs\PruneStaleConnections; use Laravel\Reverb\Servers\ApiGateway\Request; @@ -300,9 +299,3 @@ $this->assertSent('abc-123', 'connection_established', 1); }); - -it('clears application state between requests', function () { - $this->subscribe('test-channel'); - - expect($this->app->make(ChannelManager::class)->app())->toBeNull(); -})->todo(); diff --git a/tests/Feature/Reverb/ChannelsControllerTest.php b/tests/Feature/Reverb/ChannelsControllerTest.php index 2195e1fb..b1a5dac5 100644 --- a/tests/Feature/Reverb/ChannelsControllerTest.php +++ b/tests/Feature/Reverb/ChannelsControllerTest.php @@ -13,20 +13,18 @@ $response = await($this->signedRequest('channels?info=user_count')); - $this->assertSame(200, $response->getStatusCode()); + expect($response->getStatusCode())->toBe(200); $this->assertSame('{"channels":{"test-channel-one":{},"presence-test-channel-two":{"user_count":1}}}', $response->getBody()->getContents()); }); it('can return filtered channels', function () { - $this->subscribe('test-channel-one'); - $this->subscribe('presence-test-channel-two'); subscribe('test-channel-one'); - subscribe('test-channel-two'); + subscribe('presence-test-channel-two'); $response = await($this->signedRequest('channels?info=user_count')); expect($response->getStatusCode())->toBe(200); - expect($response->getBody()->getContents())->toBe('{"channels":{"test-channel-one":{"user_count":1},"test-channel-two":{"user_count":1}}}'); + expect($response->getBody()->getContents())->toBe('{"channels":{"test-channel-one":{},"presence-test-channel-two":{"user_count":1}}}'); }); it('returns empty results if no metrics requested', function () { @@ -35,22 +33,20 @@ $response = await($this->signedRequest('channels')); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('{"channels":{"test-channel-one":{},"test-channel-two":{}}}', $response->getBody()->getContents()); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{"channels":{"test-channel-one":{},"test-channel-two":{}}}'); }); it('only returns occupied channels', function () { - $this->subscribe('test-channel-one'); - $this->subscribe('test-channel-two'); + subscribe('test-channel-one'); + subscribe('test-channel-two'); - $channels = channelManager(); + $channels = channels(); $connection = Arr::first($channels->connections()); $channels->unsubscribeFromAll($connection->connection()); $response = await($this->signedRequest('channels')); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('{"channels":{"test-channel-two":{}}}', $response->getBody()->getContents()); expect($response->getStatusCode())->toBe(200); - expect($response->getBody()->getContents())->toBe('{"channels":{"test-channel-one":[],"test-channel-two":[]}}'); + expect($response->getBody()->getContents())->toBe('{"channels":{"test-channel-two":{}}}'); }); diff --git a/tests/Feature/Reverb/ServerTest.php b/tests/Feature/Reverb/ServerTest.php index 09115e62..28cddb1e 100644 --- a/tests/Feature/Reverb/ServerTest.php +++ b/tests/Feature/Reverb/ServerTest.php @@ -2,7 +2,6 @@ use Illuminate\Support\Arr; use Illuminate\Support\Str; -use Laravel\Reverb\Contracts\ChannelManager; use Laravel\Reverb\Jobs\PingInactiveConnections; use Laravel\Reverb\Jobs\PruneStaleConnections; use Laravel\Reverb\Tests\ReverbTestCase; @@ -408,9 +407,3 @@ expect(channels()->all())->toHaveCount(0); }); - -it('clears application state between requests', function () { - subscribe('test-channel'); - - expect($this->app->make(ChannelManager::class)->app())->toBeNull(); -})->todo(); diff --git a/tests/ReverbTestCase.php b/tests/ReverbTestCase.php index a34a5895..9fdeb329 100644 --- a/tests/ReverbTestCase.php +++ b/tests/ReverbTestCase.php @@ -4,7 +4,6 @@ use Illuminate\Support\Str; use Laravel\Reverb\Concerns\InteractsWithAsyncRedis; -use Laravel\Reverb\Contracts\Logger; use Laravel\Reverb\Event; use Laravel\Reverb\ServerManager; use Laravel\Reverb\Servers\Reverb\Factory; From 26fe4fca4e39e7d1a683e7c38ae5cc460a8179e5 Mon Sep 17 00:00:00 2001 From: Joe Dixon Date: Wed, 6 Dec 2023 15:24:13 +0000 Subject: [PATCH 09/10] clean up --- tests/ApiGatewayTestCase.php | 21 ++----- tests/FakeConnection.php | 57 +++++++++++++++++-- .../Feature/Reverb/ChannelControllerTest.php | 4 +- .../Feature/Reverb/ChannelsControllerTest.php | 2 +- tests/Feature/Reverb/ServerTest.php | 8 +-- tests/Feature/ServerTest.php | 32 +++++------ tests/Helpers/Reverb.php | 16 ------ tests/Pest.php | 3 +- tests/ReverbTestCase.php | 48 ++++++++-------- tests/TestConnection.php | 38 ++++++++++--- tests/Unit/Channels/CacheChannelTest.php | 2 +- tests/Unit/Channels/ChannelBrokerTest.php | 12 ++++ tests/Unit/Channels/ChannelTest.php | 8 +-- .../Channels/PresenceCacheChannelTest.php | 14 ++--- tests/Unit/Channels/PresenceChannelTest.php | 12 ++-- .../Unit/Channels/PrivateCacheChannelTest.php | 4 +- tests/Unit/Channels/PrivateChannelTest.php | 2 +- tests/Unit/ClientEventTest.php | 4 +- .../Unit/Jobs/PingInactiveConnectionsTest.php | 2 +- tests/Unit/Pusher/EventTest.php | 8 +-- 20 files changed, 173 insertions(+), 124 deletions(-) diff --git a/tests/ApiGatewayTestCase.php b/tests/ApiGatewayTestCase.php index a6abb9b5..106379a4 100644 --- a/tests/ApiGatewayTestCase.php +++ b/tests/ApiGatewayTestCase.php @@ -70,11 +70,8 @@ protected function defineEnvironment($app) /** * Connect to the server. - * - * @param string $connectionId $name - * @param string $appKey */ - public function connect($connectionId = 'abc-123', $appKey = 'pusher-key'): void + public function connect(string $connectionId = 'abc-123', string $appKey = 'pusher-key'): void { resolve(Server::class) ->handle(Request::fromLambdaEvent( @@ -94,10 +91,8 @@ public function connect($connectionId = 'abc-123', $appKey = 'pusher-key'): void /** * Send a message to the connected client. - * - * @param string $appKey */ - public function send(array $message, ?string $connectionId = 'abc-123', $appKey = 'pusher-key'): void + public function send(array $message, ?string $connectionId = 'abc-123', string $appKey = 'pusher-key'): void { $this->connect($connectionId, $appKey); @@ -115,10 +110,8 @@ public function send(array $message, ?string $connectionId = 'abc-123', $appKey /** * Subscribe to a channel. - * - * @param string $appKey */ - public function subscribe(string $channel, ?array $data = [], ?string $auth = null, ?string $connectionId = 'abc-123', $appKey = 'pusher-key'): void + public function subscribe(string $channel, ?array $data = [], ?string $auth = null, ?string $connectionId = 'abc-123', string $appKey = 'pusher-key'): void { $data = ! empty($data) ? json_encode($data) : null; @@ -140,10 +133,8 @@ public function subscribe(string $channel, ?array $data = [], ?string $auth = nu /** * Disconnect a connected client. - * - * @param string $connectionId */ - public function disconnect($connectionId = 'abc-123'): void + public function disconnect(string $connectionId = 'abc-123'): void { resolve(Server::class) ->handle(Request::fromLambdaEvent( @@ -158,10 +149,8 @@ public function disconnect($connectionId = 'abc-123'): void /** * Assert a message was sent to the given connection. - * - * @return void */ - public function assertSent(?string $connectionId = null, mixed $message = null, ?int $times = null) + public function assertSent(?string $connectionId = null, mixed $message = null, ?int $times = null): void { Bus::assertDispatched(SendToConnection::class, function ($job) use ($connectionId, $message) { return ($connectionId ? $job->connectionId === $connectionId : true) diff --git a/tests/FakeConnection.php b/tests/FakeConnection.php index 3231fa38..f01903d2 100644 --- a/tests/FakeConnection.php +++ b/tests/FakeConnection.php @@ -12,10 +12,23 @@ class FakeConnection extends BaseConnection { use GeneratesPusherIdentifiers; + /** + * Messages reveived by the connection. + * + * @var array + */ public $messages = []; - public $identifier = '19c1c8e8-351b-4eb5-b6d9-6cbfc54a3446'; + /** + * Connection identifier. + */ + public string $identifier = '19c1c8e8-351b-4eb5-b6d9-6cbfc54a3446'; + /** + * Connection socket ID. + * + * @var string + */ public $id; public function __construct(?string $identifier = null) @@ -25,11 +38,17 @@ public function __construct(?string $identifier = null) } } + /** + * Get the raw socket connection identifier. + */ public function identifier(): string { return $this->identifier; } + /** + * Get the normalized socket ID. + */ public function id(): string { if (! $this->id) { @@ -39,16 +58,25 @@ public function id(): string return $this->id; } + /** + * Get the application the connection belongs to. + */ public function app(): Application { return app()->make(ApplicationProvider::class)->findByKey('pusher-key'); } + /** + * Get the origin of the connection. + */ public function origin(): string { return 'http://localhost'; } + /** + * Set the connection last seen at timestamp. + */ public function setLastSeenAt(int $time): FakeConnection { $this->lastSeenAt = $time; @@ -56,36 +84,57 @@ public function setLastSeenAt(int $time): FakeConnection return $this; } + /** + * Set the connection as pinged. + */ public function setHasBeenPinged(): void { $this->hasBeenPinged = true; } + /** + * Send a message to the connection. + */ public function send(string $message): void { $this->messages[] = $message; } + /** + * Terminate a connection. + */ public function terminate(): void { // } - public function assertSent(array $message): void + /** + * Assert the given message was received by the connection. + */ + public function assertReceived(array $message): void { Assert::assertContains(json_encode($message), $this->messages); } - public function assertSendCount(int $count): void + /** + * Assert the connection received the given message count. + */ + public function assertReceivedCount(int $count): void { Assert::assertCount($count, $this->messages); } - public function assertNothingSent(): void + /** + * Assert the connection didn't receive any messages. + */ + public function assertNothingReceived(): void { Assert::assertEmpty($this->messages); } + /** + * Assert the connection has been pinged. + */ public function assertHasBeenPinged(): void { Assert::assertTrue($this->hasBeenPinged); diff --git a/tests/Feature/Reverb/ChannelControllerTest.php b/tests/Feature/Reverb/ChannelControllerTest.php index 8d14b22a..8a26271c 100644 --- a/tests/Feature/Reverb/ChannelControllerTest.php +++ b/tests/Feature/Reverb/ChannelControllerTest.php @@ -19,8 +19,8 @@ it('returns unoccupied when no connections', function () { $response = await($this->signedRequest('channels/test-channel-one?info=user_count,subscription_count,cache')); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('{"occupied":false,"subscription_count":0}', $response->getBody()->getContents()); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{"occupied":false,"subscription_count":0}'); }); it('can return cache channel attributes', function () { diff --git a/tests/Feature/Reverb/ChannelsControllerTest.php b/tests/Feature/Reverb/ChannelsControllerTest.php index b1a5dac5..f00b2085 100644 --- a/tests/Feature/Reverb/ChannelsControllerTest.php +++ b/tests/Feature/Reverb/ChannelsControllerTest.php @@ -14,7 +14,7 @@ $response = await($this->signedRequest('channels?info=user_count')); expect($response->getStatusCode())->toBe(200); - $this->assertSame('{"channels":{"test-channel-one":{},"presence-test-channel-two":{"user_count":1}}}', $response->getBody()->getContents()); + expect($response->getBody()->getContents())->toBe('{"channels":{"test-channel-one":{},"presence-test-channel-two":{"user_count":1}}}'); }); it('can return filtered channels', function () { diff --git a/tests/Feature/Reverb/ServerTest.php b/tests/Feature/Reverb/ServerTest.php index 28cddb1e..bd706b09 100644 --- a/tests/Feature/Reverb/ServerTest.php +++ b/tests/Feature/Reverb/ServerTest.php @@ -320,12 +320,8 @@ $promise->resolve((string) $message); }); - $this->assertTrue( - Str::contains( - await($promise->promise()), - '{"event":"pusher:error","data":"{\"code\":4001,\"message\":\"Application does not exist\"}"}' - ) - ); + expect(await($promise->promise())) + ->toBe('{"event":"pusher:error","data":"{\"code\":4001,\"message\":\"Application does not exist\"}"}'); }); it('can publish and subscribe to a triggered event', function () { diff --git a/tests/Feature/ServerTest.php b/tests/Feature/ServerTest.php index 1c364aa7..542c8628 100644 --- a/tests/Feature/ServerTest.php +++ b/tests/Feature/ServerTest.php @@ -16,7 +16,7 @@ expect($connection->lastSeenAt())->not->toBeNull(); - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher:connection_established', 'data' => json_encode([ 'socket_id' => $connection->id(), @@ -49,7 +49,7 @@ ], ])); - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher:connection_established', 'data' => json_encode([ 'socket_id' => $connection->id(), @@ -57,7 +57,7 @@ ]), ]); - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher_internal:subscription_succeeded', 'channel' => 'test-channel', ]); @@ -79,7 +79,7 @@ ], ])); - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher:error', 'data' => json_encode([ 'code' => 4200, @@ -87,7 +87,7 @@ ]), ]); - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher:error', 'data' => json_encode([ 'code' => 4009, @@ -109,7 +109,7 @@ expect($connection->lastSeenAt())->not->toBeNull(); - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher_internal:subscription_succeeded', 'channel' => 'test-channel', ]); @@ -126,7 +126,7 @@ ], ])); - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher_internal:subscription_succeeded', 'channel' => 'private-test-channel', ]); @@ -143,7 +143,7 @@ ], ])); - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher_internal:subscription_succeeded', 'data' => json_encode([ 'presence' => [ @@ -166,15 +166,15 @@ ], ])); - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher_internal:subscription_succeeded', 'channel' => 'cache-test-channel', ]); - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher:cache_miss', 'channel' => 'cache-test-channel', ]); - $connection->assertSendCount(2); + $connection->assertReceivedCount(2); }); it('receives last triggered event when joining a cache channel', function () { @@ -200,12 +200,12 @@ ], ])); - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher_internal:subscription_succeeded', 'channel' => 'cache-test-channel', ]); - $connection->assertSent(['foo' => 'bar']); - $connection->assertSendCount(2); + $connection->assertReceived(['foo' => 'bar']); + $connection->assertReceivedCount(2); }); it('unsubscribes a user from a channel on disconnection', function () { @@ -284,7 +284,7 @@ $this->app['config']->set('reverb.apps.apps.0.allowed_origins', ['laravel.com']); $this->server->open($connection = new FakeConnection); - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher:error', 'data' => json_encode([ 'code' => 4009, @@ -297,7 +297,7 @@ $this->app['config']->set('reverb.apps.0.allowed_origins', ['localhost']); $this->server->open($connection = new FakeConnection); - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher:connection_established', 'data' => json_encode([ 'socket_id' => $connection->id(), diff --git a/tests/Helpers/Reverb.php b/tests/Helpers/Reverb.php index 6592616e..65ca5dd0 100644 --- a/tests/Helpers/Reverb.php +++ b/tests/Helpers/Reverb.php @@ -94,19 +94,3 @@ function disconnect(TestConnection $connection): string return await($promise->promise()); } - -/** - * Return a promise when a given connection is disconnected. - * - * @param \Ratchet\Client\WebSocketWebSocket $connection - */ -function disconnectPromise(WebSocket $connection): PromiseInterface -{ - $promise = new Deferred; - - $connection->on('close', function ($message) use ($promise) { - $promise->resolve('Connection Closed.'); - }); - - return $promise->promise(); -} diff --git a/tests/Pest.php b/tests/Pest.php index 0d58b29d..85af36c7 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -16,10 +16,9 @@ /** * Create a defined number of connections. * - * @param bool $serializable * @return array */ -function factory(int $count = 1, array $data = [], $serializable = false): array +function factory(int $count = 1, array $data = [], bool $serializable = false): array { return Collection::make(range(1, $count))->map(function () use ($data, $serializable) { return new ChannelConnection( diff --git a/tests/ReverbTestCase.php b/tests/ReverbTestCase.php index 9fdeb329..8a195910 100644 --- a/tests/ReverbTestCase.php +++ b/tests/ReverbTestCase.php @@ -45,9 +45,8 @@ protected function tearDown(): void * Define environment setup. * * @param \Illuminate\Foundation\Application $app - * @return void */ - protected function defineEnvironment($app) + protected function defineEnvironment($app): void { parent::defineEnvironment($app); @@ -72,7 +71,10 @@ protected function defineEnvironment($app) ]); } - public function usingRedis() + /** + * Configure the server to use Redis. + */ + public function usingRedis(): void { app(ServerManager::class)->withPublishing(); @@ -82,12 +84,8 @@ public function usingRedis() /** * Start the WebSocket server. - * - * @param string $host - * @param string $port - * @return void */ - public function startServer($host = '0.0.0.0', $port = '8080') + public function startServer(string $host = '0.0.0.0', string $port = '8080'): void { $this->resetFiber(); $this->server = Factory::make($host, $port, $this->loop); @@ -96,10 +94,8 @@ public function startServer($host = '0.0.0.0', $port = '8080') /** * Reset the Fiber instance. * This prevents using a stale fiber between tests. - * - * @return void */ - protected function resetFiber() + protected function resetFiber(): void { $fiber = new SimpleFiber(); $fiberRef = new ReflectionObject($fiber); @@ -110,10 +106,8 @@ protected function resetFiber() /** * Stop the running WebSocket server. - * - * @return void */ - public function stopServer() + public function stopServer(): void { if ($this->server) { $this->server->stop(); @@ -131,10 +125,13 @@ public function triggerEvent(string $channel, string $event, array $data = []): 'data' => $data, ])); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('{}', $response->getBody()->getContents()); + expect($response->getStatusCode())->toBe(200); + expect($response->getBody()->getContents())->toBe('{}'); } + /** + * Send a request to the server. + */ public function request(string $path, string $method = 'GET', mixed $data = '', string $host = '0.0.0.0', string $port = '8080', string $appId = '123456'): PromiseInterface { return (new Browser($this->loop)) @@ -146,6 +143,9 @@ public function request(string $path, string $method = 'GET', mixed $data = '', ); } + /** + * Send a signed request to the server. + */ public function signedRequest(string $path, string $method = 'GET', mixed $data = '', string $host = '0.0.0.0', string $port = '8080', string $appId = '123456'): PromiseInterface { $hash = md5(json_encode($data)); @@ -159,7 +159,7 @@ public function signedRequest(string $path, string $method = 'GET', mixed $data } /** - * Post a request to the server. + * Send a POST request to the server. */ public function postReqeust(string $path, array $data = [], string $host = '0.0.0.0', string $port = '8080', string $appId = '123456'): PromiseInterface { @@ -167,7 +167,7 @@ public function postReqeust(string $path, array $data = [], string $host = '0.0. } /** - * Post a signed request to the server. + * Send a signed POST request to the server. */ public function signedPostRequest(string $path, array $data = [], string $host = '0.0.0.0', string $port = '8080', string $appId = '123456'): PromiseInterface { @@ -180,13 +180,11 @@ public function signedPostRequest(string $path, array $data = [], string $host = return $this->postReqeust("{$path}?{$query}&auth_signature={$signature}", $data, $host, $port, $appId); } - public function getWithSignature( - string $path, - array $data = [], - string $host = '0.0.0.0', - string $port = '8080', - string $appId = '123456' - ): PromiseInterface { + /** + * Send a signed GET request to the server. + */ + public function getWithSignature(string $path, array $data = [], string $host = '0.0.0.0', string $port = '8080', string $appId = '123456'): PromiseInterface + { $hash = md5(json_encode($data)); $timestamp = time(); $query = "auth_key=pusher-key&auth_timestamp={$timestamp}&auth_version=1.0&body_md5={$hash}"; diff --git a/tests/TestConnection.php b/tests/TestConnection.php index 5677cbcd..a2817c3d 100644 --- a/tests/TestConnection.php +++ b/tests/TestConnection.php @@ -11,8 +11,18 @@ class TestConnection { + /** + * The socket ID. + * + * @var string + */ public $socketId; + /** + * Messages received by the connection. + * + * @var array + */ public $receivedMessages = []; public function __construct(public WebSocket $connection) @@ -26,17 +36,18 @@ public function __construct(public WebSocket $connection) }); } + /** + * Get the socket ID of the connection. + */ public function socketId(): string { return $this->socketId; } - public function __call($method, $arguments) - { - return $this->connection->{$method}(...$arguments); - } - - public function await() + /** + * Await all messages to the connection to be resolved. + */ + public function await(): mixed { $promise = new Deferred(); @@ -57,7 +68,10 @@ public function await() ); } - public function assertReceived(string $message, ?int $count = null) + /** + * Assert that the connection received the given message. + */ + public function assertReceived(string $message, ?int $count = null): void { if (! in_array($message, $this->receivedMessages) || $count !== null) { $this->await(); @@ -69,6 +83,14 @@ public function assertReceived(string $message, ?int $count = null) expect($matches)->toHaveCount($count); } - return expect($this->receivedMessages)->toContain($message); + expect($this->receivedMessages)->toContain($message); + } + + /** + * Proxy method calls to the connection. + */ + public function __call($method, $arguments) + { + return $this->connection->{$method}(...$arguments); } } diff --git a/tests/Unit/Channels/CacheChannelTest.php b/tests/Unit/Channels/CacheChannelTest.php index 3e39d751..f741f640 100644 --- a/tests/Unit/Channels/CacheChannelTest.php +++ b/tests/Unit/Channels/CacheChannelTest.php @@ -21,7 +21,7 @@ $channel->subscribe($this->connection); - $this->connection->assertNothingSent(); + $this->connection->assertNothingReceived(); }); it('stores last triggered event', function () { diff --git a/tests/Unit/Channels/ChannelBrokerTest.php b/tests/Unit/Channels/ChannelBrokerTest.php index a0cbd51e..2ae52562 100644 --- a/tests/Unit/Channels/ChannelBrokerTest.php +++ b/tests/Unit/Channels/ChannelBrokerTest.php @@ -3,7 +3,9 @@ use Laravel\Reverb\Channels\CacheChannel; use Laravel\Reverb\Channels\Channel; use Laravel\Reverb\Channels\ChannelBroker; +use Laravel\Reverb\Channels\PresenceCacheChannel; use Laravel\Reverb\Channels\PresenceChannel; +use Laravel\Reverb\Channels\PrivateCacheChannel; use Laravel\Reverb\Channels\PrivateChannel; it('can return a channel instance', function () { @@ -25,3 +27,13 @@ expect(ChannelBroker::create('cache-foo')) ->toBeInstanceOf(CacheChannel::class); }); + +it('can return a private cache channel instance', function () { + expect(ChannelBroker::create('private-cache-foo')) + ->toBeInstanceOf(PrivateCacheChannel::class); +}); + +it('can return a presence cache channel instance', function () { + expect(ChannelBroker::create('presence-cache-foo')) + ->toBeInstanceOf(PresenceCacheChannel::class); +}); diff --git a/tests/Unit/Channels/ChannelTest.php b/tests/Unit/Channels/ChannelTest.php index 046360ff..45c9a5a6 100644 --- a/tests/Unit/Channels/ChannelTest.php +++ b/tests/Unit/Channels/ChannelTest.php @@ -70,7 +70,7 @@ $channel->broadcast(['foo' => 'bar']); - collect($connections)->each(fn ($connection) => $connection->assertSent(['foo' => 'bar'])); + collect($connections)->each(fn ($connection) => $connection->assertReceived(['foo' => 'bar'])); }); it('does not broadcast to the connection sending the message', function () { @@ -82,8 +82,8 @@ ->once() ->andReturn($connections = factory(3)); - $channel->broadcast(['foo' => 'bar'], $connections[0]->connection()); + $channel->broadcast(['foo' => 'bar'], collect($connections)->first()->connection()); - $connections[0]->assertNothingSent(); - collect(array_slice($connections, -2))->each(fn ($connection) => $connection->assertSent(['foo' => 'bar'])); + collect($connections)->first()->assertNothingReceived(); + collect(array_slice($connections, -2))->each(fn ($connection) => $connection->assertReceived(['foo' => 'bar'])); }); diff --git a/tests/Unit/Channels/PresenceCacheChannelTest.php b/tests/Unit/Channels/PresenceCacheChannelTest.php index de24d66a..5ad5c655 100644 --- a/tests/Unit/Channels/PresenceCacheChannelTest.php +++ b/tests/Unit/Channels/PresenceCacheChannelTest.php @@ -47,7 +47,7 @@ $channel->broadcast(['foo' => 'bar']); - collect($connections)->each(fn ($connection) => $connection->assertSent(['foo' => 'bar'])); + collect($connections)->each(fn ($connection) => $connection->assertReceived(['foo' => 'bar'])); }); it('fails to subscribe if the signature is invalid', function () { @@ -62,8 +62,8 @@ $channel = new PresenceCacheChannel('presence-cache-test-channel'); $connections = [ - factory(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 1])[0], - factory(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 2])[0], + collect(factory(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 1]))->first(), + collect(factory(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 2]))->first(), ]; $this->channelConnectionManager->shouldReceive('all') @@ -94,7 +94,7 @@ $channel->subscribe($this->connection, validAuth($this->connection->id(), 'presence-cache-test-channel')); - collect($connections)->each(fn ($connection) => $connection->assertSent([ + collect($connections)->each(fn ($connection) => $connection->assertReceived([ 'event' => 'pusher_internal:member_added', 'data' => [], 'channel' => 'presence-cache-test-channel', @@ -122,7 +122,7 @@ $data ); - collect($connections)->each(fn ($connection) => $connection->assertSent([ + collect($connections)->each(fn ($connection) => $connection->assertReceived([ 'event' => 'pusher_internal:member_added', 'data' => ['name' => 'Joe'], 'channel' => 'presence-cache-test-channel', @@ -155,7 +155,7 @@ $channel->unsubscribe($this->connection); - collect($connections)->each(fn ($connection) => $connection->assertSent([ + collect($connections)->each(fn ($connection) => $connection->assertReceived([ 'event' => 'pusher_internal:member_removed', 'data' => ['user_id' => 1], 'channel' => 'presence-cache-test-channel', @@ -171,7 +171,7 @@ $channel->subscribe($this->connection, validAuth($this->connection->id(), 'presence-cache-test-channel')); - $this->connection->assertNothingSent(); + $this->connection->assertNothingReceived(); }); it('stores last triggered event', function () { diff --git a/tests/Unit/Channels/PresenceChannelTest.php b/tests/Unit/Channels/PresenceChannelTest.php index 0c8afff0..068cd248 100644 --- a/tests/Unit/Channels/PresenceChannelTest.php +++ b/tests/Unit/Channels/PresenceChannelTest.php @@ -47,7 +47,7 @@ $channel->broadcast(['foo' => 'bar']); - collect($connections)->each(fn ($connection) => $connection->assertSent(['foo' => 'bar'])); + collect($connections)->each(fn ($connection) => $connection->assertReceived(['foo' => 'bar'])); }); it('fails to subscribe if the signature is invalid', function () { @@ -62,8 +62,8 @@ $channel = new PresenceChannel('presence-test-channel'); $connections = [ - factory(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 1])[0], - factory(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 2])[0], + collect(factory(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 1]))->first(), + collect(factory(data: ['user_info' => ['name' => 'Joe'], 'user_id' => 2]))->first(), ]; $this->channelConnectionManager->shouldReceive('all') @@ -94,7 +94,7 @@ $channel->subscribe($this->connection, validAuth($this->connection->id(), 'presence-test-channel')); - collect($connections)->each(fn ($connection) => $connection->assertSent([ + collect($connections)->each(fn ($connection) => $connection->assertReceived([ 'event' => 'pusher_internal:member_added', 'data' => [], 'channel' => 'presence-test-channel', @@ -122,7 +122,7 @@ $data ); - collect($connections)->each(fn ($connection) => $connection->assertSent([ + collect($connections)->each(fn ($connection) => $connection->assertReceived([ 'event' => 'pusher_internal:member_added', 'data' => ['name' => 'Joe'], 'channel' => 'presence-test-channel', @@ -155,7 +155,7 @@ $channel->unsubscribe($this->connection); - collect($connections)->each(fn ($connection) => $connection->assertSent([ + collect($connections)->each(fn ($connection) => $connection->assertReceived([ 'event' => 'pusher_internal:member_removed', 'data' => ['user_id' => 1], 'channel' => 'presence-test-channel', diff --git a/tests/Unit/Channels/PrivateCacheChannelTest.php b/tests/Unit/Channels/PrivateCacheChannelTest.php index abb91e99..6dc26147 100644 --- a/tests/Unit/Channels/PrivateCacheChannelTest.php +++ b/tests/Unit/Channels/PrivateCacheChannelTest.php @@ -44,7 +44,7 @@ $channel->broadcast(['foo' => 'bar']); - collect($connections)->each(fn ($connection) => $connection->assertSent(['foo' => 'bar'])); + collect($connections)->each(fn ($connection) => $connection->assertReceived(['foo' => 'bar'])); }); it('fails to subscribe if the signature is invalid', function () { @@ -64,7 +64,7 @@ $channel->subscribe($this->connection, validAuth($this->connection->id(), 'private-cache-test-channel')); - $this->connection->assertNothingSent(); + $this->connection->assertNothingReceived(); }); it('stores last triggered event', function () { diff --git a/tests/Unit/Channels/PrivateChannelTest.php b/tests/Unit/Channels/PrivateChannelTest.php index 4b4a8c73..610b5b8a 100644 --- a/tests/Unit/Channels/PrivateChannelTest.php +++ b/tests/Unit/Channels/PrivateChannelTest.php @@ -44,7 +44,7 @@ $channel->broadcast(['foo' => 'bar']); - collect($connections)->each(fn ($connection) => $connection->assertSent(['foo' => 'bar'])); + collect($connections)->each(fn ($connection) => $connection->assertReceived(['foo' => 'bar'])); }); it('fails to subscribe if the signature is invalid', function () { diff --git a/tests/Unit/ClientEventTest.php b/tests/Unit/ClientEventTest.php index b61e6153..9700b58f 100644 --- a/tests/Unit/ClientEventTest.php +++ b/tests/Unit/ClientEventTest.php @@ -26,7 +26,7 @@ ] ); - $connections[0]->assertSent([ + collect($connections)->first()->assertReceived([ 'event' => 'client-test-message', 'channel' => 'test-channel', 'data' => ['foo' => 'bar'], @@ -46,7 +46,7 @@ ] ); - $this->connection->assertNothingSent(); + $this->connection->assertNothingReceived(); }); it('fails on unsupported message', function () { diff --git a/tests/Unit/Jobs/PingInactiveConnectionsTest.php b/tests/Unit/Jobs/PingInactiveConnectionsTest.php index e2364d8d..e66e88ed 100644 --- a/tests/Unit/Jobs/PingInactiveConnectionsTest.php +++ b/tests/Unit/Jobs/PingInactiveConnectionsTest.php @@ -27,7 +27,7 @@ (new PingInactiveConnections)->handle($this->channelManager); $connections->each(function ($connection) { - $connection->assertSent([ + $connection->assertReceived([ 'event' => 'pusher:ping', ]); $connection->assertHasBeenPinged(); diff --git a/tests/Unit/Pusher/EventTest.php b/tests/Unit/Pusher/EventTest.php index fedceac8..99e6e5ac 100644 --- a/tests/Unit/Pusher/EventTest.php +++ b/tests/Unit/Pusher/EventTest.php @@ -15,7 +15,7 @@ 'pusher:connection_established' ); - $this->connection->assertSent([ + $this->connection->assertReceived([ 'event' => 'pusher:connection_established', 'data' => json_encode([ 'socket_id' => $this->connection->id(), @@ -31,7 +31,7 @@ ['channel' => 'test-channel'] ); - $this->connection->assertSent([ + $this->connection->assertReceived([ 'event' => 'pusher_internal:subscription_succeeded', 'channel' => 'test-channel', ]); @@ -44,7 +44,7 @@ ['channel' => 'test-channel'] ); - $this->connection->assertNothingSent(); + $this->connection->assertNothingReceived(); }); it('can respond to a ping', function () { @@ -53,7 +53,7 @@ 'pusher:ping', ); - $this->connection->assertSent([ + $this->connection->assertReceived([ 'event' => 'pusher:pong', ]); }); From 4eca1ffcc182dbad3bb9a7ea1baadf0ee890e230 Mon Sep 17 00:00:00 2001 From: joedixon Date: Wed, 6 Dec 2023 15:25:38 +0000 Subject: [PATCH 10/10] Fix code styling --- tests/Feature/Reverb/ServerTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Feature/Reverb/ServerTest.php b/tests/Feature/Reverb/ServerTest.php index bd706b09..ba3c5430 100644 --- a/tests/Feature/Reverb/ServerTest.php +++ b/tests/Feature/Reverb/ServerTest.php @@ -1,7 +1,6 @@