Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>pull/41340/head
parent
f313b12d54
commit
5b7a5474b9
@ -0,0 +1,210 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/** |
||||
* @copyright 2023 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @author 2023 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @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\Listener; |
||||
|
||||
use DateTimeImmutable; |
||||
use OCA\DAV\CalDAV\CalDavBackend; |
||||
use OCA\DAV\CalDAV\Calendar; |
||||
use OCA\DAV\CalDAV\CalendarHome; |
||||
use OCA\DAV\ServerFactory; |
||||
use OCP\EventDispatcher\Event; |
||||
use OCP\EventDispatcher\IEventListener; |
||||
use OCP\IConfig; |
||||
use OCP\User\Events\OutOfOfficeChangedEvent; |
||||
use OCP\User\Events\OutOfOfficeClearedEvent; |
||||
use OCP\User\Events\OutOfOfficeScheduledEvent; |
||||
use OCP\User\IOutOfOfficeData; |
||||
use Psr\Log\LoggerInterface; |
||||
use Sabre\DAV\Exception\NotFound; |
||||
use Sabre\VObject\Component\VCalendar; |
||||
use Sabre\VObject\Component\VEvent; |
||||
use Sabre\VObject\Component\VTimeZone; |
||||
use Sabre\VObject\Reader; |
||||
use function fclose; |
||||
use function fopen; |
||||
use function fwrite; |
||||
use function rewind; |
||||
|
||||
/** |
||||
* @template-implements IEventListener<OutOfOfficeScheduledEvent|OutOfOfficeChangedEvent|OutOfOfficeClearedEvent> |
||||
*/ |
||||
class OutOfOfficeListener implements IEventListener { |
||||
public function __construct(private ServerFactory $serverFactory, |
||||
private IConfig $appConfig, |
||||
private LoggerInterface $logger) { |
||||
} |
||||
|
||||
public function handle(Event $event): void { |
||||
if ($event instanceof OutOfOfficeScheduledEvent) { |
||||
$userId = $event->getData()->getUser()->getUID(); |
||||
$principal = "principals/users/$userId"; |
||||
|
||||
$calendarNode = $this->getCalendarNode($principal, $userId); |
||||
if ($calendarNode === null) { |
||||
return; |
||||
} |
||||
|
||||
$tz = $calendarNode->getProperties([])['{urn:ietf:params:xml:ns:caldav}calendar-timezone'] ?? null; |
||||
$vCalendarEvent = $this->createVCalendarEvent($event->getData(), $tz); |
||||
$stream = fopen('php://memory', 'rb+'); |
||||
try { |
||||
fwrite($stream, $vCalendarEvent->serialize()); |
||||
rewind($stream); |
||||
$calendarNode->createFile( |
||||
$this->getEventFileName($event->getData()->getId()), |
||||
$stream, |
||||
); |
||||
} finally { |
||||
fclose($stream); |
||||
} |
||||
} else if ($event instanceof OutOfOfficeChangedEvent) { |
||||
$userId = $event->getData()->getUser()->getUID(); |
||||
$principal = "principals/users/$userId"; |
||||
|
||||
$calendarNode = $this->getCalendarNode($principal, $userId); |
||||
if ($calendarNode === null) { |
||||
return; |
||||
} |
||||
$tz = $calendarNode->getProperties([])['{urn:ietf:params:xml:ns:caldav}calendar-timezone'] ?? null; |
||||
$vCalendarEvent = $this->createVCalendarEvent($event->getData(), $tz); |
||||
try { |
||||
$oldEvent = $calendarNode->getChild($this->getEventFileName($event->getData()->getId())); |
||||
$oldEvent->put($vCalendarEvent->serialize()); |
||||
return; |
||||
} catch (NotFound) { |
||||
$stream = fopen('php://memory', 'rb+'); |
||||
try { |
||||
fwrite($stream, $vCalendarEvent->serialize()); |
||||
rewind($stream); |
||||
$calendarNode->createFile( |
||||
$this->getEventFileName($event->getData()->getId()), |
||||
$stream, |
||||
); |
||||
} finally { |
||||
fclose($stream); |
||||
} |
||||
} |
||||
} else if ($event instanceof OutOfOfficeClearedEvent) { |
||||
$userId = $event->getData()->getUser()->getUID(); |
||||
$principal = "principals/users/$userId"; |
||||
|
||||
$calendarNode = $this->getCalendarNode($principal, $userId); |
||||
if ($calendarNode === null) { |
||||
return; |
||||
} |
||||
|
||||
try { |
||||
$oldEvent = $calendarNode->getChild($this->getEventFileName($event->getData()->getId())); |
||||
$oldEvent->delete(); |
||||
} catch (NotFound) { |
||||
// The user must have deleted it or the default calendar changed -> ignore |
||||
} |
||||
} |
||||
} |
||||
|
||||
private function getCalendarNode(string $principal, string $userId): ?Calendar { |
||||
$invitationServer = $this->serverFactory->createInviationResponseServer(false); |
||||
$server = $invitationServer->getServer(); |
||||
|
||||
/** @var \OCA\DAV\CalDAV\Plugin $caldavPlugin */ |
||||
$caldavPlugin = $server->getPlugin('caldav'); |
||||
$calendarHomePath = $caldavPlugin->getCalendarHomeForPrincipal($principal); |
||||
if ($calendarHomePath === null) { |
||||
$this->logger->debug('Principal has no calendar home path'); |
||||
return null; |
||||
} |
||||
try { |
||||
/** @var CalendarHome $calendarHome */ |
||||
$calendarHome = $server->tree->getNodeForPath($calendarHomePath); |
||||
} catch (NotFound $e) { |
||||
$this->logger->debug('Calendar home not found', [ |
||||
'exception' => $e, |
||||
]); |
||||
return null; |
||||
} |
||||
$uri = $this->appConfig->getUserValue($userId, 'dav', 'defaultCalendar', CalDavBackend::PERSONAL_CALENDAR_URI); |
||||
try { |
||||
$calendarNode = $calendarHome->getChild($uri); |
||||
} catch (NotFound $e) { |
||||
$this->logger->debug('Personal calendar does not exist', [ |
||||
'exception' => $e, |
||||
'uri' => $uri, |
||||
]); |
||||
return null; |
||||
} |
||||
if (!($calendarNode instanceof Calendar)) { |
||||
$this->logger->warning('Personal calendar node is not a calendar'); |
||||
return null; |
||||
} |
||||
if ($calendarNode->isDeleted()) { |
||||
$this->logger->warning('Personal calendar has been deleted'); |
||||
return null; |
||||
} |
||||
|
||||
return $calendarNode; |
||||
} |
||||
|
||||
private function getEventFileName(string $id): string { |
||||
return "out_of_office_$id.ics"; |
||||
} |
||||
|
||||
private function createVCalendarEvent(IOutOfOfficeData $data, ?string $timeZoneData): VCalendar { |
||||
$shortMessage = $data->getShortMessage(); |
||||
$longMessage = $data->getMessage(); |
||||
$start = (new DateTimeImmutable) |
||||
->setTimestamp($data->getStartDate()) |
||||
->setTime(0, 0); |
||||
$end = (new DateTimeImmutable()) |
||||
->setTimestamp($data->getEndDate()) |
||||
->modify('+ 2 days') |
||||
->setTime(0, 0); |
||||
$vCalendar = new VCalendar(); |
||||
$vCalendar->add('VEVENT', [ |
||||
'SUMMARY' => $shortMessage, |
||||
'DESCRIPTION' => $longMessage, |
||||
'STATUS' => 'CONFIRMED', |
||||
'DTSTART' => $start, |
||||
'DTEND' => $end, |
||||
'X-NEXTCLOUD-OUT-OF-OFFICE' => $data->getId(), |
||||
]); |
||||
/** @var VEvent $vEvent */ |
||||
$vEvent = $vCalendar->VEVENT; |
||||
if ($timeZoneData !== null) { |
||||
/** @var VCalendar $vtimezoneObj */ |
||||
$vtimezoneObj = Reader::read($timeZoneData); |
||||
/** @var VTimeZone $vtimezone */ |
||||
$vtimezone = $vtimezoneObj->VTIMEZONE; |
||||
$calendarTimeZone = $vtimezone->getTimeZone(); |
||||
$vCalendar->add($vtimezone); |
||||
|
||||
/** @psalm-suppress UndefinedMethod */ |
||||
$vEvent->DTSTART->setDateTime($start->setTimezone($calendarTimeZone)->setTime(0, 0)); |
||||
/** @psalm-suppress UndefinedMethod */ |
||||
$vEvent->DTEND->setDateTime($end->setTimezone($calendarTimeZone)->setTime(0, 0)); |
||||
} |
||||
return $vCalendar; |
||||
} |
||||
} |
@ -0,0 +1,35 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/** |
||||
* @copyright 2023 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @author 2023 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @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; |
||||
|
||||
use OCA\DAV\CalDAV\InvitationResponse\InvitationResponseServer; |
||||
|
||||
class ServerFactory { |
||||
|
||||
public function createInviationResponseServer(bool $public): InvitationResponseServer { |
||||
return new InvitationResponseServer(false); |
||||
} |
||||
} |
@ -0,0 +1,546 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* |
||||
* @copyright 2023 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @author 2023 Christoph Wurst <christoph@winzerhof-wurst.at> |
||||
* |
||||
* @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\Tests\Unit\Listener; |
||||
|
||||
use OCA\DAV\CalDAV\Calendar; |
||||
use OCA\DAV\CalDAV\CalendarHome; |
||||
use OCA\DAV\CalDAV\CalendarObject; |
||||
use OCA\DAV\CalDAV\InvitationResponse\InvitationResponseServer; |
||||
use OCA\DAV\CalDAV\Plugin; |
||||
use OCA\DAV\Connector\Sabre\Server; |
||||
use OCA\DAV\Listener\OutOfOfficeListener; |
||||
use OCA\DAV\ServerFactory; |
||||
use OCP\EventDispatcher\Event; |
||||
use OCP\IConfig; |
||||
use OCP\IUser; |
||||
use OCP\User\Events\OutOfOfficeChangedEvent; |
||||
use OCP\User\Events\OutOfOfficeClearedEvent; |
||||
use OCP\User\Events\OutOfOfficeScheduledEvent; |
||||
use OCP\User\IOutOfOfficeData; |
||||
use PHPUnit\Framework\MockObject\MockObject; |
||||
use Psr\Log\LoggerInterface; |
||||
use Sabre\DAV\Exception\NotFound; |
||||
use Sabre\DAV\Tree; |
||||
use Test\TestCase; |
||||
|
||||
/** |
||||
* @covers \OCA\DAV\Listener\OutOfOfficeListener |
||||
*/ |
||||
class OutOfOfficeListenerTest extends TestCase { |
||||
|
||||
private ServerFactory|MockObject $serverFactory; |
||||
private IConfig|MockObject $appConfig; |
||||
private LoggerInterface|MockObject $loggerInterface; |
||||
private OutOfOfficeListener $listener; |
||||
|
||||
protected function setUp(): void { |
||||
parent::setUp(); |
||||
|
||||
$this->serverFactory = $this->createMock(ServerFactory::class); |
||||
$this->appConfig = $this->createMock(IConfig::class); |
||||
$this->loggerInterface = $this->createMock(LoggerInterface::class); |
||||
|
||||
$this->listener = new OutOfOfficeListener( |
||||
$this->serverFactory, |
||||
$this->appConfig, |
||||
$this->loggerInterface, |
||||
); |
||||
} |
||||
|
||||
public function testHandleUnrelated(): void { |
||||
$event = new Event(); |
||||
|
||||
$this->listener->handle($event); |
||||
|
||||
$this->addToAssertionCount(1); |
||||
} |
||||
|
||||
public function testHandleSchedulingNoCalendarHome(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$event = new OutOfOfficeScheduledEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
|
||||
public function testHandleSchedulingNoCalendarHomeNode(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$caldavPlugin->expects(self::once()) |
||||
->method('getCalendarHomeForPrincipal') |
||||
->willReturn('/home/calendar'); |
||||
$tree = $this->createMock(Tree::class); |
||||
$davServer->tree = $tree; |
||||
$tree->expects(self::once()) |
||||
->method('getNodeForPath') |
||||
->with('/home/calendar') |
||||
->willThrowException(new NotFound('nope')); |
||||
$event = new OutOfOfficeScheduledEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
|
||||
public function testHandleSchedulingPersonalCalendarNotFound(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$caldavPlugin->expects(self::once()) |
||||
->method('getCalendarHomeForPrincipal') |
||||
->willReturn('/home/calendar'); |
||||
$tree = $this->createMock(Tree::class); |
||||
$davServer->tree = $tree; |
||||
$calendarHome = $this->createMock(CalendarHome::class); |
||||
$tree->expects(self::once()) |
||||
->method('getNodeForPath') |
||||
->with('/home/calendar') |
||||
->willReturn($calendarHome); |
||||
$this->appConfig->expects(self::once()) |
||||
->method('getUserValue') |
||||
->with('user123', 'dav', 'defaultCalendar', 'personal') |
||||
->willReturn('personal-1'); |
||||
$calendarHome->expects(self::once()) |
||||
->method('getChild') |
||||
->with('personal-1') |
||||
->willThrowException(new NotFound('nope')); |
||||
$event = new OutOfOfficeScheduledEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
|
||||
public function testHandleScheduling(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$caldavPlugin->expects(self::once()) |
||||
->method('getCalendarHomeForPrincipal') |
||||
->willReturn('/home/calendar'); |
||||
$tree = $this->createMock(Tree::class); |
||||
$davServer->tree = $tree; |
||||
$calendarHome = $this->createMock(CalendarHome::class); |
||||
$tree->expects(self::once()) |
||||
->method('getNodeForPath') |
||||
->with('/home/calendar') |
||||
->willReturn($calendarHome); |
||||
$this->appConfig->expects(self::once()) |
||||
->method('getUserValue') |
||||
->with('user123', 'dav', 'defaultCalendar', 'personal') |
||||
->willReturn('personal-1'); |
||||
$calendar = $this->createMock(Calendar::class); |
||||
$calendarHome->expects(self::once()) |
||||
->method('getChild') |
||||
->with('personal-1') |
||||
->willReturn($calendar); |
||||
$calendar->expects(self::once()) |
||||
->method('createFile'); |
||||
$event = new OutOfOfficeScheduledEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
|
||||
public function testHandleChangeNoCalendarHome(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$event = new OutOfOfficeChangedEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
|
||||
public function testHandleChangeNoCalendarHomeNode(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$caldavPlugin->expects(self::once()) |
||||
->method('getCalendarHomeForPrincipal') |
||||
->willReturn('/home/calendar'); |
||||
$tree = $this->createMock(Tree::class); |
||||
$davServer->tree = $tree; |
||||
$tree->expects(self::once()) |
||||
->method('getNodeForPath') |
||||
->with('/home/calendar') |
||||
->willThrowException(new NotFound('nope')); |
||||
$event = new OutOfOfficeChangedEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
|
||||
public function testHandleChangePersonalCalendarNotFound(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$caldavPlugin->expects(self::once()) |
||||
->method('getCalendarHomeForPrincipal') |
||||
->willReturn('/home/calendar'); |
||||
$tree = $this->createMock(Tree::class); |
||||
$davServer->tree = $tree; |
||||
$calendarHome = $this->createMock(CalendarHome::class); |
||||
$tree->expects(self::once()) |
||||
->method('getNodeForPath') |
||||
->with('/home/calendar') |
||||
->willReturn($calendarHome); |
||||
$this->appConfig->expects(self::once()) |
||||
->method('getUserValue') |
||||
->with('user123', 'dav', 'defaultCalendar', 'personal') |
||||
->willReturn('personal-1'); |
||||
$calendarHome->expects(self::once()) |
||||
->method('getChild') |
||||
->with('personal-1') |
||||
->willThrowException(new NotFound('nope')); |
||||
$event = new OutOfOfficeChangedEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
|
||||
public function testHandleChangeRecreate(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$caldavPlugin->expects(self::once()) |
||||
->method('getCalendarHomeForPrincipal') |
||||
->willReturn('/home/calendar'); |
||||
$tree = $this->createMock(Tree::class); |
||||
$davServer->tree = $tree; |
||||
$calendarHome = $this->createMock(CalendarHome::class); |
||||
$tree->expects(self::once()) |
||||
->method('getNodeForPath') |
||||
->with('/home/calendar') |
||||
->willReturn($calendarHome); |
||||
$this->appConfig->expects(self::once()) |
||||
->method('getUserValue') |
||||
->with('user123', 'dav', 'defaultCalendar', 'personal') |
||||
->willReturn('personal-1'); |
||||
$calendar = $this->createMock(Calendar::class); |
||||
$calendarHome->expects(self::once()) |
||||
->method('getChild') |
||||
->with('personal-1') |
||||
->willReturn($calendar); |
||||
$calendar->expects(self::once()) |
||||
->method('getChild') |
||||
->willThrowException(new NotFound()); |
||||
$calendar->expects(self::once()) |
||||
->method('createFile'); |
||||
$event = new OutOfOfficeChangedEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
|
||||
public function testHandleChange(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$caldavPlugin->expects(self::once()) |
||||
->method('getCalendarHomeForPrincipal') |
||||
->willReturn('/home/calendar'); |
||||
$tree = $this->createMock(Tree::class); |
||||
$davServer->tree = $tree; |
||||
$calendarHome = $this->createMock(CalendarHome::class); |
||||
$tree->expects(self::once()) |
||||
->method('getNodeForPath') |
||||
->with('/home/calendar') |
||||
->willReturn($calendarHome); |
||||
$this->appConfig->expects(self::once()) |
||||
->method('getUserValue') |
||||
->with('user123', 'dav', 'defaultCalendar', 'personal') |
||||
->willReturn('personal-1'); |
||||
$calendar = $this->createMock(Calendar::class); |
||||
$calendarHome->expects(self::once()) |
||||
->method('getChild') |
||||
->with('personal-1') |
||||
->willReturn($calendar); |
||||
$eventNode = $this->createMock(CalendarObject::class); |
||||
$calendar->expects(self::once()) |
||||
->method('getChild') |
||||
->willReturn($eventNode); |
||||
$eventNode->expects(self::once()) |
||||
->method('put'); |
||||
$calendar->expects(self::never()) |
||||
->method('createFile'); |
||||
$event = new OutOfOfficeChangedEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
|
||||
public function testHandleClearNoCalendarHome(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$event = new OutOfOfficeClearedEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
|
||||
public function testHandleClearNoCalendarHomeNode(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$caldavPlugin->expects(self::once()) |
||||
->method('getCalendarHomeForPrincipal') |
||||
->willReturn('/home/calendar'); |
||||
$tree = $this->createMock(Tree::class); |
||||
$davServer->tree = $tree; |
||||
$tree->expects(self::once()) |
||||
->method('getNodeForPath') |
||||
->with('/home/calendar') |
||||
->willThrowException(new NotFound('nope')); |
||||
$event = new OutOfOfficeClearedEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
|
||||
public function testHandleClearPersonalCalendarNotFound(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$caldavPlugin->expects(self::once()) |
||||
->method('getCalendarHomeForPrincipal') |
||||
->willReturn('/home/calendar'); |
||||
$tree = $this->createMock(Tree::class); |
||||
$davServer->tree = $tree; |
||||
$calendarHome = $this->createMock(CalendarHome::class); |
||||
$tree->expects(self::once()) |
||||
->method('getNodeForPath') |
||||
->with('/home/calendar') |
||||
->willReturn($calendarHome); |
||||
$this->appConfig->expects(self::once()) |
||||
->method('getUserValue') |
||||
->with('user123', 'dav', 'defaultCalendar', 'personal') |
||||
->willReturn('personal-1'); |
||||
$calendarHome->expects(self::once()) |
||||
->method('getChild') |
||||
->with('personal-1') |
||||
->willThrowException(new NotFound('nope')); |
||||
$event = new OutOfOfficeClearedEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
|
||||
public function testHandleClearRecreate(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$caldavPlugin->expects(self::once()) |
||||
->method('getCalendarHomeForPrincipal') |
||||
->willReturn('/home/calendar'); |
||||
$tree = $this->createMock(Tree::class); |
||||
$davServer->tree = $tree; |
||||
$calendarHome = $this->createMock(CalendarHome::class); |
||||
$tree->expects(self::once()) |
||||
->method('getNodeForPath') |
||||
->with('/home/calendar') |
||||
->willReturn($calendarHome); |
||||
$this->appConfig->expects(self::once()) |
||||
->method('getUserValue') |
||||
->with('user123', 'dav', 'defaultCalendar', 'personal') |
||||
->willReturn('personal-1'); |
||||
$calendar = $this->createMock(Calendar::class); |
||||
$calendarHome->expects(self::once()) |
||||
->method('getChild') |
||||
->with('personal-1') |
||||
->willReturn($calendar); |
||||
$calendar->expects(self::once()) |
||||
->method('getChild') |
||||
->willThrowException(new NotFound()); |
||||
$event = new OutOfOfficeClearedEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
|
||||
public function testHandleClear(): void { |
||||
$user = $this->createMock(IUser::class); |
||||
$user->method('getUID')->willReturn('user123'); |
||||
$data = $this->createMock(IOutOfOfficeData::class); |
||||
$data->method('getUser')->willReturn($user); |
||||
$davServer = $this->createMock(Server::class); |
||||
$invitationServer = $this->createMock(InvitationResponseServer::class); |
||||
$invitationServer->method('getServer')->willReturn($davServer); |
||||
$this->serverFactory->method('createInviationResponseServer')->willReturn($invitationServer); |
||||
$caldavPlugin = $this->createMock(Plugin::class); |
||||
$davServer->expects(self::once()) |
||||
->method('getPlugin') |
||||
->with('caldav') |
||||
->willReturn($caldavPlugin); |
||||
$caldavPlugin->expects(self::once()) |
||||
->method('getCalendarHomeForPrincipal') |
||||
->willReturn('/home/calendar'); |
||||
$tree = $this->createMock(Tree::class); |
||||
$davServer->tree = $tree; |
||||
$calendarHome = $this->createMock(CalendarHome::class); |
||||
$tree->expects(self::once()) |
||||
->method('getNodeForPath') |
||||
->with('/home/calendar') |
||||
->willReturn($calendarHome); |
||||
$this->appConfig->expects(self::once()) |
||||
->method('getUserValue') |
||||
->with('user123', 'dav', 'defaultCalendar', 'personal') |
||||
->willReturn('personal-1'); |
||||
$calendar = $this->createMock(Calendar::class); |
||||
$calendarHome->expects(self::once()) |
||||
->method('getChild') |
||||
->with('personal-1') |
||||
->willReturn($calendar); |
||||
$eventNode = $this->createMock(CalendarObject::class); |
||||
$calendar->expects(self::once()) |
||||
->method('getChild') |
||||
->willReturn($eventNode); |
||||
$eventNode->expects(self::once()) |
||||
->method('delete'); |
||||
$event = new OutOfOfficeClearedEvent($data); |
||||
|
||||
$this->listener->handle($event); |
||||
} |
||||
} |
Loading…
Reference in new issue