diff options
author | Anna Larch <anna@nextcloud.com> | 2023-11-24 01:49:30 +0100 |
---|---|---|
committer | Anna Larch <anna@nextcloud.com> | 2023-11-28 10:28:06 +0100 |
commit | f19645adab404a9c2642b42ec335bf2830dd8aa7 (patch) | |
tree | 3f97f43788aadabce26c1a859c669274639fa695 /apps/user_status | |
parent | 53f31498049cf0dcd61c6ef1d840801bd81f055c (diff) | |
download | nextcloud-server-f19645adab404a9c2642b42ec335bf2830dd8aa7.tar.gz nextcloud-server-f19645adab404a9c2642b42ec335bf2830dd8aa7.zip |
enh(userstatus): add OOO automation and remove calendar automation
Signed-off-by: Anna Larch <anna@nextcloud.com>
Diffstat (limited to 'apps/user_status')
10 files changed, 151 insertions, 415 deletions
diff --git a/apps/user_status/composer/composer/ClassLoader.php b/apps/user_status/composer/composer/ClassLoader.php index 7824d8f7eaf..fd56bd7d840 100644 --- a/apps/user_status/composer/composer/ClassLoader.php +++ b/apps/user_status/composer/composer/ClassLoader.php @@ -45,34 +45,35 @@ class ClassLoader /** @var \Closure(string):void */ private static $includeFile; - /** @var string|null */ + /** @var ?string */ private $vendorDir; // PSR-4 /** - * @var array<string, array<string, int>> + * @var array[] + * @psalm-var array<string, array<string, int>> */ private $prefixLengthsPsr4 = array(); /** - * @var array<string, list<string>> + * @var array[] + * @psalm-var array<string, array<int, string>> */ private $prefixDirsPsr4 = array(); /** - * @var list<string> + * @var array[] + * @psalm-var array<string, string> */ private $fallbackDirsPsr4 = array(); // PSR-0 /** - * List of PSR-0 prefixes - * - * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) - * - * @var array<string, array<string, list<string>>> + * @var array[] + * @psalm-var array<string, array<string, string[]>> */ private $prefixesPsr0 = array(); /** - * @var list<string> + * @var array[] + * @psalm-var array<string, string> */ private $fallbackDirsPsr0 = array(); @@ -80,7 +81,8 @@ class ClassLoader private $useIncludePath = false; /** - * @var array<string, string> + * @var string[] + * @psalm-var array<string, string> */ private $classMap = array(); @@ -88,20 +90,21 @@ class ClassLoader private $classMapAuthoritative = false; /** - * @var array<string, bool> + * @var bool[] + * @psalm-var array<string, bool> */ private $missingClasses = array(); - /** @var string|null */ + /** @var ?string */ private $apcuPrefix; /** - * @var array<string, self> + * @var self[] */ private static $registeredLoaders = array(); /** - * @param string|null $vendorDir + * @param ?string $vendorDir */ public function __construct($vendorDir = null) { @@ -110,7 +113,7 @@ class ClassLoader } /** - * @return array<string, list<string>> + * @return string[] */ public function getPrefixes() { @@ -122,7 +125,8 @@ class ClassLoader } /** - * @return array<string, list<string>> + * @return array[] + * @psalm-return array<string, array<int, string>> */ public function getPrefixesPsr4() { @@ -130,7 +134,8 @@ class ClassLoader } /** - * @return list<string> + * @return array[] + * @psalm-return array<string, string> */ public function getFallbackDirs() { @@ -138,7 +143,8 @@ class ClassLoader } /** - * @return list<string> + * @return array[] + * @psalm-return array<string, string> */ public function getFallbackDirsPsr4() { @@ -146,7 +152,8 @@ class ClassLoader } /** - * @return array<string, string> Array of classname => path + * @return string[] Array of classname => path + * @psalm-return array<string, string> */ public function getClassMap() { @@ -154,7 +161,8 @@ class ClassLoader } /** - * @param array<string, string> $classMap Class to filename map + * @param string[] $classMap Class to filename map + * @psalm-param array<string, string> $classMap * * @return void */ @@ -171,25 +179,24 @@ class ClassLoader * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param list<string>|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories * * @return void */ public function add($prefix, $paths, $prepend = false) { - $paths = (array) $paths; if (!$prefix) { if ($prepend) { $this->fallbackDirsPsr0 = array_merge( - $paths, + (array) $paths, $this->fallbackDirsPsr0 ); } else { $this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0, - $paths + (array) $paths ); } @@ -198,19 +205,19 @@ class ClassLoader $first = $prefix[0]; if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = $paths; + $this->prefixesPsr0[$first][$prefix] = (array) $paths; return; } if ($prepend) { $this->prefixesPsr0[$first][$prefix] = array_merge( - $paths, + (array) $paths, $this->prefixesPsr0[$first][$prefix] ); } else { $this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix], - $paths + (array) $paths ); } } @@ -219,9 +226,9 @@ class ClassLoader * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param list<string>|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException * @@ -229,18 +236,17 @@ class ClassLoader */ public function addPsr4($prefix, $paths, $prepend = false) { - $paths = (array) $paths; if (!$prefix) { // Register directories for the root namespace. if ($prepend) { $this->fallbackDirsPsr4 = array_merge( - $paths, + (array) $paths, $this->fallbackDirsPsr4 ); } else { $this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4, - $paths + (array) $paths ); } } elseif (!isset($this->prefixDirsPsr4[$prefix])) { @@ -250,18 +256,18 @@ class ClassLoader throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); } $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = $paths; + $this->prefixDirsPsr4[$prefix] = (array) $paths; } elseif ($prepend) { // Prepend directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( - $paths, + (array) $paths, $this->prefixDirsPsr4[$prefix] ); } else { // Append directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix], - $paths + (array) $paths ); } } @@ -270,8 +276,8 @@ class ClassLoader * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param list<string>|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 base directories * * @return void */ @@ -288,8 +294,8 @@ class ClassLoader * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param list<string>|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException * @@ -423,8 +429,7 @@ class ClassLoader public function loadClass($class) { if ($file = $this->findFile($class)) { - $includeFile = self::$includeFile; - $includeFile($file); + (self::$includeFile)($file); return true; } @@ -475,9 +480,9 @@ class ClassLoader } /** - * Returns the currently registered loaders keyed by their corresponding vendor directories. + * Returns the currently registered loaders indexed by their corresponding vendor directories. * - * @return array<string, self> + * @return self[] */ public static function getRegisteredLoaders() { @@ -555,10 +560,7 @@ class ClassLoader return false; } - /** - * @return void - */ - private static function initializeIncludeClosure() + private static function initializeIncludeClosure(): void { if (self::$includeFile !== null) { return; @@ -572,8 +574,8 @@ class ClassLoader * @param string $file * @return void */ - self::$includeFile = \Closure::bind(static function($file) { + self::$includeFile = static function($file) { include $file; - }, null, null); + }; } } diff --git a/apps/user_status/composer/composer/autoload_classmap.php b/apps/user_status/composer/composer/autoload_classmap.php index ecdd83dbb68..b57df813bc9 100644 --- a/apps/user_status/composer/composer/autoload_classmap.php +++ b/apps/user_status/composer/composer/autoload_classmap.php @@ -26,6 +26,7 @@ return array( 'OCA\\UserStatus\\Exception\\InvalidStatusTypeException' => $baseDir . '/../lib/Exception/InvalidStatusTypeException.php', 'OCA\\UserStatus\\Exception\\StatusMessageTooLongException' => $baseDir . '/../lib/Exception/StatusMessageTooLongException.php', 'OCA\\UserStatus\\Listener\\BeforeTemplateRenderedListener' => $baseDir . '/../lib/Listener/BeforeTemplateRenderedListener.php', + 'OCA\\UserStatus\\Listener\\OutOfOfficeStatusListener' => $baseDir . '/../lib/Listener/OutOfOfficeStatusListener.php', 'OCA\\UserStatus\\Listener\\UserDeletedListener' => $baseDir . '/../lib/Listener/UserDeletedListener.php', 'OCA\\UserStatus\\Listener\\UserLiveStatusListener' => $baseDir . '/../lib/Listener/UserLiveStatusListener.php', 'OCA\\UserStatus\\Migration\\Version0001Date20200602134824' => $baseDir . '/../lib/Migration/Version0001Date20200602134824.php', diff --git a/apps/user_status/composer/composer/autoload_static.php b/apps/user_status/composer/composer/autoload_static.php index 55be0c04d43..7e494344490 100644 --- a/apps/user_status/composer/composer/autoload_static.php +++ b/apps/user_status/composer/composer/autoload_static.php @@ -41,6 +41,7 @@ class ComposerStaticInitUserStatus 'OCA\\UserStatus\\Exception\\InvalidStatusTypeException' => __DIR__ . '/..' . '/../lib/Exception/InvalidStatusTypeException.php', 'OCA\\UserStatus\\Exception\\StatusMessageTooLongException' => __DIR__ . '/..' . '/../lib/Exception/StatusMessageTooLongException.php', 'OCA\\UserStatus\\Listener\\BeforeTemplateRenderedListener' => __DIR__ . '/..' . '/../lib/Listener/BeforeTemplateRenderedListener.php', + 'OCA\\UserStatus\\Listener\\OutOfOfficeStatusListener' => __DIR__ . '/..' . '/../lib/Listener/OutOfOfficeStatusListener.php', 'OCA\\UserStatus\\Listener\\UserDeletedListener' => __DIR__ . '/..' . '/../lib/Listener/UserDeletedListener.php', 'OCA\\UserStatus\\Listener\\UserLiveStatusListener' => __DIR__ . '/..' . '/../lib/Listener/UserLiveStatusListener.php', 'OCA\\UserStatus\\Migration\\Version0001Date20200602134824' => __DIR__ . '/..' . '/../lib/Migration/Version0001Date20200602134824.php', diff --git a/apps/user_status/lib/AppInfo/Application.php b/apps/user_status/lib/AppInfo/Application.php index 68e5e6169ee..26f736bbc24 100644 --- a/apps/user_status/lib/AppInfo/Application.php +++ b/apps/user_status/lib/AppInfo/Application.php @@ -29,6 +29,7 @@ use OCA\UserStatus\Capabilities; use OCA\UserStatus\Connector\UserStatusProvider; use OCA\UserStatus\Dashboard\UserStatusWidget; use OCA\UserStatus\Listener\BeforeTemplateRenderedListener; +use OCA\UserStatus\Listener\OutOfOfficeStatusListener; use OCA\UserStatus\Listener\UserDeletedListener; use OCA\UserStatus\Listener\UserLiveStatusListener; use OCP\AppFramework\App; @@ -37,6 +38,9 @@ use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; use OCP\IConfig; +use OCP\User\Events\OutOfOfficeChangedEvent; +use OCP\User\Events\OutOfOfficeClearedEvent; +use OCP\User\Events\OutOfOfficeScheduledEvent; use OCP\User\Events\UserDeletedEvent; use OCP\User\Events\UserLiveStatusEvent; use OCP\UserStatus\IManager; @@ -71,6 +75,9 @@ class Application extends App implements IBootstrap { $context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class); $context->registerEventListener(UserLiveStatusEvent::class, UserLiveStatusListener::class); $context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class); + $context->registerEventListener(OutOfOfficeChangedEvent::class, OutOfOfficeStatusListener::class); + $context->registerEventListener(OutOfOfficeScheduledEvent::class, OutOfOfficeStatusListener::class); + $context->registerEventListener(OutOfOfficeClearedEvent::class, OutOfOfficeStatusListener::class); $config = $this->getContainer()->query(IConfig::class); $shareeEnumeration = $config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes'; diff --git a/apps/user_status/lib/Connector/UserStatusProvider.php b/apps/user_status/lib/Connector/UserStatusProvider.php index 4bc2645dceb..700cd3c10fc 100644 --- a/apps/user_status/lib/Connector/UserStatusProvider.php +++ b/apps/user_status/lib/Connector/UserStatusProvider.php @@ -57,8 +57,8 @@ class UserStatusProvider implements IProvider, ISettableProvider { return $userStatuses; } - public function setUserStatus(string $userId, string $messageId, string $status, bool $createBackup): void { - $this->service->setUserStatus($userId, $status, $messageId, $createBackup); + public function setUserStatus(string $userId, string $messageId, string $status, bool $createBackup, ?string $customMessage = null): void { + $this->service->setUserStatus($userId, $status, $messageId, $createBackup, $customMessage); } public function revertUserStatus(string $userId, string $messageId, string $status): void { diff --git a/apps/user_status/lib/Db/UserStatusMapper.php b/apps/user_status/lib/Db/UserStatusMapper.php index febee32c821..3621c1bfa96 100644 --- a/apps/user_status/lib/Db/UserStatusMapper.php +++ b/apps/user_status/lib/Db/UserStatusMapper.php @@ -30,7 +30,6 @@ use OCP\AppFramework\Db\QBMapper; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; use OCP\UserStatus\IUserStatus; -use Sabre\CalDAV\Schedule\Plugin; /** * @template-extends QBMapper<UserStatus> @@ -211,23 +210,4 @@ class UserStatusMapper extends QBMapper { $qb->executeStatement(); } - - public function getAvailabilityFromPropertiesTable(string $userId): ?string { - $propertyPath = 'calendars/' . $userId . '/inbox'; - $propertyName = '{' . Plugin::NS_CALDAV . '}calendar-availability'; - - $query = $this->db->getQueryBuilder(); - $query->select('propertyvalue') - ->from('properties') - ->where($query->expr()->eq('userid', $query->createNamedParameter($userId))) - ->andWhere($query->expr()->eq('propertypath', $query->createNamedParameter($propertyPath))) - ->andWhere($query->expr()->eq('propertyname', $query->createNamedParameter($propertyName))) - ->setMaxResults(1); - - $result = $query->executeQuery(); - $property = $result->fetchOne(); - $result->closeCursor(); - - return ($property === false ? null : $property); - } } diff --git a/apps/user_status/lib/Listener/OutOfOfficeStatusListener.php b/apps/user_status/lib/Listener/OutOfOfficeStatusListener.php new file mode 100644 index 00000000000..0d793c3f306 --- /dev/null +++ b/apps/user_status/lib/Listener/OutOfOfficeStatusListener.php @@ -0,0 +1,67 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Anna Larch <anna.larch@gmx.net> + * + * @author Anna Larch <anna.larch@gmx.net> + * + * @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\Listener; + +use OCA\DAV\BackgroundJob\UserStatusAutomation; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\IJobList; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\User\Events\OutOfOfficeChangedEvent; +use OCP\User\Events\OutOfOfficeClearedEvent; +use OCP\User\Events\OutOfOfficeScheduledEvent; +use OCP\UserStatus\IManager; +use OCP\UserStatus\IUserStatus; + +/** + * Class UserDeletedListener + * + * @template-implements IEventListener<OutOfOfficeScheduledEvent|OutOfOfficeChangedEvent|OutOfOfficeClearedEvent> + * + */ +class OutOfOfficeStatusListener implements IEventListener { + public function __construct(private IJobList $jobsList, + private ITimeFactory $time, + private IManager $manager) { + } + + /** + * @inheritDoc + */ + public function handle(Event $event): void { + if($event instanceof OutOfOfficeClearedEvent) { + $this->manager->revertUserStatus($event->getData()->getUser()->getUID(), IUserStatus::MESSAGE_VACATION, IUserStatus::DND); + $this->jobsList->scheduleAfter(UserStatusAutomation::class, $this->time->getTime(), ['userId' => $event->getData()->getUser()->getUID()]); + return; + } + + if ($event instanceof OutOfOfficeScheduledEvent + || $event instanceof OutOfOfficeChangedEvent) { + // This might be overwritten by the office hours automation, but that is ok. This is just in case no office hours are set + $this->jobsList->scheduleAfter(UserStatusAutomation::class, $this->time->getTime(), ['userId' => $event->getData()->getUser()->getUID()]); + } + } +} diff --git a/apps/user_status/lib/Service/PredefinedStatusService.php b/apps/user_status/lib/Service/PredefinedStatusService.php index 516680ba683..c77ca588ebb 100644 --- a/apps/user_status/lib/Service/PredefinedStatusService.php +++ b/apps/user_status/lib/Service/PredefinedStatusService.php @@ -202,6 +202,7 @@ class PredefinedStatusService { self::REMOTE_WORK, IUserStatus::MESSAGE_CALL, IUserStatus::MESSAGE_AVAILABILITY, + IUserStatus::MESSAGE_VACATION, IUserStatus::MESSAGE_CALENDAR_BUSY, IUserStatus::MESSAGE_CALENDAR_BUSY_TENTATIVE, ], true); diff --git a/apps/user_status/lib/Service/StatusService.php b/apps/user_status/lib/Service/StatusService.php index 829c6c58570..114764f193d 100644 --- a/apps/user_status/lib/Service/StatusService.php +++ b/apps/user_status/lib/Service/StatusService.php @@ -137,37 +137,8 @@ class StatusService { * @return UserStatus * @throws DoesNotExistException */ - public function findByUserId(string $userId): UserStatus { - $userStatus = $this->mapper->findByUserId($userId); - // If the status is user-defined and one of the persistent status, we - // will not override it. - if ($userStatus->getIsUserDefined() && \in_array($userStatus->getStatus(), StatusService::PERSISTENT_STATUSES, true)) { - return $this->processStatus($userStatus); - } - - $calendarStatus = $this->getCalendarStatus($userId); - // We found no status from the calendar, proceed with the existing status - if($calendarStatus === null) { - return $this->processStatus($userStatus); - } - - // if we have the same status result for the calendar and the current status, - // and a custom message to boot, we leave the existing status alone - // as to not overwrite a custom message / emoji - if($userStatus->getIsUserDefined() - && $calendarStatus->getStatus() === $userStatus->getStatus() - && !empty($userStatus->getCustomMessage())) { - return $this->processStatus($userStatus); - } - - // If the new status is null, there's already an identical status in place - $newUserStatus = $this->setUserStatus($userId, - $calendarStatus->getStatus(), - $calendarStatus->getMessage() ?? IUserStatus::MESSAGE_AVAILABILITY, - true, - $calendarStatus->getCustomMessage() ?? ''); - - return $newUserStatus === null ? $this->processStatus($userStatus) : $this->processStatus($newUserStatus); + public function findByUserId(string $userId):UserStatus { + return $this->processStatus($this->mapper->findByUserId($userId)); } /** @@ -271,6 +242,7 @@ class StatusService { * @param string $status * @param string $messageId * @param bool $createBackup + * @param string|null $customMessage * @throws InvalidStatusTypeException * @throws InvalidMessageIdException */ @@ -278,7 +250,7 @@ class StatusService { string $status, string $messageId, bool $createBackup, - string $customMessage = null): ?UserStatus { + ?string $customMessage = null): ?UserStatus { // Check if status-type is valid if (!in_array($status, self::PRIORITY_ORDERED_STATUSES, true)) { throw new InvalidStatusTypeException('Status-type "' . $status . '" is not supported'); @@ -313,13 +285,7 @@ class StatusService { $userStatus->setCustomIcon(null); $userStatus->setCustomMessage($customMessage); $userStatus->setClearAt(null); - if ($this->predefinedStatusService->getTranslatedStatusForId($messageId) !== null - || ($customMessage !== null && $customMessage !== '')) { - // Only track status message ID if there is one - $userStatus->setStatusMessageTimestamp($this->timeFactory->now()->getTimestamp()); - } else { - $userStatus->setStatusMessageTimestamp(0); - } + $userStatus->setStatusMessageTimestamp($this->timeFactory->now()->getTimestamp()); if ($userStatus->getId() !== null) { return $this->mapper->update($userStatus); @@ -506,8 +472,14 @@ class StatusService { private function addDefaultMessage(UserStatus $status): void { // If the message is predefined, insert the translated message and icon $predefinedMessage = $this->predefinedStatusService->getDefaultStatusById($status->getMessageId()); - if ($predefinedMessage !== null) { + if ($predefinedMessage === null) { + return; + } + // If there is a custom message, don't overwrite it + if(empty($status->getCustomMessage())) { $status->setCustomMessage($predefinedMessage['message']); + } + if(empty($status->getCustomIcon())) { $status->setCustomIcon($predefinedMessage['icon']); } } @@ -588,8 +560,7 @@ class StatusService { } /** - * Calculate a users' status according to their availabilit settings and their calendar - * events + * Calculate a users' status according to their calendar events * * There are 4 predefined types of FBTYPE - 'FREE', 'BUSY', 'BUSY-UNAVAILABLE', 'BUSY-TENTATIVE', * but 'X-' properties are possible @@ -598,11 +569,10 @@ class StatusService { * * The status will be changed for types * - 'BUSY' - * - 'BUSY-UNAVAILABLE' (ex.: when a VAVILABILITY setting is in effect) * - 'BUSY-TENTATIVE' (ex.: an event has been accepted tentatively) * and all FREEBUSY components without a type (implicitly a 'BUSY' status) * - * 'X-' properties are not handled for now + * 'X-' properties and BUSY-UNAVAILABLE is not handled * * @param string $userId * @return CalendarStatus|null @@ -612,9 +582,6 @@ class StatusService { if ($user === null) { return null; } - - $availability = $this->mapper->getAvailabilityFromPropertiesTable($userId); - - return $this->calendarStatusService->processCalendarAvailability($user, $availability); + return $this->calendarStatusService->processCalendarAvailability($user); } } diff --git a/apps/user_status/tests/Unit/Service/StatusServiceTest.php b/apps/user_status/tests/Unit/Service/StatusServiceTest.php index 8789a425622..2de041712bd 100644 --- a/apps/user_status/tests/Unit/Service/StatusServiceTest.php +++ b/apps/user_status/tests/Unit/Service/StatusServiceTest.php @@ -845,15 +845,13 @@ class StatusServiceTest extends TestCase { ->method('get') ->with($userId) ->willReturn(null); - $this->mapper->expects(self::never()) - ->method('getAvailabilityFromPropertiesTable'); $this->calendarStatusService->expects(self::never()) ->method('processCalendarAvailability'); $this->service->getCalendarStatus($userId); } - public function testCalendarAvailabilityNoVavailablility(): void { + public function testCalendarAvailabilityNoStatus(): void { $user = $this->createConfiguredMock(IUser::class, [ 'getUID' => 'admin', 'getEMailAddress' => 'test@test.com', @@ -863,299 +861,11 @@ class StatusServiceTest extends TestCase { ->method('get') ->with($user->getUID()) ->willReturn($user); - $this->mapper->expects(self::once()) - ->method('getAvailabilityFromPropertiesTable') - ->willReturn(''); $this->calendarStatusService->expects(self::once()) ->method('processCalendarAvailability') - ->with($user, '') + ->with($user) ->willReturn(null); $this->service->getCalendarStatus($user->getUID()); } - - public function testCalendarAvailabilityVavailablilityAvailable(): void { - $user = $this->createConfiguredMock(IUser::class, [ - 'getUID' => 'admin', - 'getEMailAddress' => 'test@test.com', - ]); - - $vavailability = <<<EOF -BEGIN:VCALENDAR -PRODID:Nextcloud DAV app -BEGIN:VTIMEZONE -TZID:Europe/Vienna -BEGIN:STANDARD -TZNAME:CET -TZOFFSETFROM:+0200 -TZOFFSETTO:+0100 -DTSTART:19701025T030000 -RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU -END:STANDARD -BEGIN:DAYLIGHT -TZNAME:CEST -TZOFFSETFROM:+0100 -TZOFFSETTO:+0200 -DTSTART:19700329T020000 -RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU -END:DAYLIGHT -END:VTIMEZONE -BEGIN:VAVAILABILITY -BEGIN:AVAILABLE -DTSTART;TZID=Europe/Vienna:20231025T000000 -DTEND;TZID=Europe/Vienna:20231025T235900 -UID:d866782e-e003-4906-9ece-303f270a2c6b -RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA,SU -END:AVAILABLE -END:VAVAILABILITY -END:VCALENDAR -EOF; - $status = new Status(IUserStatus::AWAY); - $this->userManager->expects(self::once()) - ->method('get') - ->with($user->getUID()) - ->willReturn($user); - $this->mapper->expects(self::once()) - ->method('getAvailabilityFromPropertiesTable') - ->willReturn($vavailability); - $this->calendarStatusService->expects(self::once()) - ->method('processCalendarAvailability') - ->with($user, $vavailability) - ->willReturn($status); - - $this->service->getCalendarStatus($user->getUID()); - } - - public function testCalendarAvailabilityVavailablilityUpdate(): void { - $user = $this->createConfiguredMock(IUser::class, [ - 'getUID' => 'admin', - 'getEMailAddress' => 'test@test.com', - ]); - $calDavStatus = new Status(IUserStatus::BUSY, 'meeting', 'In a meeting'); - $vavailability = <<<EOF -BEGIN:VCALENDAR -PRODID:Nextcloud DAV app -BEGIN:VTIMEZONE -TZID:Europe/Vienna -BEGIN:STANDARD -TZNAME:CET -TZOFFSETFROM:+0200 -TZOFFSETTO:+0100 -DTSTART:19701025T030000 -RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU -END:STANDARD -BEGIN:DAYLIGHT -TZNAME:CEST -TZOFFSETFROM:+0100 -TZOFFSETTO:+0200 -DTSTART:19700329T020000 -RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU -END:DAYLIGHT -END:VTIMEZONE -BEGIN:VAVAILABILITY -BEGIN:AVAILABLE -DTSTART;TZID=Europe/Vienna:20231025T000000 -DTEND;TZID=Europe/Vienna:20231025T235900 -UID:d866782e-e003-4906-9ece-303f270a2c6b -RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA,SU -END:AVAILABLE -END:VAVAILABILITY -END:VCALENDAR -EOF; - $this->userManager->expects(self::once()) - ->method('get') - ->with($user->getUID()) - ->willReturn($user); - $this->mapper->expects(self::once()) - ->method('getAvailabilityFromPropertiesTable') - ->willReturn($vavailability); - $this->calendarStatusService->expects(self::once()) - ->method('processCalendarAvailability') - ->with($user, $vavailability) - ->willReturn($calDavStatus); - - $this->service->getCalendarStatus($user->getUID()); - } - - public function testFindByUserIdUserDefinedAndPersistent(): void { - $status = new UserStatus(); - $status->setIsUserDefined(true); - $status->setStatus(IUserStatus::DND); - - $this->mapper->expects($this->once()) - ->method('findByUserId') - ->with('admin') - ->willReturn($status); - $this->mapper->expects(self::never()) - ->method('getAvailabilityFromPropertiesTable'); - $this->calendarStatusService->expects(self::never()) - ->method('processCalendarAvailability'); - - $this->assertEquals($status, $this->service->findByUserId('admin')); - } - - public function testFindByUserIdUserDefinedNoCalStatus(): void { - $user = $this->createConfiguredMock(IUser::class, [ - 'getUID' => 'admin', - 'getEMailAddress' => 'test@test.com', - ]); - $status = new UserStatus(); - $status->setIsUserDefined(true); - $status->setStatus(IUserStatus::ONLINE); - - $this->mapper->expects($this->once()) - ->method('findByUserId') - ->with($user->getUID()) - ->willReturn($status); - $this->userManager->expects(self::once()) - ->method('get') - ->willReturn($user); - $this->mapper->expects(self::once()) - ->method('getAvailabilityFromPropertiesTable') - ->willReturn(''); - $this->calendarStatusService->expects(self::once()) - ->method('processCalendarAvailability') - ->with($user, '') - ->willReturn(null); - - $this->assertEquals($status, $this->service->findByUserId('admin')); - } - - public function testFindByUserIdUserDefinedCalStatusIdentical(): void { - $user = $this->createConfiguredMock(IUser::class, [ - 'getUID' => 'admin', - 'getEMailAddress' => 'test@test.com', - ]); - $calDavStatus = new Status(IUserStatus::ONLINE); - $userStatus = new UserStatus(); - $userStatus->setStatus(IUserStatus::ONLINE); - $userStatus->setIsUserDefined(true); - $userStatus->setCustomMessage('Test'); - - $this->mapper->expects(self::once()) - ->method('findByUserId') - ->with($user->getUID()) - ->willReturn($userStatus); - $this->userManager->expects(self::once()) - ->method('get') - ->willReturn($user); - $this->mapper->expects(self::once()) - ->method('getAvailabilityFromPropertiesTable') - ->willReturn(''); - $this->calendarStatusService->expects(self::once()) - ->method('processCalendarAvailability') - ->with($user, '') - ->willReturn($calDavStatus); - - $this->assertEquals($userStatus, $this->service->findByUserId('admin')); - } - - public function testFindByUserIdUserDefinedCalStatusUpdate(): void { - $user = $this->createConfiguredMock(IUser::class, [ - 'getUID' => 'admin', - 'getEMailAddress' => 'test@test.com', - ]); - $calDavStatus = new Status(IUserStatus::BUSY, 'meeting', 'In a meeting'); - - $oldStatus = new UserStatus(); - $oldStatus->setId(42); - $oldStatus->setUserId($user->getUID()); - $oldStatus->setStatus(IUserStatus::ONLINE); - $oldStatus->setStatusTimestamp(0); - $oldStatus->setIsUserDefined(true); - - $expected = new UserStatus(); - $expected->setUserId($user->getUID()); - $expected->setStatus(IUserStatus::BUSY); - $expected->setStatusTimestamp(0); - $expected->setIsUserDefined(true); - $expected->setIsBackup(false); - - $this->mapper->expects(self::once()) - ->method('findByUserId') - ->with($user->getUID()) - ->willReturn($oldStatus); - $this->userManager->expects(self::once()) - ->method('get') - ->willReturn($user); - $this->mapper->expects(self::once()) - ->method('getAvailabilityFromPropertiesTable') - ->willReturn(''); - $this->mapper->expects(self::once()) - ->method('createBackupStatus') - ->with($user->getUID()) - ->willReturn(true); - $this->calendarStatusService->expects(self::once()) - ->method('processCalendarAvailability') - ->with($user, '') - ->willReturn($calDavStatus); - $this->predefinedStatusService->expects(self::once()) - ->method('isValidId') - ->with($calDavStatus->getMessage()) - ->willReturn(true); - $this->mapper->expects(self::once()) - ->method('insert') - ->willReturn($expected); - - $actual = $this->service->findByUserId('admin'); - $this->assertEquals($expected->getStatus(), $actual->getStatus()); - $this->assertEquals($expected->getCustomMessage(), $actual->getCustomMessage()); - } - - public function testFindByUserIdSystemDefined(): void { - $user = $this->createConfiguredMock(IUser::class, [ - 'getUID' => 'admin', - 'getEMailAddress' => 'test@test.com', - ]); - $status = new UserStatus(); - $status->setIsUserDefined(false); - $status->setStatus(IUserStatus::ONLINE); - - $this->mapper->expects($this->once()) - ->method('findByUserId') - ->with($user->getUID()) - ->willReturn($status); - $this->userManager->expects(self::once()) - ->method('get') - ->willReturn($user); - $this->mapper->expects(self::once()) - ->method('getAvailabilityFromPropertiesTable') - ->willReturn(''); - $this->calendarStatusService->expects(self::once()) - ->method('processCalendarAvailability') - ->with($user, '') - ->willReturn(null); - - $this->assertEquals($status, $this->service->findByUserId('admin')); - } - - public function testSetStatusWithoutMessage(): void { - $this->predefinedStatusService->expects(self::once()) - ->method('isValidId') - ->with(IUserStatus::MESSAGE_AVAILABILITY) - ->willReturn(true); - $this->timeFactory - ->method('getTime') - ->willReturn(1234); - $status = new UserStatus(); - $status->setUserId('admin'); - $status->setStatusTimestamp(1234); - $status->setIsUserDefined(true); - $status->setStatus(IUserStatus::DND); - $status->setIsBackup(false); - $status->setMessageId(IUserStatus::MESSAGE_AVAILABILITY); - $this->mapper->expects(self::once()) - ->method('insert') - ->with($this->equalTo($status)) - ->willReturnArgument(0); - - $result = $this->service->setUserStatus( - 'admin', - IUserStatus::DND, - IUserStatus::MESSAGE_AVAILABILITY, - true, - ); - - self::assertNotNull($result); - } } |