Skip to content

Commit

Permalink
Upgraded tests
Browse files Browse the repository at this point in the history
  • Loading branch information
slavarazum committed Dec 8, 2023
1 parent 735c972 commit d5c08be
Show file tree
Hide file tree
Showing 16 changed files with 256 additions and 81 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
},
"require-dev": {
"laravel/pint": "^1.13",
"m6web/redis-mock": "^5.4",
"m6web/redis-mock": "v5.6",
"nunomaduro/collision": "^7.10",
"nunomaduro/larastan": "^2.6",
"orchestra/testbench": "^7.22.1|^8.0",
Expand Down
47 changes: 23 additions & 24 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,39 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
executionOrder="random"
failOnWarning="true"
failOnRisky="true"
failOnEmptyTestSuite="true"
beStrictAboutOutputDuringTests="true"
verbose="true"
cacheDirectory=".phpunit.cache"
backupStaticProperties="false"
>
<testsuites>
<testsuite name="Qruto Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<coverage>
<include>
<directory suffix=".php">./src</directory>
</include>
<report>
<html outputDirectory="build/coverage"/>
<text outputFile="build/coverage.txt"/>
<clover outputFile="build/logs/clover.xml"/>
</report>
</coverage>
<logging>
<junit outputFile="build/report.junit.xml"/>
</logging>
<testsuites>
<testsuite name="Qruto Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<coverage>
<report>
<html outputDirectory="build/coverage"/>
<text outputFile="build/coverage.txt"/>
<clover outputFile="build/logs/clover.xml"/>
</report>
</coverage>
<logging>
<junit outputFile="build/report.junit.xml"/>
</logging>
<source>
<include>
<directory suffix=".php">./src</directory>
</include>
</source>
</phpunit>
10 changes: 0 additions & 10 deletions src/Events/PresenceChannelLeaveEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,4 @@ public function broadcastAs(): string
{
return 'leave';
}
//
// /**
// * Get the data to broadcast.
// *
// * @return array<string, mixed>
// */
// public function broadcastWith(): array
// {
// return $this->userInfo;
// }
}
17 changes: 15 additions & 2 deletions src/Storage/BroadcastEventHistoryRedisStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ public function getEventsFrom(string $id): Collection

public function lastEventTimestamp(): int
{
$keys = array_keys($this->db->xRevRange('broadcasted_events', '+', '-', 1));
$keys = array_keys($this->db->xRevRange('broadcasted_events', '-', '+', 1));

return explode('-', reset($keys))[0] ?? 0;
return empty($keys) ? 0 : explode('-', reset($keys))[0];
}

public function pushEvent(BroadcastingEvent $event)
{
$this->removeOldEvents();

$eventData = \get_object_vars($event);
$eventData['data'] = json_encode($eventData['data']);
$id = $this->db->xAdd('broadcasted_events', '*', $eventData);
Expand All @@ -52,4 +54,15 @@ public function pushEvent(BroadcastingEvent $event)

return $id;
}

public function removeOldEvents()
{
// Calculate the threshold timestamp. Events older than this should be removed.
$thresholdTimestamp = now()->subSeconds($this->lifetime)->getPreciseTimestamp(3);

// Fetch all events up to the threshold
$oldEvents = $this->db->xRange('broadcasted_events', '-', $thresholdTimestamp.'-0');

$this->db->xDel('broadcasted_events', \array_keys($oldEvents));
}
}
3 changes: 1 addition & 2 deletions src/Storage/BroadcastingEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ public function __construct(
public ?string $id,
public ?string $socket,
) {
// $this->timestamp = now()->getTimestamp();
}

