wip
This commit is contained in:
parent
38b2e4d404
commit
04ff39d75e
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace BeyondCode\LaravelWebSockets\Tests\Channels;
|
namespace BeyondCode\LaravelWebSockets\Tests\Channels;
|
||||||
|
|
||||||
|
use BeyondCode\LaravelWebSockets\Tests\Mocks\Message;
|
||||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||||
|
|
||||||
class ChannelReplicationTest extends TestCase
|
class ChannelReplicationTest extends TestCase
|
||||||
|
|
@ -16,10 +17,142 @@ class ChannelReplicationTest extends TestCase
|
||||||
$this->runOnlyOnRedisReplication();
|
$this->runOnlyOnRedisReplication();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_not_implemented()
|
/** @test */
|
||||||
{
|
public function replication_clients_can_subscribe_to_channels()
|
||||||
$this->markTestIncomplete(
|
{
|
||||||
'Not yet implemented tests.'
|
$connection = $this->getWebSocketConnection();
|
||||||
);
|
|
||||||
}
|
$message = new Message(json_encode([
|
||||||
|
'event' => 'pusher:subscribe',
|
||||||
|
'data' => [
|
||||||
|
'channel' => 'basic-channel',
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
|
||||||
|
$this->pusherServer->onOpen($connection);
|
||||||
|
|
||||||
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
$connection->assertSentEvent('pusher_internal:subscription_succeeded', [
|
||||||
|
'channel' => 'basic-channel',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function replication_clients_can_unsubscribe_from_channels()
|
||||||
|
{
|
||||||
|
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||||
|
|
||||||
|
$channel = $this->getChannel($connection, 'test-channel');
|
||||||
|
|
||||||
|
$this->assertTrue($channel->hasConnections());
|
||||||
|
|
||||||
|
$message = new Message(json_encode([
|
||||||
|
'event' => 'pusher:unsubscribe',
|
||||||
|
'data' => [
|
||||||
|
'channel' => 'test-channel',
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
|
||||||
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
$this->assertFalse($channel->hasConnections());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function replication_a_client_cannot_broadcast_to_other_clients_by_default()
|
||||||
|
{
|
||||||
|
// One connection inside channel "test-channel".
|
||||||
|
$existingConnection = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||||
|
|
||||||
|
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||||
|
|
||||||
|
$message = new Message('{"event": "client-test", "data": {}, "channel": "test-channel"}');
|
||||||
|
|
||||||
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
$existingConnection->assertNotSentEvent('client-test');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function replication_a_client_can_be_enabled_to_broadcast_to_other_clients()
|
||||||
|
{
|
||||||
|
config()->set('websockets.apps.0.enable_client_messages', true);
|
||||||
|
|
||||||
|
// One connection inside channel "test-channel".
|
||||||
|
$existingConnection = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||||
|
|
||||||
|
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||||
|
|
||||||
|
$message = new Message('{"event": "client-test", "data": {}, "channel": "test-channel"}');
|
||||||
|
|
||||||
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
$existingConnection->assertSentEvent('client-test');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function replication_closed_connections_get_removed_from_all_connected_channels()
|
||||||
|
{
|
||||||
|
$connection = $this->getConnectedWebSocketConnection(['test-channel-1', 'test-channel-2']);
|
||||||
|
|
||||||
|
$channel1 = $this->getChannel($connection, 'test-channel-1');
|
||||||
|
$channel2 = $this->getChannel($connection, 'test-channel-2');
|
||||||
|
|
||||||
|
$this->assertTrue($channel1->hasConnections());
|
||||||
|
$this->assertTrue($channel2->hasConnections());
|
||||||
|
|
||||||
|
$this->pusherServer->onClose($connection);
|
||||||
|
|
||||||
|
$this->assertFalse($channel1->hasConnections());
|
||||||
|
$this->assertFalse($channel2->hasConnections());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function replication_channels_can_broadcast_messages_to_all_connections()
|
||||||
|
{
|
||||||
|
$connection1 = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||||
|
$connection2 = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||||
|
|
||||||
|
$channel = $this->getChannel($connection1, 'test-channel');
|
||||||
|
|
||||||
|
$channel->broadcast([
|
||||||
|
'event' => 'broadcasted-event',
|
||||||
|
'channel' => 'test-channel',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$connection1->assertSentEvent('broadcasted-event');
|
||||||
|
$connection2->assertSentEvent('broadcasted-event');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function replication_channels_can_broadcast_messages_to_all_connections_except_the_given_connection()
|
||||||
|
{
|
||||||
|
$connection1 = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||||
|
$connection2 = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||||
|
|
||||||
|
$channel = $this->getChannel($connection1, 'test-channel');
|
||||||
|
|
||||||
|
$channel->broadcastToOthers($connection1, (object) [
|
||||||
|
'event' => 'broadcasted-event',
|
||||||
|
'channel' => 'test-channel',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$connection1->assertNotSentEvent('broadcasted-event');
|
||||||
|
$connection2->assertSentEvent('broadcasted-event');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function replication_it_responds_correctly_to_the_ping_message()
|
||||||
|
{
|
||||||
|
$connection = $this->getConnectedWebSocketConnection();
|
||||||
|
|
||||||
|
$message = new Message(json_encode([
|
||||||
|
'event' => 'pusher:ping',
|
||||||
|
]));
|
||||||
|
|
||||||
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
$connection->assertSentEvent('pusher:pong');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,20 +50,87 @@ class PresenceChannelReplicationTest extends TestCase
|
||||||
$connection->socketId,
|
$connection->socketId,
|
||||||
json_encode($channelData),
|
json_encode($channelData),
|
||||||
])
|
])
|
||||||
->assertCalledWithArgs('hgetall', [
|
->assertCalledWithArgs('hgetall', ['1234:presence-channel'])
|
||||||
'1234:presence-channel',
|
->assertCalled('publish');
|
||||||
]);
|
}
|
||||||
// TODO: This fails somehow
|
|
||||||
// Debugging shows the exact same pattern as good.
|
/** @test */
|
||||||
/* ->assertCalledWithArgs('publish', [
|
public function clients_with_valid_auth_signatures_can_leave_presence_channels()
|
||||||
'1234:presence-channel',
|
{
|
||||||
json_encode([
|
$connection = $this->getWebSocketConnection();
|
||||||
'event' => 'pusher_internal:member_added',
|
|
||||||
'channel' => 'presence-channel',
|
$this->pusherServer->onOpen($connection);
|
||||||
'data' => $channelData,
|
|
||||||
'appId' => '1234',
|
$channelData = [
|
||||||
'serverId' => $this->app->make(ReplicationInterface::class)->getServerId(),
|
'user_id' => 1,
|
||||||
]),
|
];
|
||||||
]) */
|
|
||||||
|
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||||
|
|
||||||
|
$message = new Message(json_encode([
|
||||||
|
'event' => 'pusher:subscribe',
|
||||||
|
'data' => [
|
||||||
|
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||||
|
'channel' => 'presence-channel',
|
||||||
|
'channel_data' => json_encode($channelData),
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
|
||||||
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
$this->getSubscribeClient()
|
||||||
|
->assertEventDispatched('message');
|
||||||
|
|
||||||
|
$this->getPublishClient()
|
||||||
|
->assertCalled('hset')
|
||||||
|
->assertCalledWithArgs('hgetall', ['1234:presence-channel'])
|
||||||
|
->assertCalled('publish');
|
||||||
|
|
||||||
|
$this->getPublishClient()
|
||||||
|
->resetAssertions();
|
||||||
|
|
||||||
|
$message = new Message(json_encode([
|
||||||
|
'event' => 'pusher:unsubscribe',
|
||||||
|
'data' => [
|
||||||
|
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||||
|
'channel' => 'presence-channel',
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
|
||||||
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
$this->getPublishClient()
|
||||||
|
->assertCalled('hdel')
|
||||||
|
->assertCalled('publish');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function clients_with_no_user_info_can_join_presence_channels()
|
||||||
|
{
|
||||||
|
$connection = $this->getWebSocketConnection();
|
||||||
|
|
||||||
|
$this->pusherServer->onOpen($connection);
|
||||||
|
|
||||||
|
$channelData = [
|
||||||
|
'user_id' => 1,
|
||||||
|
];
|
||||||
|
|
||||||
|
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||||
|
|
||||||
|
$message = new Message(json_encode([
|
||||||
|
'event' => 'pusher:subscribe',
|
||||||
|
'data' => [
|
||||||
|
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||||
|
'channel' => 'presence-channel',
|
||||||
|
'channel_data' => json_encode($channelData),
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
|
||||||
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
$this->getPublishClient()
|
||||||
|
->assertCalled('hset')
|
||||||
|
->assertcalledWithArgs('hgetall', ['1234:presence-channel'])
|
||||||
|
->assertCalled('publish');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,10 @@
|
||||||
|
|
||||||
namespace BeyondCode\LaravelWebSockets\Tests\Channels;
|
namespace BeyondCode\LaravelWebSockets\Tests\Channels;
|
||||||
|
|
||||||
|
use BeyondCode\LaravelWebSockets\Tests\Mocks\Message;
|
||||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||||
|
use BeyondCode\LaravelWebSockets\WebSockets\Exceptions\InvalidSignature;
|
||||||
|
|
||||||
|
|
||||||
class PrivateChannelReplicationTest extends TestCase
|
class PrivateChannelReplicationTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
@ -16,10 +19,49 @@ class PrivateChannelReplicationTest extends TestCase
|
||||||
$this->runOnlyOnRedisReplication();
|
$this->runOnlyOnRedisReplication();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_not_implemented()
|
/** @test */
|
||||||
|
public function replication_clients_need_valid_auth_signatures_to_join_private_channels()
|
||||||
{
|
{
|
||||||
$this->markTestIncomplete(
|
$this->expectException(InvalidSignature::class);
|
||||||
'Not yet implemented tests.'
|
|
||||||
);
|
$connection = $this->getWebSocketConnection();
|
||||||
|
|
||||||
|
$message = new Message(json_encode([
|
||||||
|
'event' => 'pusher:subscribe',
|
||||||
|
'data' => [
|
||||||
|
'auth' => 'invalid',
|
||||||
|
'channel' => 'private-channel',
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
|
||||||
|
$this->pusherServer->onOpen($connection);
|
||||||
|
|
||||||
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function replication_clients_with_valid_auth_signatures_can_join_private_channels()
|
||||||
|
{
|
||||||
|
$connection = $this->getWebSocketConnection();
|
||||||
|
|
||||||
|
$this->pusherServer->onOpen($connection);
|
||||||
|
|
||||||
|
$signature = "{$connection->socketId}:private-channel";
|
||||||
|
|
||||||
|
$hashedAppSecret = hash_hmac('sha256', $signature, $connection->app->secret);
|
||||||
|
|
||||||
|
$message = new Message(json_encode([
|
||||||
|
'event' => 'pusher:subscribe',
|
||||||
|
'data' => [
|
||||||
|
'auth' => "{$connection->app->key}:{$hashedAppSecret}",
|
||||||
|
'channel' => 'private-channel',
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
|
||||||
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
$connection->assertSentEvent('pusher_internal:subscription_succeeded', [
|
||||||
|
'channel' => 'private-channel',
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,8 @@ class FetchChannelReplicationTest extends TestCase
|
||||||
/** @var JsonResponse $response */
|
/** @var JsonResponse $response */
|
||||||
$response = array_pop($connection->sentRawData);
|
$response = array_pop($connection->sentRawData);
|
||||||
|
|
||||||
$this->getSubscribeClient()->assertNothingCalled();
|
$this->getSubscribeClient()
|
||||||
|
->assertEventDispatched('message');
|
||||||
|
|
||||||
$this->getPublishClient()
|
$this->getPublishClient()
|
||||||
->assertCalled('hset')
|
->assertCalled('hset')
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,13 @@
|
||||||
|
|
||||||
namespace BeyondCode\LaravelWebSockets\Tests\HttpApi;
|
namespace BeyondCode\LaravelWebSockets\Tests\HttpApi;
|
||||||
|
|
||||||
|
use BeyondCode\LaravelWebSockets\HttpApi\Controllers\FetchChannelsController;
|
||||||
|
use BeyondCode\LaravelWebSockets\Tests\Mocks\Connection;
|
||||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||||
|
use GuzzleHttp\Psr7\Request;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Pusher\Pusher;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||||
|
|
||||||
class FetchChannelsReplicationTest extends TestCase
|
class FetchChannelsReplicationTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
@ -16,10 +22,161 @@ class FetchChannelsReplicationTest extends TestCase
|
||||||
$this->runOnlyOnRedisReplication();
|
$this->runOnlyOnRedisReplication();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_not_implemented()
|
/** @test */
|
||||||
|
public function replication_it_returns_the_channel_information()
|
||||||
{
|
{
|
||||||
$this->markTestIncomplete(
|
$this->joinPresenceChannel('presence-channel');
|
||||||
'Not yet implemented tests.'
|
|
||||||
);
|
$connection = new Connection();
|
||||||
|
|
||||||
|
$requestPath = '/apps/1234/channels';
|
||||||
|
$routeParams = [
|
||||||
|
'appId' => '1234',
|
||||||
|
];
|
||||||
|
|
||||||
|
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath);
|
||||||
|
|
||||||
|
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||||
|
|
||||||
|
$controller = app(FetchChannelsController::class);
|
||||||
|
|
||||||
|
$controller->onOpen($connection, $request);
|
||||||
|
|
||||||
|
/** @var JsonResponse $response */
|
||||||
|
$response = array_pop($connection->sentRawData);
|
||||||
|
|
||||||
|
$this->getSubscribeClient()
|
||||||
|
->assertEventDispatched('message');
|
||||||
|
|
||||||
|
$this->getPublishClient()
|
||||||
|
->assertCalled('hset')
|
||||||
|
->assertCalledWithArgs('hgetall', ['1234:presence-channel'])
|
||||||
|
->assertCalled('publish')
|
||||||
|
->assertCalled('multi')
|
||||||
|
->assertCalledWithArgs('hlen', ['1234:presence-channel'])
|
||||||
|
->assertCalled('exec');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function replication_it_returns_the_channel_information_for_prefix()
|
||||||
|
{
|
||||||
|
$this->joinPresenceChannel('presence-global.1');
|
||||||
|
$this->joinPresenceChannel('presence-global.1');
|
||||||
|
$this->joinPresenceChannel('presence-global.2');
|
||||||
|
$this->joinPresenceChannel('presence-notglobal.2');
|
||||||
|
|
||||||
|
$connection = new Connection();
|
||||||
|
|
||||||
|
$requestPath = '/apps/1234/channels';
|
||||||
|
$routeParams = [
|
||||||
|
'appId' => '1234',
|
||||||
|
];
|
||||||
|
|
||||||
|
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath, [
|
||||||
|
'filter_by_prefix' => 'presence-global',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||||
|
|
||||||
|
$controller = app(FetchChannelsController::class);
|
||||||
|
|
||||||
|
$controller->onOpen($connection, $request);
|
||||||
|
|
||||||
|
/** @var JsonResponse $response */
|
||||||
|
$response = array_pop($connection->sentRawData);
|
||||||
|
|
||||||
|
$this->getSubscribeClient()
|
||||||
|
->assertEventDispatched('message');
|
||||||
|
|
||||||
|
$this->getPublishClient()
|
||||||
|
->assertCalled('hset')
|
||||||
|
->assertCalledWithArgs('hgetall', ['1234:presence-global.1'])
|
||||||
|
->assertCalledWithArgs('hgetall', ['1234:presence-global.2'])
|
||||||
|
->assertCalledWithArgs('hgetall', ['1234:presence-notglobal.2'])
|
||||||
|
->assertCalled('publish')
|
||||||
|
->assertCalled('multi')
|
||||||
|
->assertCalledWithArgs('hlen', ['1234:presence-global.1'])
|
||||||
|
->assertCalledWithArgs('hlen', ['1234:presence-global.2'])
|
||||||
|
->assertNotCalledWithArgs('hlen', ['1234:presence-notglobal.2'])
|
||||||
|
->assertCalled('exec');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function replication_it_returns_the_channel_information_for_prefix_with_user_count()
|
||||||
|
{
|
||||||
|
$this->joinPresenceChannel('presence-global.1');
|
||||||
|
$this->joinPresenceChannel('presence-global.1');
|
||||||
|
$this->joinPresenceChannel('presence-global.2');
|
||||||
|
$this->joinPresenceChannel('presence-notglobal.2');
|
||||||
|
|
||||||
|
$connection = new Connection();
|
||||||
|
|
||||||
|
$requestPath = '/apps/1234/channels';
|
||||||
|
$routeParams = [
|
||||||
|
'appId' => '1234',
|
||||||
|
];
|
||||||
|
|
||||||
|
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath, [
|
||||||
|
'filter_by_prefix' => 'presence-global',
|
||||||
|
'info' => 'user_count',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||||
|
|
||||||
|
$controller = app(FetchChannelsController::class);
|
||||||
|
|
||||||
|
$controller->onOpen($connection, $request);
|
||||||
|
|
||||||
|
/** @var JsonResponse $response */
|
||||||
|
$response = array_pop($connection->sentRawData);
|
||||||
|
|
||||||
|
$this->getSubscribeClient()
|
||||||
|
->assertEventDispatched('message');
|
||||||
|
|
||||||
|
$this->getPublishClient()
|
||||||
|
->assertCalled('hset')
|
||||||
|
->assertCalledWithArgs('hgetall', ['1234:presence-global.1'])
|
||||||
|
->assertCalledWithArgs('hgetall', ['1234:presence-global.2'])
|
||||||
|
->assertCalledWithArgs('hgetall', ['1234:presence-notglobal.2'])
|
||||||
|
->assertCalled('publish')
|
||||||
|
->assertCalled('multi')
|
||||||
|
->assertCalledWithArgs('hlen', ['1234:presence-global.1'])
|
||||||
|
->assertCalledWithArgs('hlen', ['1234:presence-global.2'])
|
||||||
|
->assertNotCalledWithArgs('hlen', ['1234:presence-notglobal.2'])
|
||||||
|
->assertCalled('exec');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function replication_it_returns_empty_object_for_no_channels_found()
|
||||||
|
{
|
||||||
|
$connection = new Connection();
|
||||||
|
|
||||||
|
$requestPath = '/apps/1234/channels';
|
||||||
|
$routeParams = [
|
||||||
|
'appId' => '1234',
|
||||||
|
];
|
||||||
|
|
||||||
|
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath);
|
||||||
|
|
||||||
|
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||||
|
|
||||||
|
$controller = app(FetchChannelsController::class);
|
||||||
|
|
||||||
|
$controller->onOpen($connection, $request);
|
||||||
|
|
||||||
|
/** @var JsonResponse $response */
|
||||||
|
$response = array_pop($connection->sentRawData);
|
||||||
|
|
||||||
|
$this->getSubscribeClient()
|
||||||
|
->assertEventDispatched('message');
|
||||||
|
|
||||||
|
$this->getPublishClient()
|
||||||
|
->assertNotCalled('hset')
|
||||||
|
->assertNotCalled('hgetall')
|
||||||
|
->assertNotCalled('publish')
|
||||||
|
->assertCalled('multi')
|
||||||
|
->assertNotCalled('hlen')
|
||||||
|
->assertCalled('exec');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,12 @@
|
||||||
|
|
||||||
namespace BeyondCode\LaravelWebSockets\Tests\HttpApi;
|
namespace BeyondCode\LaravelWebSockets\Tests\HttpApi;
|
||||||
|
|
||||||
|
use BeyondCode\LaravelWebSockets\HttpApi\Controllers\FetchUsersController;
|
||||||
|
use BeyondCode\LaravelWebSockets\Tests\Mocks\Connection;
|
||||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||||
|
use GuzzleHttp\Psr7\Request;
|
||||||
|
use Pusher\Pusher;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||||
|
|
||||||
class FetchUsersReplicationTest extends TestCase
|
class FetchUsersReplicationTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
@ -16,10 +21,111 @@ class FetchUsersReplicationTest extends TestCase
|
||||||
$this->runOnlyOnRedisReplication();
|
$this->runOnlyOnRedisReplication();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_not_implemented()
|
/** @test */
|
||||||
|
public function test_invalid_signatures_can_not_access_the_api()
|
||||||
{
|
{
|
||||||
$this->markTestIncomplete(
|
$this->expectException(HttpException::class);
|
||||||
'Not yet implemented tests.'
|
$this->expectExceptionMessage('Invalid auth signature provided.');
|
||||||
);
|
|
||||||
|
$connection = new Connection();
|
||||||
|
|
||||||
|
$requestPath = '/apps/1234/channel/my-channel';
|
||||||
|
$routeParams = [
|
||||||
|
'appId' => '1234',
|
||||||
|
'channelName' => 'my-channel',
|
||||||
|
];
|
||||||
|
|
||||||
|
$queryString = Pusher::build_auth_query_string('TestKey', 'InvalidSecret', 'GET', $requestPath);
|
||||||
|
|
||||||
|
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||||
|
|
||||||
|
$controller = app(FetchUsersController::class);
|
||||||
|
|
||||||
|
$controller->onOpen($connection, $request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function test_it_only_returns_data_for_presence_channels()
|
||||||
|
{
|
||||||
|
$this->expectException(HttpException::class);
|
||||||
|
$this->expectExceptionMessage('Invalid presence channel');
|
||||||
|
|
||||||
|
$this->getConnectedWebSocketConnection(['my-channel']);
|
||||||
|
|
||||||
|
$connection = new Connection();
|
||||||
|
|
||||||
|
$requestPath = '/apps/1234/channel/my-channel/users';
|
||||||
|
$routeParams = [
|
||||||
|
'appId' => '1234',
|
||||||
|
'channelName' => 'my-channel',
|
||||||
|
];
|
||||||
|
|
||||||
|
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath);
|
||||||
|
|
||||||
|
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||||
|
|
||||||
|
$controller = app(FetchUsersController::class);
|
||||||
|
|
||||||
|
$controller->onOpen($connection, $request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function test_it_returns_404_for_invalid_channels()
|
||||||
|
{
|
||||||
|
$this->expectException(HttpException::class);
|
||||||
|
$this->expectExceptionMessage('Unknown channel');
|
||||||
|
|
||||||
|
$this->getConnectedWebSocketConnection(['my-channel']);
|
||||||
|
|
||||||
|
$connection = new Connection();
|
||||||
|
|
||||||
|
$requestPath = '/apps/1234/channel/invalid-channel/users';
|
||||||
|
$routeParams = [
|
||||||
|
'appId' => '1234',
|
||||||
|
'channelName' => 'invalid-channel',
|
||||||
|
];
|
||||||
|
|
||||||
|
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath);
|
||||||
|
|
||||||
|
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||||
|
|
||||||
|
$controller = app(FetchUsersController::class);
|
||||||
|
|
||||||
|
$controller->onOpen($connection, $request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function test_it_returns_connected_user_information()
|
||||||
|
{
|
||||||
|
$this->skipOnRedisReplication();
|
||||||
|
|
||||||
|
$this->joinPresenceChannel('presence-channel');
|
||||||
|
|
||||||
|
$connection = new Connection();
|
||||||
|
|
||||||
|
$requestPath = '/apps/1234/channel/presence-channel/users';
|
||||||
|
$routeParams = [
|
||||||
|
'appId' => '1234',
|
||||||
|
'channelName' => 'presence-channel',
|
||||||
|
];
|
||||||
|
|
||||||
|
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath);
|
||||||
|
|
||||||
|
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||||
|
|
||||||
|
$controller = app(FetchUsersController::class);
|
||||||
|
|
||||||
|
$controller->onOpen($connection, $request);
|
||||||
|
|
||||||
|
/** @var \Illuminate\Http\JsonResponse $response */
|
||||||
|
$response = array_pop($connection->sentRawData);
|
||||||
|
|
||||||
|
$this->assertSame([
|
||||||
|
'users' => [
|
||||||
|
[
|
||||||
|
'id' => 1,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
], json_decode($response->getContent(), true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,13 @@ class LazyClient extends BaseLazyClient
|
||||||
*/
|
*/
|
||||||
protected $calls = [];
|
protected $calls = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of called events for the connector.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $events = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
@ -24,6 +31,16 @@ class LazyClient extends BaseLazyClient
|
||||||
return parent::__call($name, $args);
|
return parent::__call($name, $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function on($event, callable $listener)
|
||||||
|
{
|
||||||
|
$this->events[] = $event;
|
||||||
|
|
||||||
|
return parent::on($event, $listener);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the method got called.
|
* Check if the method got called.
|
||||||
*
|
*
|
||||||
|
|
@ -71,6 +88,53 @@ class LazyClient extends BaseLazyClient
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the method didn't call.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function assertNotCalled($name)
|
||||||
|
{
|
||||||
|
foreach ($this->getCalledFunctions() as $function) {
|
||||||
|
[$calledName, ] = $function;
|
||||||
|
|
||||||
|
if ($calledName === $name) {
|
||||||
|
PHPUnit::assertFalse(true);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PHPUnit::assertTrue(true);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the method got not called with specific args.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param array $args
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function assertNotCalledWithArgs($name, array $args)
|
||||||
|
{
|
||||||
|
foreach ($this->getCalledFunctions() as $function) {
|
||||||
|
[$calledName, $calledArgs] = $function;
|
||||||
|
|
||||||
|
if ($calledName === $name && $calledArgs === $args) {
|
||||||
|
PHPUnit::assertFalse(true);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PHPUnit::assertTrue(true);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if no function got called.
|
* Check if no function got called.
|
||||||
*
|
*
|
||||||
|
|
@ -83,6 +147,39 @@ class LazyClient extends BaseLazyClient
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the event got dispatched.
|
||||||
|
*
|
||||||
|
* @param string $event
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function assertEventDispatched($event)
|
||||||
|
{
|
||||||
|
foreach ($this->getCalledEvents() as $dispatchedEvent) {
|
||||||
|
if ($dispatchedEvent === $event) {
|
||||||
|
PHPUnit::assertTrue(true);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PHPUnit::assertFalse(true);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if no function got called.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function assertNothingDispatched()
|
||||||
|
{
|
||||||
|
PHPUnit::assertEquals([], $this->getCalledEvents());
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of all calls.
|
* Get the list of all calls.
|
||||||
*
|
*
|
||||||
|
|
@ -92,4 +189,40 @@ class LazyClient extends BaseLazyClient
|
||||||
{
|
{
|
||||||
return $this->calls;
|
return $this->calls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of events.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getCalledEvents()
|
||||||
|
{
|
||||||
|
return $this->events;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump the assertions.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function dd()
|
||||||
|
{
|
||||||
|
dd([
|
||||||
|
'functions' => $this->getCalledFunctions(),
|
||||||
|
'events' => $this->getCalledEvents(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the assertions.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function resetAssertions()
|
||||||
|
{
|
||||||
|
$this->calls = [];
|
||||||
|
$this->events = [];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue