Merge pull request #482 from beyondcode/code-coverage
[2.x] Code coverage fixes
This commit is contained in:
commit
793dc24c24
|
|
@ -0,0 +1,18 @@
|
|||
codecov:
|
||||
notify:
|
||||
require_ci_to_pass: yes
|
||||
|
||||
coverage:
|
||||
precision: 2
|
||||
round: down
|
||||
range: "70...100"
|
||||
|
||||
status:
|
||||
project: yes
|
||||
patch: yes
|
||||
changes: no
|
||||
|
||||
comment:
|
||||
layout: "reach, diff, flags, files, footer"
|
||||
behavior: default
|
||||
require_changes: no
|
||||
|
|
@ -45,7 +45,7 @@ jobs:
|
|||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update
|
||||
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench-browser-kit:${{ matrix.testbench }}" --no-interaction --no-update
|
||||
composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-suggest
|
||||
|
||||
- name: Execute tests with Local driver
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@ vendor
|
|||
coverage
|
||||
.phpunit.result.cache
|
||||
.idea/
|
||||
database.sqlite
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.3",
|
||||
"orchestra/testbench": "3.8.*|^4.0|^5.0",
|
||||
"orchestra/testbench-browser-kit": "^4.0|^5.0",
|
||||
"phpunit/phpunit": "^8.0|^9.0"
|
||||
},
|
||||
"autoload": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebSockets\Contracts;
|
||||
|
||||
use BeyondCode\LaravelWebSockets\PubSub\Broadcasters\RedisPusherBroadcaster;
|
||||
use Illuminate\Broadcasting\Broadcasters\PusherBroadcaster;
|
||||
use Pusher\Pusher;
|
||||
|
||||
trait PushesToPusher
|
||||
{
|
||||
/**
|
||||
* Get the right Pusher broadcaster for the used driver.
|
||||
*
|
||||
* @param array $app
|
||||
* @return \Illuminate\Broadcasting\Broadcasters\Broadcaster
|
||||
*/
|
||||
public function getPusherBroadcaster(array $app)
|
||||
{
|
||||
if (config('websockets.replication.driver') === 'redis') {
|
||||
return new RedisPusherBroadcaster(
|
||||
new Pusher($app['key'], $app['secret'], $app['id'], config('broadcasting.connections.websockets.options', [])),
|
||||
$app['id'],
|
||||
app('redis'),
|
||||
config('broadcasting.connections.websockets.connection', null)
|
||||
);
|
||||
}
|
||||
|
||||
return new PusherBroadcaster(
|
||||
new Pusher($app['key'], $app['secret'], $app['id'], config('broadcasting.connections.pusher.options', []))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,12 +3,14 @@
|
|||
namespace BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers;
|
||||
|
||||
use BeyondCode\LaravelWebSockets\Apps\App;
|
||||
use BeyondCode\LaravelWebSockets\Contracts\PushesToPusher;
|
||||
use Illuminate\Broadcasting\Broadcasters\PusherBroadcaster;
|
||||
use Illuminate\Http\Request;
|
||||
use Pusher\Pusher;
|
||||
|
||||
class AuthenticateDashboard
|
||||
{
|
||||
use PushesToPusher;
|
||||
|
||||
/**
|
||||
* Find the app by using the header
|
||||
* and then reconstruct the PusherBroadcaster
|
||||
|
|
@ -21,12 +23,11 @@ class AuthenticateDashboard
|
|||
{
|
||||
$app = App::findById($request->header('x-app-id'));
|
||||
|
||||
$broadcaster = new PusherBroadcaster(new Pusher(
|
||||
$app->key,
|
||||
$app->secret,
|
||||
$app->id,
|
||||
[]
|
||||
));
|
||||
$broadcaster = $this->getPusherBroadcaster([
|
||||
'key' => $app->key,
|
||||
'secret' => $app->secret,
|
||||
'id' =>$app->id,
|
||||
]);
|
||||
|
||||
/*
|
||||
* Since the dashboard itself is already secured by the
|
||||
|
|
|
|||
|
|
@ -2,13 +2,15 @@
|
|||
|
||||
namespace BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers;
|
||||
|
||||
use BeyondCode\LaravelWebSockets\Contracts\PushesToPusher;
|
||||
use BeyondCode\LaravelWebSockets\Statistics\Rules\AppId;
|
||||
use Illuminate\Broadcasting\Broadcasters\PusherBroadcaster;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Pusher\Pusher;
|
||||
|
||||
class SendMessage
|
||||
{
|
||||
use PushesToPusher;
|
||||
|
||||
/**
|
||||
* Send the message to the requested channel.
|
||||
*
|
||||
|
|
@ -17,7 +19,7 @@ class SendMessage
|
|||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
$request->validate([
|
||||
'appId' => ['required', new AppId],
|
||||
'key' => 'required|string',
|
||||
'secret' => 'required|string',
|
||||
|
|
@ -26,30 +28,27 @@ class SendMessage
|
|||
'data' => 'required|json',
|
||||
]);
|
||||
|
||||
$this->getPusherBroadcaster($validated)->broadcast(
|
||||
[$validated['channel']],
|
||||
$validated['event'],
|
||||
json_decode($validated['data'], true)
|
||||
);
|
||||
$broadcaster = $this->getPusherBroadcaster([
|
||||
'key' => $request->key,
|
||||
'secret' => $request->secret,
|
||||
'id' => $request->appId,
|
||||
]);
|
||||
|
||||
return 'ok';
|
||||
}
|
||||
try {
|
||||
$broadcaster->broadcast(
|
||||
[$request->channel],
|
||||
$request->event,
|
||||
json_decode($request->data, true)
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'exception' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pusher broadcaster for the current request.
|
||||
*
|
||||
* @param array $validated
|
||||
* @return \Illuminate\Broadcasting\Broadcasters\PusherBroadcaster
|
||||
*/
|
||||
protected function getPusherBroadcaster(array $validated): PusherBroadcaster
|
||||
{
|
||||
$pusher = new Pusher(
|
||||
$validated['key'],
|
||||
$validated['secret'],
|
||||
$validated['appId'],
|
||||
config('broadcasting.connections.pusher.options', [])
|
||||
);
|
||||
|
||||
return new PusherBroadcaster($pusher);
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers;
|
|||
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DashboardApiController
|
||||
class ShowStatistics
|
||||
{
|
||||
/**
|
||||
* Get statistics for an app ID.
|
||||
|
|
@ -15,7 +15,7 @@ class DashboardApiController
|
|||
* @param mixed $appId
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function getStatistics(Request $request, StatisticsDriver $driver, $appId)
|
||||
public function __invoke(Request $request, StatisticsDriver $driver, $appId)
|
||||
{
|
||||
return $driver::get($appId, $request);
|
||||
}
|
||||
|
|
@ -45,10 +45,10 @@ class RedisPusherBroadcaster extends Broadcaster
|
|||
/**
|
||||
* Create a new broadcaster instance.
|
||||
*
|
||||
* @param Pusher $pusher
|
||||
* @param $appId
|
||||
* @param \Illuminate\Contracts\Redis\Factory $redis
|
||||
* @param string|null $connection
|
||||
* @param Pusher $pusher
|
||||
* @param mixed $appId
|
||||
* @param \Illuminate\Contracts\Redis\Factory $redis
|
||||
* @param string|null $connection
|
||||
*/
|
||||
public function __construct(Pusher $pusher, $appId, Redis $redis, $connection = null)
|
||||
{
|
||||
|
|
@ -63,7 +63,6 @@ class RedisPusherBroadcaster extends Broadcaster
|
|||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
|
||||
*/
|
||||
public function auth($request)
|
||||
|
|
@ -83,8 +82,8 @@ class RedisPusherBroadcaster extends Broadcaster
|
|||
/**
|
||||
* Return the valid authentication response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param mixed $result
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param mixed $result
|
||||
* @return mixed
|
||||
* @throws \Pusher\PusherException
|
||||
*/
|
||||
|
|
@ -144,7 +143,7 @@ class RedisPusherBroadcaster extends Broadcaster
|
|||
]);
|
||||
|
||||
foreach ($this->formatChannels($channels) as $channel) {
|
||||
$connection->publish("{$this->appId}:$channel", $payload);
|
||||
$connection->publish("{$this->appId}:{$channel}", $payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ class RedisClient extends LocalClient
|
|||
* @param string $payload
|
||||
* @return void
|
||||
*/
|
||||
protected function onMessage(string $redisChannel, string $payload)
|
||||
public function onMessage(string $redisChannel, string $payload)
|
||||
{
|
||||
$payload = json_decode($payload);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebSockets\Statistics;
|
||||
|
||||
use React\Dns\Resolver\ResolverInterface;
|
||||
use React\Promise\FulfilledPromise;
|
||||
|
||||
class DnsResolver implements ResolverInterface
|
||||
{
|
||||
/**
|
||||
* The internal IP to use.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $internalIp = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* Resolve the DNSes.
|
||||
*
|
||||
* @param string $domain
|
||||
* @return \React\Promise\PromiseInterface
|
||||
*/
|
||||
public function resolve($domain)
|
||||
{
|
||||
return $this->resolveInternal($domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve all domains.
|
||||
*
|
||||
* @param string $domain
|
||||
* @param string $type
|
||||
* @return FulfilledPromise
|
||||
*/
|
||||
public function resolveAll($domain, $type)
|
||||
{
|
||||
return $this->resolveInternal($domain, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the internal domain.
|
||||
*
|
||||
* @param string $domain
|
||||
* @param string $type
|
||||
* @return FulfilledPromise
|
||||
*/
|
||||
private function resolveInternal($domain, $type = null)
|
||||
{
|
||||
return new FulfilledPromise($this->internalIp);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->internalIp;
|
||||
}
|
||||
}
|
||||
|
|
@ -92,10 +92,10 @@ class DatabaseDriver implements StatisticsDriver
|
|||
* Get the records to show to the dashboard.
|
||||
*
|
||||
* @param mixed $appId
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Illuminate\Http\Request|null $request
|
||||
* @return array
|
||||
*/
|
||||
public static function get($appId, Request $request): array
|
||||
public static function get($appId, ?Request $request): array
|
||||
{
|
||||
$class = config('websockets.statistics.database.model');
|
||||
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ interface StatisticsDriver
|
|||
* Get the records to show to the dashboard.
|
||||
*
|
||||
* @param mixed $appId
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Illuminate\Http\Request|null $request
|
||||
* @return void
|
||||
*/
|
||||
public static function get($appId, Request $request);
|
||||
public static function get($appId, ?Request $request);
|
||||
|
||||
/**
|
||||
* Delete statistics from the store,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ use BeyondCode\LaravelWebSockets\Apps\App;
|
|||
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
|
||||
use BeyondCode\LaravelWebSockets\Statistics\Statistic;
|
||||
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
|
||||
use Ratchet\ConnectionInterface;
|
||||
|
||||
class MemoryStatisticsLogger implements StatisticsLogger
|
||||
{
|
||||
|
|
@ -47,12 +46,12 @@ class MemoryStatisticsLogger implements StatisticsLogger
|
|||
/**
|
||||
* Handle the incoming websocket message.
|
||||
*
|
||||
* @param \Ratchet\ConnectionInterface $connection
|
||||
* @param mixed $appId
|
||||
* @return void
|
||||
*/
|
||||
public function webSocketMessage(ConnectionInterface $connection)
|
||||
public function webSocketMessage($appId)
|
||||
{
|
||||
$this->findOrMakeStatisticForAppId($connection->app->id)
|
||||
$this->findOrMakeStatisticForAppId($appId)
|
||||
->webSocketMessage();
|
||||
}
|
||||
|
||||
|
|
@ -71,24 +70,24 @@ class MemoryStatisticsLogger implements StatisticsLogger
|
|||
/**
|
||||
* Handle the new conection.
|
||||
*
|
||||
* @param \Ratchet\ConnectionInterface $connection
|
||||
* @param mixed $appId
|
||||
* @return void
|
||||
*/
|
||||
public function connection(ConnectionInterface $connection)
|
||||
public function connection($appId)
|
||||
{
|
||||
$this->findOrMakeStatisticForAppId($connection->app->id)
|
||||
$this->findOrMakeStatisticForAppId($appId)
|
||||
->connection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle disconnections.
|
||||
*
|
||||
* @param \Ratchet\ConnectionInterface $connection
|
||||
* @param mixed $appId
|
||||
* @return void
|
||||
*/
|
||||
public function disconnection(ConnectionInterface $connection)
|
||||
public function disconnection($appId)
|
||||
{
|
||||
$this->findOrMakeStatisticForAppId($connection->app->id)
|
||||
$this->findOrMakeStatisticForAppId($appId)
|
||||
->disconnection();
|
||||
}
|
||||
|
||||
|
|
@ -126,4 +125,14 @@ class MemoryStatisticsLogger implements StatisticsLogger
|
|||
|
||||
return $this->statistics[$appId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the saved statistics.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getStatistics(): array
|
||||
{
|
||||
return $this->statistics;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ namespace BeyondCode\LaravelWebSockets\Statistics\Logger;
|
|||
|
||||
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
|
||||
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
|
||||
use Ratchet\ConnectionInterface;
|
||||
|
||||
class NullStatisticsLogger implements StatisticsLogger
|
||||
{
|
||||
|
|
@ -38,10 +37,10 @@ class NullStatisticsLogger implements StatisticsLogger
|
|||
/**
|
||||
* Handle the incoming websocket message.
|
||||
*
|
||||
* @param \Ratchet\ConnectionInterface $connection
|
||||
* @param mixed $appId
|
||||
* @return void
|
||||
*/
|
||||
public function webSocketMessage(ConnectionInterface $connection)
|
||||
public function webSocketMessage($appId)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
|
@ -60,10 +59,10 @@ class NullStatisticsLogger implements StatisticsLogger
|
|||
/**
|
||||
* Handle the new conection.
|
||||
*
|
||||
* @param \Ratchet\ConnectionInterface $connection
|
||||
* @param mixed $appId
|
||||
* @return void
|
||||
*/
|
||||
public function connection(ConnectionInterface $connection)
|
||||
public function connection($appId)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
|
@ -71,10 +70,10 @@ class NullStatisticsLogger implements StatisticsLogger
|
|||
/**
|
||||
* Handle disconnections.
|
||||
*
|
||||
* @param \Ratchet\ConnectionInterface $connection
|
||||
* @param mixed $appId
|
||||
* @return void
|
||||
*/
|
||||
public function disconnection(ConnectionInterface $connection)
|
||||
public function disconnection($appId)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,17 +2,15 @@
|
|||
|
||||
namespace BeyondCode\LaravelWebSockets\Statistics\Logger;
|
||||
|
||||
use Ratchet\ConnectionInterface;
|
||||
|
||||
interface StatisticsLogger
|
||||
{
|
||||
/**
|
||||
* Handle the incoming websocket message.
|
||||
*
|
||||
* @param \Ratchet\ConnectionInterface $connection
|
||||
* @param mixed $appId
|
||||
* @return void
|
||||
*/
|
||||
public function webSocketMessage(ConnectionInterface $connection);
|
||||
public function webSocketMessage($appId);
|
||||
|
||||
/**
|
||||
* Handle the incoming API message.
|
||||
|
|
@ -25,18 +23,18 @@ interface StatisticsLogger
|
|||
/**
|
||||
* Handle the new conection.
|
||||
*
|
||||
* @param \Ratchet\ConnectionInterface $connection
|
||||
* @param mixed $appId
|
||||
* @return void
|
||||
*/
|
||||
public function connection(ConnectionInterface $connection);
|
||||
public function connection($appId);
|
||||
|
||||
/**
|
||||
* Handle disconnections.
|
||||
*
|
||||
* @param \Ratchet\ConnectionInterface $connection
|
||||
* @param mixed $appId
|
||||
* @return void
|
||||
*/
|
||||
public function disconnection(ConnectionInterface $connection);
|
||||
public function disconnection($appId);
|
||||
|
||||
/**
|
||||
* Save all the stored statistics.
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ class WebSocketHandler implements MessageComponentInterface
|
|||
|
||||
$message->respond();
|
||||
|
||||
StatisticsLogger::webSocketMessage($connection);
|
||||
StatisticsLogger::webSocketMessage($connection->app->id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -82,7 +82,7 @@ class WebSocketHandler implements MessageComponentInterface
|
|||
'socketId' => $connection->socketId,
|
||||
]);
|
||||
|
||||
StatisticsLogger::disconnection($connection);
|
||||
StatisticsLogger::disconnection($connection->app->id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -200,7 +200,7 @@ class WebSocketHandler implements MessageComponentInterface
|
|||
'socketId' => $connection->socketId,
|
||||
]);
|
||||
|
||||
StatisticsLogger::connection($connection);
|
||||
StatisticsLogger::connection($connection->app->id);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ namespace BeyondCode\LaravelWebSockets;
|
|||
|
||||
use BeyondCode\LaravelWebSockets\Apps\AppManager;
|
||||
use BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers\AuthenticateDashboard;
|
||||
use BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers\DashboardApiController;
|
||||
use BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers\SendMessage;
|
||||
use BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers\ShowDashboard;
|
||||
use BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers\ShowStatistics;
|
||||
use BeyondCode\LaravelWebSockets\Dashboard\Http\Middleware\Authorize as AuthorizeDashboard;
|
||||
use BeyondCode\LaravelWebSockets\PubSub\Broadcasters\RedisPusherBroadcaster;
|
||||
use BeyondCode\LaravelWebSockets\Server\Router;
|
||||
|
|
@ -118,13 +118,15 @@ class WebSocketsServiceProvider extends ServiceProvider
|
|||
*/
|
||||
protected function registerDashboardRoutes()
|
||||
{
|
||||
Route::prefix(config('websockets.dashboard.path'))->group(function () {
|
||||
Route::middleware(config('websockets.dashboard.middleware', [AuthorizeDashboard::class]))->group(function () {
|
||||
Route::get('/', ShowDashboard::class);
|
||||
Route::get('/api/{appId}/statistics', [DashboardApiController::class, 'getStatistics']);
|
||||
Route::post('auth', AuthenticateDashboard::class);
|
||||
Route::post('event', SendMessage::class);
|
||||
});
|
||||
Route::group([
|
||||
'prefix' => config('websockets.dashboard.path'),
|
||||
'as' => 'laravel-websockets.',
|
||||
'middleware' => config('websockets.dashboard.middleware', [AuthorizeDashboard::class]),
|
||||
], function () {
|
||||
Route::get('/', ShowDashboard::class)->name('dashboard');
|
||||
Route::get('/api/{appId}/statistics', ShowStatistics::class)->name('statistics');
|
||||
Route::post('/auth', AuthenticateDashboard::class)->name('auth');
|
||||
Route::post('/event', SendMessage::class)->name('event');
|
||||
});
|
||||
|
||||
return $this;
|
||||
|
|
|
|||
|
|
@ -22,12 +22,12 @@ class ChannelReplicationTest extends TestCase
|
|||
{
|
||||
$connection = $this->getWebSocketConnection();
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:subscribe',
|
||||
'data' => [
|
||||
'channel' => 'basic-channel',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onOpen($connection);
|
||||
|
||||
|
|
@ -47,12 +47,12 @@ class ChannelReplicationTest extends TestCase
|
|||
|
||||
$this->assertTrue($channel->hasConnections());
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:unsubscribe',
|
||||
'data' => [
|
||||
'channel' => 'test-channel',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ class ChannelReplicationTest extends TestCase
|
|||
|
||||
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||
|
||||
$message = new Message('{"event": "client-test", "data": {}, "channel": "test-channel"}');
|
||||
$message = new Message(['event' => 'client-test', 'data' => [], 'channel' => 'test-channel']);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ class ChannelReplicationTest extends TestCase
|
|||
|
||||
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||
|
||||
$message = new Message('{"event": "client-test", "data": {}, "channel": "test-channel"}');
|
||||
$message = new Message(['event' => 'client-test', 'data' => [], 'channel' => 'test-channel']);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
@ -147,9 +147,9 @@ class ChannelReplicationTest extends TestCase
|
|||
{
|
||||
$connection = $this->getConnectedWebSocketConnection();
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:ping',
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ class ChannelTest extends TestCase
|
|||
{
|
||||
$connection = $this->getWebSocketConnection();
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:subscribe',
|
||||
'data' => [
|
||||
'channel' => 'basic-channel',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onOpen($connection);
|
||||
|
||||
|
|
@ -37,12 +37,12 @@ class ChannelTest extends TestCase
|
|||
|
||||
$this->assertTrue($channel->hasConnections());
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:unsubscribe',
|
||||
'data' => [
|
||||
'channel' => 'test-channel',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ class ChannelTest extends TestCase
|
|||
|
||||
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||
|
||||
$message = new Message('{"event": "client-test", "data": {}, "channel": "test-channel"}');
|
||||
$message = new Message(['event' => 'client-test', 'data' => [], 'channel' => 'test-channel']);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ class ChannelTest extends TestCase
|
|||
|
||||
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||
|
||||
$message = new Message('{"event": "client-test", "data": {}, "channel": "test-channel"}');
|
||||
$message = new Message(['event' => 'client-test', 'data' => [], 'channel' => 'test-channel']);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
@ -137,9 +137,9 @@ class ChannelTest extends TestCase
|
|||
{
|
||||
$connection = $this->getConnectedWebSocketConnection();
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:ping',
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,14 +33,14 @@ class PresenceChannelReplicationTest extends TestCase
|
|||
|
||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'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);
|
||||
|
||||
|
|
@ -67,14 +67,14 @@ class PresenceChannelReplicationTest extends TestCase
|
|||
|
||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'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);
|
||||
|
||||
|
|
@ -89,13 +89,13 @@ class PresenceChannelReplicationTest extends TestCase
|
|||
$this->getPublishClient()
|
||||
->resetAssertions();
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:unsubscribe',
|
||||
'data' => [
|
||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||
'channel' => 'presence-channel',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
@ -117,14 +117,14 @@ class PresenceChannelReplicationTest extends TestCase
|
|||
|
||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'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);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@ class PresenceChannelTest extends TestCase
|
|||
|
||||
$connection = $this->getWebSocketConnection();
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:subscribe',
|
||||
'data' => [
|
||||
'auth' => 'invalid',
|
||||
'channel' => 'presence-channel',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onOpen($connection);
|
||||
|
||||
|
|
@ -46,14 +46,14 @@ class PresenceChannelTest extends TestCase
|
|||
|
||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'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);
|
||||
|
||||
|
|
@ -77,14 +77,14 @@ class PresenceChannelTest extends TestCase
|
|||
|
||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'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);
|
||||
|
||||
|
|
@ -92,13 +92,13 @@ class PresenceChannelTest extends TestCase
|
|||
'channel' => 'presence-channel',
|
||||
]);
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:unsubscribe',
|
||||
'data' => [
|
||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||
'channel' => 'presence-channel',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
}
|
||||
|
|
@ -118,14 +118,14 @@ class PresenceChannelTest extends TestCase
|
|||
|
||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'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);
|
||||
|
||||
|
|
@ -150,13 +150,13 @@ class PresenceChannelTest extends TestCase
|
|||
|
||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:unsubscribe',
|
||||
'data' => [
|
||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||
'channel' => 'presence-channel',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,13 +25,13 @@ class PrivateChannelReplicationTest extends TestCase
|
|||
|
||||
$connection = $this->getWebSocketConnection();
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:subscribe',
|
||||
'data' => [
|
||||
'auth' => 'invalid',
|
||||
'channel' => 'private-channel',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onOpen($connection);
|
||||
|
||||
|
|
@ -49,13 +49,13 @@ class PrivateChannelReplicationTest extends TestCase
|
|||
|
||||
$hashedAppSecret = hash_hmac('sha256', $signature, $connection->app->secret);
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:subscribe',
|
||||
'data' => [
|
||||
'auth' => "{$connection->app->key}:{$hashedAppSecret}",
|
||||
'channel' => 'private-channel',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@ class PrivateChannelTest extends TestCase
|
|||
|
||||
$connection = $this->getWebSocketConnection();
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:subscribe',
|
||||
'data' => [
|
||||
'auth' => 'invalid',
|
||||
'channel' => 'private-channel',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onOpen($connection);
|
||||
|
||||
|
|
@ -39,13 +39,13 @@ class PrivateChannelTest extends TestCase
|
|||
|
||||
$hashedAppSecret = hash_hmac('sha256', $signature, $connection->app->secret);
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:subscribe',
|
||||
'data' => [
|
||||
'auth' => "{$connection->app->key}:{$hashedAppSecret}",
|
||||
'channel' => 'private-channel',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
|
|||
|
|
@ -42,4 +42,34 @@ class CleanStatisticsTest extends TestCase
|
|||
|
||||
$this->assertCount(0, WebSocketsStatisticsEntry::where('created_at', '<', $cutOffDate)->get());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_can_clean_the_statistics_for_app_id_only()
|
||||
{
|
||||
Collection::times(60)->each(function (int $index) {
|
||||
WebSocketsStatisticsEntry::create([
|
||||
'app_id' => 'app_id',
|
||||
'peak_connection_count' => 1,
|
||||
'websocket_message_count' => 2,
|
||||
'api_message_count' => 3,
|
||||
'created_at' => Carbon::now()->subDays($index)->startOfDay(),
|
||||
]);
|
||||
});
|
||||
|
||||
Collection::times(60)->each(function (int $index) {
|
||||
WebSocketsStatisticsEntry::create([
|
||||
'app_id' => 'app_id2',
|
||||
'peak_connection_count' => 1,
|
||||
'websocket_message_count' => 2,
|
||||
'api_message_count' => 3,
|
||||
'created_at' => Carbon::now()->subDays($index)->startOfDay(),
|
||||
]);
|
||||
});
|
||||
|
||||
$this->assertCount(120, WebSocketsStatisticsEntry::all());
|
||||
|
||||
Artisan::call('websockets:clean', ['appId' => 'app_id']);
|
||||
|
||||
$this->assertCount(91, WebSocketsStatisticsEntry::all());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ class StartWebSocketServerTest extends TestCase
|
|||
/** @test */
|
||||
public function does_not_fail_if_building_up()
|
||||
{
|
||||
$this->artisan('websockets:serve', ['--test' => true]);
|
||||
$this->artisan('websockets:serve', ['--test' => true, '--debug' => true]);
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class ConnectionTest extends TestCase
|
|||
{
|
||||
$connection = $this->getWebSocketConnection();
|
||||
|
||||
$message = new Message('{"event": "pusher:ping"}');
|
||||
$message = new Message(['event' => 'pusher:ping']);
|
||||
|
||||
$this->pusherServer->onOpen($connection);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebSockets\Tests\Dashboard;
|
||||
|
||||
use BeyondCode\LaravelWebSockets\Tests\Mocks\Message;
|
||||
use BeyondCode\LaravelWebSockets\Tests\Models\User;
|
||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||
|
||||
class AuthTest extends TestCase
|
||||
{
|
||||
/** @test */
|
||||
public function can_authenticate_dashboard_over_channel()
|
||||
{
|
||||
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||
|
||||
$this->pusherServer->onOpen($connection);
|
||||
|
||||
$this->actingAs(factory(User::class)->create())
|
||||
->json('POST', route('laravel-websockets.auth'), [
|
||||
'socket_id' => $connection->socketId,
|
||||
'channel_name' => 'test-channel',
|
||||
], ['x-app-id' => '1234'])
|
||||
->seeJsonStructure([
|
||||
'auth',
|
||||
'channel_data',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function can_authenticate_dashboard_over_private_channel()
|
||||
{
|
||||
$connection = $this->getWebSocketConnection();
|
||||
|
||||
$this->pusherServer->onOpen($connection);
|
||||
|
||||
$signature = "{$connection->socketId}:private-channel";
|
||||
|
||||
$hashedAppSecret = hash_hmac('sha256', $signature, $connection->app->secret);
|
||||
|
||||
$message = new Message([
|
||||
'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',
|
||||
]);
|
||||
|
||||
$this->actingAs(factory(User::class)->create())
|
||||
->json('POST', route('laravel-websockets.auth'), [
|
||||
'socket_id' => $connection->socketId,
|
||||
'channel_name' => 'private-test-channel',
|
||||
], ['x-app-id' => '1234'])
|
||||
->seeJsonStructure([
|
||||
'auth',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function can_authenticate_dashboard_over_presence_channel()
|
||||
{
|
||||
$connection = $this->getWebSocketConnection();
|
||||
|
||||
$this->pusherServer->onOpen($connection);
|
||||
|
||||
$channelData = [
|
||||
'user_id' => 1,
|
||||
'user_info' => [
|
||||
'name' => 'Marcel',
|
||||
],
|
||||
];
|
||||
|
||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||
|
||||
$message = new Message([
|
||||
'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->actingAs(factory(User::class)->create())
|
||||
->json('POST', route('laravel-websockets.auth'), [
|
||||
'socket_id' => $connection->socketId,
|
||||
'channel_name' => 'presence-channel',
|
||||
], ['x-app-id' => '1234'])
|
||||
->seeJsonStructure([
|
||||
'auth',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebSockets\Tests\Dashboard;
|
||||
|
||||
use BeyondCode\LaravelWebSockets\Tests\Models\User;
|
||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||
|
||||
class DashboardTest extends TestCase
|
||||
{
|
||||
/** @test */
|
||||
public function cant_see_dashboard_without_authorization()
|
||||
{
|
||||
$this->get(route('laravel-websockets.dashboard'))
|
||||
->assertResponseStatus(403);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function can_see_dashboard()
|
||||
{
|
||||
$this->actingAs(factory(User::class)->create())
|
||||
->get(route('laravel-websockets.dashboard'))
|
||||
->assertResponseOk()
|
||||
->see('WebSockets Dashboard');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebSockets\Tests\Dashboard;
|
||||
|
||||
use BeyondCode\LaravelWebSockets\Tests\Models\User;
|
||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||
|
||||
class SendMessageTest extends TestCase
|
||||
{
|
||||
/** @test */
|
||||
public function can_send_message()
|
||||
{
|
||||
$this->skipOnRedisReplication();
|
||||
|
||||
// Because the Pusher server is not active,
|
||||
// we expect it to turn out ok: false.
|
||||
|
||||
$this->actingAs(factory(User::class)->create())
|
||||
->json('POST', route('laravel-websockets.event'), [
|
||||
'appId' => '1234',
|
||||
'key' => 'TestKey',
|
||||
'secret' => 'TestSecret',
|
||||
'channel' => 'test-channel',
|
||||
'event' => 'some-event',
|
||||
'data' => json_encode(['data' => 'yes']),
|
||||
])
|
||||
->seeJson([
|
||||
'ok' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function can_send_message_on_redis_replication()
|
||||
{
|
||||
$this->skipOnLocalReplication();
|
||||
|
||||
// Because the Pusher server is not active,
|
||||
// we expect it to turn out ok: false.
|
||||
// However, the driver is set to redis,
|
||||
// so Redis would take care of this
|
||||
// and stream the message to all active servers instead.
|
||||
|
||||
$this->actingAs(factory(User::class)->create())
|
||||
->json('POST', route('laravel-websockets.event'), [
|
||||
'appId' => '1234',
|
||||
'key' => 'TestKey',
|
||||
'secret' => 'TestSecret',
|
||||
'channel' => 'test-channel',
|
||||
'event' => 'some-event',
|
||||
'data' => json_encode(['data' => 'yes']),
|
||||
])
|
||||
->seeJson([
|
||||
'ok' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function cant_send_message_for_invalid_app()
|
||||
{
|
||||
$this->skipOnRedisReplication();
|
||||
|
||||
// Because the Pusher server is not active,
|
||||
// we expect it to turn out ok: false.
|
||||
|
||||
$this->actingAs(factory(User::class)->create())
|
||||
->json('POST', route('laravel-websockets.event'), [
|
||||
'appId' => '9999',
|
||||
'key' => 'TestKey',
|
||||
'secret' => 'TestSecret',
|
||||
'channel' => 'test-channel',
|
||||
'event' => 'some-event',
|
||||
'data' => json_encode(['data' => 'yes']),
|
||||
])
|
||||
->assertResponseStatus(422);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebSockets\Tests\Dashboard;
|
||||
|
||||
use BeyondCode\LaravelWebSockets\Statistics\Logger\MemoryStatisticsLogger;
|
||||
use BeyondCode\LaravelWebSockets\Tests\Models\User;
|
||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||
|
||||
class StatisticsTest extends TestCase
|
||||
{
|
||||
/** @test */
|
||||
public function can_get_statistics()
|
||||
{
|
||||
$connection = $this->getConnectedWebSocketConnection(['channel-1']);
|
||||
|
||||
$logger = new MemoryStatisticsLogger(
|
||||
$this->channelManager,
|
||||
$this->statisticsDriver
|
||||
);
|
||||
|
||||
$logger->webSocketMessage($connection->app->id);
|
||||
$logger->apiMessage($connection->app->id);
|
||||
$logger->connection($connection->app->id);
|
||||
$logger->disconnection($connection->app->id);
|
||||
|
||||
$logger->save();
|
||||
|
||||
$this->actingAs(factory(User::class)->create())
|
||||
->json('GET', route('laravel-websockets.statistics', ['appId' => '1234']))
|
||||
->assertResponseOk()
|
||||
->seeJsonStructure([
|
||||
'peak_connections' => ['x', 'y'],
|
||||
'websocket_message_count' => ['x', 'y'],
|
||||
'api_message_count' => ['x', 'y'],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function cant_get_statistics_for_invalid_app_id()
|
||||
{
|
||||
$connection = $this->getConnectedWebSocketConnection(['channel-1']);
|
||||
|
||||
$logger = new MemoryStatisticsLogger(
|
||||
$this->channelManager,
|
||||
$this->statisticsDriver
|
||||
);
|
||||
|
||||
$logger->webSocketMessage($connection->app->id);
|
||||
$logger->apiMessage($connection->app->id);
|
||||
$logger->connection($connection->app->id);
|
||||
$logger->disconnection($connection->app->id);
|
||||
|
||||
$logger->save();
|
||||
|
||||
$this->actingAs(factory(User::class)->create())
|
||||
->json('GET', route('laravel-websockets.statistics', ['appId' => 'not_found']))
|
||||
->seeJson([
|
||||
'peak_connections' => ['x' => [], 'y' => []],
|
||||
'websocket_message_count' => ['x' => [], 'y' => []],
|
||||
'api_message_count' => ['x' => [], 'y' => []],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -12,13 +12,13 @@ class PusherClientMessageTest extends TestCase
|
|||
{
|
||||
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'client-test',
|
||||
'channel' => 'test-channel',
|
||||
'data' => [
|
||||
'client-event' => 'test',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
@ -42,13 +42,13 @@ class PusherClientMessageTest extends TestCase
|
|||
$connection1 = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||
$connection2 = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'client-test',
|
||||
'channel' => 'test-channel',
|
||||
'data' => [
|
||||
'client-event' => 'test',
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onMessage($connection1, $message);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,17 +2,35 @@
|
|||
|
||||
namespace BeyondCode\LaravelWebSockets\Tests\Mocks;
|
||||
|
||||
class Message extends \Ratchet\RFC6455\Messaging\Message
|
||||
use Ratchet\RFC6455\Messaging\Message as BaseMessage;
|
||||
|
||||
class Message extends BaseMessage
|
||||
{
|
||||
/**
|
||||
* The payload as array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $payload;
|
||||
|
||||
public function __construct($payload)
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param array $payload
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(array $payload)
|
||||
{
|
||||
$this->payload = $payload;
|
||||
}
|
||||
|
||||
public function getPayload()
|
||||
/**
|
||||
* Get the payload as json-encoded string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPayload(): string
|
||||
{
|
||||
return $this->payload;
|
||||
return json_encode($this->payload);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebSockets\Tests\Models;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
protected $fillable = [
|
||||
'name', 'email', 'password',
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'password', 'remember_token',
|
||||
];
|
||||
}
|
||||
|
|
@ -2,7 +2,10 @@
|
|||
|
||||
namespace BeyondCode\LaravelWebSockets\Tests\PubSub;
|
||||
|
||||
use BeyondCode\LaravelWebSockets\PubSub\Drivers\RedisClient;
|
||||
use BeyondCode\LaravelWebSockets\Tests\Mocks\RedisFactory;
|
||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||
use React\EventLoop\Factory as LoopFactory;
|
||||
|
||||
class RedisDriverTest extends TestCase
|
||||
{
|
||||
|
|
@ -46,4 +49,35 @@ class RedisDriverTest extends TestCase
|
|||
'1234:test-channel', $payload,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function redis_listener_responds_properly_on_payload_by_direct_call()
|
||||
{
|
||||
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||
|
||||
$this->pusherServer->onOpen($connection);
|
||||
|
||||
$channelData = [
|
||||
'user_id' => 1,
|
||||
'user_info' => [
|
||||
'name' => 'Marcel',
|
||||
],
|
||||
];
|
||||
|
||||
$payload = json_encode([
|
||||
'appId' => '1234',
|
||||
'event' => 'test',
|
||||
'data' => $channelData,
|
||||
'socket' => $connection->socketId,
|
||||
]);
|
||||
|
||||
$client = (new RedisClient)->boot(
|
||||
LoopFactory::create(), RedisFactory::class
|
||||
);
|
||||
|
||||
$client->onMessage('1234:test-channel', $payload);
|
||||
|
||||
$client->getSubscribeClient()
|
||||
->assertEventDispatched('message');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
namespace BeyondCode\LaravelWebSockets\Tests\Statistics\Controllers;
|
||||
|
||||
use BeyondCode\LaravelWebSockets\Facades\StatisticsLogger;
|
||||
use BeyondCode\LaravelWebSockets\Statistics\Logger\MemoryStatisticsLogger;
|
||||
use BeyondCode\LaravelWebSockets\Statistics\Logger\NullStatisticsLogger;
|
||||
use BeyondCode\LaravelWebSockets\Statistics\Models\WebSocketsStatisticsEntry;
|
||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||
|
||||
class StatisticsLoggerTest extends TestCase
|
||||
|
|
@ -43,4 +46,50 @@ class StatisticsLoggerTest extends TestCase
|
|||
|
||||
$this->assertEquals(1, StatisticsLogger::getForAppId(1234)['peak_connection_count']);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_counts_connections_with_memory_logger()
|
||||
{
|
||||
$connection = $this->getConnectedWebSocketConnection(['channel-1']);
|
||||
|
||||
$logger = new MemoryStatisticsLogger(
|
||||
$this->channelManager,
|
||||
$this->statisticsDriver
|
||||
);
|
||||
|
||||
$logger->webSocketMessage($connection->app->id);
|
||||
$logger->apiMessage($connection->app->id);
|
||||
$logger->connection($connection->app->id);
|
||||
$logger->disconnection($connection->app->id);
|
||||
|
||||
$logger->save();
|
||||
|
||||
$this->assertCount(1, WebSocketsStatisticsEntry::all());
|
||||
|
||||
$entry = WebSocketsStatisticsEntry::first();
|
||||
|
||||
$this->assertEquals(1, $entry->peak_connection_count);
|
||||
$this->assertEquals(1, $entry->websocket_message_count);
|
||||
$this->assertEquals(1, $entry->api_message_count);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_counts_connections_with_null_logger()
|
||||
{
|
||||
$connection = $this->getConnectedWebSocketConnection(['channel-1']);
|
||||
|
||||
$logger = new NullStatisticsLogger(
|
||||
$this->channelManager,
|
||||
$this->statisticsDriver
|
||||
);
|
||||
|
||||
$logger->webSocketMessage($connection->app->id);
|
||||
$logger->apiMessage($connection->app->id);
|
||||
$logger->connection($connection->app->id);
|
||||
$logger->disconnection($connection->app->id);
|
||||
|
||||
$logger->save();
|
||||
|
||||
$this->assertCount(0, WebSocketsStatisticsEntry::all());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,11 @@ use BeyondCode\LaravelWebSockets\Tests\Mocks\Message;
|
|||
use BeyondCode\LaravelWebSockets\Tests\Statistics\Logger\FakeStatisticsLogger;
|
||||
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use Orchestra\Testbench\BrowserKit\TestCase as BaseTestCase;
|
||||
use Ratchet\ConnectionInterface;
|
||||
use React\EventLoop\Factory as LoopFactory;
|
||||
|
||||
abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||
abstract class TestCase extends BaseTestCase
|
||||
{
|
||||
/**
|
||||
* A test Pusher server.
|
||||
|
|
@ -31,6 +32,13 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
|||
*/
|
||||
protected $channelManager;
|
||||
|
||||
/**
|
||||
* The used statistics driver.
|
||||
*
|
||||
* @var \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver
|
||||
*/
|
||||
protected $statisticsDriver;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
@ -38,9 +46,17 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
|||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->pusherServer = app(config('websockets.handlers.websocket'));
|
||||
$this->resetDatabase();
|
||||
|
||||
$this->channelManager = app(ChannelManager::class);
|
||||
$this->loadLaravelMigrations(['--database' => 'sqlite']);
|
||||
|
||||
$this->withFactories(__DIR__.'/database/factories');
|
||||
|
||||
$this->pusherServer = $this->app->make(config('websockets.handlers.websocket'));
|
||||
|
||||
$this->channelManager = $this->app->make(ChannelManager::class);
|
||||
|
||||
$this->statisticsDriver = $this->app->make(StatisticsDriver::class);
|
||||
|
||||
StatisticsLogger::swap(new FakeStatisticsLogger(
|
||||
$this->channelManager,
|
||||
|
|
@ -59,6 +75,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
|||
{
|
||||
return [
|
||||
\BeyondCode\LaravelWebSockets\WebSocketsServiceProvider::class,
|
||||
TestServiceProvider::class,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -67,6 +84,18 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
|||
*/
|
||||
protected function getEnvironmentSetUp($app)
|
||||
{
|
||||
$app['config']->set('app.key', 'wslxrEFGWY6GfGhvN9L3wH3KSRJQQpBD');
|
||||
|
||||
$app['config']->set('auth.providers.users.model', Models\User::class);
|
||||
|
||||
$app['config']->set('database.default', 'sqlite');
|
||||
|
||||
$app['config']->set('database.connections.sqlite', [
|
||||
'driver' => 'sqlite',
|
||||
'database' => __DIR__.'/database.sqlite',
|
||||
'prefix' => '',
|
||||
]);
|
||||
|
||||
$app['config']->set('websockets.apps', [
|
||||
[
|
||||
'name' => 'Test App',
|
||||
|
|
@ -160,12 +189,12 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
|||
$this->pusherServer->onOpen($connection);
|
||||
|
||||
foreach ($channelsToJoin as $channel) {
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:subscribe',
|
||||
'data' => [
|
||||
'channel' => $channel,
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
}
|
||||
|
|
@ -194,14 +223,14 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
|||
|
||||
$signature = "{$connection->socketId}:{$channel}:".json_encode($channelData);
|
||||
|
||||
$message = new Message(json_encode([
|
||||
$message = new Message([
|
||||
'event' => 'pusher:subscribe',
|
||||
'data' => [
|
||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||
'channel' => $channel,
|
||||
'channel_data' => json_encode($channelData),
|
||||
],
|
||||
]));
|
||||
]);
|
||||
|
||||
$this->pusherServer->onMessage($connection, $message);
|
||||
|
||||
|
|
@ -295,4 +324,14 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
|||
->make(ReplicationInterface::class)
|
||||
->getPublishClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function resetDatabase()
|
||||
{
|
||||
file_put_contents(__DIR__.'/database.sqlite', null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace BeyondCode\LaravelWebSockets\Tests;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class TestServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Boot the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
Gate::define('viewWebSocketsDashboard', function ($user = null) {
|
||||
return ! is_null($user);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Model Factories
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This directory should contain each of the model factory definitions for
|
||||
| your application. Factories provide a convenient way to generate new
|
||||
| model instances for testing / seeding your application's database.
|
||||
|
|
||||
*/
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
$factory->define(\BeyondCode\LaravelWebSockets\Tests\Models\User::class, function () {
|
||||
return [
|
||||
'name' => 'Name'.Str::random(5),
|
||||
'email' => Str::random(5).'@gmail.com',
|
||||
'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
|
||||
'remember_token' => Str::random(10),
|
||||
];
|
||||
});
|
||||
Loading…
Reference in New Issue