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
|
- name: Install dependencies
|
||||||
run: |
|
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
|
composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-suggest
|
||||||
|
|
||||||
- name: Execute tests with Local driver
|
- name: Execute tests with Local driver
|
||||||
|
|
|
||||||
|
|
@ -4,3 +4,4 @@ vendor
|
||||||
coverage
|
coverage
|
||||||
.phpunit.result.cache
|
.phpunit.result.cache
|
||||||
.idea/
|
.idea/
|
||||||
|
database.sqlite
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"mockery/mockery": "^1.3",
|
"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"
|
"phpunit/phpunit": "^8.0|^9.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"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;
|
namespace BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers;
|
||||||
|
|
||||||
use BeyondCode\LaravelWebSockets\Apps\App;
|
use BeyondCode\LaravelWebSockets\Apps\App;
|
||||||
|
use BeyondCode\LaravelWebSockets\Contracts\PushesToPusher;
|
||||||
use Illuminate\Broadcasting\Broadcasters\PusherBroadcaster;
|
use Illuminate\Broadcasting\Broadcasters\PusherBroadcaster;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Pusher\Pusher;
|
|
||||||
|
|
||||||
class AuthenticateDashboard
|
class AuthenticateDashboard
|
||||||
{
|
{
|
||||||
|
use PushesToPusher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the app by using the header
|
* Find the app by using the header
|
||||||
* and then reconstruct the PusherBroadcaster
|
* and then reconstruct the PusherBroadcaster
|
||||||
|
|
@ -21,12 +23,11 @@ class AuthenticateDashboard
|
||||||
{
|
{
|
||||||
$app = App::findById($request->header('x-app-id'));
|
$app = App::findById($request->header('x-app-id'));
|
||||||
|
|
||||||
$broadcaster = new PusherBroadcaster(new Pusher(
|
$broadcaster = $this->getPusherBroadcaster([
|
||||||
$app->key,
|
'key' => $app->key,
|
||||||
$app->secret,
|
'secret' => $app->secret,
|
||||||
$app->id,
|
'id' =>$app->id,
|
||||||
[]
|
]);
|
||||||
));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since the dashboard itself is already secured by the
|
* Since the dashboard itself is already secured by the
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,15 @@
|
||||||
|
|
||||||
namespace BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers;
|
namespace BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers;
|
||||||
|
|
||||||
|
use BeyondCode\LaravelWebSockets\Contracts\PushesToPusher;
|
||||||
use BeyondCode\LaravelWebSockets\Statistics\Rules\AppId;
|
use BeyondCode\LaravelWebSockets\Statistics\Rules\AppId;
|
||||||
use Illuminate\Broadcasting\Broadcasters\PusherBroadcaster;
|
use Exception;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Pusher\Pusher;
|
|
||||||
|
|
||||||
class SendMessage
|
class SendMessage
|
||||||
{
|
{
|
||||||
|
use PushesToPusher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send the message to the requested channel.
|
* Send the message to the requested channel.
|
||||||
*
|
*
|
||||||
|
|
@ -17,7 +19,7 @@ class SendMessage
|
||||||
*/
|
*/
|
||||||
public function __invoke(Request $request)
|
public function __invoke(Request $request)
|
||||||
{
|
{
|
||||||
$validated = $request->validate([
|
$request->validate([
|
||||||
'appId' => ['required', new AppId],
|
'appId' => ['required', new AppId],
|
||||||
'key' => 'required|string',
|
'key' => 'required|string',
|
||||||
'secret' => 'required|string',
|
'secret' => 'required|string',
|
||||||
|
|
@ -26,30 +28,27 @@ class SendMessage
|
||||||
'data' => 'required|json',
|
'data' => 'required|json',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->getPusherBroadcaster($validated)->broadcast(
|
$broadcaster = $this->getPusherBroadcaster([
|
||||||
[$validated['channel']],
|
'key' => $request->key,
|
||||||
$validated['event'],
|
'secret' => $request->secret,
|
||||||
json_decode($validated['data'], true)
|
'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(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
return response()->json([
|
||||||
* Get the pusher broadcaster for the current request.
|
'ok' => true,
|
||||||
*
|
]);
|
||||||
* @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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ namespace BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers;
|
||||||
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
|
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class DashboardApiController
|
class ShowStatistics
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get statistics for an app ID.
|
* Get statistics for an app ID.
|
||||||
|
|
@ -15,7 +15,7 @@ class DashboardApiController
|
||||||
* @param mixed $appId
|
* @param mixed $appId
|
||||||
* @return \Illuminate\Http\Response
|
* @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);
|
return $driver::get($appId, $request);
|
||||||
}
|
}
|
||||||
|
|
@ -45,10 +45,10 @@ class RedisPusherBroadcaster extends Broadcaster
|
||||||
/**
|
/**
|
||||||
* Create a new broadcaster instance.
|
* Create a new broadcaster instance.
|
||||||
*
|
*
|
||||||
* @param Pusher $pusher
|
* @param Pusher $pusher
|
||||||
* @param $appId
|
* @param mixed $appId
|
||||||
* @param \Illuminate\Contracts\Redis\Factory $redis
|
* @param \Illuminate\Contracts\Redis\Factory $redis
|
||||||
* @param string|null $connection
|
* @param string|null $connection
|
||||||
*/
|
*/
|
||||||
public function __construct(Pusher $pusher, $appId, Redis $redis, $connection = null)
|
public function __construct(Pusher $pusher, $appId, Redis $redis, $connection = null)
|
||||||
{
|
{
|
||||||
|
|
@ -63,7 +63,6 @@ class RedisPusherBroadcaster extends Broadcaster
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*
|
|
||||||
* @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
|
* @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
|
||||||
*/
|
*/
|
||||||
public function auth($request)
|
public function auth($request)
|
||||||
|
|
@ -83,8 +82,8 @@ class RedisPusherBroadcaster extends Broadcaster
|
||||||
/**
|
/**
|
||||||
* Return the valid authentication response.
|
* Return the valid authentication response.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @param mixed $result
|
* @param mixed $result
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws \Pusher\PusherException
|
* @throws \Pusher\PusherException
|
||||||
*/
|
*/
|
||||||
|
|
@ -144,7 +143,7 @@ class RedisPusherBroadcaster extends Broadcaster
|
||||||
]);
|
]);
|
||||||
|
|
||||||
foreach ($this->formatChannels($channels) as $channel) {
|
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
|
* @param string $payload
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function onMessage(string $redisChannel, string $payload)
|
public function onMessage(string $redisChannel, string $payload)
|
||||||
{
|
{
|
||||||
$payload = json_decode($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.
|
* Get the records to show to the dashboard.
|
||||||
*
|
*
|
||||||
* @param mixed $appId
|
* @param mixed $appId
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request|null $request
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function get($appId, Request $request): array
|
public static function get($appId, ?Request $request): array
|
||||||
{
|
{
|
||||||
$class = config('websockets.statistics.database.model');
|
$class = config('websockets.statistics.database.model');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,10 +61,10 @@ interface StatisticsDriver
|
||||||
* Get the records to show to the dashboard.
|
* Get the records to show to the dashboard.
|
||||||
*
|
*
|
||||||
* @param mixed $appId
|
* @param mixed $appId
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request|null $request
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function get($appId, Request $request);
|
public static function get($appId, ?Request $request);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete statistics from the store,
|
* Delete statistics from the store,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ use BeyondCode\LaravelWebSockets\Apps\App;
|
||||||
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
|
use BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver;
|
||||||
use BeyondCode\LaravelWebSockets\Statistics\Statistic;
|
use BeyondCode\LaravelWebSockets\Statistics\Statistic;
|
||||||
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
|
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
|
||||||
use Ratchet\ConnectionInterface;
|
|
||||||
|
|
||||||
class MemoryStatisticsLogger implements StatisticsLogger
|
class MemoryStatisticsLogger implements StatisticsLogger
|
||||||
{
|
{
|
||||||
|
|
@ -47,12 +46,12 @@ class MemoryStatisticsLogger implements StatisticsLogger
|
||||||
/**
|
/**
|
||||||
* Handle the incoming websocket message.
|
* Handle the incoming websocket message.
|
||||||
*
|
*
|
||||||
* @param \Ratchet\ConnectionInterface $connection
|
* @param mixed $appId
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function webSocketMessage(ConnectionInterface $connection)
|
public function webSocketMessage($appId)
|
||||||
{
|
{
|
||||||
$this->findOrMakeStatisticForAppId($connection->app->id)
|
$this->findOrMakeStatisticForAppId($appId)
|
||||||
->webSocketMessage();
|
->webSocketMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,24 +70,24 @@ class MemoryStatisticsLogger implements StatisticsLogger
|
||||||
/**
|
/**
|
||||||
* Handle the new conection.
|
* Handle the new conection.
|
||||||
*
|
*
|
||||||
* @param \Ratchet\ConnectionInterface $connection
|
* @param mixed $appId
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function connection(ConnectionInterface $connection)
|
public function connection($appId)
|
||||||
{
|
{
|
||||||
$this->findOrMakeStatisticForAppId($connection->app->id)
|
$this->findOrMakeStatisticForAppId($appId)
|
||||||
->connection();
|
->connection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle disconnections.
|
* Handle disconnections.
|
||||||
*
|
*
|
||||||
* @param \Ratchet\ConnectionInterface $connection
|
* @param mixed $appId
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function disconnection(ConnectionInterface $connection)
|
public function disconnection($appId)
|
||||||
{
|
{
|
||||||
$this->findOrMakeStatisticForAppId($connection->app->id)
|
$this->findOrMakeStatisticForAppId($appId)
|
||||||
->disconnection();
|
->disconnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,4 +125,14 @@ class MemoryStatisticsLogger implements StatisticsLogger
|
||||||
|
|
||||||
return $this->statistics[$appId];
|
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\Statistics\Drivers\StatisticsDriver;
|
||||||
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
|
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
|
||||||
use Ratchet\ConnectionInterface;
|
|
||||||
|
|
||||||
class NullStatisticsLogger implements StatisticsLogger
|
class NullStatisticsLogger implements StatisticsLogger
|
||||||
{
|
{
|
||||||
|
|
@ -38,10 +37,10 @@ class NullStatisticsLogger implements StatisticsLogger
|
||||||
/**
|
/**
|
||||||
* Handle the incoming websocket message.
|
* Handle the incoming websocket message.
|
||||||
*
|
*
|
||||||
* @param \Ratchet\ConnectionInterface $connection
|
* @param mixed $appId
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function webSocketMessage(ConnectionInterface $connection)
|
public function webSocketMessage($appId)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
@ -60,10 +59,10 @@ class NullStatisticsLogger implements StatisticsLogger
|
||||||
/**
|
/**
|
||||||
* Handle the new conection.
|
* Handle the new conection.
|
||||||
*
|
*
|
||||||
* @param \Ratchet\ConnectionInterface $connection
|
* @param mixed $appId
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function connection(ConnectionInterface $connection)
|
public function connection($appId)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
@ -71,10 +70,10 @@ class NullStatisticsLogger implements StatisticsLogger
|
||||||
/**
|
/**
|
||||||
* Handle disconnections.
|
* Handle disconnections.
|
||||||
*
|
*
|
||||||
* @param \Ratchet\ConnectionInterface $connection
|
* @param mixed $appId
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function disconnection(ConnectionInterface $connection)
|
public function disconnection($appId)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,15 @@
|
||||||
|
|
||||||
namespace BeyondCode\LaravelWebSockets\Statistics\Logger;
|
namespace BeyondCode\LaravelWebSockets\Statistics\Logger;
|
||||||
|
|
||||||
use Ratchet\ConnectionInterface;
|
|
||||||
|
|
||||||
interface StatisticsLogger
|
interface StatisticsLogger
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Handle the incoming websocket message.
|
* Handle the incoming websocket message.
|
||||||
*
|
*
|
||||||
* @param \Ratchet\ConnectionInterface $connection
|
* @param mixed $appId
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function webSocketMessage(ConnectionInterface $connection);
|
public function webSocketMessage($appId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the incoming API message.
|
* Handle the incoming API message.
|
||||||
|
|
@ -25,18 +23,18 @@ interface StatisticsLogger
|
||||||
/**
|
/**
|
||||||
* Handle the new conection.
|
* Handle the new conection.
|
||||||
*
|
*
|
||||||
* @param \Ratchet\ConnectionInterface $connection
|
* @param mixed $appId
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function connection(ConnectionInterface $connection);
|
public function connection($appId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle disconnections.
|
* Handle disconnections.
|
||||||
*
|
*
|
||||||
* @param \Ratchet\ConnectionInterface $connection
|
* @param mixed $appId
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function disconnection(ConnectionInterface $connection);
|
public function disconnection($appId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save all the stored statistics.
|
* Save all the stored statistics.
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ class WebSocketHandler implements MessageComponentInterface
|
||||||
|
|
||||||
$message->respond();
|
$message->respond();
|
||||||
|
|
||||||
StatisticsLogger::webSocketMessage($connection);
|
StatisticsLogger::webSocketMessage($connection->app->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -82,7 +82,7 @@ class WebSocketHandler implements MessageComponentInterface
|
||||||
'socketId' => $connection->socketId,
|
'socketId' => $connection->socketId,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
StatisticsLogger::disconnection($connection);
|
StatisticsLogger::disconnection($connection->app->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -200,7 +200,7 @@ class WebSocketHandler implements MessageComponentInterface
|
||||||
'socketId' => $connection->socketId,
|
'socketId' => $connection->socketId,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
StatisticsLogger::connection($connection);
|
StatisticsLogger::connection($connection->app->id);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ namespace BeyondCode\LaravelWebSockets;
|
||||||
|
|
||||||
use BeyondCode\LaravelWebSockets\Apps\AppManager;
|
use BeyondCode\LaravelWebSockets\Apps\AppManager;
|
||||||
use BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers\AuthenticateDashboard;
|
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\SendMessage;
|
||||||
use BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers\ShowDashboard;
|
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\Dashboard\Http\Middleware\Authorize as AuthorizeDashboard;
|
||||||
use BeyondCode\LaravelWebSockets\PubSub\Broadcasters\RedisPusherBroadcaster;
|
use BeyondCode\LaravelWebSockets\PubSub\Broadcasters\RedisPusherBroadcaster;
|
||||||
use BeyondCode\LaravelWebSockets\Server\Router;
|
use BeyondCode\LaravelWebSockets\Server\Router;
|
||||||
|
|
@ -118,13 +118,15 @@ class WebSocketsServiceProvider extends ServiceProvider
|
||||||
*/
|
*/
|
||||||
protected function registerDashboardRoutes()
|
protected function registerDashboardRoutes()
|
||||||
{
|
{
|
||||||
Route::prefix(config('websockets.dashboard.path'))->group(function () {
|
Route::group([
|
||||||
Route::middleware(config('websockets.dashboard.middleware', [AuthorizeDashboard::class]))->group(function () {
|
'prefix' => config('websockets.dashboard.path'),
|
||||||
Route::get('/', ShowDashboard::class);
|
'as' => 'laravel-websockets.',
|
||||||
Route::get('/api/{appId}/statistics', [DashboardApiController::class, 'getStatistics']);
|
'middleware' => config('websockets.dashboard.middleware', [AuthorizeDashboard::class]),
|
||||||
Route::post('auth', AuthenticateDashboard::class);
|
], function () {
|
||||||
Route::post('event', SendMessage::class);
|
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;
|
return $this;
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,12 @@ class ChannelReplicationTest extends TestCase
|
||||||
{
|
{
|
||||||
$connection = $this->getWebSocketConnection();
|
$connection = $this->getWebSocketConnection();
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'channel' => 'basic-channel',
|
'channel' => 'basic-channel',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onOpen($connection);
|
$this->pusherServer->onOpen($connection);
|
||||||
|
|
||||||
|
|
@ -47,12 +47,12 @@ class ChannelReplicationTest extends TestCase
|
||||||
|
|
||||||
$this->assertTrue($channel->hasConnections());
|
$this->assertTrue($channel->hasConnections());
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:unsubscribe',
|
'event' => 'pusher:unsubscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'channel' => 'test-channel',
|
'channel' => 'test-channel',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ class ChannelReplicationTest extends TestCase
|
||||||
|
|
||||||
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
$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);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@ class ChannelReplicationTest extends TestCase
|
||||||
|
|
||||||
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
$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);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -147,9 +147,9 @@ class ChannelReplicationTest extends TestCase
|
||||||
{
|
{
|
||||||
$connection = $this->getConnectedWebSocketConnection();
|
$connection = $this->getConnectedWebSocketConnection();
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:ping',
|
'event' => 'pusher:ping',
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,12 @@ class ChannelTest extends TestCase
|
||||||
{
|
{
|
||||||
$connection = $this->getWebSocketConnection();
|
$connection = $this->getWebSocketConnection();
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'channel' => 'basic-channel',
|
'channel' => 'basic-channel',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onOpen($connection);
|
$this->pusherServer->onOpen($connection);
|
||||||
|
|
||||||
|
|
@ -37,12 +37,12 @@ class ChannelTest extends TestCase
|
||||||
|
|
||||||
$this->assertTrue($channel->hasConnections());
|
$this->assertTrue($channel->hasConnections());
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:unsubscribe',
|
'event' => 'pusher:unsubscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'channel' => 'test-channel',
|
'channel' => 'test-channel',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ class ChannelTest extends TestCase
|
||||||
|
|
||||||
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
$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);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -74,7 +74,7 @@ class ChannelTest extends TestCase
|
||||||
|
|
||||||
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
$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);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -137,9 +137,9 @@ class ChannelTest extends TestCase
|
||||||
{
|
{
|
||||||
$connection = $this->getConnectedWebSocketConnection();
|
$connection = $this->getConnectedWebSocketConnection();
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:ping',
|
'event' => 'pusher:ping',
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,14 +33,14 @@ class PresenceChannelReplicationTest extends TestCase
|
||||||
|
|
||||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||||
'channel' => 'presence-channel',
|
'channel' => 'presence-channel',
|
||||||
'channel_data' => json_encode($channelData),
|
'channel_data' => json_encode($channelData),
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -67,14 +67,14 @@ class PresenceChannelReplicationTest extends TestCase
|
||||||
|
|
||||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||||
'channel' => 'presence-channel',
|
'channel' => 'presence-channel',
|
||||||
'channel_data' => json_encode($channelData),
|
'channel_data' => json_encode($channelData),
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -89,13 +89,13 @@ class PresenceChannelReplicationTest extends TestCase
|
||||||
$this->getPublishClient()
|
$this->getPublishClient()
|
||||||
->resetAssertions();
|
->resetAssertions();
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:unsubscribe',
|
'event' => 'pusher:unsubscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||||
'channel' => 'presence-channel',
|
'channel' => 'presence-channel',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -117,14 +117,14 @@ class PresenceChannelReplicationTest extends TestCase
|
||||||
|
|
||||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||||
'channel' => 'presence-channel',
|
'channel' => 'presence-channel',
|
||||||
'channel_data' => json_encode($channelData),
|
'channel_data' => json_encode($channelData),
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@ class PresenceChannelTest extends TestCase
|
||||||
|
|
||||||
$connection = $this->getWebSocketConnection();
|
$connection = $this->getWebSocketConnection();
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => 'invalid',
|
'auth' => 'invalid',
|
||||||
'channel' => 'presence-channel',
|
'channel' => 'presence-channel',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onOpen($connection);
|
$this->pusherServer->onOpen($connection);
|
||||||
|
|
||||||
|
|
@ -46,14 +46,14 @@ class PresenceChannelTest extends TestCase
|
||||||
|
|
||||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||||
'channel' => 'presence-channel',
|
'channel' => 'presence-channel',
|
||||||
'channel_data' => json_encode($channelData),
|
'channel_data' => json_encode($channelData),
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -77,14 +77,14 @@ class PresenceChannelTest extends TestCase
|
||||||
|
|
||||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||||
'channel' => 'presence-channel',
|
'channel' => 'presence-channel',
|
||||||
'channel_data' => json_encode($channelData),
|
'channel_data' => json_encode($channelData),
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -92,13 +92,13 @@ class PresenceChannelTest extends TestCase
|
||||||
'channel' => 'presence-channel',
|
'channel' => 'presence-channel',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:unsubscribe',
|
'event' => 'pusher:unsubscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||||
'channel' => 'presence-channel',
|
'channel' => 'presence-channel',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
}
|
}
|
||||||
|
|
@ -118,14 +118,14 @@ class PresenceChannelTest extends TestCase
|
||||||
|
|
||||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||||
'channel' => 'presence-channel',
|
'channel' => 'presence-channel',
|
||||||
'channel_data' => json_encode($channelData),
|
'channel_data' => json_encode($channelData),
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -150,13 +150,13 @@ class PresenceChannelTest extends TestCase
|
||||||
|
|
||||||
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
$signature = "{$connection->socketId}:presence-channel:".json_encode($channelData);
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:unsubscribe',
|
'event' => 'pusher:unsubscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||||
'channel' => 'presence-channel',
|
'channel' => 'presence-channel',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,13 @@ class PrivateChannelReplicationTest extends TestCase
|
||||||
|
|
||||||
$connection = $this->getWebSocketConnection();
|
$connection = $this->getWebSocketConnection();
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => 'invalid',
|
'auth' => 'invalid',
|
||||||
'channel' => 'private-channel',
|
'channel' => 'private-channel',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onOpen($connection);
|
$this->pusherServer->onOpen($connection);
|
||||||
|
|
||||||
|
|
@ -49,13 +49,13 @@ class PrivateChannelReplicationTest extends TestCase
|
||||||
|
|
||||||
$hashedAppSecret = hash_hmac('sha256', $signature, $connection->app->secret);
|
$hashedAppSecret = hash_hmac('sha256', $signature, $connection->app->secret);
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => "{$connection->app->key}:{$hashedAppSecret}",
|
'auth' => "{$connection->app->key}:{$hashedAppSecret}",
|
||||||
'channel' => 'private-channel',
|
'channel' => 'private-channel',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@ class PrivateChannelTest extends TestCase
|
||||||
|
|
||||||
$connection = $this->getWebSocketConnection();
|
$connection = $this->getWebSocketConnection();
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => 'invalid',
|
'auth' => 'invalid',
|
||||||
'channel' => 'private-channel',
|
'channel' => 'private-channel',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onOpen($connection);
|
$this->pusherServer->onOpen($connection);
|
||||||
|
|
||||||
|
|
@ -39,13 +39,13 @@ class PrivateChannelTest extends TestCase
|
||||||
|
|
||||||
$hashedAppSecret = hash_hmac('sha256', $signature, $connection->app->secret);
|
$hashedAppSecret = hash_hmac('sha256', $signature, $connection->app->secret);
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => "{$connection->app->key}:{$hashedAppSecret}",
|
'auth' => "{$connection->app->key}:{$hashedAppSecret}",
|
||||||
'channel' => 'private-channel',
|
'channel' => 'private-channel',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,4 +42,34 @@ class CleanStatisticsTest extends TestCase
|
||||||
|
|
||||||
$this->assertCount(0, WebSocketsStatisticsEntry::where('created_at', '<', $cutOffDate)->get());
|
$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 */
|
/** @test */
|
||||||
public function does_not_fail_if_building_up()
|
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);
|
$this->assertTrue(true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class ConnectionTest extends TestCase
|
||||||
{
|
{
|
||||||
$connection = $this->getWebSocketConnection();
|
$connection = $this->getWebSocketConnection();
|
||||||
|
|
||||||
$message = new Message('{"event": "pusher:ping"}');
|
$message = new Message(['event' => 'pusher:ping']);
|
||||||
|
|
||||||
$this->pusherServer->onOpen($connection);
|
$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']);
|
$connection = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'client-test',
|
'event' => 'client-test',
|
||||||
'channel' => 'test-channel',
|
'channel' => 'test-channel',
|
||||||
'data' => [
|
'data' => [
|
||||||
'client-event' => 'test',
|
'client-event' => 'test',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -42,13 +42,13 @@ class PusherClientMessageTest extends TestCase
|
||||||
$connection1 = $this->getConnectedWebSocketConnection(['test-channel']);
|
$connection1 = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||||
$connection2 = $this->getConnectedWebSocketConnection(['test-channel']);
|
$connection2 = $this->getConnectedWebSocketConnection(['test-channel']);
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'client-test',
|
'event' => 'client-test',
|
||||||
'channel' => 'test-channel',
|
'channel' => 'test-channel',
|
||||||
'data' => [
|
'data' => [
|
||||||
'client-event' => 'test',
|
'client-event' => 'test',
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection1, $message);
|
$this->pusherServer->onMessage($connection1, $message);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,35 @@
|
||||||
|
|
||||||
namespace BeyondCode\LaravelWebSockets\Tests\Mocks;
|
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;
|
protected $payload;
|
||||||
|
|
||||||
public function __construct($payload)
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*
|
||||||
|
* @param array $payload
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(array $payload)
|
||||||
{
|
{
|
||||||
$this->payload = $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;
|
namespace BeyondCode\LaravelWebSockets\Tests\PubSub;
|
||||||
|
|
||||||
|
use BeyondCode\LaravelWebSockets\PubSub\Drivers\RedisClient;
|
||||||
|
use BeyondCode\LaravelWebSockets\Tests\Mocks\RedisFactory;
|
||||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||||
|
use React\EventLoop\Factory as LoopFactory;
|
||||||
|
|
||||||
class RedisDriverTest extends TestCase
|
class RedisDriverTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
@ -46,4 +49,35 @@ class RedisDriverTest extends TestCase
|
||||||
'1234:test-channel', $payload,
|
'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;
|
namespace BeyondCode\LaravelWebSockets\Tests\Statistics\Controllers;
|
||||||
|
|
||||||
use BeyondCode\LaravelWebSockets\Facades\StatisticsLogger;
|
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;
|
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||||
|
|
||||||
class StatisticsLoggerTest extends TestCase
|
class StatisticsLoggerTest extends TestCase
|
||||||
|
|
@ -43,4 +46,50 @@ class StatisticsLoggerTest extends TestCase
|
||||||
|
|
||||||
$this->assertEquals(1, StatisticsLogger::getForAppId(1234)['peak_connection_count']);
|
$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\Tests\Statistics\Logger\FakeStatisticsLogger;
|
||||||
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
|
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
|
||||||
use GuzzleHttp\Psr7\Request;
|
use GuzzleHttp\Psr7\Request;
|
||||||
|
use Orchestra\Testbench\BrowserKit\TestCase as BaseTestCase;
|
||||||
use Ratchet\ConnectionInterface;
|
use Ratchet\ConnectionInterface;
|
||||||
use React\EventLoop\Factory as LoopFactory;
|
use React\EventLoop\Factory as LoopFactory;
|
||||||
|
|
||||||
abstract class TestCase extends \Orchestra\Testbench\TestCase
|
abstract class TestCase extends BaseTestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* A test Pusher server.
|
* A test Pusher server.
|
||||||
|
|
@ -31,6 +32,13 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
*/
|
*/
|
||||||
protected $channelManager;
|
protected $channelManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The used statistics driver.
|
||||||
|
*
|
||||||
|
* @var \BeyondCode\LaravelWebSockets\Statistics\Drivers\StatisticsDriver
|
||||||
|
*/
|
||||||
|
protected $statisticsDriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
@ -38,9 +46,17 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
{
|
{
|
||||||
parent::setUp();
|
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(
|
StatisticsLogger::swap(new FakeStatisticsLogger(
|
||||||
$this->channelManager,
|
$this->channelManager,
|
||||||
|
|
@ -59,6 +75,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
\BeyondCode\LaravelWebSockets\WebSocketsServiceProvider::class,
|
\BeyondCode\LaravelWebSockets\WebSocketsServiceProvider::class,
|
||||||
|
TestServiceProvider::class,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,6 +84,18 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
*/
|
*/
|
||||||
protected function getEnvironmentSetUp($app)
|
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', [
|
$app['config']->set('websockets.apps', [
|
||||||
[
|
[
|
||||||
'name' => 'Test App',
|
'name' => 'Test App',
|
||||||
|
|
@ -160,12 +189,12 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
$this->pusherServer->onOpen($connection);
|
$this->pusherServer->onOpen($connection);
|
||||||
|
|
||||||
foreach ($channelsToJoin as $channel) {
|
foreach ($channelsToJoin as $channel) {
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'channel' => $channel,
|
'channel' => $channel,
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
}
|
}
|
||||||
|
|
@ -194,14 +223,14 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
|
|
||||||
$signature = "{$connection->socketId}:{$channel}:".json_encode($channelData);
|
$signature = "{$connection->socketId}:{$channel}:".json_encode($channelData);
|
||||||
|
|
||||||
$message = new Message(json_encode([
|
$message = new Message([
|
||||||
'event' => 'pusher:subscribe',
|
'event' => 'pusher:subscribe',
|
||||||
'data' => [
|
'data' => [
|
||||||
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
'auth' => $connection->app->key.':'.hash_hmac('sha256', $signature, $connection->app->secret),
|
||||||
'channel' => $channel,
|
'channel' => $channel,
|
||||||
'channel_data' => json_encode($channelData),
|
'channel_data' => json_encode($channelData),
|
||||||
],
|
],
|
||||||
]));
|
]);
|
||||||
|
|
||||||
$this->pusherServer->onMessage($connection, $message);
|
$this->pusherServer->onMessage($connection, $message);
|
||||||
|
|
||||||
|
|
@ -295,4 +324,14 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
->make(ReplicationInterface::class)
|
->make(ReplicationInterface::class)
|
||||||
->getPublishClient();
|
->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