UPSTREAM BASELINE: nextcloud/spreed v22.0.12 (без изменений)
Type checking / changes (push) Has been cancelled
Type checking / test (push) Has been cancelled
Type checking / typescript-summary (push) Has been cancelled
Node tests / changes (push) Has been cancelled
Node tests / test (push) Has been cancelled
Node tests / test-summary (push) Has been cancelled
Type checking / changes (push) Has been cancelled
Type checking / test (push) Has been cancelled
Type checking / typescript-summary (push) Has been cancelled
Node tests / changes (push) Has been cancelled
Node tests / test (push) Has been cancelled
Node tests / test-summary (push) Has been cancelled
Источник: https://github.com/nextcloud/spreed/archive/refs/tags/v22.0.12.tar.gz С этого коммита ветка официального Nextcloud Talk отрезана (решение владельца 2026-07-06). Все дальнейшие изменения — только наши; версии релизов: 22.0.12-f7.N.
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Tests\php\Service;
|
||||
|
||||
use OCA\Talk\Room;
|
||||
use OCA\Talk\Service\AvatarService;
|
||||
use OCA\Talk\Service\EmojiService;
|
||||
use OCA\Talk\Service\RoomService;
|
||||
use OCP\Files\IAppData;
|
||||
use OCP\IAvatarManager;
|
||||
use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\Security\ISecureRandom;
|
||||
use OCP\Server;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\Attributes\Group;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Test\TestCase;
|
||||
|
||||
#[Group('DB')]
|
||||
class AvatarServiceTest extends TestCase {
|
||||
protected IAppData&MockObject $appData;
|
||||
protected IL10N&MockObject $l;
|
||||
protected IURLGenerator&MockObject $url;
|
||||
protected ISecureRandom&MockObject $random;
|
||||
protected RoomService&MockObject $roomService;
|
||||
protected IAvatarManager&MockObject $avatarManager;
|
||||
protected EmojiService $emojiService;
|
||||
protected ?AvatarService $service = null;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->appData = $this->createMock(IAppData::class);
|
||||
$this->l = $this->createMock(IL10N::class);
|
||||
$this->url = $this->createMock(IURLGenerator::class);
|
||||
$this->random = $this->createMock(ISecureRandom::class);
|
||||
$this->roomService = $this->createMock(RoomService::class);
|
||||
$this->avatarManager = $this->createMock(IAvatarManager::class);
|
||||
$this->emojiService = Server::get(EmojiService::class);
|
||||
$this->service = new AvatarService(
|
||||
$this->appData,
|
||||
$this->l,
|
||||
$this->url,
|
||||
$this->random,
|
||||
$this->roomService,
|
||||
$this->avatarManager,
|
||||
$this->emojiService,
|
||||
);
|
||||
}
|
||||
|
||||
public static function dataGetAvatarVersion(): array {
|
||||
return [
|
||||
['', 'STRING WITH 8 CHARS'],
|
||||
['1', '1'],
|
||||
['1.png', '1'],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('dataGetAvatarVersion')]
|
||||
public function testGetAvatarVersion(string $avatar, string $expected): void {
|
||||
/** @var Room&MockObject $room */
|
||||
$room = $this->createMock(Room::class);
|
||||
$room->method('getAvatar')
|
||||
->willReturn($avatar);
|
||||
$actual = $this->service->getAvatarVersion($room);
|
||||
if ($expected === 'STRING WITH 8 CHARS') {
|
||||
$this->assertEquals(8, strlen($actual));
|
||||
} else {
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Tests\php\Service;
|
||||
|
||||
use OCA\Talk\Chat\ChatManager;
|
||||
use OCA\Talk\Config;
|
||||
use OCA\Talk\Manager;
|
||||
use OCA\Talk\Service\BreakoutRoomService;
|
||||
use OCA\Talk\Service\ParticipantService;
|
||||
use OCA\Talk\Service\RoomService;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\IL10N;
|
||||
use OCP\Notification\IManager as INotificationManager;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Test\TestCase;
|
||||
|
||||
class BreakoutRoomServiceTest extends TestCase {
|
||||
protected Config&MockObject $config;
|
||||
protected Manager&MockObject $manager;
|
||||
protected RoomService&MockObject $roomService;
|
||||
protected ParticipantService&MockObject $participantService;
|
||||
protected ChatManager&MockObject $chatManager;
|
||||
protected INotificationManager&MockObject $notificationManager;
|
||||
protected ITimeFactory&MockObject $timeFactory;
|
||||
protected IEventDispatcher&MockObject $dispatcher;
|
||||
protected IL10N&MockObject $l;
|
||||
protected BreakoutRoomService $service;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->config = $this->createMock(Config::class);
|
||||
$this->manager = $this->createMock(Manager::class);
|
||||
$this->roomService = $this->createMock(RoomService::class);
|
||||
$this->participantService = $this->createMock(ParticipantService::class);
|
||||
$this->chatManager = $this->createMock(ChatManager::class);
|
||||
$this->notificationManager = $this->createMock(INotificationManager::class);
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
$this->dispatcher = $this->createMock(IEventDispatcher::class);
|
||||
$this->l = $this->createMock(IL10N::class);
|
||||
$this->service = new BreakoutRoomService(
|
||||
$this->config,
|
||||
$this->manager,
|
||||
$this->roomService,
|
||||
$this->participantService,
|
||||
$this->chatManager,
|
||||
$this->notificationManager,
|
||||
$this->timeFactory,
|
||||
$this->dispatcher,
|
||||
$this->l
|
||||
);
|
||||
}
|
||||
public static function dataParseAttendeeMap(): array {
|
||||
return [
|
||||
'Empty string means no map' => ['', 3, [], false],
|
||||
'Empty array means no map' => ['[]', 3, [], false],
|
||||
'OK' => [json_encode([1 => 1, 13 => 0, 42 => 2]), 3, [1 => 1, 13 => 0, 42 => 2], false],
|
||||
'Not an array' => ['"hello"', 3, null, true],
|
||||
'Room above max' => [json_encode([1 => 0, 13 => 1, 42 => 2]), 2, null, true],
|
||||
'Room below min' => [json_encode([1 => 0, 13 => -1, 42 => 2]), 3, null, true],
|
||||
'Room not int' => [json_encode([1 => 0, 13 => 'foo', 42 => 2]), 3, null, true],
|
||||
'Room null' => [json_encode([1 => 0, 13 => null, 42 => 2]), 3, null, true],
|
||||
'Attendee not int' => [json_encode([1 => 0, 'foo' => 1, 42 => 2]), 3, null, true],
|
||||
'Attendee negative' => [json_encode([1 => 0, -13 => 1, 42 => 2]), 3, null, true],
|
||||
'Attendee zero' => [json_encode([1 => 0, 0 => 1, 42 => 2]), 3, null, true],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('dataParseAttendeeMap')]
|
||||
public function testParseAttendeeMap(string $json, int $max, ?array $expected, bool $throws): void {
|
||||
if ($throws) {
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
}
|
||||
|
||||
$actual = self::invokePrivate($this->service, 'parseAttendeeMap', [$json, $max]);
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Tests\php\Service;
|
||||
|
||||
use OCA\Talk\Service\CertificateService;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
class CertificateServiceTest extends TestCase {
|
||||
protected CertificateService $service;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$logger = $this->createMock(LoggerInterface::class);
|
||||
$this->service = new CertificateService($logger);
|
||||
}
|
||||
|
||||
public function testGetParsedTlsHost(): void {
|
||||
$actual = $this->service->getParsedTlsHost('domain.com');
|
||||
$this->assertEquals($actual, 'domain.com');
|
||||
|
||||
$actual = $this->service->getParsedTlsHost('subdomain.domain.com');
|
||||
$this->assertEquals($actual, 'subdomain.domain.com');
|
||||
|
||||
$actual = $this->service->getParsedTlsHost('https://domain.com');
|
||||
$this->assertEquals($actual, 'domain.com');
|
||||
|
||||
$actual = $this->service->getParsedTlsHost('https://domain.com:1234');
|
||||
$this->assertEquals($actual, 'domain.com:1234');
|
||||
|
||||
$actual = $this->service->getParsedTlsHost('https://domain.com:1234/path/1/');
|
||||
$this->assertEquals($actual, 'domain.com:1234');
|
||||
|
||||
$actual = $this->service->getParsedTlsHost('http://domain.com:1234/path/1/');
|
||||
$this->assertNull($actual);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Tests\php\Service;
|
||||
|
||||
use OCA\Talk\Exceptions\UnauthorizedException;
|
||||
use OCA\Talk\Service\ChecksumVerificationService;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use Test\TestCase;
|
||||
|
||||
class ChecksumVerificationServiceTest extends TestCase {
|
||||
protected ChecksumVerificationService $service;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->service = new ChecksumVerificationService();
|
||||
}
|
||||
|
||||
public static function dataValidateRequest(): array {
|
||||
$validRandom = md5(random_bytes(15));
|
||||
$fakeData = json_encode(['fake' => 'data']);
|
||||
$validSecret = 'valid secret';
|
||||
$validChecksum = hash_hmac('sha256', $validRandom . $fakeData, $validSecret);
|
||||
return [
|
||||
['', '', '', '', '', false],
|
||||
['1234', '', '', '', 'Invalid random provided', false],
|
||||
[str_repeat('1', 32), '', '', '', 'Invalid checksum provided', false],
|
||||
[str_repeat('1', 32), 'fake', '', '', 'No secret provided', false],
|
||||
[str_repeat('1', 32), 'fake', 'invalid', '', 'Invalid HMAC provided', false],
|
||||
[$validRandom, $validChecksum, $validSecret, $fakeData, '', true],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('dataValidateRequest')]
|
||||
public function testValidateRequest(string $random, string $checksum, string $secret, string $token, string $exceptionMessage, bool $expectedReturn): void {
|
||||
if ($exceptionMessage) {
|
||||
$this->expectException(UnauthorizedException::class);
|
||||
$this->expectExceptionMessage($exceptionMessage);
|
||||
}
|
||||
$actual = $this->service->validateRequest($random, $checksum, $secret, $token);
|
||||
if (!$exceptionMessage) {
|
||||
$this->assertEquals($expectedReturn, $actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Tests\php\Service;
|
||||
|
||||
use OCA\Talk\Service\EmojiService;
|
||||
use OCP\IEmojiHelper;
|
||||
use OCP\Server;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\Attributes\Group;
|
||||
use Test\TestCase;
|
||||
|
||||
#[Group('DB')]
|
||||
class EmojiServiceTest extends TestCase {
|
||||
protected ?EmojiService $service = null;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->service = new EmojiService(
|
||||
Server::get(IEmojiHelper::class),
|
||||
);
|
||||
}
|
||||
|
||||
public static function dataGetFirstCombinedEmoji(): array {
|
||||
return [
|
||||
['👋 Hello', '👋'],
|
||||
['Only leading emojis 🚀', ''],
|
||||
['👩🏽💻👩🏻💻👨🏿💻 Only one, but with all attributes', '👩🏽💻'],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('dataGetFirstCombinedEmoji')]
|
||||
public function testGetFirstCombinedEmoji(string $roomName, string $avatarEmoji): void {
|
||||
$this->assertSame($avatarEmoji, self::invokePrivate($this->service, 'getFirstCombinedEmoji', [$roomName]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Tests\php\Service;
|
||||
|
||||
use OCA\Talk\Config;
|
||||
use OCA\Talk\Federation\BackendNotifier;
|
||||
use OCA\Talk\Model\Attendee;
|
||||
use OCA\Talk\Model\AttendeeMapper;
|
||||
use OCA\Talk\Model\Session;
|
||||
use OCA\Talk\Model\SessionMapper;
|
||||
use OCA\Talk\Participant;
|
||||
use OCA\Talk\Room;
|
||||
use OCA\Talk\Service\MembershipService;
|
||||
use OCA\Talk\Service\ParticipantService;
|
||||
use OCA\Talk\Service\SessionService;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Federation\ICloudIdManager;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IConfig;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Security\ISecureRandom;
|
||||
use OCP\UserStatus\IManager;
|
||||
use PHPUnit\Framework\Attributes\Group;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
#[Group('DB')]
|
||||
class ParticipantServiceTest extends TestCase {
|
||||
protected IConfig&MockObject $serverConfig;
|
||||
protected Config&MockObject $talkConfig;
|
||||
protected ?AttendeeMapper $attendeeMapper = null;
|
||||
protected ?SessionMapper $sessionMapper = null;
|
||||
protected SessionService&MockObject $sessionService;
|
||||
protected ISecureRandom&MockObject $secureRandom;
|
||||
protected IEventDispatcher&MockObject $dispatcher;
|
||||
protected IUserManager&MockObject $userManager;
|
||||
protected ICloudIdManager&MockObject $cloudIdManager;
|
||||
protected IGroupManager&MockObject $groupManager;
|
||||
protected MembershipService&MockObject $membershipService;
|
||||
protected BackendNotifier&MockObject $federationBackendNotifier;
|
||||
protected ITimeFactory&MockObject $time;
|
||||
protected ICacheFactory&MockObject $cacheFactory;
|
||||
protected IManager&MockObject $userStatusManager;
|
||||
private ?ParticipantService $service = null;
|
||||
protected LoggerInterface&MockObject $logger;
|
||||
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->serverConfig = $this->createMock(IConfig::class);
|
||||
$this->talkConfig = $this->createMock(Config::class);
|
||||
$this->attendeeMapper = new AttendeeMapper(\OCP\Server::get(IDBConnection::class));
|
||||
$this->sessionMapper = new SessionMapper(\OCP\Server::get(IDBConnection::class));
|
||||
$this->sessionService = $this->createMock(SessionService::class);
|
||||
$this->secureRandom = $this->createMock(ISecureRandom::class);
|
||||
$this->dispatcher = $this->createMock(IEventDispatcher::class);
|
||||
$this->userManager = $this->createMock(IUserManager::class);
|
||||
$this->cloudIdManager = $this->createMock(ICloudIdManager::class);
|
||||
$this->groupManager = $this->createMock(IGroupManager::class);
|
||||
$this->membershipService = $this->createMock(MembershipService::class);
|
||||
$this->federationBackendNotifier = $this->createMock(BackendNotifier::class);
|
||||
$this->time = $this->createMock(ITimeFactory::class);
|
||||
$this->cacheFactory = $this->createMock(ICacheFactory::class);
|
||||
$this->userStatusManager = $this->createMock(IManager::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->service = new ParticipantService(
|
||||
$this->serverConfig,
|
||||
$this->talkConfig,
|
||||
$this->attendeeMapper,
|
||||
$this->sessionMapper,
|
||||
$this->sessionService,
|
||||
$this->secureRandom,
|
||||
\OCP\Server::get(IDBConnection::class),
|
||||
$this->dispatcher,
|
||||
$this->userManager,
|
||||
$this->cloudIdManager,
|
||||
$this->groupManager,
|
||||
$this->membershipService,
|
||||
$this->federationBackendNotifier,
|
||||
$this->time,
|
||||
$this->cacheFactory,
|
||||
$this->userStatusManager,
|
||||
$this->logger
|
||||
);
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
try {
|
||||
$attendee = $this->attendeeMapper->findByActor(123456789, Attendee::ACTOR_USERS, 'test');
|
||||
$this->sessionMapper->deleteByAttendeeId($attendee->getId());
|
||||
$this->attendeeMapper->delete($attendee);
|
||||
} catch (DoesNotExistException $exception) {
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testGetParticipantsByNotificationLevel(): void {
|
||||
$attendee = new Attendee();
|
||||
$attendee->setActorType(Attendee::ACTOR_USERS);
|
||||
$attendee->setActorId('test');
|
||||
$attendee->setRoomId(123456789);
|
||||
$attendee->setNotificationLevel(Participant::NOTIFY_MENTION);
|
||||
$this->attendeeMapper->insert($attendee);
|
||||
|
||||
$session1 = new Session();
|
||||
$session1->setAttendeeId($attendee->getId());
|
||||
$session1->setSessionId(self::getUniqueID('session1'));
|
||||
$this->sessionMapper->insert($session1);
|
||||
|
||||
$session2 = new Session();
|
||||
$session2->setAttendeeId($attendee->getId());
|
||||
$session2->setSessionId(self::getUniqueID('session2'));
|
||||
$this->sessionMapper->insert($session2);
|
||||
|
||||
$room = $this->createMock(Room::class);
|
||||
$room->method('getId')
|
||||
->willReturn(123456789);
|
||||
$participants = $this->service->getParticipantsByNotificationLevel($room, Participant::NOTIFY_MENTION);
|
||||
self::assertCount(1, $participants);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Tests\php\Service;
|
||||
|
||||
use OCA\Talk\Exceptions\InvalidRoomException;
|
||||
use OCA\Talk\Model\ProxyCacheMessage;
|
||||
use OCA\Talk\Model\ProxyCacheMessageMapper;
|
||||
use OCA\Talk\Room;
|
||||
use OCA\Talk\Service\ProxyCacheMessageService;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\IDBConnection;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\Attributes\Group;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
#[Group('DB')]
|
||||
class ProxyCacheMessageServiceTest extends TestCase {
|
||||
protected LoggerInterface&MockObject $logger;
|
||||
protected ITimeFactory&MockObject $timeFactory;
|
||||
protected ?ProxyCacheMessageMapper $mapper = null;
|
||||
protected ?ProxyCacheMessageService $service = null;
|
||||
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->mapper = new ProxyCacheMessageMapper(\OCP\Server::get(IDBConnection::class));
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
|
||||
$this->service = new ProxyCacheMessageService(
|
||||
$this->mapper,
|
||||
$this->logger,
|
||||
$this->timeFactory,
|
||||
);
|
||||
$this->clearMessages();
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
$this->clearMessages();
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
protected function clearMessages(): void {
|
||||
$query = \OCP\Server::get(IDBConnection::class)->getQueryBuilder();
|
||||
$query->delete('talk_proxy_messages')
|
||||
->where($query->expr()->eq('remote_server_url', $query->createNamedParameter('phpunittests')));
|
||||
$query->executeStatement();
|
||||
}
|
||||
|
||||
public static function dataDeleteExpiredMessages(): array {
|
||||
return [
|
||||
[1234, 12345, true],
|
||||
[1234567, 12345, false],
|
||||
[null, 12345, false],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('dataDeleteExpiredMessages')]
|
||||
public function testDeleteExpiredMessages(?int $messageTime, int $currentTime, bool $expired): void {
|
||||
$room = $this->createMock(Room::class);
|
||||
$room->method('isFederatedConversation')
|
||||
->willReturn(true);
|
||||
|
||||
$m1 = new ProxyCacheMessage();
|
||||
$m1->setLocalToken('local_token');
|
||||
$m1->setRemoteServerUrl('phpunittests');
|
||||
$m1->setRemoteToken('remote_token');
|
||||
$m1->setRemoteMessageId(12345);
|
||||
$m1->setActorType('actor_type');
|
||||
$m1->setActorId('actor_id');
|
||||
$m1->setMessageType('message_type');
|
||||
if ($messageTime === null) {
|
||||
$m1->setExpirationDatetime($messageTime);
|
||||
} else {
|
||||
$m1->setExpirationDatetime(new \DateTime('@' . $messageTime));
|
||||
}
|
||||
$this->mapper->insert($m1);
|
||||
|
||||
$this->mapper->findById($room, $m1->getId());
|
||||
|
||||
$this->timeFactory->method('getDateTime')
|
||||
->willReturn(new \DateTime('@' . $currentTime));
|
||||
$this->service->deleteExpiredMessages();
|
||||
|
||||
if ($expired) {
|
||||
$this->expectException(DoesNotExistException::class);
|
||||
}
|
||||
$actual = $this->mapper->findById($room, $m1->getId());
|
||||
if (!$expired) {
|
||||
$this->assertEquals($m1->getId(), $actual->getId());
|
||||
}
|
||||
}
|
||||
|
||||
public function testFindByIdThrows(): void {
|
||||
$this->expectException(InvalidRoomException::class);
|
||||
$room = $this->createMock(Room::class);
|
||||
$room->method('isFederatedConversation')
|
||||
->willReturn(false);
|
||||
|
||||
$this->mapper->findById($room, 42);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Service;
|
||||
|
||||
/**
|
||||
* Overwrite is_uploaded_file in the OCA\Talk\Service namespace
|
||||
* to allow proper unit testing of the postAvatar call.
|
||||
*/
|
||||
function is_uploaded_file($filename) {
|
||||
return file_exists($filename);
|
||||
}
|
||||
|
||||
namespace OCA\Talk\Tests\php\Service;
|
||||
|
||||
use OCA\Talk\Chat\ChatManager;
|
||||
use OCA\Talk\Config;
|
||||
use OCA\Talk\Manager;
|
||||
use OCA\Talk\Model\Attendee;
|
||||
use OCA\Talk\Participant;
|
||||
use OCA\Talk\Recording\BackendNotifier;
|
||||
use OCA\Talk\Room;
|
||||
use OCA\Talk\Service\ParticipantService;
|
||||
use OCA\Talk\Service\RecordingService;
|
||||
use OCA\Talk\Service\RoomService;
|
||||
use OCP\AppFramework\Services\IAppConfig;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Files\IMimeTypeDetector;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\IConfig;
|
||||
use OCP\IUserManager;
|
||||
use OCP\L10N\IFactory;
|
||||
use OCP\Notification\IManager;
|
||||
use OCP\Share\IManager as ShareManager;
|
||||
use OCP\TaskProcessing\IManager as ITaskProcessingManager;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
class RecordingServiceTest extends TestCase {
|
||||
private IMimeTypeDetector $mimeTypeDetector;
|
||||
protected ParticipantService&MockObject $participantService;
|
||||
protected IRootFolder&MockObject $rootFolder;
|
||||
protected Config&MockObject $config;
|
||||
protected IConfig&MockObject $serverConfig;
|
||||
protected IAppConfig&MockObject $appConfig;
|
||||
protected IManager&MockObject $notificationManager;
|
||||
protected Manager&MockObject $roomManager;
|
||||
protected ITimeFactory&MockObject $timeFactory;
|
||||
protected RoomService&MockObject $roomService;
|
||||
protected ShareManager&MockObject $shareManager;
|
||||
protected ChatManager&MockObject $chatManager;
|
||||
protected LoggerInterface&MockObject $logger;
|
||||
protected BackendNotifier&MockObject $backendNotifier;
|
||||
protected ITaskProcessingManager&MockObject $taskProcessingManager;
|
||||
protected IFactory&MockObject $l10nFactory;
|
||||
protected IUserManager&MockObject $userManager;
|
||||
protected RecordingService $recordingService;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->mimeTypeDetector = \OCP\Server::get(IMimeTypeDetector::class);
|
||||
$this->participantService = $this->createMock(ParticipantService::class);
|
||||
$this->rootFolder = $this->createMock(IRootFolder::class);
|
||||
$this->notificationManager = $this->createMock(IManager::class);
|
||||
$this->roomManager = $this->createMock(Manager::class);
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
$this->config = $this->createMock(Config::class);
|
||||
$this->serverConfig = $this->createMock(IConfig::class);
|
||||
$this->appConfig = $this->createMock(IAppConfig::class);
|
||||
$this->roomService = $this->createMock(RoomService::class);
|
||||
$this->shareManager = $this->createMock(ShareManager::class);
|
||||
$this->chatManager = $this->createMock(ChatManager::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->backendNotifier = $this->createMock(BackendNotifier::class);
|
||||
$this->taskProcessingManager = $this->createMock(ITaskProcessingManager::class);
|
||||
$this->l10nFactory = $this->createMock(IFactory::class);
|
||||
$this->userManager = $this->createMock(IUserManager::class);
|
||||
|
||||
$this->recordingService = new RecordingService(
|
||||
$this->mimeTypeDetector,
|
||||
$this->participantService,
|
||||
$this->rootFolder,
|
||||
$this->notificationManager,
|
||||
$this->roomManager,
|
||||
$this->timeFactory,
|
||||
$this->config,
|
||||
$this->serverConfig,
|
||||
$this->appConfig,
|
||||
$this->roomService,
|
||||
$this->shareManager,
|
||||
$this->chatManager,
|
||||
$this->logger,
|
||||
$this->backendNotifier,
|
||||
$this->taskProcessingManager,
|
||||
$this->l10nFactory,
|
||||
$this->userManager,
|
||||
);
|
||||
}
|
||||
|
||||
public static function dataValidateFileFormat(): array {
|
||||
return [
|
||||
# file_invalid_path
|
||||
['', '', 'file_invalid_path'],
|
||||
# file_mimetype
|
||||
['', realpath(__DIR__ . '/../../../img/app.svg'), 'file_mimetype'],
|
||||
['name.ogg', realpath(__DIR__ . '/../../../img/app.svg'), 'file_mimetype'],
|
||||
# file_extension
|
||||
['', realpath(__DIR__ . '/../../../img/join_call.ogg'), 'file_extension'],
|
||||
['name', realpath(__DIR__ . '/../../../img/join_call.ogg'), 'file_extension'],
|
||||
['name.mp3', realpath(__DIR__ . '/../../../img/join_call.ogg'), 'file_extension'],
|
||||
# Success
|
||||
['name.ogg', realpath(__DIR__ . '/../../../img/join_call.ogg'), ''],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('dataValidateFileFormat')]
|
||||
public function testValidateFileFormat(string $fileName, string $fileRealPath, string $exceptionMessage): void {
|
||||
if ($exceptionMessage) {
|
||||
$this->expectExceptionMessage($exceptionMessage);
|
||||
} else {
|
||||
$this->expectNotToPerformAssertions();
|
||||
}
|
||||
$this->recordingService->validateFileFormat($fileName, $fileRealPath);
|
||||
}
|
||||
|
||||
public static function dataGetResourceFromFileArray(): array {
|
||||
$fileWithContent = tempnam(sys_get_temp_dir(), 'txt');
|
||||
file_put_contents($fileWithContent, 'bla');
|
||||
return [
|
||||
[['error' => 1, 'tmp_name' => ''], '', 'invalid_file'],
|
||||
[['error' => 1, 'tmp_name' => 'a'], '', 'invalid_file'],
|
||||
# Empty file
|
||||
[['error' => 0, 'tmp_name' => tempnam(sys_get_temp_dir(), 'txt')], '', 'empty_file'],
|
||||
# file with content
|
||||
[['error' => 0, 'tmp_name' => $fileWithContent], 'bla', ''],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('dataGetResourceFromFileArray')]
|
||||
public function testGetResourceFromFileArray(array $file, string $expected, string $exceptionMessage): void {
|
||||
if ($exceptionMessage) {
|
||||
$this->expectExceptionMessage($exceptionMessage);
|
||||
}
|
||||
|
||||
$room = $this->createMock(Room::class);
|
||||
$attendee = Attendee::fromRow([
|
||||
'actor_type' => Attendee::ACTOR_USERS,
|
||||
'actor_id' => 'participant1',
|
||||
]);
|
||||
$participant = new Participant($room, $attendee, null);
|
||||
|
||||
$actual = stream_get_contents($this->recordingService->getResourceFromFileArray($file, $room, $participant));
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,390 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Tests\php\Service;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use OC\EventDispatcher\EventDispatcher;
|
||||
use OCA\Talk\Config;
|
||||
use OCA\Talk\Events\RoomPasswordVerifyEvent;
|
||||
use OCA\Talk\Exceptions\RoomNotFoundException;
|
||||
use OCA\Talk\Manager;
|
||||
use OCA\Talk\Model\Attendee;
|
||||
use OCA\Talk\Model\BreakoutRoom;
|
||||
use OCA\Talk\Participant;
|
||||
use OCA\Talk\Room;
|
||||
use OCA\Talk\Service\EmojiService;
|
||||
use OCA\Talk\Service\ParticipantService;
|
||||
use OCA\Talk\Service\RecordingService;
|
||||
use OCA\Talk\Service\RoomService;
|
||||
use OCA\Talk\Webinary;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\Calendar\IManager;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IL10N;
|
||||
use OCP\IUser;
|
||||
use OCP\Security\IHasher;
|
||||
use OCP\Server;
|
||||
use OCP\Share\IManager as IShareManager;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\Attributes\Group;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
#[Group('DB')]
|
||||
class RoomServiceTest extends TestCase {
|
||||
protected Manager&MockObject $manager;
|
||||
protected ParticipantService&MockObject $participantService;
|
||||
protected ITimeFactory&MockObject $timeFactory;
|
||||
protected IShareManager&MockObject $shareManager;
|
||||
protected Config&MockObject $config;
|
||||
protected IHasher&MockObject $hasher;
|
||||
protected IEventDispatcher&MockObject $dispatcher;
|
||||
protected IJobList&MockObject $jobList;
|
||||
protected LoggerInterface&MockObject $logger;
|
||||
protected IL10N&MockObject $l10n;
|
||||
protected IManager $calendarManager;
|
||||
protected EmojiService $emojiService;
|
||||
protected ?RoomService $service = null;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->manager = $this->createMock(Manager::class);
|
||||
$this->participantService = $this->createMock(ParticipantService::class);
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
$this->shareManager = $this->createMock(IShareManager::class);
|
||||
$this->config = $this->createMock(Config::class);
|
||||
$this->hasher = $this->createMock(IHasher::class);
|
||||
$this->dispatcher = $this->createMock(IEventDispatcher::class);
|
||||
$this->jobList = $this->createMock(IJobList::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->l10n = $this->createMock(IL10N::class);
|
||||
$this->emojiService = Server::get(EmojiService::class);
|
||||
$this->calendarManager = $this->createMock(IManager::class);
|
||||
$this->service = new RoomService(
|
||||
$this->manager,
|
||||
$this->participantService,
|
||||
\OCP\Server::get(IDBConnection::class),
|
||||
$this->timeFactory,
|
||||
$this->shareManager,
|
||||
$this->config,
|
||||
$this->hasher,
|
||||
$this->dispatcher,
|
||||
$this->jobList,
|
||||
$this->emojiService,
|
||||
$this->logger,
|
||||
$this->l10n,
|
||||
$this->calendarManager,
|
||||
);
|
||||
}
|
||||
|
||||
public function testCreateOneToOneConversationWithSameUser(): void {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->method('getUID')
|
||||
->willReturn('uid');
|
||||
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('invite');
|
||||
$this->service->createOneToOneConversation($user, $user);
|
||||
}
|
||||
|
||||
public function testCreateOneToOneConversationWithNotCurrentUserCanEnumerateTargetUser(): void {
|
||||
$user1 = $this->createMock(IUser::class);
|
||||
$user1->method('getUID')
|
||||
->willReturn('uid1');
|
||||
$user2 = $this->createMock(IUser::class);
|
||||
$user2->method('getUID')
|
||||
->willReturn('uid2');
|
||||
|
||||
$this->expectException(RoomNotFoundException::class);
|
||||
$this->shareManager
|
||||
->expects($this->once())
|
||||
->method('currentUserCanEnumerateTargetUser')
|
||||
->willReturn(false);
|
||||
$this->manager
|
||||
->method('getOne2OneRoom')
|
||||
->willThrowException(new RoomNotFoundException());
|
||||
$this->service->createOneToOneConversation($user1, $user2);
|
||||
}
|
||||
|
||||
public function testCreateOneToOneConversationAlreadyExists(): void {
|
||||
$user1 = $this->createMock(IUser::class);
|
||||
$user1->method('getUID')
|
||||
->willReturn('uid1');
|
||||
$user2 = $this->createMock(IUser::class);
|
||||
$user2->method('getUID')
|
||||
->willReturn('uid2');
|
||||
|
||||
$room = $this->createMock(Room::class);
|
||||
$this->participantService->expects($this->once())
|
||||
->method('ensureOneToOneRoomIsFilled')
|
||||
->with($room);
|
||||
|
||||
$this->manager->expects($this->once())
|
||||
->method('getOne2OneRoom')
|
||||
->with('uid1', 'uid2')
|
||||
->willReturn($room);
|
||||
|
||||
$this->assertSame($room, $this->service->createOneToOneConversation($user1, $user2));
|
||||
}
|
||||
|
||||
public function testCreateOneToOneConversationCreated(): void {
|
||||
$user1 = $this->createMock(IUser::class);
|
||||
$user1->method('getUID')
|
||||
->willReturn('uid1');
|
||||
$user1->method('getDisplayName')
|
||||
->willReturn('display-1');
|
||||
$user2 = $this->createMock(IUser::class);
|
||||
$user2->method('getUID')
|
||||
->willReturn('uid2');
|
||||
$user2->method('getDisplayName')
|
||||
->willReturn('display-2');
|
||||
|
||||
$this->shareManager
|
||||
->expects($this->once())
|
||||
->method('currentUserCanEnumerateTargetUser')
|
||||
->willReturn(true);
|
||||
|
||||
$room = $this->createMock(Room::class);
|
||||
$this->participantService->expects($this->once())
|
||||
->method('addUsers')
|
||||
->with($room, [[
|
||||
'actorType' => 'users',
|
||||
'actorId' => 'uid1',
|
||||
'displayName' => 'display-1',
|
||||
'participantType' => Participant::OWNER,
|
||||
]]);
|
||||
|
||||
$this->participantService->expects($this->never())
|
||||
->method('ensureOneToOneRoomIsFilled')
|
||||
->with($room);
|
||||
|
||||
$this->manager->expects($this->once())
|
||||
->method('getOne2OneRoom')
|
||||
->with('uid1', 'uid2')
|
||||
->willThrowException(new RoomNotFoundException());
|
||||
|
||||
$this->manager->expects($this->once())
|
||||
->method('createRoom')
|
||||
->with(Room::TYPE_ONE_TO_ONE)
|
||||
->willReturn($room);
|
||||
|
||||
$this->assertSame($room, $this->service->createOneToOneConversation($user1, $user2));
|
||||
}
|
||||
|
||||
public static function dataCreateConversationInvalidNames(): array {
|
||||
return [
|
||||
[''],
|
||||
[' '],
|
||||
[str_repeat('a', 256)],
|
||||
// Isn't a multibyte emoji
|
||||
[str_repeat('😃', 256)],
|
||||
// This is a multibyte emoji and need 2 chars in database
|
||||
// 256 / 2 = 128
|
||||
[str_repeat('💻', 128)],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('dataCreateConversationInvalidNames')]
|
||||
public function testCreateConversationInvalidNames(string $name): void {
|
||||
$this->manager->expects($this->never())
|
||||
->method('createRoom');
|
||||
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('name');
|
||||
$this->service->createConversation(Room::TYPE_GROUP, $name);
|
||||
}
|
||||
|
||||
public static function dataCreateConversationInvalidTypes(): array {
|
||||
return [
|
||||
[Room::TYPE_ONE_TO_ONE],
|
||||
[Room::TYPE_UNKNOWN],
|
||||
[Room::TYPE_ONE_TO_ONE_FORMER],
|
||||
[7],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('dataCreateConversationInvalidTypes')]
|
||||
public function testCreateConversationInvalidTypes(int $type): void {
|
||||
$this->manager->expects($this->never())
|
||||
->method('createRoom');
|
||||
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('type');
|
||||
$this->service->createConversation($type, 'abc');
|
||||
}
|
||||
|
||||
public static function dataCreateConversationInvalidObjects(): array {
|
||||
return [
|
||||
[str_repeat('a', 65), 'a', 'object-type'],
|
||||
['a', str_repeat('a', 65), 'object-id'],
|
||||
['a', '', 'object'],
|
||||
['', 'b', 'object'],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('dataCreateConversationInvalidObjects')]
|
||||
public function testCreateConversationInvalidObjects(string $type, string $id, string $exception): void {
|
||||
$this->manager->expects($this->never())
|
||||
->method('createRoom');
|
||||
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage($exception);
|
||||
$this->service->createConversation(Room::TYPE_PUBLIC, 'a', null, $type, $id);
|
||||
}
|
||||
|
||||
public static function dataCreateConversation(): array {
|
||||
return [
|
||||
[Room::TYPE_GROUP, 'Group conversation', 'admin', '', '', ''],
|
||||
[Room::TYPE_PUBLIC, 'Public conversation', '', 'file', '123456', ''],
|
||||
[Room::TYPE_PUBLIC, 'Public conversation', '', 'file', '123456', 'AGoodPassword123?'],
|
||||
[Room::TYPE_CHANGELOG, 'Talk updates ✅', 'test1', '', '', ''],
|
||||
[Room::TYPE_GROUP, 'Let\'s get started!', 'test1', 'sample', 'test1', ''],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('dataCreateConversation')]
|
||||
public function testCreateConversation(int $type, string $name, string $ownerId, string $objectType, string $objectId, string $password): void {
|
||||
$room = $this->createMock(Room::class);
|
||||
|
||||
if ($ownerId !== '') {
|
||||
$owner = $this->createMock(IUser::class);
|
||||
$owner->method('getUID')
|
||||
->willReturn($ownerId);
|
||||
$owner->method('getDisplayName')
|
||||
->willReturn($ownerId . '-display');
|
||||
|
||||
$this->participantService->expects($this->once())
|
||||
->method('addUsers')
|
||||
->with($room, [[
|
||||
'actorType' => 'users',
|
||||
'actorId' => $ownerId,
|
||||
'displayName' => $ownerId . '-display',
|
||||
'participantType' => Participant::OWNER,
|
||||
]]);
|
||||
} else {
|
||||
$owner = null;
|
||||
$this->participantService->expects($this->never())
|
||||
->method('addUsers');
|
||||
}
|
||||
|
||||
if ($password !== '') {
|
||||
$this->hasher->expects(self::once())
|
||||
->method('hash')
|
||||
->willReturn($password);
|
||||
}
|
||||
$this->manager->expects($this->once())
|
||||
->method('createRoom')
|
||||
->with($type, $name, $objectType, $objectId, $password)
|
||||
->willReturn($room);
|
||||
|
||||
$this->assertSame($room, $this->service->createConversation($type, $name, $owner, $objectType, $objectId, $password));
|
||||
}
|
||||
|
||||
public static function dataPrepareConversationName(): array {
|
||||
return [
|
||||
['', ''],
|
||||
[' ', ''],
|
||||
['A ', 'A'],
|
||||
[' B', 'B'],
|
||||
[' C ', 'C'],
|
||||
['A' . str_repeat(' ', 100) . 'B', 'A'],
|
||||
['A' . str_repeat(' ', 32) . 'B', 'A' . str_repeat(' ', 32) . 'B'],
|
||||
['Лорем ипсум долор сит амет, но антиопам алияуандо витуперата еам, мел те цонгуе хомеро адолесценс.', 'Лорем ипсум долор сит амет, но антиопам алияуандо витуперата еам'],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('dataPrepareConversationName')]
|
||||
public function testPrepareConversationName(string $input, string $expected): void {
|
||||
$this->assertSame($expected, $this->service->prepareConversationName($input));
|
||||
}
|
||||
|
||||
public function testVerifyPassword(): void {
|
||||
$dispatcher = new EventDispatcher(
|
||||
new \Symfony\Component\EventDispatcher\EventDispatcher(),
|
||||
\OC::$server,
|
||||
$this->createMock(LoggerInterface::class)
|
||||
);
|
||||
$dispatcher->addListener(RoomPasswordVerifyEvent::class, static function (RoomPasswordVerifyEvent $event): void {
|
||||
$password = $event->getPassword();
|
||||
|
||||
if ($password === '1234') {
|
||||
$event->setIsPasswordValid(true);
|
||||
$event->setRedirectUrl('');
|
||||
} else {
|
||||
$event->setIsPasswordValid(false);
|
||||
$event->setRedirectUrl('https://test');
|
||||
}
|
||||
});
|
||||
|
||||
$service = new RoomService(
|
||||
$this->manager,
|
||||
$this->participantService,
|
||||
\OCP\Server::get(IDBConnection::class),
|
||||
$this->timeFactory,
|
||||
$this->shareManager,
|
||||
$this->config,
|
||||
$this->hasher,
|
||||
$dispatcher,
|
||||
$this->jobList,
|
||||
$this->emojiService,
|
||||
$this->logger,
|
||||
$this->l10n,
|
||||
$this->calendarManager,
|
||||
);
|
||||
|
||||
$room = new Room(
|
||||
$this->createMock(Manager::class),
|
||||
$this->createMock(IDBConnection::class),
|
||||
$dispatcher,
|
||||
$this->createMock(ITimeFactory::class),
|
||||
1,
|
||||
Room::TYPE_PUBLIC,
|
||||
Room::READ_WRITE,
|
||||
Room::LISTABLE_NONE,
|
||||
0,
|
||||
Webinary::LOBBY_NONE,
|
||||
Webinary::SIP_DISABLED,
|
||||
null,
|
||||
'foobar',
|
||||
'Test',
|
||||
'description',
|
||||
'passy',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
Attendee::PERMISSIONS_DEFAULT,
|
||||
Attendee::PERMISSIONS_DEFAULT,
|
||||
Participant::FLAG_DISCONNECTED,
|
||||
null,
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
null,
|
||||
'',
|
||||
'',
|
||||
BreakoutRoom::MODE_NOT_CONFIGURED,
|
||||
BreakoutRoom::STATUS_STOPPED,
|
||||
Room::RECORDING_NONE,
|
||||
RecordingService::CONSENT_REQUIRED_NO,
|
||||
Room::HAS_FEDERATION_NONE,
|
||||
Room::MENTION_PERMISSIONS_EVERYONE,
|
||||
'',
|
||||
);
|
||||
|
||||
$verificationResult = $service->verifyPassword($room, '1234');
|
||||
$this->assertSame($verificationResult, ['result' => true, 'url' => '']);
|
||||
$verificationResult = $service->verifyPassword($room, '4321');
|
||||
$this->assertSame($verificationResult, ['result' => false, 'url' => 'https://test']);
|
||||
$this->assertSame('passy', $room->getPassword());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Tests\php\Service;
|
||||
|
||||
use OCA\Talk\Service\SIPDialOutService;
|
||||
use OCA\Talk\Signaling\BackendNotifier;
|
||||
use OCA\Talk\Signaling\Responses\DialOut;
|
||||
use OCA\Talk\Signaling\Responses\DialOutError;
|
||||
use OCA\Talk\Signaling\Responses\Response;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
class SIPDialOutServiceTest extends TestCase {
|
||||
protected BackendNotifier&MockObject $backendNotifier;
|
||||
protected LoggerInterface&MockObject $logger;
|
||||
protected ?SIPDialOutService $service = null;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->backendNotifier = $this->createMock(BackendNotifier::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->service = new SIPDialOutService(
|
||||
$this->backendNotifier,
|
||||
$this->logger,
|
||||
);
|
||||
}
|
||||
|
||||
public function testValidateDialOutResponseSuccess(): void {
|
||||
$data = <<<JSON
|
||||
{
|
||||
"type": "dialout",
|
||||
"dialout": {
|
||||
"callid": "the-call-id"
|
||||
}
|
||||
}
|
||||
JSON;
|
||||
|
||||
/** @var Response $response */
|
||||
$response = self::invokePrivate($this->service, 'validateDialOutResponse', [$data]);
|
||||
|
||||
$this->assertInstanceOf(Response::class, $response);
|
||||
$this->assertInstanceOf(DialOut::class, $response->dialOut);
|
||||
$this->assertSame('the-call-id', $response->dialOut->callId);
|
||||
$this->assertNull($response->dialOut->error);
|
||||
}
|
||||
|
||||
public function testValidateDialOutResponseError(): void {
|
||||
$data = <<<JSON
|
||||
{
|
||||
"type": "dialout",
|
||||
"dialout": {
|
||||
"error": {
|
||||
"code": "error-code",
|
||||
"message": "Human readable error."
|
||||
}
|
||||
}
|
||||
}
|
||||
JSON;
|
||||
|
||||
/** @var Response $response */
|
||||
$response = self::invokePrivate($this->service, 'validateDialOutResponse', [$data]);
|
||||
|
||||
$this->assertInstanceOf(Response::class, $response);
|
||||
$this->assertInstanceOf(DialOut::class, $response->dialOut);
|
||||
$this->assertInstanceOf(DialOutError::class, $response->dialOut->error);
|
||||
$this->assertNull($response->dialOut->callId);
|
||||
$this->assertSame('error-code', $response->dialOut->error->code);
|
||||
$this->assertSame('Human readable error.', $response->dialOut->error->message);
|
||||
}
|
||||
|
||||
public function testValidateDialOutResponseErrorWithDetails(): void {
|
||||
$data = <<<JSON
|
||||
{
|
||||
"type": "dialout",
|
||||
"dialout": {
|
||||
"error": {
|
||||
"code": "error-code",
|
||||
"message": "Human readable error.",
|
||||
"details": {
|
||||
"attendeeId": 32
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
JSON;
|
||||
|
||||
/** @var Response $response */
|
||||
$response = self::invokePrivate($this->service, 'validateDialOutResponse', [$data]);
|
||||
|
||||
$this->assertInstanceOf(Response::class, $response);
|
||||
$this->assertInstanceOf(DialOut::class, $response->dialOut);
|
||||
$this->assertInstanceOf(DialOutError::class, $response->dialOut->error);
|
||||
$this->assertNull($response->dialOut->callId);
|
||||
$this->assertSame('error-code', $response->dialOut->error->code);
|
||||
$this->assertSame('Human readable error.', $response->dialOut->error->message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Talk\Tests\php\Service;
|
||||
|
||||
use OCA\Talk\Model\Attendee;
|
||||
use OCA\Talk\Model\SessionMapper;
|
||||
use OCA\Talk\Service\SessionService;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Security\ISecureRandom;
|
||||
use PHPUnit\Framework\Attributes\Group;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Test\TestCase;
|
||||
|
||||
#[Group('DB')]
|
||||
class SessionServiceTest extends TestCase {
|
||||
protected ?SessionMapper $sessionMapper = null;
|
||||
protected ISecureRandom&MockObject $secureRandom;
|
||||
protected ITimeFactory&MockObject $timeFactory;
|
||||
private ?SessionService $service = null;
|
||||
|
||||
private const RANDOM_254 = '123456789abcdef0123456789abcdef1123456789abcdef2123456789abcdef3123456789abcdef4123456789abcdef5123456789abcdef6123456789abcdef7123456789abcdef8123456789abcdef9123456789abcdefa123456789abcdefb123456789abcdefc123456789abcdefd123456789abcdefe123456789abcde';
|
||||
|
||||
private array $attendeeIds = [];
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->sessionMapper = \OCP\Server::get(SessionMapper::class);
|
||||
$this->secureRandom = $this->createMock(ISecureRandom::class);
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
$this->service = new SessionService(
|
||||
$this->sessionMapper,
|
||||
\OCP\Server::get(IDBConnection::class),
|
||||
$this->secureRandom,
|
||||
$this->timeFactory,
|
||||
);
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
foreach ($this->attendeeIds as $attendeeId) {
|
||||
try {
|
||||
$this->sessionMapper->deleteByAttendeeId($attendeeId);
|
||||
} catch (DoesNotExistException $exception) {
|
||||
}
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testCreateSessionForAttendee() {
|
||||
$attendee = new Attendee();
|
||||
$attendee->setId(42);
|
||||
$attendee->setActorType(Attendee::ACTOR_USERS);
|
||||
$attendee->setActorId('test');
|
||||
$this->attendeeIds[] = $attendee->getId();
|
||||
|
||||
$random = self::RANDOM_254 . 'x';
|
||||
|
||||
$this->secureRandom->expects($this->once())
|
||||
->method('generate')
|
||||
->with(255)
|
||||
->willReturn($random);
|
||||
|
||||
$session = $this->service->createSessionForAttendee($attendee);
|
||||
|
||||
self::assertEquals($random, $session->getSessionId());
|
||||
}
|
||||
|
||||
public function testCreateSessionForAttendeeWithDuplicatedSessionId() {
|
||||
$attendee1 = new Attendee();
|
||||
$attendee1->setId(42);
|
||||
$attendee1->setActorType(Attendee::ACTOR_USERS);
|
||||
$attendee1->setActorId('test1');
|
||||
$this->attendeeIds[] = $attendee1->getId();
|
||||
|
||||
$attendee2 = new Attendee();
|
||||
$attendee2->setId(108);
|
||||
$attendee2->setActorType(Attendee::ACTOR_USERS);
|
||||
$attendee2->setActorId('test2');
|
||||
$this->attendeeIds[] = $attendee2->getId();
|
||||
|
||||
$random1 = self::RANDOM_254 . 'x';
|
||||
$random2 = self::RANDOM_254 . 'y';
|
||||
|
||||
$this->secureRandom->expects($this->exactly(3))
|
||||
->method('generate')
|
||||
->with(255)
|
||||
->willReturn(
|
||||
$random1,
|
||||
$random1,
|
||||
$random2,
|
||||
);
|
||||
|
||||
$session1 = $this->service->createSessionForAttendee($attendee1);
|
||||
$session2 = $this->service->createSessionForAttendee($attendee2);
|
||||
|
||||
self::assertEquals($random1, $session1->getSessionId());
|
||||
self::assertEquals($random2, $session2->getSessionId());
|
||||
}
|
||||
|
||||
public function testCreateSessionForAttendeeWithoutId() {
|
||||
$attendee = new Attendee();
|
||||
$attendee->setActorType(Attendee::ACTOR_USERS);
|
||||
$attendee->setActorId('test');
|
||||
|
||||
$random = self::RANDOM_254 . 'x';
|
||||
|
||||
$this->secureRandom->expects($this->once())
|
||||
->method('generate')
|
||||
->with(255)
|
||||
->willReturn($random);
|
||||
|
||||
$this->expectException(\OC\DB\Exceptions\DbalException::class);
|
||||
|
||||
$session = $this->service->createSessionForAttendee($attendee);
|
||||
}
|
||||
|
||||
public function testCreateSessionForAttendeeWithInvitedCloudId() {
|
||||
$attendee = new Attendee();
|
||||
$attendee->setId(42);
|
||||
$attendee->setActorType(Attendee::ACTOR_USERS);
|
||||
$attendee->setActorId('test');
|
||||
$this->attendeeIds[] = $attendee->getId();
|
||||
|
||||
$random = self::RANDOM_254 . 'x';
|
||||
|
||||
$this->secureRandom->expects($this->once())
|
||||
->method('generate')
|
||||
->with(255)
|
||||
->willReturn($random);
|
||||
|
||||
$cloudId = 'user@server.com';
|
||||
$attendee->setInvitedCloudId($cloudId);
|
||||
|
||||
$session = $this->service->createSessionForAttendee($attendee);
|
||||
|
||||
self::assertEquals($random . '#' . $cloudId, $session->getSessionId());
|
||||
}
|
||||
|
||||
public function testExtendSessionIdWithMaximumLengthCloudId(): void {
|
||||
$attendee = new Attendee();
|
||||
$attendee->setId(42);
|
||||
$attendee->setActorType(Attendee::ACTOR_USERS);
|
||||
$attendee->setActorId('test');
|
||||
$this->attendeeIds[] = $attendee->getId();
|
||||
|
||||
$random = self::RANDOM_254 . 'x';
|
||||
|
||||
$this->secureRandom->expects($this->once())
|
||||
->method('generate')
|
||||
->with(255)
|
||||
->willReturn($random);
|
||||
|
||||
// User ids are 64 characters long at most; total cloud id length needs
|
||||
// to leave room for the '#' joining the ids.
|
||||
$cloudId = 'user123456789abcdef0123456789abcdef1123456789abcdef2123456789abc@server123456789abcdef0123456789abcdef1123456789abcdef2123456789abcdef3123456789abcdef4123456789abcdef5123456789abcdef6123456789abcdef7123456789abcdef8123456789abcdef9123456789abcdefa12345.com';
|
||||
$attendee->setInvitedCloudId($cloudId);
|
||||
|
||||
$session = $this->service->createSessionForAttendee($attendee);
|
||||
|
||||
self::assertEquals(256, strlen($cloudId));
|
||||
self::assertEquals(512, strlen($session->getSessionId()));
|
||||
self::assertEquals($random . '#' . $cloudId, $session->getSessionId());
|
||||
}
|
||||
|
||||
public function testExtendSessionIdWithTooLongCloudId(): void {
|
||||
$attendee = new Attendee();
|
||||
$attendee->setId(42);
|
||||
$attendee->setActorType(Attendee::ACTOR_USERS);
|
||||
$attendee->setActorId('test');
|
||||
$this->attendeeIds[] = $attendee->getId();
|
||||
|
||||
$random = self::RANDOM_254 . 'x';
|
||||
|
||||
$this->secureRandom->expects($this->once())
|
||||
->method('generate')
|
||||
->with(255)
|
||||
->willReturn($random);
|
||||
|
||||
// User ids are 64 characters long at most; total cloud id length needs
|
||||
// to leave room for the '#' joining the ids.
|
||||
$cloudId = 'user123456789abcdef0123456789abcdef1123456789abcdef2123456789abc@server123456789abcdef0123456789abcdef1123456789abcdef2123456789abcdef3123456789abcdef4123456789abcdef5123456789abcdef6123456789abcdef7123456789abcdef8123456789abcdef9123456789abcdefa123456.com';
|
||||
$trimmedCloudId = 'user123456789abcdef0123456789abcdef1123456789abcdef2123456789abc@server123456789abcdef0123456789abcdef1123456789abcdef2123456789abcdef3123456789abcdef4123456789abcdef5123456789abcdef6123456789abcdef7123456789abcdef8123456789abcdef9123456789abcdefa123456.co';
|
||||
$attendee->setInvitedCloudId($cloudId);
|
||||
|
||||
$session = $this->service->createSessionForAttendee($attendee);
|
||||
|
||||
self::assertEquals(257, strlen($cloudId));
|
||||
self::assertEquals(512, strlen($session->getSessionId()));
|
||||
self::assertEquals($random . '#' . $trimmedCloudId, $session->getSessionId());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user