mirror of
https://github.com/nextcloud/server.git
synced 2026-06-08 16:26:59 -04:00
fix(userstatus): set user status to 'In a meeting' if calendar is busy
Signed-off-by: Anna Larch <anna@nextcloud.com>
This commit is contained in:
parent
82e0f1f370
commit
5fd10dc398
11 changed files with 459 additions and 874 deletions
|
|
@ -99,7 +99,6 @@ return array(
|
|||
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/PropFilter.php',
|
||||
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter' => $baseDir . '/../lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php',
|
||||
'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport' => $baseDir . '/../lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php',
|
||||
'OCA\\DAV\\CalDAV\\Status\\Status' => $baseDir . '/../lib/CalDAV/Status/Status.php',
|
||||
'OCA\\DAV\\CalDAV\\Status\\StatusService' => $baseDir . '/../lib/CalDAV/Status/StatusService.php',
|
||||
'OCA\\DAV\\CalDAV\\TimezoneService' => $baseDir . '/../lib/CalDAV/TimezoneService.php',
|
||||
'OCA\\DAV\\CalDAV\\Trashbin\\DeletedCalendarObject' => $baseDir . '/../lib/CalDAV/Trashbin/DeletedCalendarObject.php',
|
||||
|
|
|
|||
|
|
@ -114,7 +114,6 @@ class ComposerStaticInitDAV
|
|||
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/PropFilter.php',
|
||||
'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php',
|
||||
'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport' => __DIR__ . '/..' . '/../lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php',
|
||||
'OCA\\DAV\\CalDAV\\Status\\Status' => __DIR__ . '/..' . '/../lib/CalDAV/Status/Status.php',
|
||||
'OCA\\DAV\\CalDAV\\Status\\StatusService' => __DIR__ . '/..' . '/../lib/CalDAV/Status/StatusService.php',
|
||||
'OCA\\DAV\\CalDAV\\TimezoneService' => __DIR__ . '/..' . '/../lib/CalDAV/TimezoneService.php',
|
||||
'OCA\\DAV\\CalDAV\\Trashbin\\DeletedCalendarObject' => __DIR__ . '/..' . '/../lib/CalDAV/Trashbin/DeletedCalendarObject.php',
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 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\DAV\CalDAV\Status;
|
||||
|
||||
class Status {
|
||||
public function __construct(private string $status = '', private ?string $message = null, private ?string $customMessage = null, private ?int $timestamp = null, private ?string $customEmoji = null) {
|
||||
}
|
||||
|
||||
public function getStatus(): string {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function setStatus(string $status): void {
|
||||
$this->status = $status;
|
||||
}
|
||||
|
||||
public function getMessage(): ?string {
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
public function setMessage(?string $message): void {
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
public function getCustomMessage(): ?string {
|
||||
return $this->customMessage;
|
||||
}
|
||||
|
||||
public function setCustomMessage(?string $customMessage): void {
|
||||
$this->customMessage = $customMessage;
|
||||
}
|
||||
|
||||
public function setEndTime(?int $timestamp): void {
|
||||
$this->timestamp = $timestamp;
|
||||
}
|
||||
|
||||
public function getEndTime(): ?int {
|
||||
return $this->timestamp;
|
||||
}
|
||||
|
||||
public function getCustomEmoji(): ?string {
|
||||
return $this->customEmoji;
|
||||
}
|
||||
|
||||
public function setCustomEmoji(?string $emoji): void {
|
||||
$this->customEmoji = $emoji;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,83 +25,123 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\DAV\CalDAV\Status;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use OC\Calendar\CalendarQuery;
|
||||
use OCA\DAV\CalDAV\CalendarImpl;
|
||||
use OCA\DAV\CalDAV\FreeBusy\FreeBusyGenerator;
|
||||
use OCA\DAV\CalDAV\InvitationResponse\InvitationResponseServer;
|
||||
use OCA\DAV\CalDAV\Schedule\Plugin as SchedulePlugin;
|
||||
use OCA\UserStatus\Service\StatusService as UserStatusService;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Calendar\IManager;
|
||||
use OCP\IL10N;
|
||||
use OCP\ICache;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IUser as User;
|
||||
use OCP\IUserManager;
|
||||
use OCP\User\IAvailabilityCoordinator;
|
||||
use OCP\UserStatus\IUserStatus;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp;
|
||||
use Sabre\DAV\Exception\NotAuthenticated;
|
||||
use Sabre\DAVACL\Exception\NeedPrivileges;
|
||||
use Sabre\DAVACL\Plugin as AclPlugin;
|
||||
use Sabre\VObject\Component;
|
||||
use Sabre\VObject\Component\VEvent;
|
||||
use Sabre\VObject\Parameter;
|
||||
use Sabre\VObject\Property;
|
||||
|
||||
class StatusService {
|
||||
private ICache $cache;
|
||||
public function __construct(private ITimeFactory $timeFactory,
|
||||
private IManager $calendarManager,
|
||||
private InvitationResponseServer $server,
|
||||
private IL10N $l10n,
|
||||
private FreeBusyGenerator $generator) {
|
||||
private IUserManager $userManager,
|
||||
private UserStatusService $userStatusService,
|
||||
private IAvailabilityCoordinator $availabilityCoordinator,
|
||||
private ICacheFactory $cacheFactory,
|
||||
private LoggerInterface $logger) {
|
||||
$this->cache = $cacheFactory->createLocal('CalendarStatusService');
|
||||
}
|
||||
|
||||
public function processCalendarAvailability(User $user): ?Status {
|
||||
$userId = $user->getUID();
|
||||
$email = $user->getEMailAddress();
|
||||
if($email === null) {
|
||||
return null;
|
||||
public function processCalendarStatus(string $userId): void {
|
||||
$user = $this->userManager->get($userId);
|
||||
if($user === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$server = $this->server->getServer();
|
||||
|
||||
/** @var SchedulePlugin $schedulingPlugin */
|
||||
$schedulingPlugin = $server->getPlugin('caldav-schedule');
|
||||
$caldavNS = '{'.$schedulingPlugin::NS_CALDAV.'}';
|
||||
|
||||
/** @var AclPlugin $aclPlugin */
|
||||
$aclPlugin = $server->getPlugin('acl');
|
||||
if ('mailto:' === substr($email, 0, 7)) {
|
||||
$email = substr($email, 7);
|
||||
$availability = $this->availabilityCoordinator->getCurrentOutOfOfficeData($user);
|
||||
if($availability !== null && $this->availabilityCoordinator->isInEffect($availability)) {
|
||||
$this->logger->debug('An Absence is in effect, skipping calendar status check', ['user' => $userId]);
|
||||
return;
|
||||
}
|
||||
|
||||
$result = $aclPlugin->principalSearch(
|
||||
['{http://sabredav.org/ns}email-address' => $email],
|
||||
[
|
||||
'{DAV:}principal-URL',
|
||||
$caldavNS.'calendar-home-set',
|
||||
$caldavNS.'schedule-inbox-URL',
|
||||
'{http://sabredav.org/ns}email-address',
|
||||
]
|
||||
$calendarEvents = $this->cache->get($userId);
|
||||
if($calendarEvents === null) {
|
||||
$calendarEvents = $this->getCalendarEvents($user);
|
||||
$this->cache->set($userId, $calendarEvents, 300);
|
||||
}
|
||||
|
||||
if(empty($calendarEvents)) {
|
||||
$this->userStatusService->revertUserStatus($userId, IUserStatus::MESSAGE_CALENDAR_BUSY);
|
||||
$this->logger->debug('No calendar events found for status check', ['user' => $userId]);
|
||||
return;
|
||||
}
|
||||
|
||||
$userStatusTimestamp = null;
|
||||
$currentStatus = null;
|
||||
try {
|
||||
$currentStatus = $this->userStatusService->findByUserId($userId);
|
||||
$userStatusTimestamp = $currentStatus->getIsUserDefined() ? $currentStatus->getStatusTimestamp() : null;
|
||||
} catch (DoesNotExistException) {
|
||||
}
|
||||
|
||||
if($currentStatus !== null && $currentStatus->getMessageId() === IUserStatus::MESSAGE_CALL
|
||||
|| $currentStatus !== null && $currentStatus->getStatus() === IUserStatus::DND
|
||||
|| $currentStatus !== null && $currentStatus->getStatus() === IUserStatus::INVISIBLE) {
|
||||
// We don't overwrite the call status, DND status or Invisible status
|
||||
$this->logger->debug('Higher priority status detected, skipping calendar status change', ['user' => $userId]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter events to see if we have any that apply to the calendar status
|
||||
$applicableEvents = array_filter($calendarEvents, function (array $calendarEvent) use ($userStatusTimestamp) {
|
||||
$component = $calendarEvent['objects'][0];
|
||||
if(isset($component['X-NEXTCLOUD-OUT-OF-OFFICE'])) {
|
||||
return false;
|
||||
}
|
||||
if(isset($component['DTSTART']) && $userStatusTimestamp !== null) {
|
||||
/** @var DateTimeImmutable $dateTime */
|
||||
$dateTime = $component['DTSTART'][0];
|
||||
$timestamp = $dateTime->getTimestamp();
|
||||
if($userStatusTimestamp > $timestamp) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Ignore events that are transparent
|
||||
if(isset($component['TRANSP']) && strcasecmp($component['TRANSP'][0], 'TRANSPARENT') === 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if(empty($applicableEvents)) {
|
||||
$this->userStatusService->revertUserStatus($userId, IUserStatus::MESSAGE_CALENDAR_BUSY);
|
||||
$this->logger->debug('No status relevant events found, skipping calendar status change', ['user' => $userId]);
|
||||
return;
|
||||
}
|
||||
|
||||
// One event that fulfills all status conditions is enough
|
||||
// 1. Not an OOO event
|
||||
// 2. Current user status was not set after the start of this event
|
||||
// 3. Event is not set to be transparent
|
||||
$count = count($applicableEvents);
|
||||
$this->logger->debug("Found $count applicable event(s), changing user status", ['user' => $userId]);
|
||||
$this->userStatusService->setUserStatus(
|
||||
$userId,
|
||||
IUserStatus::AWAY,
|
||||
IUserStatus::MESSAGE_CALENDAR_BUSY,
|
||||
true
|
||||
);
|
||||
|
||||
if (!count($result) || !isset($result[0][200][$caldavNS.'schedule-inbox-URL'])) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
$inboxUrl = $result[0][200][$caldavNS.'schedule-inbox-URL']->getHref();
|
||||
|
||||
// Do we have permission?
|
||||
try {
|
||||
$aclPlugin->checkPrivileges($inboxUrl, $caldavNS.'schedule-query-freebusy');
|
||||
} catch (NeedPrivileges | NotAuthenticated $exception) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$now = $this->timeFactory->now();
|
||||
$calendarTimeZone = $now->getTimezone();
|
||||
$calendars = $this->calendarManager->getCalendarsForPrincipal('principals/users/' . $userId);
|
||||
private function getCalendarEvents(User $user): array {
|
||||
$calendars = $this->calendarManager->getCalendarsForPrincipal('principals/users/' . $user->getUID());
|
||||
if(empty($calendars)) {
|
||||
return null;
|
||||
return [];
|
||||
}
|
||||
|
||||
$query = $this->calendarManager->newQuery('principals/users/' . $userId);
|
||||
$query = $this->calendarManager->newQuery('principals/users/' . $user->getUID());
|
||||
foreach ($calendars as $calendarObject) {
|
||||
// We can only work with a calendar if it exposes its scheduling information
|
||||
if (!$calendarObject instanceof CalendarImpl) {
|
||||
|
|
@ -114,83 +154,20 @@ class StatusService {
|
|||
// ignore it for free-busy purposes.
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @var Component\VTimeZone|null $ctz */
|
||||
$ctz = $calendarObject->getSchedulingTimezone();
|
||||
if ($ctz !== null) {
|
||||
$calendarTimeZone = $ctz->getTimeZone();
|
||||
}
|
||||
$query->addSearchCalendar($calendarObject->getUri());
|
||||
}
|
||||
|
||||
$calendarEvents = [];
|
||||
$dtStart = $now;
|
||||
$dtEnd = \DateTimeImmutable::createFromMutable($this->timeFactory->getDateTime('+10 minutes'));
|
||||
$dtStart = DateTimeImmutable::createFromMutable($this->timeFactory->getDateTime());
|
||||
$dtEnd = DateTimeImmutable::createFromMutable($this->timeFactory->getDateTime('+5 minutes'));
|
||||
|
||||
// Only query the calendars when there's any to search
|
||||
if($query instanceof CalendarQuery && !empty($query->getCalendarUris())) {
|
||||
// Query the next hour
|
||||
$query->setTimerangeStart($dtStart);
|
||||
$query->setTimerangeEnd($dtEnd);
|
||||
$calendarEvents = $this->calendarManager->searchForPrincipal($query);
|
||||
return $this->calendarManager->searchForPrincipal($query);
|
||||
}
|
||||
|
||||
// @todo we can cache that
|
||||
if(empty($calendarEvents)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$calendar = $this->generator->getVCalendar();
|
||||
foreach ($calendarEvents as $calendarEvent) {
|
||||
$vEvent = new VEvent($calendar, 'VEVENT');
|
||||
foreach($calendarEvent['objects'] as $component) {
|
||||
foreach ($component as $key => $value) {
|
||||
$vEvent->add($key, $value[0]);
|
||||
}
|
||||
}
|
||||
$calendar->add($vEvent);
|
||||
}
|
||||
|
||||
$calendar->METHOD = 'REQUEST';
|
||||
|
||||
$this->generator->setObjects($calendar);
|
||||
$this->generator->setTimeRange($dtStart, $dtEnd);
|
||||
$this->generator->setTimeZone($calendarTimeZone);
|
||||
$result = $this->generator->getResult();
|
||||
|
||||
if (!isset($result->VFREEBUSY)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var Component $freeBusyComponent */
|
||||
$freeBusyComponent = $result->VFREEBUSY;
|
||||
$freeBusyProperties = $freeBusyComponent->select('FREEBUSY');
|
||||
// If there is no FreeBusy property, the time-range is empty and available
|
||||
if (count($freeBusyProperties) === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var Property $freeBusyProperty */
|
||||
$freeBusyProperty = $freeBusyProperties[0];
|
||||
if (!$freeBusyProperty->offsetExists('FBTYPE')) {
|
||||
// If there is no FBTYPE, it means it's busy from a regular event
|
||||
return new Status(IUserStatus::BUSY, IUserStatus::MESSAGE_CALENDAR_BUSY);
|
||||
}
|
||||
|
||||
// If we can't deal with the FBTYPE (custom properties are a possibility)
|
||||
// we should ignore it and leave the current status
|
||||
$fbTypeParameter = $freeBusyProperty->offsetGet('FBTYPE');
|
||||
if (!($fbTypeParameter instanceof Parameter)) {
|
||||
return null;
|
||||
}
|
||||
$fbType = $fbTypeParameter->getValue();
|
||||
switch ($fbType) {
|
||||
// Ignore BUSY-UNAVAILABLE, that's for the automation
|
||||
case 'BUSY':
|
||||
case 'BUSY-TENTATIVE':
|
||||
return new Status(IUserStatus::BUSY, IUserStatus::MESSAGE_CALENDAR_BUSY, $this->l10n->t('In a meeting'));
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,31 +24,31 @@ namespace OCA\DAV\Tests\unit\CalDAV\Status;
|
|||
|
||||
use OC\Calendar\CalendarQuery;
|
||||
use OCA\DAV\CalDAV\CalendarImpl;
|
||||
use OCA\DAV\CalDAV\FreeBusy\FreeBusyGenerator;
|
||||
use OCA\DAV\CalDAV\InvitationResponse\InvitationResponseServer;
|
||||
use OCA\DAV\CalDAV\Schedule\Plugin;
|
||||
use OCA\DAV\CalDAV\Status\StatusService;
|
||||
use OCA\DAV\Connector\Sabre\Server;
|
||||
use OCA\UserStatus\Db\UserStatus;
|
||||
use OCA\UserStatus\Service\StatusService as UserStatusService;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Calendar\IManager;
|
||||
use OCP\IL10N;
|
||||
use OCP\ICache;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\User\IAvailabilityCoordinator;
|
||||
use OCP\User\IOutOfOfficeData;
|
||||
use OCP\UserStatus\IUserStatus;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp;
|
||||
use Sabre\DAV\Exception\NotAuthenticated;
|
||||
use Sabre\DAV\Xml\Property\LocalHref;
|
||||
use Sabre\DAVACL\Exception\NeedPrivileges;
|
||||
use Sabre\VObject\Component\VCalendar;
|
||||
use Sabre\VObject\Component\VTimeZone;
|
||||
use Sabre\VObject\Reader;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
class StatusServiceTest extends TestCase {
|
||||
private ITimeFactory|MockObject $timeFactory;
|
||||
private IManager|MockObject $calendarManager;
|
||||
private InvitationResponseServer|MockObject $server;
|
||||
private IL10N|MockObject $l10n;
|
||||
private FreeBusyGenerator|MockObject $generator;
|
||||
private IUserManager|MockObject $userManager;
|
||||
private UserStatusService|MockObject $userStatusService;
|
||||
private IAvailabilityCoordinator|MockObject $availabilityCoordinator;
|
||||
private ICacheFactory|MockObject $cacheFactory;
|
||||
private LoggerInterface|MockObject $logger;
|
||||
private StatusService $service;
|
||||
|
||||
protected function setUp(): void {
|
||||
|
|
@ -56,644 +56,360 @@ class StatusServiceTest extends TestCase {
|
|||
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
$this->calendarManager = $this->createMock(IManager::class);
|
||||
$this->server = $this->createMock(InvitationResponseServer::class);
|
||||
$this->l10n = $this->createMock(IL10N::class);
|
||||
$this->generator = $this->createMock(FreeBusyGenerator::class);
|
||||
$this->userManager = $this->createMock(IUserManager::class);
|
||||
$this->userStatusService = $this->createMock(UserStatusService::class);
|
||||
$this->availabilityCoordinator = $this->createMock(IAvailabilityCoordinator::class);
|
||||
$this->cacheFactory = $this->createMock(ICacheFactory::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->cache = $this->createMock(ICache::class);
|
||||
$this->cacheFactory->expects(self::once())
|
||||
->method('createLocal')
|
||||
->with('CalendarStatusService')
|
||||
->willReturn($this->cache);
|
||||
|
||||
$this->service = new StatusService($this->timeFactory,
|
||||
$this->calendarManager,
|
||||
$this->server,
|
||||
$this->l10n,
|
||||
$this->generator);
|
||||
$this->userManager,
|
||||
$this->userStatusService,
|
||||
$this->availabilityCoordinator,
|
||||
$this->cacheFactory,
|
||||
$this->logger,
|
||||
);
|
||||
}
|
||||
|
||||
public function testNoEmail(): void {
|
||||
$user = $this->createConfiguredMock(IUser::class, [
|
||||
'getUID' => 'admin',
|
||||
'getEMailAddress' => null,
|
||||
]);
|
||||
|
||||
$user->expects(self::once())
|
||||
->method('getUID')
|
||||
->willReturn('admin');
|
||||
$user->expects(self::once())
|
||||
->method('getEMailAddress')
|
||||
public function testNoUser(): void {
|
||||
$this->userManager->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn(null);
|
||||
$this->server->expects(self::never())
|
||||
->method('getServer');
|
||||
$this->timeFactory->expects(self::never())
|
||||
->method('now');
|
||||
$this->timeFactory->expects(self::never())
|
||||
->method('getDateTime');
|
||||
$this->availabilityCoordinator->expects(self::never())
|
||||
->method('getCurrentOutOfOfficeData');
|
||||
$this->availabilityCoordinator->expects(self::never())
|
||||
->method('isInEffect');
|
||||
$this->logger->expects(self::never())
|
||||
->method('debug');
|
||||
$this->cache->expects(self::never())
|
||||
->method('get');
|
||||
$this->cache->expects(self::never())
|
||||
->method('set');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('getCalendarsForPrincipal');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('newQuery');
|
||||
$this->timeFactory->expects(self::never())
|
||||
->method('getDateTime');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('searchForPrincipal');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getVCalendar');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setObjects');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeRange');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeZone');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getResult');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('revertUserStatus');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('setUserStatus');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('findByUserId');
|
||||
|
||||
$status = $this->service->processCalendarAvailability($user);
|
||||
$this->assertNull($status);
|
||||
$this->service->processCalendarStatus('admin');
|
||||
}
|
||||
|
||||
public function testNoAcl(): void {
|
||||
public function testOOOInEffect(): void {
|
||||
$user = $this->createConfiguredMock(IUser::class, [
|
||||
'getUID' => 'admin',
|
||||
'getEMailAddress' => 'test@test.com',
|
||||
]);
|
||||
$availability = '';
|
||||
$server = $this->createMock(Server::class);
|
||||
$schedulingPlugin = $this->createMock(Plugin::class);
|
||||
$aclPlugin = $this->createMock(\Sabre\DAVACL\Plugin::class);
|
||||
|
||||
$user->expects(self::once())
|
||||
->method('getUID')
|
||||
->willReturn('admin');
|
||||
$user->expects(self::once())
|
||||
->method('getEMailAddress')
|
||||
->willReturn('test@test.com');
|
||||
$this->server->expects(self::once())
|
||||
->method('getServer')
|
||||
->willReturn($server);
|
||||
$server->expects(self::exactly(2))
|
||||
->method('getPlugin')
|
||||
->withConsecutive(
|
||||
['caldav-schedule'],
|
||||
['acl'],
|
||||
)->willReturnOnConsecutiveCalls($schedulingPlugin, $aclPlugin);
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('principalSearch')
|
||||
->with([ '{http://sabredav.org/ns}email-address' => 'test@test.com'])
|
||||
->willReturn([]);
|
||||
$aclPlugin->expects(self::never())
|
||||
->method('checkPrivileges');
|
||||
$this->timeFactory->expects(self::never())
|
||||
->method('now');
|
||||
$this->timeFactory->expects(self::never())
|
||||
->method('getDateTime');
|
||||
$this->userManager->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn($user);
|
||||
$this->availabilityCoordinator->expects(self::once())
|
||||
->method('getCurrentOutOfOfficeData')
|
||||
->willReturn($this->createMock(IOutOfOfficeData::class));
|
||||
$this->availabilityCoordinator->expects(self::once())
|
||||
->method('isInEffect')
|
||||
->willReturn(true);
|
||||
$this->logger->expects(self::once())
|
||||
->method('debug');
|
||||
$this->cache->expects(self::never())
|
||||
->method('get');
|
||||
$this->cache->expects(self::never())
|
||||
->method('set');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('getCalendarsForPrincipal');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('newQuery');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('searchForPrincipal');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getVCalendar');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setObjects');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeRange');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeZone');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getResult');
|
||||
|
||||
$status = $this->service->processCalendarAvailability($user);
|
||||
$this->assertNull($status);
|
||||
}
|
||||
|
||||
public function testNoInbox(): void {
|
||||
$user = $this->createConfiguredMock(IUser::class, [
|
||||
'getUID' => 'admin',
|
||||
'getEMailAddress' => 'test@test.com',
|
||||
]);
|
||||
$availability = '';
|
||||
$server = $this->createMock(Server::class);
|
||||
$schedulingPlugin = $this->createMock(Plugin::class);
|
||||
$aclPlugin = $this->createMock(\Sabre\DAVACL\Plugin::class);
|
||||
|
||||
$user->expects(self::once())
|
||||
->method('getUID')
|
||||
->willReturn('admin');
|
||||
$user->expects(self::once())
|
||||
->method('getEMailAddress')
|
||||
->willReturn('test@test.com');
|
||||
$this->server->expects(self::once())
|
||||
->method('getServer')
|
||||
->willReturn($server);
|
||||
$server->expects(self::exactly(2))
|
||||
->method('getPlugin')
|
||||
->withConsecutive(
|
||||
['caldav-schedule'],
|
||||
['acl'],
|
||||
)->willReturnOnConsecutiveCalls($schedulingPlugin, $aclPlugin);
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('principalSearch')
|
||||
->with([ '{http://sabredav.org/ns}email-address' => 'test@test.com'])
|
||||
->willReturn([]);
|
||||
$aclPlugin->expects(self::never())
|
||||
->method('checkPrivileges');
|
||||
$this->timeFactory->expects(self::never())
|
||||
->method('now');
|
||||
$this->timeFactory->expects(self::never())
|
||||
->method('getDateTime');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('getCalendarsForPrincipal');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('newQuery');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('searchForPrincipal');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getVCalendar');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setObjects');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeRange');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeZone');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getResult');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('revertUserStatus');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('setUserStatus');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('findByUserId');
|
||||
|
||||
$status = $this->service->processCalendarAvailability($user);
|
||||
$this->assertNull($status);
|
||||
}
|
||||
|
||||
public function testNoPrivilegesAcl(): void {
|
||||
$user = $this->createConfiguredMock(IUser::class, [
|
||||
'getUID' => 'admin',
|
||||
'getEMailAddress' => 'test@test.com',
|
||||
]);
|
||||
$availability = '';
|
||||
$server = $this->createMock(Server::class);
|
||||
$schedulingPlugin = $this->createMock(Plugin::class);
|
||||
$aclPlugin = $this->createMock(\Sabre\DAVACL\Plugin::class);
|
||||
$principal = 'principals/users/admin';
|
||||
$calendarHome = $this->createMock(LocalHref::class);
|
||||
$acl = [[200 => ['{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL' => $calendarHome]]];
|
||||
|
||||
$user->expects(self::once())
|
||||
->method('getUID')
|
||||
->willReturn('admin');
|
||||
$user->expects(self::once())
|
||||
->method('getEMailAddress')
|
||||
->willReturn('test@test.com');
|
||||
$this->server->expects(self::once())
|
||||
->method('getServer')
|
||||
->willReturn($server);
|
||||
$server->expects(self::exactly(2))
|
||||
->method('getPlugin')
|
||||
->withConsecutive(
|
||||
['caldav-schedule'],
|
||||
['acl'],
|
||||
)->willReturnOnConsecutiveCalls($schedulingPlugin, $aclPlugin);
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('principalSearch')
|
||||
->with([ '{http://sabredav.org/ns}email-address' => 'test@test.com'])
|
||||
->willReturn($acl);
|
||||
$calendarHome->expects(self::once())
|
||||
->method('getHref')
|
||||
->willReturn('calendars/admin/inbox/');
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('checkPrivileges')
|
||||
->willThrowException(new NeedPrivileges($principal, ['{DAV:}all']));
|
||||
$this->timeFactory->expects(self::never())
|
||||
->method('now');
|
||||
$this->timeFactory->expects(self::never())
|
||||
->method('getDateTime');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('getCalendarsForPrincipal');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('newQuery');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('searchForPrincipal');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getVCalendar');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setObjects');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeRange');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeZone');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getResult');
|
||||
|
||||
$status = $this->service->processCalendarAvailability($user);
|
||||
$this->assertNull($status);
|
||||
}
|
||||
|
||||
public function testNotAuthenticated(): void {
|
||||
$user = $this->createConfiguredMock(IUser::class, [
|
||||
'getUID' => 'admin',
|
||||
'getEMailAddress' => 'test@test.com',
|
||||
]);
|
||||
$availability = '';
|
||||
$server = $this->createMock(Server::class);
|
||||
$schedulingPlugin = $this->createMock(Plugin::class);
|
||||
$aclPlugin = $this->createMock(\Sabre\DAVACL\Plugin::class);
|
||||
$calendarHome = $this->createMock(LocalHref::class);
|
||||
$acl = [[200 => ['{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL' => $calendarHome]]];
|
||||
|
||||
$user->expects(self::once())
|
||||
->method('getUID')
|
||||
->willReturn('admin');
|
||||
$user->expects(self::once())
|
||||
->method('getEMailAddress')
|
||||
->willReturn('test@test.com');
|
||||
$this->server->expects(self::once())
|
||||
->method('getServer')
|
||||
->willReturn($server);
|
||||
$server->expects(self::exactly(2))
|
||||
->method('getPlugin')
|
||||
->withConsecutive(
|
||||
['caldav-schedule'],
|
||||
['acl'],
|
||||
)->willReturnOnConsecutiveCalls($schedulingPlugin, $aclPlugin);
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('principalSearch')
|
||||
->with([ '{http://sabredav.org/ns}email-address' => 'test@test.com'])
|
||||
->willReturn($acl);
|
||||
$calendarHome->expects(self::once())
|
||||
->method('getHref')
|
||||
->willReturn('calendars/admin/inbox/');
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('checkPrivileges')
|
||||
->willThrowException(new NotAuthenticated());
|
||||
$this->timeFactory->expects(self::never())
|
||||
->method('now');
|
||||
$this->timeFactory->expects(self::never())
|
||||
->method('getDateTime');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('getCalendarsForPrincipal');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('newQuery');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('searchForPrincipal');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getVCalendar');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setObjects');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeRange');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeZone');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getResult');
|
||||
|
||||
$status = $this->service->processCalendarAvailability($user);
|
||||
$this->assertNull($status);
|
||||
$this->service->processCalendarStatus('admin');
|
||||
}
|
||||
|
||||
public function testNoCalendars(): void {
|
||||
$user = $this->createConfiguredMock(IUser::class, [
|
||||
'getUID' => 'admin',
|
||||
'getEMailAddress' => 'test@test.com',
|
||||
]);
|
||||
$availability = '';
|
||||
$server = $this->createMock(Server::class);
|
||||
$schedulingPlugin = $this->createMock(Plugin::class);
|
||||
$aclPlugin = $this->createMock(\Sabre\DAVACL\Plugin::class);
|
||||
$calendarHome = $this->createMock(LocalHref::class);
|
||||
$acl = [[200 => ['{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL' => $calendarHome]]];
|
||||
$now = new \DateTimeImmutable('1970-1-1', new \DateTimeZone('UTC'));
|
||||
$principal = 'principals/users/admin';
|
||||
|
||||
$user->expects(self::once())
|
||||
->method('getUID')
|
||||
->willReturn('admin');
|
||||
$user->expects(self::once())
|
||||
->method('getEMailAddress')
|
||||
->willReturn('test@test.com');
|
||||
$this->server->expects(self::once())
|
||||
->method('getServer')
|
||||
->willReturn($server);
|
||||
$server->expects(self::exactly(2))
|
||||
->method('getPlugin')
|
||||
->withConsecutive(
|
||||
['caldav-schedule'],
|
||||
['acl'],
|
||||
)->willReturnOnConsecutiveCalls($schedulingPlugin, $aclPlugin);
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('principalSearch')
|
||||
->with([ '{http://sabredav.org/ns}email-address' => 'test@test.com'])
|
||||
->willReturn($acl);
|
||||
$calendarHome->expects(self::once())
|
||||
->method('getHref')
|
||||
->willReturn('calendars/admin/inbox/');
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('checkPrivileges')
|
||||
->willReturn(true);
|
||||
$this->timeFactory->expects(self::once())
|
||||
->method('now')
|
||||
->willReturn($now);
|
||||
$this->userManager->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn($user);
|
||||
$this->availabilityCoordinator->expects(self::once())
|
||||
->method('getCurrentOutOfOfficeData')
|
||||
->willReturn(null);
|
||||
$this->availabilityCoordinator->expects(self::never())
|
||||
->method('isInEffect');
|
||||
$this->cache->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn(null);
|
||||
$this->cache->expects(self::once())
|
||||
->method('set');
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('getCalendarsForPrincipal')
|
||||
->with($principal)
|
||||
->willReturn([]);
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('newQuery');
|
||||
$this->timeFactory->expects(self::never())
|
||||
->method('getDateTime');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('newQuery');
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('searchForPrincipal');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getVCalendar');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setObjects');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeRange');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeZone');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getResult');
|
||||
$this->userStatusService->expects(self::once())
|
||||
->method('revertUserStatus');
|
||||
$this->logger->expects(self::once())
|
||||
->method('debug');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('setUserStatus');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('findByUserId');
|
||||
|
||||
$status = $this->service->processCalendarAvailability($user);
|
||||
$this->assertNull($status);
|
||||
$this->service->processCalendarStatus('admin');
|
||||
}
|
||||
|
||||
public function testEmptyAvailabilityAndNoSearchCalendars(): void {
|
||||
public function testNoCalendarEvents(): void {
|
||||
$user = $this->createConfiguredMock(IUser::class, [
|
||||
'getUID' => 'admin',
|
||||
'getEMailAddress' => 'test@test.com',
|
||||
]);
|
||||
$availability = '';
|
||||
$server = $this->createMock(Server::class);
|
||||
$schedulingPlugin = $this->createMock(Plugin::class);
|
||||
$aclPlugin = $this->createMock(\Sabre\DAVACL\Plugin::class);
|
||||
$calendarHome = $this->createMock(LocalHref::class);
|
||||
$now = new \DateTimeImmutable('1970-1-1', new \DateTimeZone('UTC'));
|
||||
$inTenMinutes = new \DateTime('1970-1-1 01:00');
|
||||
$acl = [[200 => ['{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL' => $calendarHome]]];
|
||||
$principal = 'principals/users/admin';
|
||||
$calendar = $this->createMock(CalendarImpl::class);
|
||||
$query = $this->createMock(CalendarQuery::class);
|
||||
|
||||
$user->expects(self::once())
|
||||
->method('getUID')
|
||||
->willReturn('admin');
|
||||
$user->expects(self::once())
|
||||
->method('getEMailAddress')
|
||||
->willReturn('test@test.com');
|
||||
$this->server->expects(self::once())
|
||||
->method('getServer')
|
||||
->willReturn($server);
|
||||
$server->expects(self::exactly(2))
|
||||
->method('getPlugin')
|
||||
->withConsecutive(
|
||||
['caldav-schedule'],
|
||||
['acl'],
|
||||
)->willReturnOnConsecutiveCalls($schedulingPlugin, $aclPlugin);
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('principalSearch')
|
||||
->with([ '{http://sabredav.org/ns}email-address' => 'test@test.com'])
|
||||
->willReturn($acl);
|
||||
$calendarHome->expects(self::once())
|
||||
->method('getHref')
|
||||
->willReturn('calendars/admin/inbox/');
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('checkPrivileges')
|
||||
->willReturn(true);
|
||||
$this->timeFactory->expects(self::once())
|
||||
->method('now')
|
||||
->willReturn($now);
|
||||
$this->userManager->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn($user);
|
||||
$this->availabilityCoordinator->expects(self::once())
|
||||
->method('getCurrentOutOfOfficeData')
|
||||
->willReturn(null);
|
||||
$this->availabilityCoordinator->expects(self::never())
|
||||
->method('isInEffect');
|
||||
$this->cache->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn(null);
|
||||
$this->cache->expects(self::once())
|
||||
->method('set');
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('getCalendarsForPrincipal')
|
||||
->with($principal)
|
||||
->willReturn([$calendar]);
|
||||
->willReturn([$this->createMock(CalendarImpl::class)]);
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('newQuery')
|
||||
->with($principal)
|
||||
->willReturn($query);
|
||||
$calendar->expects(self::once())
|
||||
->method('getSchedulingTransparency')
|
||||
->willReturn(new ScheduleCalendarTransp('transparent'));
|
||||
$this->timeFactory->expects(self::once())
|
||||
->willReturn(new CalendarQuery('admin'));
|
||||
$this->timeFactory->expects(self::exactly(2))
|
||||
->method('getDateTime')
|
||||
->with('+10 minutes')
|
||||
->willReturn($inTenMinutes);
|
||||
$this->calendarManager->expects(self::never())
|
||||
->method('searchForPrincipal');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getVCalendar');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setObjects');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeRange');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeZone');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getResult');
|
||||
|
||||
$status = $this->service->processCalendarAvailability($user);
|
||||
$this->assertNull($status);
|
||||
}
|
||||
|
||||
public function testEmptyAvailabilityAndSearchCalendarsNoResults(): void {
|
||||
$user = $this->createConfiguredMock(IUser::class, [
|
||||
'getUID' => 'admin',
|
||||
'getEMailAddress' => 'test@test.com',
|
||||
]);
|
||||
$availability = '';
|
||||
$server = $this->createMock(Server::class);
|
||||
$schedulingPlugin = $this->createMock(Plugin::class);
|
||||
$aclPlugin = $this->createMock(\Sabre\DAVACL\Plugin::class);
|
||||
$calendarHome = $this->createMock(LocalHref::class);
|
||||
$acl = [[200 => ['{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL' => $calendarHome]]];
|
||||
$now = new \DateTimeImmutable('1970-1-1 00:00', new \DateTimeZone('UTC'));
|
||||
$inTenMinutes = new \DateTime('1970-1-1 01:00');
|
||||
$immutableInTenMinutes = \DateTimeImmutable::createFromMutable($inTenMinutes);
|
||||
$principal = 'principals/users/admin';
|
||||
$query = $this->createMock(CalendarQuery::class);
|
||||
$timezone = new \DateTimeZone('UTC');
|
||||
$timezoneObj = $this->createMock(VTimeZone::class);
|
||||
$calendar = $this->createMock(CalendarImpl::class);
|
||||
|
||||
$user->expects(self::once())
|
||||
->method('getUID')
|
||||
->willReturn('admin');
|
||||
$user->expects(self::once())
|
||||
->method('getEMailAddress')
|
||||
->willReturn('test@test.com');
|
||||
$this->server->expects(self::once())
|
||||
->method('getServer')
|
||||
->willReturn($server);
|
||||
$server->expects(self::exactly(2))
|
||||
->method('getPlugin')
|
||||
->withConsecutive(
|
||||
['caldav-schedule'],
|
||||
['acl'],
|
||||
)->willReturnOnConsecutiveCalls($schedulingPlugin, $aclPlugin);
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('principalSearch')
|
||||
->with(['{http://sabredav.org/ns}email-address' => 'test@test.com'])
|
||||
->willReturn($acl);
|
||||
$calendarHome->expects(self::once())
|
||||
->method('getHref')
|
||||
->willReturn('calendars/admin/inbox/');
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('checkPrivileges')
|
||||
->willReturn(true);
|
||||
$this->timeFactory->expects(self::once())
|
||||
->method('now')
|
||||
->willReturn($now);
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('getCalendarsForPrincipal')
|
||||
->with($principal)
|
||||
->willReturn([$calendar]);
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('newQuery')
|
||||
->with($principal)
|
||||
->willReturn($query);
|
||||
$calendar->expects(self::once())
|
||||
->method('getSchedulingTransparency')
|
||||
->willReturn(new ScheduleCalendarTransp('opaque'));
|
||||
$calendar->expects(self::once())
|
||||
->method('getSchedulingTimezone')
|
||||
->willReturn($timezoneObj);
|
||||
$timezoneObj->expects(self::once())
|
||||
->method('getTimeZone')
|
||||
->willReturn($timezone);
|
||||
$calendar->expects(self::once())
|
||||
->method('getUri');
|
||||
$query->expects(self::once())
|
||||
->method('addSearchCalendar');
|
||||
$query->expects(self::once())
|
||||
->method('getCalendarUris')
|
||||
->willReturn([$calendar]);
|
||||
$this->timeFactory->expects(self::once())
|
||||
->method('getDateTime')
|
||||
->with('+10 minutes')
|
||||
->willReturn($inTenMinutes);
|
||||
$query->expects(self::once())
|
||||
->method('setTimerangeStart')
|
||||
->with($now);
|
||||
$query->expects(self::once())
|
||||
->method('setTimerangeEnd')
|
||||
->with($immutableInTenMinutes);
|
||||
->willReturn(new \DateTime());
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('searchForPrincipal')
|
||||
->with($query)
|
||||
->willReturn([]);
|
||||
$this->generator->expects(self::never())
|
||||
->method('getVCalendar');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setObjects');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeRange');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeZone');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getResult');
|
||||
$this->userStatusService->expects(self::once())
|
||||
->method('revertUserStatus');
|
||||
$this->logger->expects(self::once())
|
||||
->method('debug');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('setUserStatus');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('findByUserId');
|
||||
|
||||
$status = $this->service->processCalendarAvailability($user);
|
||||
$this->assertNull($status);
|
||||
$this->service->processCalendarStatus('admin');
|
||||
}
|
||||
|
||||
public function testSearchCalendarsNoResults(): void {
|
||||
public function testCalendarEvent(): void {
|
||||
$user = $this->createConfiguredMock(IUser::class, [
|
||||
'getUID' => 'admin',
|
||||
'getEMailAddress' => 'test@test.com',
|
||||
]);
|
||||
$server = $this->createMock(Server::class);
|
||||
$schedulingPlugin = $this->createMock(Plugin::class);
|
||||
$aclPlugin = $this->createMock(\Sabre\DAVACL\Plugin::class);
|
||||
$calendarHome = $this->createMock(LocalHref::class);
|
||||
$acl = [[200 => ['{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL' => $calendarHome]]];
|
||||
$now = new \DateTimeImmutable('1970-1-1 00:00', new \DateTimeZone('UTC'));
|
||||
$inTenMinutes = new \DateTime('1970-1-1 01:00');
|
||||
$immutableInTenMinutes = \DateTimeImmutable::createFromMutable($inTenMinutes);
|
||||
$principal = 'principals/users/admin';
|
||||
$query = $this->createMock(CalendarQuery::class);
|
||||
$timezone = new \DateTimeZone('UTC');
|
||||
$timezoneObj = $this->createMock(VTimeZone::class);
|
||||
$calendar = $this->createMock(CalendarImpl::class);
|
||||
$vCalendar = $this->createMock(VCalendar::class);
|
||||
$result = Reader::read('BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Sabre//Sabre VObject 4.5.3//EN
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:REQUEST
|
||||
END:VCALENDAR');
|
||||
|
||||
$user->expects(self::once())
|
||||
->method('getUID')
|
||||
->willReturn('admin');
|
||||
$user->expects(self::once())
|
||||
->method('getEMailAddress')
|
||||
->willReturn('test@test.com');
|
||||
$this->server->expects(self::once())
|
||||
->method('getServer')
|
||||
->willReturn($server);
|
||||
$server->expects(self::exactly(2))
|
||||
->method('getPlugin')
|
||||
->withConsecutive(
|
||||
['caldav-schedule'],
|
||||
['acl'],
|
||||
)->willReturnOnConsecutiveCalls($schedulingPlugin, $aclPlugin);
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('principalSearch')
|
||||
->with(['{http://sabredav.org/ns}email-address' => 'test@test.com'])
|
||||
->willReturn($acl);
|
||||
$calendarHome->expects(self::once())
|
||||
->method('getHref')
|
||||
->willReturn('calendars/admin/inbox/');
|
||||
$aclPlugin->expects(self::once())
|
||||
->method('checkPrivileges')
|
||||
->willReturn(true);
|
||||
$this->timeFactory->expects(self::once())
|
||||
->method('now')
|
||||
->willReturn($now);
|
||||
$this->userManager->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn($user);
|
||||
$this->availabilityCoordinator->expects(self::once())
|
||||
->method('getCurrentOutOfOfficeData')
|
||||
->willReturn(null);
|
||||
$this->availabilityCoordinator->expects(self::never())
|
||||
->method('isInEffect');
|
||||
$this->cache->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn(null);
|
||||
$this->cache->expects(self::once())
|
||||
->method('set');
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('getCalendarsForPrincipal')
|
||||
->with($principal)
|
||||
->willReturn([$calendar]);
|
||||
->willReturn([$this->createMock(CalendarImpl::class)]);
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('newQuery')
|
||||
->with($principal)
|
||||
->willReturn($query);
|
||||
$calendar->expects(self::once())
|
||||
->method('getSchedulingTransparency')
|
||||
->willReturn(new ScheduleCalendarTransp('opaque'));
|
||||
$calendar->expects(self::once())
|
||||
->method('getSchedulingTimezone')
|
||||
->willReturn($timezoneObj);
|
||||
$timezoneObj->expects(self::once())
|
||||
->method('getTimeZone')
|
||||
->willReturn($timezone);
|
||||
$calendar->expects(self::once())
|
||||
->method('getUri');
|
||||
$query->expects(self::once())
|
||||
->method('addSearchCalendar');
|
||||
$query->expects(self::once())
|
||||
->method('getCalendarUris')
|
||||
->willReturn([$calendar]);
|
||||
$this->timeFactory->expects(self::once())
|
||||
->willReturn(new CalendarQuery('admin'));
|
||||
$this->timeFactory->expects(self::exactly(2))
|
||||
->method('getDateTime')
|
||||
->with('+10 minutes')
|
||||
->willReturn($inTenMinutes);
|
||||
$query->expects(self::once())
|
||||
->method('setTimerangeStart')
|
||||
->with($now);
|
||||
$query->expects(self::once())
|
||||
->method('setTimerangeEnd')
|
||||
->with($immutableInTenMinutes);
|
||||
->willReturn(new \DateTime());
|
||||
$this->userStatusService->expects(self::once())
|
||||
->method('findByUserId')
|
||||
->willThrowException(new DoesNotExistException(''));
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('searchForPrincipal')
|
||||
->with($query)
|
||||
->willReturn([]);
|
||||
$this->generator->expects(self::never())
|
||||
->method('getVCalendar');
|
||||
$vCalendar->expects(self::never())
|
||||
->method('add');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setObjects');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeRange');
|
||||
$this->generator->expects(self::never())
|
||||
->method('setTimeZone');
|
||||
$this->generator->expects(self::never())
|
||||
->method('getResult');
|
||||
->willReturn([['objects' => [[]]]]);
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('revertUserStatus');
|
||||
$this->logger->expects(self::once())
|
||||
->method('debug');
|
||||
$this->userStatusService->expects(self::once())
|
||||
->method('setUserStatus');
|
||||
|
||||
$status = $this->service->processCalendarAvailability($user);
|
||||
$this->assertNull($status);
|
||||
|
||||
$this->service->processCalendarStatus('admin');
|
||||
}
|
||||
|
||||
public function testCallStatus(): void {
|
||||
$user = $this->createConfiguredMock(IUser::class, [
|
||||
'getUID' => 'admin',
|
||||
]);
|
||||
|
||||
$this->userManager->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn($user);
|
||||
$this->availabilityCoordinator->expects(self::once())
|
||||
->method('getCurrentOutOfOfficeData')
|
||||
->willReturn(null);
|
||||
$this->availabilityCoordinator->expects(self::never())
|
||||
->method('isInEffect');
|
||||
$this->cache->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn(null);
|
||||
$this->cache->expects(self::once())
|
||||
->method('set');
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('getCalendarsForPrincipal')
|
||||
->willReturn([$this->createMock(CalendarImpl::class)]);
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('newQuery')
|
||||
->willReturn(new CalendarQuery('admin'));
|
||||
$this->timeFactory->expects(self::exactly(2))
|
||||
->method('getDateTime')
|
||||
->willReturn(new \DateTime());
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('searchForPrincipal')
|
||||
->willReturn([['objects' => [[]]]]);
|
||||
$userStatus = new UserStatus();
|
||||
$userStatus->setMessageId(IUserStatus::MESSAGE_CALL);
|
||||
$userStatus->setStatusTimestamp(123456);
|
||||
$this->userStatusService->expects(self::once())
|
||||
->method('findByUserId')
|
||||
->willReturn($userStatus);
|
||||
$this->logger->expects(self::once())
|
||||
->method('debug');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('revertUserStatus');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('setUserStatus');
|
||||
|
||||
|
||||
$this->service->processCalendarStatus('admin');
|
||||
}
|
||||
|
||||
public function testInvisibleStatus(): void {
|
||||
$user = $this->createConfiguredMock(IUser::class, [
|
||||
'getUID' => 'admin',
|
||||
]);
|
||||
|
||||
$this->userManager->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn($user);
|
||||
$this->availabilityCoordinator->expects(self::once())
|
||||
->method('getCurrentOutOfOfficeData')
|
||||
->willReturn(null);
|
||||
$this->availabilityCoordinator->expects(self::never())
|
||||
->method('isInEffect');
|
||||
$this->cache->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn(null);
|
||||
$this->cache->expects(self::once())
|
||||
->method('set');
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('getCalendarsForPrincipal')
|
||||
->willReturn([$this->createMock(CalendarImpl::class)]);
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('newQuery')
|
||||
->willReturn(new CalendarQuery('admin'));
|
||||
$this->timeFactory->expects(self::exactly(2))
|
||||
->method('getDateTime')
|
||||
->willReturn(new \DateTime());
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('searchForPrincipal')
|
||||
->willReturn([['objects' => [[]]]]);
|
||||
$userStatus = new UserStatus();
|
||||
$userStatus->setStatus(IUserStatus::INVISIBLE);
|
||||
$userStatus->setStatusTimestamp(123456);
|
||||
$this->userStatusService->expects(self::once())
|
||||
->method('findByUserId')
|
||||
->willReturn($userStatus);
|
||||
$this->logger->expects(self::once())
|
||||
->method('debug');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('revertUserStatus');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('setUserStatus');
|
||||
|
||||
|
||||
$this->service->processCalendarStatus('admin');
|
||||
}
|
||||
|
||||
public function testDNDStatus(): void {
|
||||
$user = $this->createConfiguredMock(IUser::class, [
|
||||
'getUID' => 'admin',
|
||||
]);
|
||||
|
||||
$this->userManager->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn($user);
|
||||
$this->availabilityCoordinator->expects(self::once())
|
||||
->method('getCurrentOutOfOfficeData')
|
||||
->willReturn(null);
|
||||
$this->availabilityCoordinator->expects(self::never())
|
||||
->method('isInEffect');
|
||||
$this->cache->expects(self::once())
|
||||
->method('get')
|
||||
->willReturn(null);
|
||||
$this->cache->expects(self::once())
|
||||
->method('set');
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('getCalendarsForPrincipal')
|
||||
->willReturn([$this->createMock(CalendarImpl::class)]);
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('newQuery')
|
||||
->willReturn(new CalendarQuery('admin'));
|
||||
$this->timeFactory->expects(self::exactly(2))
|
||||
->method('getDateTime')
|
||||
->willReturn(new \DateTime());
|
||||
$this->calendarManager->expects(self::once())
|
||||
->method('searchForPrincipal')
|
||||
->willReturn([['objects' => [[]]]]);
|
||||
$userStatus = new UserStatus();
|
||||
$userStatus->setStatus(IUserStatus::DND);
|
||||
$userStatus->setStatusTimestamp(123456);
|
||||
$this->userStatusService->expects(self::once())
|
||||
->method('findByUserId')
|
||||
->willReturn($userStatus);
|
||||
$this->logger->expects(self::once())
|
||||
->method('debug');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('revertUserStatus');
|
||||
$this->userStatusService->expects(self::never())
|
||||
->method('setUserStatus');
|
||||
|
||||
|
||||
$this->service->processCalendarStatus('admin');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\UserStatus\Controller;
|
||||
|
||||
use OCA\DAV\CalDAV\Status\StatusService as CalendarStatusService;
|
||||
use OCA\UserStatus\Db\UserStatus;
|
||||
use OCA\UserStatus\Exception\InvalidClearAtException;
|
||||
use OCA\UserStatus\Exception\InvalidMessageIdException;
|
||||
|
|
@ -55,6 +56,7 @@ class UserStatusController extends OCSController {
|
|||
private string $userId,
|
||||
private LoggerInterface $logger,
|
||||
private StatusService $service,
|
||||
private CalendarStatusService $calendarStatusService,
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
}
|
||||
|
|
@ -71,6 +73,7 @@ class UserStatusController extends OCSController {
|
|||
*/
|
||||
public function getStatus(): DataResponse {
|
||||
try {
|
||||
$this->calendarStatusService->processCalendarStatus($this->userId);
|
||||
$userStatus = $this->service->findByUserId($this->userId);
|
||||
} catch (DoesNotExistException $ex) {
|
||||
throw new OCSNotFoundException('No status for the current user');
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\UserStatus\Listener;
|
||||
|
||||
use OCA\DAV\CalDAV\Status\StatusService as CalendarStatusService;
|
||||
use OCA\UserStatus\Connector\UserStatus as ConnectorUserStatus;
|
||||
use OCA\UserStatus\Db\UserStatus;
|
||||
use OCA\UserStatus\Db\UserStatusMapper;
|
||||
|
|
@ -48,7 +49,8 @@ class UserLiveStatusListener implements IEventListener {
|
|||
|
||||
public function __construct(UserStatusMapper $mapper,
|
||||
StatusService $statusService,
|
||||
ITimeFactory $timeFactory) {
|
||||
ITimeFactory $timeFactory,
|
||||
private CalendarStatusService $calendarStatusService) {
|
||||
$this->mapper = $mapper;
|
||||
$this->statusService = $statusService;
|
||||
$this->timeFactory = $timeFactory;
|
||||
|
|
@ -65,6 +67,7 @@ class UserLiveStatusListener implements IEventListener {
|
|||
|
||||
$user = $event->getUser();
|
||||
try {
|
||||
$this->calendarStatusService->processCalendarStatus($user->getUID());
|
||||
$userStatus = $this->statusService->findByUserId($user->getUID());
|
||||
} catch (DoesNotExistException $ex) {
|
||||
$userStatus = new UserStatus();
|
||||
|
|
@ -81,6 +84,12 @@ class UserLiveStatusListener implements IEventListener {
|
|||
return;
|
||||
}
|
||||
|
||||
// Don't overwrite the "away" calendar status if it's set
|
||||
if($userStatus->getMessageId() === IUserStatus::MESSAGE_CALENDAR_BUSY) {
|
||||
$event->setUserStatus(new ConnectorUserStatus($userStatus));
|
||||
return;
|
||||
}
|
||||
|
||||
$needsUpdate = false;
|
||||
|
||||
// If the current status is older than 5 minutes,
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\UserStatus\Service;
|
||||
|
||||
use OCA\DAV\CalDAV\Status\Status as CalendarStatus;
|
||||
use OCA\DAV\CalDAV\Status\StatusService as CalendarStatusService;
|
||||
use OCA\UserStatus\Db\UserStatus;
|
||||
use OCA\UserStatus\Db\UserStatusMapper;
|
||||
use OCA\UserStatus\Exception\InvalidClearAtException;
|
||||
|
|
@ -89,8 +87,7 @@ class StatusService {
|
|||
private PredefinedStatusService $predefinedStatusService,
|
||||
private IEmojiHelper $emojiHelper,
|
||||
private IConfig $config,
|
||||
private IUserManager $userManager,
|
||||
private CalendarStatusService $calendarStatusService) {
|
||||
private IUserManager $userManager) {
|
||||
$this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
|
||||
$this->shareeEnumerationInGroupOnly = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
|
||||
$this->shareeEnumerationPhone = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
|
||||
|
|
@ -558,30 +555,4 @@ class StatusService {
|
|||
// For users that matched restore the previous status
|
||||
$this->mapper->restoreBackupStatuses($restoreIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @link https://icalendar.org/iCalendar-RFC-5545/3-2-9-free-busy-time-type.html
|
||||
*
|
||||
* The status will be changed for types
|
||||
* - 'BUSY'
|
||||
* - 'BUSY-TENTATIVE' (ex.: an event has been accepted tentatively)
|
||||
* and all FREEBUSY components without a type (implicitly a 'BUSY' status)
|
||||
*
|
||||
* 'X-' properties and BUSY-UNAVAILABLE is not handled
|
||||
*
|
||||
* @param string $userId
|
||||
* @return CalendarStatus|null
|
||||
*/
|
||||
public function getCalendarStatus(string $userId): ?CalendarStatus {
|
||||
$user = $this->userManager->get($userId);
|
||||
if ($user === null) {
|
||||
return null;
|
||||
}
|
||||
return $this->calendarStatusService->processCalendarAvailability($user);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\UserStatus\Tests\Controller;
|
||||
|
||||
use OCA\DAV\CalDAV\Status\StatusService as CalendarStatusService;
|
||||
use OCA\UserStatus\Controller\UserStatusController;
|
||||
use OCA\UserStatus\Db\UserStatus;
|
||||
use OCA\UserStatus\Exception\InvalidClearAtException;
|
||||
|
|
@ -47,7 +48,10 @@ class UserStatusControllerTest extends TestCase {
|
|||
private $logger;
|
||||
|
||||
/** @var StatusService|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $service;
|
||||
private $statusService;
|
||||
|
||||
/** @var CalendarStatusService|\PHPUnit\Framework\MockObject\MockObject $calendarStatusService */
|
||||
private $calendarStatusService;
|
||||
|
||||
/** @var UserStatusController */
|
||||
private $controller;
|
||||
|
|
@ -58,15 +62,23 @@ class UserStatusControllerTest extends TestCase {
|
|||
$request = $this->createMock(IRequest::class);
|
||||
$userId = 'john.doe';
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->service = $this->createMock(StatusService::class);
|
||||
$this->statusService = $this->createMock(StatusService::class);
|
||||
$this->calendarStatusService = $this->createMock(CalendarStatusService::class);
|
||||
|
||||
$this->controller = new UserStatusController('user_status', $request, $userId, $this->logger, $this->service);
|
||||
$this->controller = new UserStatusController(
|
||||
'user_status',
|
||||
$request,
|
||||
$userId,
|
||||
$this->logger,
|
||||
$this->statusService,
|
||||
$this->calendarStatusService,
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetStatus(): void {
|
||||
$userStatus = $this->getUserStatus();
|
||||
|
||||
$this->service->expects($this->once())
|
||||
$this->statusService->expects($this->once())
|
||||
->method('findByUserId')
|
||||
->with('john.doe')
|
||||
->willReturn($userStatus);
|
||||
|
|
@ -85,7 +97,10 @@ class UserStatusControllerTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testGetStatusDoesNotExist(): void {
|
||||
$this->service->expects($this->once())
|
||||
$this->calendarStatusService->expects(self::once())
|
||||
->method('processCalendarStatus')
|
||||
->with('john.doe');
|
||||
$this->statusService->expects($this->once())
|
||||
->method('findByUserId')
|
||||
->with('john.doe')
|
||||
->willThrowException(new DoesNotExistException(''));
|
||||
|
|
@ -121,12 +136,12 @@ class UserStatusControllerTest extends TestCase {
|
|||
$userStatus = $this->getUserStatus();
|
||||
|
||||
if ($expectException) {
|
||||
$this->service->expects($this->once())
|
||||
$this->statusService->expects($this->once())
|
||||
->method('setStatus')
|
||||
->with('john.doe', $statusType, null, true)
|
||||
->willThrowException($exception);
|
||||
} else {
|
||||
$this->service->expects($this->once())
|
||||
$this->statusService->expects($this->once())
|
||||
->method('setStatus')
|
||||
->with('john.doe', $statusType, null, true)
|
||||
->willReturn($userStatus);
|
||||
|
|
@ -187,12 +202,12 @@ class UserStatusControllerTest extends TestCase {
|
|||
$userStatus = $this->getUserStatus();
|
||||
|
||||
if ($expectException) {
|
||||
$this->service->expects($this->once())
|
||||
$this->statusService->expects($this->once())
|
||||
->method('setPredefinedMessage')
|
||||
->with('john.doe', $messageId, $clearAt)
|
||||
->willThrowException($exception);
|
||||
} else {
|
||||
$this->service->expects($this->once())
|
||||
$this->statusService->expects($this->once())
|
||||
->method('setPredefinedMessage')
|
||||
->with('john.doe', $messageId, $clearAt)
|
||||
->willReturn($userStatus);
|
||||
|
|
@ -259,28 +274,28 @@ class UserStatusControllerTest extends TestCase {
|
|||
$userStatus = $this->getUserStatus();
|
||||
|
||||
if ($expectException) {
|
||||
$this->service->expects($this->once())
|
||||
$this->statusService->expects($this->once())
|
||||
->method('setCustomMessage')
|
||||
->with('john.doe', $statusIcon, $message, $clearAt)
|
||||
->willThrowException($exception);
|
||||
} else {
|
||||
if ($expectSuccessAsReset) {
|
||||
$this->service->expects($this->never())
|
||||
$this->statusService->expects($this->never())
|
||||
->method('setCustomMessage');
|
||||
$this->service->expects($this->once())
|
||||
$this->statusService->expects($this->once())
|
||||
->method('clearMessage')
|
||||
->with('john.doe');
|
||||
$this->service->expects($this->once())
|
||||
$this->statusService->expects($this->once())
|
||||
->method('findByUserId')
|
||||
->with('john.doe')
|
||||
->willReturn($userStatus);
|
||||
} else {
|
||||
$this->service->expects($this->once())
|
||||
$this->statusService->expects($this->once())
|
||||
->method('setCustomMessage')
|
||||
->with('john.doe', $statusIcon, $message, $clearAt)
|
||||
->willReturn($userStatus);
|
||||
|
||||
$this->service->expects($this->never())
|
||||
$this->statusService->expects($this->never())
|
||||
->method('clearMessage');
|
||||
}
|
||||
}
|
||||
|
|
@ -326,7 +341,7 @@ class UserStatusControllerTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testClearMessage(): void {
|
||||
$this->service->expects($this->once())
|
||||
$this->statusService->expects($this->once())
|
||||
->method('clearMessage')
|
||||
->with('john.doe');
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\UserStatus\Tests\Listener;
|
||||
|
||||
use OCA\DAV\CalDAV\Status\StatusService as CalendarStatusService;
|
||||
use OCA\UserStatus\Db\UserStatus;
|
||||
use OCA\UserStatus\Db\UserStatusMapper;
|
||||
use OCA\UserStatus\Listener\UserDeletedListener;
|
||||
|
|
@ -36,27 +37,37 @@ use OCP\AppFramework\Utility\ITimeFactory;
|
|||
use OCP\EventDispatcher\GenericEvent;
|
||||
use OCP\IUser;
|
||||
use OCP\User\Events\UserLiveStatusEvent;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Test\TestCase;
|
||||
|
||||
class UserLiveStatusListenerTest extends TestCase {
|
||||
|
||||
/** @var UserStatusMapper|\PHPUnit\Framework\MockObject\MockObject */
|
||||
/** @var UserStatusMapper|MockObject */
|
||||
private $mapper;
|
||||
/** @var StatusService|\PHPUnit\Framework\MockObject\MockObject */
|
||||
/** @var StatusService|MockObject */
|
||||
private $statusService;
|
||||
/** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
|
||||
/** @var ITimeFactory|MockObject */
|
||||
private $timeFactory;
|
||||
|
||||
/** @var UserDeletedListener */
|
||||
private $listener;
|
||||
|
||||
private CalendarStatusService|MockObject $calendarStatusService;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->mapper = $this->createMock(UserStatusMapper::class);
|
||||
$this->statusService = $this->createMock(StatusService::class);
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
$this->listener = new UserLiveStatusListener($this->mapper, $this->statusService, $this->timeFactory);
|
||||
$this->calendarStatusService = $this->createMock(CalendarStatusService::class);
|
||||
|
||||
$this->listener = new UserLiveStatusListener(
|
||||
$this->mapper,
|
||||
$this->statusService,
|
||||
$this->timeFactory,
|
||||
$this->calendarStatusService,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -28,9 +28,6 @@ namespace OCA\UserStatus\Tests\Service;
|
|||
|
||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||
use OC\DB\Exceptions\DbalException;
|
||||
use OC\User\User;
|
||||
use OCA\DAV\CalDAV\Status\Status;
|
||||
use OCA\DAV\CalDAV\Status\StatusService as CalendarStatusService;
|
||||
use OCA\UserStatus\Db\UserStatus;
|
||||
use OCA\UserStatus\Db\UserStatusMapper;
|
||||
use OCA\UserStatus\Exception\InvalidClearAtException;
|
||||
|
|
@ -45,7 +42,6 @@ use OCP\AppFramework\Utility\ITimeFactory;
|
|||
use OCP\DB\Exception;
|
||||
use OCP\IConfig;
|
||||
use OCP\IEmojiHelper;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\UserStatus\IUserStatus;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
|
|
@ -71,9 +67,6 @@ class StatusServiceTest extends TestCase {
|
|||
/** @var IUserManager|MockObject */
|
||||
private $userManager;
|
||||
|
||||
/** @var CalendarStatusService|MockObject */
|
||||
private $calendarStatusService;
|
||||
|
||||
private StatusService $service;
|
||||
|
||||
protected function setUp(): void {
|
||||
|
|
@ -84,8 +77,6 @@ class StatusServiceTest extends TestCase {
|
|||
$this->predefinedStatusService = $this->createMock(PredefinedStatusService::class);
|
||||
$this->emojiHelper = $this->createMock(IEmojiHelper::class);
|
||||
$this->userManager = $this->createMock(IUserManager::class);
|
||||
$this->calendarStatusService = $this->createMock(CalendarStatusService::class);
|
||||
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
|
||||
$this->config->method('getAppValue')
|
||||
|
|
@ -99,8 +90,7 @@ class StatusServiceTest extends TestCase {
|
|||
$this->predefinedStatusService,
|
||||
$this->emojiHelper,
|
||||
$this->config,
|
||||
$this->userManager,
|
||||
$this->calendarStatusService,
|
||||
$this->userManager
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -156,8 +146,7 @@ class StatusServiceTest extends TestCase {
|
|||
$this->predefinedStatusService,
|
||||
$this->emojiHelper,
|
||||
$this->config,
|
||||
$this->userManager,
|
||||
$this->calendarStatusService,
|
||||
$this->userManager
|
||||
);
|
||||
|
||||
$this->assertEquals([], $this->service->findAllRecentStatusChanges(20, 50));
|
||||
|
|
@ -176,8 +165,7 @@ class StatusServiceTest extends TestCase {
|
|||
$this->predefinedStatusService,
|
||||
$this->emojiHelper,
|
||||
$this->config,
|
||||
$this->userManager,
|
||||
$this->calendarStatusService,
|
||||
$this->userManager
|
||||
);
|
||||
|
||||
$this->assertEquals([], $this->service->findAllRecentStatusChanges(20, 50));
|
||||
|
|
@ -837,35 +825,4 @@ class StatusServiceTest extends TestCase {
|
|||
|
||||
$this->service->revertMultipleUserStatus(['john', 'nobackup', 'backuponly', 'nobackupanddnd'], 'call');
|
||||
}
|
||||
|
||||
public function testCalendarAvailabilityNoUser(): void {
|
||||
$userId = 'admin';
|
||||
|
||||
$this->userManager->expects(self::once())
|
||||
->method('get')
|
||||
->with($userId)
|
||||
->willReturn(null);
|
||||
$this->calendarStatusService->expects(self::never())
|
||||
->method('processCalendarAvailability');
|
||||
|
||||
$this->service->getCalendarStatus($userId);
|
||||
}
|
||||
|
||||
public function testCalendarAvailabilityNoStatus(): void {
|
||||
$user = $this->createConfiguredMock(IUser::class, [
|
||||
'getUID' => 'admin',
|
||||
'getEMailAddress' => 'test@test.com',
|
||||
]);
|
||||
|
||||
$this->userManager->expects(self::once())
|
||||
->method('get')
|
||||
->with($user->getUID())
|
||||
->willReturn($user);
|
||||
$this->calendarStatusService->expects(self::once())
|
||||
->method('processCalendarAvailability')
|
||||
->with($user)
|
||||
->willReturn(null);
|
||||
|
||||
$this->service->getCalendarStatus($user->getUID());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue