diff options
Diffstat (limited to 'apps/user_status/tests/Unit/Service')
3 files changed, 182 insertions, 310 deletions
diff --git a/apps/user_status/tests/Unit/Service/EmojiServiceTest.php b/apps/user_status/tests/Unit/Service/EmojiServiceTest.php deleted file mode 100644 index 454f1d75a0d..00000000000 --- a/apps/user_status/tests/Unit/Service/EmojiServiceTest.php +++ /dev/null @@ -1,100 +0,0 @@ -<?php - -declare(strict_types=1); - -/** - * @copyright Copyright (c) 2020, Georg Ehrke - * - * @author Georg Ehrke <oc.list@georgehrke.com> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ -namespace OCA\UserStatus\Tests\Service; - -use OCA\UserStatus\Service\EmojiService; -use OCP\IDBConnection; -use Test\TestCase; - -class EmojiServiceTest extends TestCase { - - /** @var IDBConnection|\PHPUnit\Framework\MockObject\MockObject */ - private $db; - - /** @var EmojiService */ - private $service; - - protected function setUp(): void { - parent::setUp(); - - $this->db = $this->createMock(IDBConnection::class); - $this->service = new EmojiService($this->db); - } - - /** - * @param bool $supports4ByteText - * @param bool $expected - * - * @dataProvider doesPlatformSupportEmojiDataProvider - */ - public function testDoesPlatformSupportEmoji(bool $supports4ByteText, bool $expected): void { - $this->db->expects($this->once()) - ->method('supports4ByteText') - ->willReturn($supports4ByteText); - - $this->assertEquals($expected, $this->service->doesPlatformSupportEmoji()); - } - - /** - * @return array - */ - public function doesPlatformSupportEmojiDataProvider(): array { - return [ - [true, true], - [false, false], - ]; - } - - /** - * @param string $emoji - * @param bool $expected - * - * @dataProvider isValidEmojiDataProvider - */ - public function testIsValidEmoji(string $emoji, bool $expected): void { - $actual = $this->service->isValidEmoji($emoji); - - $this->assertEquals($expected, $actual); - } - - public function isValidEmojiDataProvider(): array { - return [ - ['🏝', true], - ['📱', true], - ['🏢', true], - ['📱📠', false], - ['a', false], - ['0', false], - ['$', false], - // Test some more complex emojis with modifiers and zero-width-joiner - ['👩🏿💻', true], - ['🤷🏼♀️', true], - ['🏳️🌈', true], - ['👨👨👦👦', true], - ['👩❤️👩', true] - ]; - } -} diff --git a/apps/user_status/tests/Unit/Service/PredefinedStatusServiceTest.php b/apps/user_status/tests/Unit/Service/PredefinedStatusServiceTest.php index 0a65256bfac..78e4a18d9f1 100644 --- a/apps/user_status/tests/Unit/Service/PredefinedStatusServiceTest.php +++ b/apps/user_status/tests/Unit/Service/PredefinedStatusServiceTest.php @@ -3,40 +3,19 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2020, Georg Ehrke - * - * @author Daniel Kesselberg <mail@danielkesselberg.de> - * @author Georg Ehrke <oc.list@georgehrke.com> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\UserStatus\Tests\Service; use OCA\UserStatus\Service\PredefinedStatusService; use OCP\IL10N; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class PredefinedStatusServiceTest extends TestCase { - - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - protected $l10n; - - /** @var PredefinedStatusService */ - protected $service; + protected IL10N&MockObject $l10n; + protected PredefinedStatusService $service; protected function setUp(): void { parent::setUp(); @@ -47,17 +26,11 @@ class PredefinedStatusServiceTest extends TestCase { } public function testGetDefaultStatuses(): void { - $this->l10n->expects($this->exactly(6)) + $this->l10n->expects($this->exactly(8)) ->method('t') - ->withConsecutive( - ['In a meeting'], - ['Commuting'], - ['Working remotely'], - ['Out sick'], - ['Vacationing'], - ['In a call'], - ) - ->willReturnArgument(0); + ->willReturnCallback(function ($text, $parameters = []) { + return vsprintf($text, $parameters); + }); $actual = $this->service->getDefaultStatuses(); $this->assertEquals([ @@ -80,6 +53,15 @@ class PredefinedStatusServiceTest extends TestCase { ], ], [ + 'id' => 'be-right-back', + 'icon' => '⏳', + 'message' => 'Be right back', + 'clearAt' => [ + 'type' => 'period', + 'time' => 900, + ], + ], + [ 'id' => 'remote-work', 'icon' => '🏡', 'message' => 'Working remotely', @@ -110,41 +92,36 @@ class PredefinedStatusServiceTest extends TestCase { 'clearAt' => null, 'visible' => false, ], + [ + 'id' => 'out-of-office', + 'icon' => '🛑', + 'message' => 'Out of office', + 'clearAt' => null, + 'visible' => false, + ], ], $actual); } - /** - * @param string $id - * @param string|null $expectedIcon - * - * @dataProvider getIconForIdDataProvider - */ + #[\PHPUnit\Framework\Attributes\DataProvider('getIconForIdDataProvider')] public function testGetIconForId(string $id, ?string $expectedIcon): void { $actual = $this->service->getIconForId($id); $this->assertEquals($expectedIcon, $actual); } - /** - * @return array - */ - public function getIconForIdDataProvider(): array { + public static function getIconForIdDataProvider(): array { return [ ['meeting', '📅'], ['commuting', '🚌'], ['sick-leave', '🤒'], ['vacationing', '🌴'], ['remote-work', '🏡'], + ['be-right-back', '⏳'], ['call', '💬'], ['unknown-id', null], ]; } - /** - * @param string $id - * @param string|null $expected - * - * @dataProvider getTranslatedStatusForIdDataProvider - */ + #[\PHPUnit\Framework\Attributes\DataProvider('getTranslatedStatusForIdDataProvider')] public function testGetTranslatedStatusForId(string $id, ?string $expected): void { $this->l10n->method('t') ->willReturnArgument(0); @@ -153,59 +130,44 @@ class PredefinedStatusServiceTest extends TestCase { $this->assertEquals($expected, $actual); } - /** - * @return array - */ - public function getTranslatedStatusForIdDataProvider(): array { + public static function getTranslatedStatusForIdDataProvider(): array { return [ ['meeting', 'In a meeting'], ['commuting', 'Commuting'], ['sick-leave', 'Out sick'], ['vacationing', 'Vacationing'], ['remote-work', 'Working remotely'], + ['be-right-back', 'Be right back'], ['call', 'In a call'], ['unknown-id', null], ]; } - /** - * @param string $id - * @param bool $expected - * - * @dataProvider isValidIdDataProvider - */ + #[\PHPUnit\Framework\Attributes\DataProvider('isValidIdDataProvider')] public function testIsValidId(string $id, bool $expected): void { $actual = $this->service->isValidId($id); $this->assertEquals($expected, $actual); } - /** - * @return array - */ - public function isValidIdDataProvider(): array { + public static function isValidIdDataProvider(): array { return [ ['meeting', true], ['commuting', true], ['sick-leave', true], ['vacationing', true], ['remote-work', true], + ['be-right-back', true], ['call', true], ['unknown-id', false], ]; } public function testGetDefaultStatusById(): void { - $this->l10n->expects($this->exactly(6)) + $this->l10n->expects($this->exactly(8)) ->method('t') - ->withConsecutive( - ['In a meeting'], - ['Commuting'], - ['Working remotely'], - ['Out sick'], - ['Vacationing'], - ['In a call'], - ) - ->willReturnArgument(0); + ->willReturnCallback(function ($text, $parameters = []) { + return vsprintf($text, $parameters); + }); $this->assertEquals([ 'id' => 'call', diff --git a/apps/user_status/tests/Unit/Service/StatusServiceTest.php b/apps/user_status/tests/Unit/Service/StatusServiceTest.php index 3dd397e1d36..7dfa5b0d064 100644 --- a/apps/user_status/tests/Unit/Service/StatusServiceTest.php +++ b/apps/user_status/tests/Unit/Service/StatusServiceTest.php @@ -3,26 +3,8 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2020, Georg Ehrke - * - * @author Georg Ehrke <oc.list@georgehrke.com> - * @author Joas Schilling <coding@schilljs.com> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\UserStatus\Tests\Service; @@ -35,35 +17,29 @@ use OCA\UserStatus\Exception\InvalidMessageIdException; use OCA\UserStatus\Exception\InvalidStatusIconException; use OCA\UserStatus\Exception\InvalidStatusTypeException; use OCA\UserStatus\Exception\StatusMessageTooLongException; -use OCA\UserStatus\Service\EmojiService; use OCA\UserStatus\Service\PredefinedStatusService; use OCA\UserStatus\Service\StatusService; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Utility\ITimeFactory; use OCP\DB\Exception; use OCP\IConfig; +use OCP\IEmojiHelper; +use OCP\IUserManager; use OCP\UserStatus\IUserStatus; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\LoggerInterface; use Test\TestCase; class StatusServiceTest extends TestCase { + private UserStatusMapper&MockObject $mapper; + private ITimeFactory&MockObject $timeFactory; + private PredefinedStatusService&MockObject $predefinedStatusService; + private IEmojiHelper&MockObject $emojiHelper; + private IConfig&MockObject $config; + private IUserManager&MockObject $userManager; + private LoggerInterface&MockObject $logger; - /** @var UserStatusMapper|\PHPUnit\Framework\MockObject\MockObject */ - private $mapper; - - /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $timeFactory; - - /** @var PredefinedStatusService|\PHPUnit\Framework\MockObject\MockObject */ - private $predefinedStatusService; - - /** @var EmojiService|\PHPUnit\Framework\MockObject\MockObject */ - private $emojiService; - - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $config; - - /** @var StatusService */ - private $service; + private StatusService $service; protected function setUp(): void { parent::setUp(); @@ -71,9 +47,10 @@ class StatusServiceTest extends TestCase { $this->mapper = $this->createMock(UserStatusMapper::class); $this->timeFactory = $this->createMock(ITimeFactory::class); $this->predefinedStatusService = $this->createMock(PredefinedStatusService::class); - $this->emojiService = $this->createMock(EmojiService::class); - + $this->emojiHelper = $this->createMock(IEmojiHelper::class); + $this->userManager = $this->createMock(IUserManager::class); $this->config = $this->createMock(IConfig::class); + $this->logger = $this->createMock(LoggerInterface::class); $this->config->method('getAppValue') ->willReturnMap([ @@ -84,8 +61,11 @@ class StatusServiceTest extends TestCase { $this->service = new StatusService($this->mapper, $this->timeFactory, $this->predefinedStatusService, - $this->emojiService, - $this->config); + $this->emojiHelper, + $this->config, + $this->userManager, + $this->logger, + ); } public function testFindAll(): void { @@ -138,8 +118,11 @@ class StatusServiceTest extends TestCase { $this->service = new StatusService($this->mapper, $this->timeFactory, $this->predefinedStatusService, - $this->emojiService, - $this->config); + $this->emojiHelper, + $this->config, + $this->userManager, + $this->logger, + ); $this->assertEquals([], $this->service->findAllRecentStatusChanges(20, 50)); @@ -155,22 +138,15 @@ class StatusServiceTest extends TestCase { $this->service = new StatusService($this->mapper, $this->timeFactory, $this->predefinedStatusService, - $this->emojiService, - $this->config); + $this->emojiHelper, + $this->config, + $this->userManager, + $this->logger, + ); $this->assertEquals([], $this->service->findAllRecentStatusChanges(20, 50)); } - public function testFindByUserId(): void { - $status = $this->createMock(UserStatus::class); - $this->mapper->expects($this->once()) - ->method('findByUserId') - ->with('john.doe') - ->willReturn($status); - - $this->assertEquals($status, $this->service->findByUserId('john.doe')); - } - public function testFindByUserIdDoesNotExist(): void { $this->mapper->expects($this->once()) ->method('findByUserId') @@ -245,30 +221,19 @@ class StatusServiceTest extends TestCase { $this->assertNull($status->getMessageId()); } - /** - * @param string $userId - * @param string $status - * @param int|null $statusTimestamp - * @param bool $isUserDefined - * @param bool $expectExisting - * @param bool $expectSuccess - * @param bool $expectTimeFactory - * @param bool $expectException - * @param string|null $expectedExceptionClass - * @param string|null $expectedExceptionMessage - * - * @dataProvider setStatusDataProvider - */ - public function testSetStatus(string $userId, - string $status, - ?int $statusTimestamp, - bool $isUserDefined, - bool $expectExisting, - bool $expectSuccess, - bool $expectTimeFactory, - bool $expectException, - ?string $expectedExceptionClass, - ?string $expectedExceptionMessage): void { + #[\PHPUnit\Framework\Attributes\DataProvider('setStatusDataProvider')] + public function testSetStatus( + string $userId, + string $status, + ?int $statusTimestamp, + bool $isUserDefined, + bool $expectExisting, + bool $expectSuccess, + bool $expectTimeFactory, + bool $expectException, + ?string $expectedExceptionClass, + ?string $expectedExceptionMessage, + ): void { $userStatus = new UserStatus(); if ($expectExisting) { @@ -319,7 +284,7 @@ class StatusServiceTest extends TestCase { } } - public function setStatusDataProvider(): array { + public static function setStatusDataProvider(): array { return [ ['john.doe', 'online', 50, true, true, true, false, false, null, null], ['john.doe', 'online', 50, true, false, true, false, false, null, null], @@ -377,28 +342,18 @@ class StatusServiceTest extends TestCase { ]; } - /** - * @param string $userId - * @param string $messageId - * @param bool $isValidMessageId - * @param int|null $clearAt - * @param bool $expectExisting - * @param bool $expectSuccess - * @param bool $expectException - * @param string|null $expectedExceptionClass - * @param string|null $expectedExceptionMessage - * - * @dataProvider setPredefinedMessageDataProvider - */ - public function testSetPredefinedMessage(string $userId, - string $messageId, - bool $isValidMessageId, - ?int $clearAt, - bool $expectExisting, - bool $expectSuccess, - bool $expectException, - ?string $expectedExceptionClass, - ?string $expectedExceptionMessage): void { + #[\PHPUnit\Framework\Attributes\DataProvider('setPredefinedMessageDataProvider')] + public function testSetPredefinedMessage( + string $userId, + string $messageId, + bool $isValidMessageId, + ?int $clearAt, + bool $expectExisting, + bool $expectSuccess, + bool $expectException, + ?string $expectedExceptionClass, + ?string $expectedExceptionMessage, + ): void { $userStatus = new UserStatus(); if ($expectExisting) { @@ -461,7 +416,7 @@ class StatusServiceTest extends TestCase { } } - public function setPredefinedMessageDataProvider(): array { + public static function setPredefinedMessageDataProvider(): array { return [ ['john.doe', 'sick-leave', true, null, true, true, false, null, null], ['john.doe', 'sick-leave', true, null, false, true, false, null, null], @@ -474,30 +429,19 @@ class StatusServiceTest extends TestCase { ]; } - /** - * @param string $userId - * @param string|null $statusIcon - * @param bool $supportsEmoji - * @param string $message - * @param int|null $clearAt - * @param bool $expectExisting - * @param bool $expectSuccess - * @param bool $expectException - * @param string|null $expectedExceptionClass - * @param string|null $expectedExceptionMessage - * - * @dataProvider setCustomMessageDataProvider - */ - public function testSetCustomMessage(string $userId, - ?string $statusIcon, - bool $supportsEmoji, - string $message, - ?int $clearAt, - bool $expectExisting, - bool $expectSuccess, - bool $expectException, - ?string $expectedExceptionClass, - ?string $expectedExceptionMessage): void { + #[\PHPUnit\Framework\Attributes\DataProvider('setCustomMessageDataProvider')] + public function testSetCustomMessage( + string $userId, + ?string $statusIcon, + bool $supportsEmoji, + string $message, + ?int $clearAt, + bool $expectExisting, + bool $expectSuccess, + bool $expectException, + ?string $expectedExceptionClass, + ?string $expectedExceptionMessage, + ): void { $userStatus = new UserStatus(); if ($expectExisting) { @@ -519,7 +463,7 @@ class StatusServiceTest extends TestCase { ->willThrowException(new DoesNotExistException('')); } - $this->emojiService->method('isValidEmoji') + $this->emojiHelper->method('isValidSingleEmoji') ->with($statusIcon) ->willReturn($supportsEmoji); @@ -558,7 +502,7 @@ class StatusServiceTest extends TestCase { } } - public function setCustomMessageDataProvider(): array { + public static function setCustomMessageDataProvider(): array { return [ ['john.doe', '😁', true, 'Custom message', null, true, true, false, null, null], ['john.doe', '😁', true, 'Custom message', null, false, true, false, null, null], @@ -749,7 +693,6 @@ class StatusServiceTest extends TestCase { } public function testBackup(): void { - $e = new Exception('', Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION); $this->mapper->expects($this->once()) ->method('createBackupStatus') ->with('john') @@ -795,24 +738,91 @@ class StatusServiceTest extends TestCase { $backupOnly->setUserId('_backuponly'); $backupOnly->setIsBackup(true); + $noBackupDND = new UserStatus(); + $noBackupDND->setId(5); + $noBackupDND->setStatus(IUserStatus::DND); + $noBackupDND->setStatusTimestamp(1337); + $noBackupDND->setIsUserDefined(false); + $noBackupDND->setMessageId('call'); + $noBackupDND->setUserId('nobackupanddnd'); + $noBackupDND->setIsBackup(false); + $this->mapper->expects($this->once()) ->method('findByUserIds') - ->with(['john', 'nobackup', 'backuponly', '_john', '_nobackup', '_backuponly']) + ->with(['john', 'nobackup', 'backuponly', 'nobackupanddnd', '_john', '_nobackup', '_backuponly', '_nobackupanddnd']) ->willReturn([ $john, $johnBackup, $noBackup, $backupOnly, + $noBackupDND, ]); $this->mapper->expects($this->once()) ->method('deleteByIds') - ->with([1, 3]); + ->with([1, 3, 5]); $this->mapper->expects($this->once()) ->method('restoreBackupStatuses') ->with([2]); - $this->service->revertMultipleUserStatus(['john', 'nobackup', 'backuponly'], 'call', IUserStatus::AWAY); + $this->service->revertMultipleUserStatus(['john', 'nobackup', 'backuponly', 'nobackupanddnd'], 'call'); + } + + public static function dataSetUserStatus(): array { + return [ + [IUserStatus::MESSAGE_CALENDAR_BUSY, '', false], + + // Call > Meeting + [IUserStatus::MESSAGE_CALENDAR_BUSY, IUserStatus::MESSAGE_CALL, false], + [IUserStatus::MESSAGE_CALL, IUserStatus::MESSAGE_CALENDAR_BUSY, true], + + // Availability > Call&Meeting + [IUserStatus::MESSAGE_CALENDAR_BUSY, IUserStatus::MESSAGE_AVAILABILITY, false], + [IUserStatus::MESSAGE_CALL, IUserStatus::MESSAGE_AVAILABILITY, false], + [IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::MESSAGE_CALENDAR_BUSY, true], + [IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::MESSAGE_CALL, true], + + // Out-of-office > Availability&Call&Meeting + [IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::MESSAGE_OUT_OF_OFFICE, false], + [IUserStatus::MESSAGE_CALENDAR_BUSY, IUserStatus::MESSAGE_OUT_OF_OFFICE, false], + [IUserStatus::MESSAGE_CALL, IUserStatus::MESSAGE_OUT_OF_OFFICE, false], + [IUserStatus::MESSAGE_OUT_OF_OFFICE, IUserStatus::MESSAGE_AVAILABILITY, true], + [IUserStatus::MESSAGE_OUT_OF_OFFICE, IUserStatus::MESSAGE_CALENDAR_BUSY, true], + [IUserStatus::MESSAGE_OUT_OF_OFFICE, IUserStatus::MESSAGE_CALL, true], + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataSetUserStatus')] + public function testSetUserStatus(string $messageId, string $oldMessageId, bool $expectedUpdateShortcut): void { + $previous = new UserStatus(); + $previous->setId(1); + $previous->setStatus(IUserStatus::AWAY); + $previous->setStatusTimestamp(1337); + $previous->setIsUserDefined(false); + $previous->setMessageId($oldMessageId); + $previous->setUserId('john'); + $previous->setIsBackup(false); + + $this->mapper->expects($this->once()) + ->method('findByUserId') + ->with('john') + ->willReturn($previous); + + $e = DbalException::wrap($this->createMock(UniqueConstraintViolationException::class)); + $this->mapper->expects($expectedUpdateShortcut ? $this->never() : $this->once()) + ->method('createBackupStatus') + ->willThrowException($e); + + $this->mapper->expects($this->any()) + ->method('update') + ->willReturnArgument(0); + + $this->predefinedStatusService->expects($this->once()) + ->method('isValidId') + ->with($messageId) + ->willReturn(true); + + $this->service->setUserStatus('john', IUserStatus::DND, $messageId, true); } } |