2021-02-27 05:01:37 +13:00
|
|
|
<?php
|
|
|
|
|
2022-08-01 22:22:04 +12:00
|
|
|
namespace Tests\Unit\Messaging;
|
2021-02-27 05:01:37 +13:00
|
|
|
|
2021-06-30 01:11:14 +12:00
|
|
|
use Appwrite\Auth\Auth;
|
2021-10-08 04:35:17 +13:00
|
|
|
use Utopia\Database\Document;
|
2021-06-30 01:11:14 +12:00
|
|
|
use Appwrite\Messaging\Adapter\Realtime;
|
2021-02-27 05:01:37 +13:00
|
|
|
use PHPUnit\Framework\TestCase;
|
2022-08-14 22:33:36 +12:00
|
|
|
use Utopia\Database\ID;
|
2022-08-19 16:04:33 +12:00
|
|
|
use Utopia\Database\Role;
|
2021-02-27 05:01:37 +13:00
|
|
|
|
2021-06-30 01:11:14 +12:00
|
|
|
class MessagingChannelsTest extends TestCase
|
2021-02-27 05:01:37 +13:00
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Configures how many Connections the Test should Mock.
|
|
|
|
*/
|
|
|
|
public $connectionsPerChannel = 10;
|
|
|
|
|
2021-06-30 01:11:14 +12:00
|
|
|
public Realtime $realtime;
|
2021-02-27 05:01:37 +13:00
|
|
|
public $connectionsCount = 0;
|
|
|
|
public $connectionsAuthenticated = 0;
|
|
|
|
public $connectionsGuest = 0;
|
|
|
|
public $connectionsTotal = 0;
|
|
|
|
public $allChannels = [
|
|
|
|
'files',
|
|
|
|
'files.1',
|
|
|
|
'collections',
|
|
|
|
'collections.1',
|
|
|
|
'collections.1.documents',
|
|
|
|
'documents',
|
|
|
|
'documents.1',
|
2021-03-25 03:17:17 +13:00
|
|
|
'executions',
|
|
|
|
'executions.1',
|
|
|
|
'functions.1',
|
2021-02-27 05:01:37 +13:00
|
|
|
];
|
|
|
|
|
|
|
|
public function setUp(): void
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Setup global Counts
|
|
|
|
*/
|
|
|
|
$this->connectionsAuthenticated = count($this->allChannels) * $this->connectionsPerChannel;
|
|
|
|
$this->connectionsGuest = count($this->allChannels) * $this->connectionsPerChannel;
|
|
|
|
$this->connectionsTotal = $this->connectionsAuthenticated + $this->connectionsGuest;
|
|
|
|
|
2021-06-30 01:11:14 +12:00
|
|
|
$this->realtime = new Realtime();
|
|
|
|
|
2021-02-27 05:01:37 +13:00
|
|
|
/**
|
2021-02-27 05:07:53 +13:00
|
|
|
* Add Authenticated Clients
|
2021-02-27 05:01:37 +13:00
|
|
|
*/
|
|
|
|
for ($i = 0; $i < $this->connectionsPerChannel; $i++) {
|
|
|
|
foreach ($this->allChannels as $index => $channel) {
|
2021-06-30 01:11:14 +12:00
|
|
|
$user = new Document([
|
2022-08-14 22:33:36 +12:00
|
|
|
'$id' => ID::custom('user' . $this->connectionsCount),
|
2021-02-27 05:01:37 +13:00
|
|
|
'memberships' => [
|
|
|
|
[
|
2022-09-09 11:58:54 +12:00
|
|
|
'$id' => ID::custom('member' . $i),
|
2022-08-14 22:33:36 +12:00
|
|
|
'teamId' => ID::custom('team' . $i),
|
2022-09-09 11:58:54 +12:00
|
|
|
'confirm' => true,
|
2021-02-27 05:01:37 +13:00
|
|
|
'roles' => [
|
2022-08-19 16:04:33 +12:00
|
|
|
empty($index % 2)
|
|
|
|
? Auth::USER_ROLE_ADMIN
|
2022-08-27 15:16:37 +12:00
|
|
|
: 'member',
|
2021-02-27 05:01:37 +13:00
|
|
|
]
|
|
|
|
]
|
|
|
|
]
|
2021-06-30 01:11:14 +12:00
|
|
|
]);
|
|
|
|
|
2021-07-01 02:29:33 +12:00
|
|
|
$roles = Auth::getRoles($user);
|
2021-06-30 01:11:14 +12:00
|
|
|
|
2021-07-14 03:18:02 +12:00
|
|
|
$parsedChannels = Realtime::convertChannels([0 => $channel], $user->getId());
|
2021-02-27 05:01:37 +13:00
|
|
|
|
2021-06-30 01:11:14 +12:00
|
|
|
$this->realtime->subscribe(
|
2021-02-27 05:01:37 +13:00
|
|
|
'1',
|
|
|
|
$this->connectionsCount,
|
2021-05-20 20:54:18 +12:00
|
|
|
$roles,
|
|
|
|
$parsedChannels
|
2021-02-27 05:01:37 +13:00
|
|
|
);
|
|
|
|
|
|
|
|
$this->connectionsCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-02-27 05:07:53 +13:00
|
|
|
* Add Guest Clients
|
2021-02-27 05:01:37 +13:00
|
|
|
*/
|
|
|
|
for ($i = 0; $i < $this->connectionsPerChannel; $i++) {
|
|
|
|
foreach ($this->allChannels as $index => $channel) {
|
2021-06-30 01:11:14 +12:00
|
|
|
$user = new Document([
|
2021-02-27 05:01:37 +13:00
|
|
|
'$id' => ''
|
2021-06-30 01:11:14 +12:00
|
|
|
]);
|
2021-02-27 05:01:37 +13:00
|
|
|
|
2021-07-01 02:29:33 +12:00
|
|
|
$roles = Auth::getRoles($user);
|
2021-06-30 01:11:14 +12:00
|
|
|
|
2021-07-14 03:18:02 +12:00
|
|
|
$parsedChannels = Realtime::convertChannels([0 => $channel], $user->getId());
|
2021-05-20 20:54:18 +12:00
|
|
|
|
2021-06-30 01:11:14 +12:00
|
|
|
$this->realtime->subscribe(
|
2021-02-27 05:01:37 +13:00
|
|
|
'1',
|
|
|
|
$this->connectionsCount,
|
2021-05-20 20:54:18 +12:00
|
|
|
$roles,
|
|
|
|
$parsedChannels
|
2021-02-27 05:01:37 +13:00
|
|
|
);
|
|
|
|
|
|
|
|
$this->connectionsCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function tearDown(): void
|
|
|
|
{
|
2021-06-30 01:11:14 +12:00
|
|
|
unset($this->realtime);
|
2021-02-27 05:01:37 +13:00
|
|
|
$this->connectionsCount = 0;
|
|
|
|
}
|
|
|
|
|
2022-08-01 22:22:04 +12:00
|
|
|
public function testSubscriptions(): void
|
2021-02-27 05:01:37 +13:00
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Check for 1 project.
|
|
|
|
*/
|
2021-06-30 01:11:14 +12:00
|
|
|
$this->assertCount(1, $this->realtime->subscriptions);
|
2021-02-27 05:01:37 +13:00
|
|
|
|
|
|
|
/**
|
2021-02-27 05:07:53 +13:00
|
|
|
* Check for correct amount of subscriptions:
|
2022-09-14 18:10:42 +12:00
|
|
|
* - XXX users (2 roles per user)
|
2021-02-27 05:09:47 +13:00
|
|
|
* - XXX teams
|
2022-09-14 18:10:42 +12:00
|
|
|
* - XXX team roles (2 roles per team)
|
|
|
|
* - XXX member roles (2 roles per team)
|
2022-08-03 16:17:49 +12:00
|
|
|
* - 1 guests
|
|
|
|
* - 1 users
|
2022-09-14 18:10:42 +12:00
|
|
|
* - 1 users unverified
|
2021-02-27 05:01:37 +13:00
|
|
|
*/
|
2022-09-14 18:10:42 +12:00
|
|
|
$userRoles = 2 * $this->connectionsAuthenticated;
|
|
|
|
$userGroupRoles = 2;
|
|
|
|
$teamRoles = 2 * $this->connectionsPerChannel;
|
|
|
|
$memberRoles = 2 * $this->connectionsPerChannel;
|
|
|
|
$guestRoles = 1;
|
|
|
|
$this->assertCount(($userRoles + $userGroupRoles + $teamRoles + $memberRoles + $guestRoles), $this->realtime->subscriptions['1']);
|
2021-02-27 05:01:37 +13:00
|
|
|
|
|
|
|
/**
|
2021-02-27 05:07:53 +13:00
|
|
|
* Check for connections
|
|
|
|
* - Authenticated
|
|
|
|
* - Guests
|
2021-02-27 05:01:37 +13:00
|
|
|
*/
|
2021-06-30 01:11:14 +12:00
|
|
|
$this->assertCount($this->connectionsTotal, $this->realtime->connections);
|
2021-10-08 09:24:09 +13:00
|
|
|
|
2021-06-30 01:11:14 +12:00
|
|
|
$this->realtime->unsubscribe(-1);
|
2021-02-27 06:26:22 +13:00
|
|
|
|
2021-06-30 01:11:14 +12:00
|
|
|
$this->assertCount($this->connectionsTotal, $this->realtime->connections);
|
2022-09-14 18:10:42 +12:00
|
|
|
$this->assertCount(($userRoles + $userGroupRoles + $teamRoles + $memberRoles + $guestRoles), $this->realtime->subscriptions['1']);
|
2021-02-27 06:26:22 +13:00
|
|
|
|
2021-03-02 00:23:45 +13:00
|
|
|
for ($i = 0; $i < $this->connectionsCount; $i++) {
|
2021-06-30 01:11:14 +12:00
|
|
|
$this->realtime->unsubscribe($i);
|
2021-02-27 06:26:22 +13:00
|
|
|
|
2021-06-30 01:11:14 +12:00
|
|
|
$this->assertCount(($this->connectionsCount - $i - 1), $this->realtime->connections);
|
2021-02-27 06:26:22 +13:00
|
|
|
}
|
|
|
|
|
2021-06-30 01:11:14 +12:00
|
|
|
$this->assertEmpty($this->realtime->connections);
|
|
|
|
$this->assertEmpty($this->realtime->subscriptions);
|
2021-02-27 05:01:37 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-08-15 19:20:10 +12:00
|
|
|
* Tests Wildcard ("any") Permissions on every channel.
|
2021-02-27 05:01:37 +13:00
|
|
|
*/
|
2022-08-01 22:22:04 +12:00
|
|
|
public function testWildcardPermission(): void
|
2021-02-27 05:01:37 +13:00
|
|
|
{
|
|
|
|
foreach ($this->allChannels as $index => $channel) {
|
|
|
|
$event = [
|
|
|
|
'project' => '1',
|
2022-08-19 16:04:33 +12:00
|
|
|
'roles' => [Role::any()->toString()],
|
2021-02-27 05:01:37 +13:00
|
|
|
'data' => [
|
|
|
|
'channels' => [
|
|
|
|
0 => $channel,
|
|
|
|
]
|
|
|
|
]
|
|
|
|
];
|
|
|
|
|
2021-07-14 03:18:02 +12:00
|
|
|
$receivers = $this->realtime->getSubscribers($event);
|
2021-02-27 05:01:37 +13:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Every Client subscribed to the Wildcard should receive this event.
|
|
|
|
*/
|
|
|
|
$this->assertCount($this->connectionsTotal / count($this->allChannels), $receivers, $channel);
|
|
|
|
|
|
|
|
foreach ($receivers as $receiver) {
|
|
|
|
/**
|
|
|
|
* Making sure the right clients receive the event.
|
|
|
|
*/
|
|
|
|
$this->assertStringEndsWith($index, $receiver);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-01 22:22:04 +12:00
|
|
|
public function testRolePermissions(): void
|
2021-02-27 05:01:37 +13:00
|
|
|
{
|
2022-08-19 16:04:33 +12:00
|
|
|
$roles = [
|
|
|
|
Role::guests()->toString(),
|
|
|
|
Role::users()->toString()
|
|
|
|
];
|
2021-02-27 05:01:37 +13:00
|
|
|
foreach ($this->allChannels as $index => $channel) {
|
|
|
|
foreach ($roles as $role) {
|
|
|
|
$permissions = [$role];
|
|
|
|
|
|
|
|
$event = [
|
|
|
|
'project' => '1',
|
2021-07-14 03:18:02 +12:00
|
|
|
'roles' => $permissions,
|
2021-02-27 05:01:37 +13:00
|
|
|
'data' => [
|
|
|
|
'channels' => [
|
|
|
|
0 => $channel,
|
|
|
|
]
|
|
|
|
]
|
|
|
|
];
|
|
|
|
|
2021-07-14 03:18:02 +12:00
|
|
|
$receivers = $this->realtime->getSubscribers($event);
|
2021-02-27 05:01:37 +13:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Every Role subscribed to a Channel should receive this event.
|
|
|
|
*/
|
|
|
|
$this->assertCount($this->connectionsPerChannel, $receivers, $channel);
|
|
|
|
|
|
|
|
foreach ($receivers as $receiver) {
|
|
|
|
/**
|
|
|
|
* Making sure the right clients receive the event.
|
|
|
|
*/
|
|
|
|
$this->assertStringEndsWith($index, $receiver);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-01 22:22:04 +12:00
|
|
|
public function testUserPermissions(): void
|
2021-02-27 05:01:37 +13:00
|
|
|
{
|
|
|
|
foreach ($this->allChannels as $index => $channel) {
|
|
|
|
$permissions = [];
|
|
|
|
for ($i = 0; $i < $this->connectionsPerChannel; $i++) {
|
2022-08-19 16:04:33 +12:00
|
|
|
$permissions[] = Role::user(ID::custom('user' . (!empty($i) ? $i : '') . $index))->toString();
|
2021-02-27 05:01:37 +13:00
|
|
|
}
|
|
|
|
$event = [
|
|
|
|
'project' => '1',
|
2021-07-14 03:18:02 +12:00
|
|
|
'roles' => $permissions,
|
2021-02-27 05:01:37 +13:00
|
|
|
'data' => [
|
|
|
|
'channels' => [
|
|
|
|
0 => $channel,
|
|
|
|
]
|
|
|
|
]
|
|
|
|
];
|
|
|
|
|
2021-07-14 03:18:02 +12:00
|
|
|
$receivers = $this->realtime->getSubscribers($event);
|
2021-02-27 05:01:37 +13:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Every Client subscribed to a Channel should receive this event.
|
|
|
|
*/
|
|
|
|
$this->assertCount($this->connectionsAuthenticated / count($this->allChannels), $receivers, $channel);
|
|
|
|
|
|
|
|
foreach ($receivers as $receiver) {
|
|
|
|
/**
|
|
|
|
* Making sure the right clients receive the event.
|
|
|
|
*/
|
|
|
|
$this->assertStringEndsWith($index, $receiver);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-01 22:22:04 +12:00
|
|
|
public function testTeamPermissions(): void
|
2021-02-27 05:01:37 +13:00
|
|
|
{
|
|
|
|
foreach ($this->allChannels as $index => $channel) {
|
|
|
|
$permissions = [];
|
|
|
|
|
|
|
|
for ($i = 0; $i < $this->connectionsPerChannel; $i++) {
|
2022-08-19 16:04:33 +12:00
|
|
|
$permissions[] = Role::team(ID::custom('team' . $i))->toString();
|
2022-09-09 11:58:54 +12:00
|
|
|
$permissions[] = Role::member(ID::custom('member' . $i))->toString();
|
2021-02-27 05:01:37 +13:00
|
|
|
}
|
|
|
|
$event = [
|
|
|
|
'project' => '1',
|
2021-07-14 03:18:02 +12:00
|
|
|
'roles' => $permissions,
|
2021-02-27 05:01:37 +13:00
|
|
|
'data' => [
|
|
|
|
'channels' => [
|
|
|
|
0 => $channel,
|
|
|
|
]
|
|
|
|
]
|
|
|
|
];
|
|
|
|
|
2021-07-14 03:18:02 +12:00
|
|
|
$receivers = $this->realtime->getSubscribers($event);
|
2021-02-27 05:01:37 +13:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Every Team Member should receive this event.
|
|
|
|
*/
|
|
|
|
$this->assertCount($this->connectionsAuthenticated / count($this->allChannels), $receivers, $channel);
|
|
|
|
|
|
|
|
foreach ($receivers as $receiver) {
|
|
|
|
/**
|
|
|
|
* Making sure the right clients receive the event.
|
|
|
|
*/
|
|
|
|
$this->assertStringEndsWith($index, $receiver);
|
|
|
|
}
|
|
|
|
|
2022-09-09 11:58:54 +12:00
|
|
|
$role = empty($index % 2)
|
|
|
|
? Auth::USER_ROLE_ADMIN
|
|
|
|
: 'member';
|
|
|
|
|
2022-08-19 16:04:33 +12:00
|
|
|
$permissions = [
|
2022-09-09 11:58:54 +12:00
|
|
|
Role::team(ID::custom('team' . $index), $role)->toString(),
|
|
|
|
Role::member(ID::custom('member' . $index))->toString()
|
2022-08-19 16:04:33 +12:00
|
|
|
];
|
2021-02-27 05:01:37 +13:00
|
|
|
|
|
|
|
$event = [
|
|
|
|
'project' => '1',
|
2021-07-14 03:18:02 +12:00
|
|
|
'roles' => $permissions,
|
2021-02-27 05:01:37 +13:00
|
|
|
'data' => [
|
|
|
|
'channels' => [
|
|
|
|
0 => $channel,
|
|
|
|
]
|
|
|
|
]
|
|
|
|
];
|
|
|
|
|
2021-07-14 03:18:02 +12:00
|
|
|
$receivers = $this->realtime->getSubscribers($event);
|
2021-02-27 05:01:37 +13:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Only 1 Team Member of a role should have access to a specific channel.
|
|
|
|
*/
|
|
|
|
$this->assertCount(1, $receivers, $channel);
|
|
|
|
|
|
|
|
foreach ($receivers as $receiver) {
|
|
|
|
/**
|
|
|
|
* Making sure the right clients receive the event.
|
|
|
|
*/
|
|
|
|
$this->assertStringEndsWith($index, $receiver);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|