Skip to content

Commit

Permalink
Tidies test suite (#31)
Browse files Browse the repository at this point in the history
* wip

* wip

* refactor tests

* wip

* Fix code styling

* fix tests

* wip

* wip

* clean up

* Fix code styling
  • Loading branch information
joedixon authored Dec 6, 2023
1 parent 2b69889 commit 1fc723b
Show file tree
Hide file tree
Showing 28 changed files with 650 additions and 593 deletions.
25 changes: 7 additions & 18 deletions tests/ApiGatewayTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,8 @@ protected function defineEnvironment($app)

/**
* Connect to the server.
*
* @param string $connectionId $name
* @param string $appKey
*/
public function connect($connectionId = 'abc-123', $appKey = 'pusher-key'): void
public function connect(string $connectionId = 'abc-123', string $appKey = 'pusher-key'): void
{
resolve(Server::class)
->handle(Request::fromLambdaEvent(
Expand All @@ -94,10 +91,8 @@ public function connect($connectionId = 'abc-123', $appKey = 'pusher-key'): void

/**
* Send a message to the connected client.
*
* @param string $appKey
*/
public function send(array $message, ?string $connectionId = 'abc-123', $appKey = 'pusher-key'): void
public function send(array $message, ?string $connectionId = 'abc-123', string $appKey = 'pusher-key'): void
{
$this->connect($connectionId, $appKey);

Expand All @@ -115,10 +110,8 @@ public function send(array $message, ?string $connectionId = 'abc-123', $appKey

/**
* Subscribe to a channel.
*
* @param string $appKey
*/
public function subscribe(string $channel, ?array $data = [], ?string $auth = null, ?string $connectionId = 'abc-123', $appKey = 'pusher-key'): void
public function subscribe(string $channel, ?array $data = [], ?string $auth = null, ?string $connectionId = 'abc-123', string $appKey = 'pusher-key'): void
{
$data = ! empty($data) ? json_encode($data) : null;

Expand All @@ -140,10 +133,8 @@ public function subscribe(string $channel, ?array $data = [], ?string $auth = nu

/**
* Disconnect a connected client.
*
* @param string $connectionId
*/
public function disconnect($connectionId = 'abc-123'): void
public function disconnect(string $connectionId = 'abc-123'): void
{
resolve(Server::class)
->handle(Request::fromLambdaEvent(
Expand All @@ -158,10 +149,8 @@ public function disconnect($connectionId = 'abc-123'): void

/**
* Assert a message was sent to the given connection.
*
* @return void
*/
public function assertSent(?string $connectionId = null, mixed $message = null, ?int $times = null)
public function assertSent(?string $connectionId = null, mixed $message = null, ?int $times = null): void
{
Bus::assertDispatched(SendToConnection::class, function ($job) use ($connectionId, $message) {
return ($connectionId ? $job->connectionId === $connectionId : true)
Expand All @@ -180,8 +169,8 @@ public function assertSent(?string $connectionId = null, mixed $message = null,
*/
public function managedConnection(): ?Connection
{
$connection = Arr::last(connectionManager()->all());
$connection = Arr::last(connections()->all());

return connectionManager()->find($connection->identifier());
return connections()->find($connection->identifier());
}
}
61 changes: 55 additions & 6 deletions tests/Connection.php → tests/FakeConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,27 @@
use Laravel\Reverb\Contracts\ApplicationProvider;
use Laravel\Reverb\Contracts\Connection as BaseConnection;

class Connection extends BaseConnection
class FakeConnection extends BaseConnection
{
use GeneratesPusherIdentifiers;

/**
* Messages reveived by the connection.
*
* @var array<int, string>
*/
public $messages = [];

public $identifier = '19c1c8e8-351b-4eb5-b6d9-6cbfc54a3446';
/**
* Connection identifier.
*/
public string $identifier = '19c1c8e8-351b-4eb5-b6d9-6cbfc54a3446';

/**
* Connection socket ID.
*
* @var string
*/
public $id;

public function __construct(?string $identifier = null)
Expand All @@ -25,11 +38,17 @@ public function __construct(?string $identifier = null)
}
}

/**
* Get the raw socket connection identifier.
*/
public function identifier(): string
{
return $this->identifier;
}

/**
* Get the normalized socket ID.
*/
public function id(): string
{
if (! $this->id) {
Expand All @@ -39,53 +58,83 @@ public function id(): string
return $this->id;
}

/**
* Get the application the connection belongs to.
*/
public function app(): Application
{
return app()->make(ApplicationProvider::class)->findByKey('pusher-key');
}

/**
* Get the origin of the connection.
*/
public function origin(): string
{
return 'http://localhost';
}

public function setLastSeenAt(int $time): Connection
/**
* Set the connection last seen at timestamp.
*/
public function setLastSeenAt(int $time): FakeConnection
{
$this->lastSeenAt = $time;

return $this;
}

/**
* Set the connection as pinged.
*/
public function setHasBeenPinged(): void
{
$this->hasBeenPinged = true;
}

/**
* Send a message to the connection.
*/
public function send(string $message): void
{
$this->messages[] = $message;
}

/**
* Terminate a connection.
*/
public function terminate(): void
{
//
}

public function assertSent(array $message): void
/**
* Assert the given message was received by the connection.
*/
public function assertReceived(array $message): void
{
Assert::assertContains(json_encode($message), $this->messages);
}

public function assertSendCount(int $count): void
/**
* Assert the connection received the given message count.
*/
public function assertReceivedCount(int $count): void
{
Assert::assertCount($count, $this->messages);
}

public function assertNothingSent(): void
/**
* Assert the connection didn't receive any messages.
*/
public function assertNothingReceived(): void
{
Assert::assertEmpty($this->messages);
}

/**
* Assert the connection has been pinged.
*/
public function assertHasBeenPinged(): void
{
Assert::assertTrue($this->hasBeenPinged);
Expand Down
62 changes: 27 additions & 35 deletions tests/Feature/ApiGateway/ServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Bus;
use Laravel\Reverb\Contracts\ChannelManager;
use Laravel\Reverb\Contracts\ConnectionManager;
use Laravel\Reverb\Jobs\PingInactiveConnections;
use Laravel\Reverb\Jobs\PruneStaleConnections;
use Laravel\Reverb\Servers\ApiGateway\Request;
Expand All @@ -17,28 +15,28 @@
});

afterEach(function () {
channelManager()->flush();
connectionManager()->flush();
channels()->flush();
connections()->flush();
});

it('can handle a new connection', function () {
$this->connect();

$this->assertCount(1, connectionManager()->all());
$this->assertCount(1, connections()->all());
});

it('can handle multiple new connections', function () {
$this->connect();
$this->connect('def-456');

$this->assertCount(2, connectionManager()->all());
$this->assertCount(2, connections()->all());
});

it('can handle connections to different applications', function () {
$this->connect();
$this->connect('def-456', appKey: 'pusher-key-2');

$connections = connectionManager()->all();
$connections = connections()->all();

expect(Arr::first($connections)->identifier())->toBe('abc-123');
expect(Arr::first($connections)->app()->id())->toBe('123456');
Expand All @@ -49,9 +47,9 @@
it('can subscribe to a channel', function () {
$this->subscribe('test-channel');

expect(connectionManager()->all())->toHaveCount(1);
expect(connections()->all())->toHaveCount(1);

expect(channelManager()->find('test-channel')->connections())->toHaveCount(1);
expect(channels()->find('test-channel')->connections())->toHaveCount(1);

$this->assertSent('abc-123', '{"event":"pusher_internal:subscription_succeeded","channel":"test-channel"}');
});
Expand Down Expand Up @@ -97,11 +95,11 @@
$this->subscribe('presence-test-channel', data: $data, connectionId: 'ghi-789');
$this->assertSent('def-456', '{"event":"pusher_internal:member_added","data":{"user_id":3,"user_info":{"name":"Test User 3"}},"channel":"presence-test-channel"}');

expect(connectionManager()->all())->toHaveCount(3);
expect(connections()->all())->toHaveCount(3);

$this->disconnect('ghi-789');

expect(connectionManager()->all())->toHaveCount(2);
expect(connections()->all())->toHaveCount(2);

$this->assertSent(
message: '{"event":"pusher_internal:member_removed","data":{"user_id":3},"channel":"presence-test-channel"}',
Expand Down Expand Up @@ -146,12 +144,12 @@
$this->subscribe('test-channel');
$this->assertSent('abc-123', 'subscription_succeeded', 1);

$connection = Arr::first(connectionManager()->all());
$connection = Arr::first(connections()->all());
$connection->setLastSeenAt(time() - 60 * 10);
connectionManager()->connect($connection);
connections()->connect($connection);

(new PingInactiveConnections)->handle(
channelManager()
channels()
);

$this->assertSent('abc-123', '{"event":"pusher:ping"}', 1);
Expand All @@ -160,21 +158,21 @@
it('it can disconnect inactive subscribers', function () {
$this->subscribe('test-channel');

$connection = Arr::first(connectionManager()->all());
$connection = Arr::first(connections()->all());
$connection->setLastSeenAt(time() - 60 * 10);
connectionManager()->connect($connection);
connections()->connect($connection);

(new PingInactiveConnections)->handle(
channelManager()
channels()
);
$this->assertSent('abc-123', '{"event":"pusher:ping"}');

(new PruneStaleConnections)->handle(
channelManager()
channels()
);

// expect(connectionManager()->all())->toHaveCount(0);
expect(channelManager()->find('test-channel')->connections())->toHaveCount(0);
// expect(connections()->all())->toHaveCount(0);
expect(channels()->find('test-channel')->connections())->toHaveCount(0);

$this->assertSent('abc-123', '{"event":"pusher:error","data":"{\"code\":4201,\"message\":\"Pong reply not received in time\"}"}', 1);
});
Expand Down Expand Up @@ -202,12 +200,12 @@
$this->subscribe('private-test-channel-3', data: ['foo' => 'bar']);
$this->subscribe('presence-test-channel-4', data: ['user_id' => 1, 'user_info' => ['name' => 'Test User 1']]);

expect(connectionManager()->all())->toHaveCount(1);
expect(channelManager()->all())->toHaveCount(4);
expect(connections()->all())->toHaveCount(1);
expect(channels()->all())->toHaveCount(4);

$connection = $this->managedConnection();

collect(channelManager()->all())->each(function ($channel) use ($connection) {
collect(channels()->all())->each(function ($channel) use ($connection) {
expect($channel->connections())->toHaveCount(1);
expect(collect($channel->connections())->map(fn ($conn, $index) => (string) $index))->toContain($connection->identifier());
});
Expand All @@ -223,13 +221,13 @@
$this->subscribe('test-channel', connectionId: 'def-456');
$this->subscribe('private-test-channel-3', connectionId: 'def-456', data: ['foo' => 'bar']);

expect(connectionManager()->all())->toHaveCount(2);
expect(channelManager()->all())->toHaveCount(4);
expect(connections()->all())->toHaveCount(2);
expect(channels()->all())->toHaveCount(4);

expect(channelManager()->find('test-channel')->connections())->toHaveCount(2);
expect(channelManager()->find('test-channel-2')->connections())->toHaveCount(1);
expect(channelManager()->find('private-test-channel-3')->connections())->toHaveCount(2);
expect(channelManager()->find('presence-test-channel-4')->connections())->toHaveCount(1);
expect(channels()->find('test-channel')->connections())->toHaveCount(2);
expect(channels()->find('test-channel-2')->connections())->toHaveCount(1);
expect(channels()->find('private-test-channel-3')->connections())->toHaveCount(2);
expect(channels()->find('presence-test-channel-4')->connections())->toHaveCount(1);
});

it('fails to subscribe to a private channel with invalid auth signature', function () {
Expand Down Expand Up @@ -301,9 +299,3 @@

$this->assertSent('abc-123', 'connection_established', 1);
});

it('clears application state between requests', function () {
$this->subscribe('test-channel');

expect($this->app->make(ChannelManager::class)->app())->toBeNull();
})->todo();
Loading

0 comments on commit 1fc723b

Please sign in to comment.