public function send(): void
Expand All @@ -32,7 +31,7 @@ public static function fake(array $attributes = []): self
return new self(
channel: $attributes['channel'] ?? fake()->word,
name: $attributes['event'] ?? fake()->word,
id: $attributes['id'] ?? fake()->uuid,
id: null,
data: $attributes['data'] ?? ['message' => fake()->sentence],
socket: $attributes['socket'] ?? fake()->randomNumber(6, true).'.'.fake()->randomNumber(6, true),
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php

use Qruto\LaravelWave\Storage\BroadcastingEvent;
use Qruto\LaravelWave\Tests\Events\PublicEvent;
use Qruto\LaravelWave\Tests\Events\SomePrivateEvent;
use Qruto\LaravelWave\Tests\Support\Events\PublicEvent;
use Qruto\LaravelWave\Tests\Support\Events\SomePrivateEvent;

it('not received event, fired before connect', function () {
PublicEvent::dispatch();
Expand Down
7 changes: 3 additions & 4 deletions tests/EventsTest.php → tests/Feature/EventsTest.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<?php

use Qruto\LaravelWave\Tests\Events\PublicEvent;
use Qruto\LaravelWave\Tests\Events\SomePresenceEvent;
use Qruto\LaravelWave\Tests\Events\SomePrivateEvent;
use Qruto\LaravelWave\Tests\Support\Events\PublicEvent;
use Qruto\LaravelWave\Tests\Support\Events\SomePresenceEvent;
use Qruto\LaravelWave\Tests\Support\Events\SomePrivateEvent;
use Qruto\LaravelWave\Tests\Support\User;

it('successfully receives events for guest user', function () {
// HERE: Bug with guest user
auth()->logout();

$connection = waveConnection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
use Illuminate\Support\Facades\Redis;
use Qruto\LaravelWave\Events\PresenceChannelJoinEvent;
use Qruto\LaravelWave\Events\SseConnectionClosedEvent;
use Qruto\LaravelWave\Tests\Events\SomePresenceEvent;
use Qruto\LaravelWave\Tests\Events\SomePrivateEvent;
use Qruto\LaravelWave\Tests\Support\Events\SomePresenceEvent;
use Qruto\LaravelWave\Tests\Support\Events\SomePrivateEvent;
use Qruto\LaravelWave\Tests\Support\User;

use function Pest\Laravel\actingAs;
Expand All @@ -22,17 +22,20 @@
Event::assertDispatched(PresenceChannelJoinEvent::class);
});

it('stores user in redis presence channel pool', function () {
it('stores user in redis presence channel hash', function () {
$connection = waveConnection();

$key = 'presence_channel:presence-presence-channel:user:'.auth()->user()->getAuthIdentifierForBroadcasting();
$key = channelMemberKey('presence-presence-channel', 'users');

joinRequest('presence-channel', $this->user, $connection->id());

expect((bool) Redis::exists($key))
expect((bool) Redis::hexists($key, $this->user->getAuthIdentifier()))
->toBeTrue()
->and(json_decode(Redis::hget($key, 'connections'), true)[0])
->toBe($connection->id());
->and(json_decode(Redis::hget($key, $this->user->getAuthIdentifier()), true))
->toBe([
'id' => auth()->user()->id,
'name' => auth()->user()->name,
]);
});

test('join request respond with actual count of channel users', function () {
Expand Down Expand Up @@ -124,6 +127,9 @@

$connectionRick->assertEventReceived('presence-presence-channel.leave');
$connectionRick->assertEventReceived('presence-presence-channel-2.leave');

$connectionMorty->assertEventNotReceived('presence-presence-channel.leave');
$connectionMorty->assertEventNotReceived('presence-presence-channel-2.leave');
});

it('successfully stores several connections', function () {
Expand All @@ -133,9 +139,9 @@
joinRequest('presence-channel', $this->user, $connectionOne->id());
joinRequest('presence-channel', $this->user, $connectionTwo->id());

$key = 'presence_channel:presence-presence-channel:user:'.auth()->user()->getAuthIdentifier();
$key = channelMemberKey('presence-presence-channel', auth()->user()->getAuthIdentifier(), 'user_sockets');

$storedUserConnections = json_decode(Redis::hget($key, 'connections'), true);
$storedUserConnections = Redis::smembers($key);

expect($storedUserConnections)->toBe([
$connectionOne->id(),
Expand All @@ -152,12 +158,12 @@

leaveRequest('presence-channel', $this->user, $connectionOne->id());

$key = 'presence_channel:presence-presence-channel:user:'.auth()->user()->getAuthIdentifier();
$key = channelMemberKey('presence-presence-channel', auth()->user()->getAuthIdentifier(), 'user_sockets');

$storedUserConnections = json_decode(Redis::hget($key, 'connections'), true);
$storedUserConnections = Redis::smembers($key);

expect($storedUserConnections)->toBe([
$connectionTwo->id(),
1 => $connectionTwo->id(),
]);
});

Expand Down
File renamed without changes.
33 changes: 31 additions & 2 deletions tests/Pest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,41 @@
use Qruto\LaravelWave\Tests\Support\User;
use Qruto\LaravelWave\Tests\TestCase;

use function Pest\Laravel\actingAs;
use function PHPUnit\Framework\assertCount;
use function PHPUnit\Framework\assertSame;
use function PHPUnit\Framework\assertTrue;

uses(TestCase::class)->in(__DIR__);

uses()->beforeEach(function () {
$redisMock = new RedisConnectionMock();
$this->instance('redis', $redisMock);
$redisMock->flushdb();
$redisMock->flushEventsQueue();

$this->user = User::factory()->create();

Broadcast::channel('private-channel', fn () => true);
Broadcast::channel('presence-channel', fn () => ['id' => request()->user()->id, 'name' => request()->user()->name]);
Broadcast::channel('presence-channel', fn () => [
'id' => request()->user()->id,
'name' => request()->user()->name,
]);

$this->actingAs($this->user);
})->in(__DIR__);

function waveConnection(Authenticatable $user = null, string $lastEventId = null)
function channelMemberKey(string $channel, string ...$suffixes): string
{
return implode(':', array_merge(["broadcasting_channels:$channel"], $suffixes));
}

function userChannelsKey(Authenticatable $user): string
{
return implode(':', ['broadcasting_channels', $user->getAuthIdentifier(), 'user_channels']);
}

function waveConnection(?Authenticatable $user = null, ?string $lastEventId = null): object
{
return new class($user, $lastEventId)
{
Expand Down Expand Up @@ -141,6 +160,12 @@ public function hasReceived($event)

public function getSentEvents()
{
$user = auth()->user();

if ($this->user) {
actingAs($this->user);
}

if (! $this->sentEvents) {
$rawEvents = array_filter(explode("\n\n", $this->response->streamedContent()));
$this->sentEvents = Collection::make($rawEvents)->map(function ($event) {
Expand All @@ -159,6 +184,10 @@ public function getSentEvents()
})->mapToGroups(fn ($item) => [$item['event'] => ['data' => $item['data'], 'id' => $item['id']]]);
}

if ($user) {
actingAs($user);
}

return $this->sentEvents;
}
};
Expand Down
Loading

0 comments on commit d5c08be

Please sign in to comment.