feat(caldav): expose calendar subscriptions

Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
backport/44752/stable27
Daniel Kesselberg 2 months ago
parent 0507be52d1
commit 5d78d75e3e
No known key found for this signature in database
GPG Key ID: 36E3664E099D0614

@ -45,7 +45,9 @@ return array(
'OCA\\DAV\\CalDAV\\BirthdayCalendar\\EnablePlugin' => $baseDir . '/../lib/CalDAV/BirthdayCalendar/EnablePlugin.php',
'OCA\\DAV\\CalDAV\\BirthdayService' => $baseDir . '/../lib/CalDAV/BirthdayService.php',
'OCA\\DAV\\CalDAV\\CachedSubscription' => $baseDir . '/../lib/CalDAV/CachedSubscription.php',
'OCA\\DAV\\CalDAV\\CachedSubscriptionImpl' => $baseDir . '/../lib/CalDAV/CachedSubscriptionImpl.php',
'OCA\\DAV\\CalDAV\\CachedSubscriptionObject' => $baseDir . '/../lib/CalDAV/CachedSubscriptionObject.php',
'OCA\\DAV\\CalDAV\\CachedSubscriptionProvider' => $baseDir . '/../lib/CalDAV/CachedSubscriptionProvider.php',
'OCA\\DAV\\CalDAV\\CalDavBackend' => $baseDir . '/../lib/CalDAV/CalDavBackend.php',
'OCA\\DAV\\CalDAV\\Calendar' => $baseDir . '/../lib/CalDAV/Calendar.php',
'OCA\\DAV\\CalDAV\\CalendarHome' => $baseDir . '/../lib/CalDAV/CalendarHome.php',

@ -60,7 +60,9 @@ class ComposerStaticInitDAV
'OCA\\DAV\\CalDAV\\BirthdayCalendar\\EnablePlugin' => __DIR__ . '/..' . '/../lib/CalDAV/BirthdayCalendar/EnablePlugin.php',
'OCA\\DAV\\CalDAV\\BirthdayService' => __DIR__ . '/..' . '/../lib/CalDAV/BirthdayService.php',
'OCA\\DAV\\CalDAV\\CachedSubscription' => __DIR__ . '/..' . '/../lib/CalDAV/CachedSubscription.php',
'OCA\\DAV\\CalDAV\\CachedSubscriptionImpl' => __DIR__ . '/..' . '/../lib/CalDAV/CachedSubscriptionImpl.php',
'OCA\\DAV\\CalDAV\\CachedSubscriptionObject' => __DIR__ . '/..' . '/../lib/CalDAV/CachedSubscriptionObject.php',
'OCA\\DAV\\CalDAV\\CachedSubscriptionProvider' => __DIR__ . '/..' . '/../lib/CalDAV/CachedSubscriptionProvider.php',
'OCA\\DAV\\CalDAV\\CalDavBackend' => __DIR__ . '/..' . '/../lib/CalDAV/CalDavBackend.php',
'OCA\\DAV\\CalDAV\\Calendar' => __DIR__ . '/..' . '/../lib/CalDAV/Calendar.php',
'OCA\\DAV\\CalDAV\\CalendarHome' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarHome.php',

@ -36,6 +36,7 @@ use Exception;
use OCA\DAV\BackgroundJob\UpdateCalendarResourcesRoomsBackgroundJob;
use OCA\DAV\CalDAV\Activity\Backend;
use OCA\DAV\CalDAV\AppCalendar\AppCalendarPlugin;
use OCA\DAV\CalDAV\CachedSubscriptionProvider;
use OCA\DAV\CalDAV\CalendarManager;
use OCA\DAV\CalDAV\CalendarProvider;
use OCA\DAV\CalDAV\Reminder\NotificationProvider\AudioProvider;
@ -199,6 +200,7 @@ class Application extends App implements IBootstrap {
$context->registerNotifierService(Notifier::class);
$context->registerCalendarProvider(CalendarProvider::class);
$context->registerCalendarProvider(CachedSubscriptionProvider::class);
$context->registerUserMigrator(CalendarMigrator::class);
$context->registerUserMigrator(ContactsMigrator::class);

@ -67,7 +67,7 @@ class AppCalendarPlugin implements ICalendarProvider {
return array_values(
array_filter($this->manager->getCalendarsForPrincipal($principalUri, $calendarUris), function ($c) {
// We must not provide a wrapper for DAV calendars
return ! ($c instanceof \OCA\DAV\CalDAV\CalendarImpl);
return ! (($c instanceof \OCA\DAV\CalDAV\CalendarImpl) || ($c instanceof \OCA\DAV\CalDAV\CachedSubscriptionImpl));
})
);
}

@ -73,6 +73,11 @@ class CachedSubscription extends \Sabre\CalDAV\Calendar {
'principal' => '{DAV:}authenticated',
'protected' => true,
],
[
'privilege' => '{DAV:}write-properties',
'principal' => $this->getOwner(),
'protected' => true,
]
];
}
@ -97,7 +102,6 @@ class CachedSubscription extends \Sabre\CalDAV\Calendar {
'principal' => $this->getOwner() . '/calendar-proxy-read',
'protected' => true,
],
];
}

@ -0,0 +1,117 @@
<?php
declare(strict_types=1);
/**
* @copyright 2024 Daniel Kesselberg <mail@danielkesselberg.de>
*
* @author Daniel Kesselberg <mail@danielkesselberg.de>
*
* @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;
use OCP\Calendar\ICalendar;
use OCP\Constants;
class CachedSubscriptionImpl implements ICalendar {
private CalDavBackend $backend;
private CachedSubscription $calendar;
/** @var array<string, mixed> */
private array $calendarInfo;
public function __construct(
CachedSubscription $calendar,
array $calendarInfo,
CalDavBackend $backend
) {
$this->calendar = $calendar;
$this->calendarInfo = $calendarInfo;
$this->backend = $backend;
}
/**
* @return string defining the technical unique key
* @since 13.0.0
*/
public function getKey(): string {
return (string) $this->calendarInfo['id'];
}
/**
* {@inheritDoc}
*/
public function getUri(): string {
return $this->calendarInfo['uri'];
}
/**
* In comparison to getKey() this function returns a human readable (maybe translated) name
* @since 13.0.0
*/
public function getDisplayName(): ?string {
return $this->calendarInfo['{DAV:}displayname'];
}
/**
* Calendar color
* @since 13.0.0
*/
public function getDisplayColor(): ?string {
return $this->calendarInfo['{http://apple.com/ns/ical/}calendar-color'];
}
/**
* @param string $pattern which should match within the $searchProperties
* @param array $searchProperties defines the properties within the query pattern should match
* @param array $options - optional parameters:
* ['timerange' => ['start' => new DateTime(...), 'end' => new DateTime(...)]]
* @param int|null $limit - limit number of search results
* @param int|null $offset - offset for paging of search results
* @return array an array of events/journals/todos which are arrays of key-value-pairs
* @since 13.0.0
*/
public function search(string $pattern, array $searchProperties = [], array $options = [], $limit = null, $offset = null): array {
return $this->backend->search($this->calendarInfo, $pattern, $searchProperties, $options, $limit, $offset);
}
/**
* @return int build up using \OCP\Constants
* @since 13.0.0
*/
public function getPermissions(): int {
$permissions = $this->calendar->getACL();
$result = 0;
foreach ($permissions as $permission) {
switch ($permission['privilege']) {
case '{DAV:}read':
$result |= Constants::PERMISSION_READ;
break;
}
}
return $result;
}
public function isDeleted(): bool {
return false;
}
public function getSource(): string {
return $this->calendarInfo['source'];
}
}

@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
/**
* @copyright 2024 Daniel Kesselberg <mail@danielkesselberg.de>
*
* @author Daniel Kesselberg <mail@danielkesselberg.de>
*
* @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;
use OCP\Calendar\ICalendarProvider;
class CachedSubscriptionProvider implements ICalendarProvider {
public function __construct(
private CalDavBackend $calDavBackend
) {
}
public function getCalendars(string $principalUri, array $calendarUris = []): array {
$calendarInfos = $this->calDavBackend->getSubscriptionsForUser($principalUri);
if (count($calendarUris) > 0) {
$calendarInfos = array_filter($calendarInfos, fn (array $subscription) => in_array($subscription['uri'], $calendarUris));
}
$calendarInfos = array_values(array_filter($calendarInfos));
$iCalendars = [];
foreach ($calendarInfos as $calendarInfo) {
$calendar = new CachedSubscription($this->calDavBackend, $calendarInfo);
$iCalendars[] = new CachedSubscriptionImpl(
$calendar,
$calendarInfo,
$this->calDavBackend,
);
}
return $iCalendars;
}
}

@ -1881,12 +1881,18 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
$outerQuery = $this->db->getQueryBuilder();
$innerQuery = $this->db->getQueryBuilder();
if (isset($calendarInfo['source'])) {
$calendarType = self::CALENDAR_TYPE_SUBSCRIPTION;
} else {
$calendarType = self::CALENDAR_TYPE_CALENDAR;
}
$innerQuery->selectDistinct('op.objectid')
->from($this->dbObjectPropertiesTable, 'op')
->andWhere($innerQuery->expr()->eq('op.calendarid',
$outerQuery->createNamedParameter($calendarInfo['id'])))
->andWhere($innerQuery->expr()->eq('op.calendartype',
$outerQuery->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
$outerQuery->createNamedParameter($calendarType)));
$outerQuery->select('c.id', 'c.calendardata', 'c.componenttype', 'c.uid', 'c.uri')
->from('calendarobjects', 'c')

@ -53,14 +53,16 @@ class CalendarHome extends \Sabre\CalDAV\CalendarHome {
/** @var PluginManager */
private $pluginManager;
/** @var bool */
private $returnCachedSubscriptions = false;
/** @var LoggerInterface */
private $logger;
private ?array $cachedChildren = null;
public function __construct(BackendInterface $caldavBackend, $principalInfo, LoggerInterface $logger) {
public function __construct(
BackendInterface $caldavBackend,
array $principalInfo,
LoggerInterface $logger,
private bool $returnCachedSubscriptions
) {
parent::__construct($caldavBackend, $principalInfo);
$this->l10n = \OC::$server->getL10N('dav');
$this->config = \OC::$server->getConfig();
@ -219,8 +221,4 @@ class CalendarHome extends \Sabre\CalDAV\CalendarHome {
$principalUri = $this->principalInfo['uri'];
return $this->caldavBackend->calendarSearch($principalUri, $filters, $limit, $offset);
}
public function enableCachedSubscriptionsForThisRequest() {
$this->returnCachedSubscriptions = true;
}
}

@ -32,6 +32,8 @@ use Sabre\DAVACL\PrincipalBackend;
class CalendarRoot extends \Sabre\CalDAV\CalendarRoot {
private LoggerInterface $logger;
private array $returnCachedSubscriptions = [];
public function __construct(
PrincipalBackend\BackendInterface $principalBackend,
Backend\BackendInterface $caldavBackend,
@ -43,7 +45,12 @@ class CalendarRoot extends \Sabre\CalDAV\CalendarRoot {
}
public function getChildForPrincipal(array $principal) {
return new CalendarHome($this->caldavBackend, $principal, $this->logger);
return new CalendarHome(
$this->caldavBackend,
$principal,
$this->logger,
array_key_exists($principal['uri'], $this->returnCachedSubscriptions)
);
}
public function getName() {
@ -56,4 +63,8 @@ class CalendarRoot extends \Sabre\CalDAV\CalendarRoot {
return parent::getName();
}
public function enableReturnCachedSubscriptions(string $principalUri): void {
$this->returnCachedSubscriptions['principals/users/' . $principalUri] = true;
}
}

@ -26,7 +26,7 @@ declare(strict_types=1);
*/
namespace OCA\DAV\CalDAV\WebcalCaching;
use OCA\DAV\CalDAV\CalendarHome;
use OCA\DAV\CalDAV\CalendarRoot;
use OCP\IRequest;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\Server;
@ -71,6 +71,11 @@ class Plugin extends ServerPlugin {
if ($magicHeader === 'On') {
$this->enabled = true;
}
$isExportRequest = $request->getMethod() === 'GET' && array_key_exists('export', $request->getParams());
if ($isExportRequest) {
$this->enabled = true;
}
}
/**
@ -85,7 +90,7 @@ class Plugin extends ServerPlugin {
*/
public function initialize(Server $server) {
$this->server = $server;
$server->on('beforeMethod:*', [$this, 'beforeMethod']);
$server->on('beforeMethod:*', [$this, 'beforeMethod'], 15);
}
/**
@ -103,16 +108,11 @@ class Plugin extends ServerPlugin {
return;
}
// $calendarHomePath will look like: calendars/username
$calendarHomePath = $pathParts[0] . '/' . $pathParts[1];
try {
$calendarHome = $this->server->tree->getNodeForPath($calendarHomePath);
if (!($calendarHome instanceof CalendarHome)) {
//how did we end up here?
return;
$calendarRoot = $this->server->tree->getNodeForPath($pathParts[0]);
if ($calendarRoot instanceof CalendarRoot) {
$calendarRoot->enableReturnCachedSubscriptions($pathParts[1]);
}
$calendarHome->enableCachedSubscriptionsForThisRequest();
} catch (NotFound $ex) {
return;
}

@ -27,6 +27,8 @@
*/
namespace OCA\DAV\Connector\Sabre;
use OCA\DAV\CalDAV\CachedSubscription;
use OCA\DAV\CalDAV\Calendar;
use OCA\DAV\CardDAV\AddressBook;
use Sabre\CalDAV\Principal\User;
use Sabre\DAV\Exception\NotFound;
@ -59,6 +61,10 @@ class DavAclPlugin extends \Sabre\DAVACL\Plugin {
case AddressBook::class:
$type = 'Addressbook';
break;
case Calendar::class:
case CachedSubscription::class:
$type = 'Calendar';
break;
default:
$type = 'Node';
break;

@ -0,0 +1,96 @@
<?php
declare(strict_types=1);
/**
* @copyright 2024 Daniel Kesselberg <mail@danielkesselberg.de>
*
* @author Daniel Kesselberg <mail@danielkesselberg.de>
*
* @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\CalDAV;
use OCA\DAV\CalDAV\CachedSubscription;
use OCA\DAV\CalDAV\CachedSubscriptionImpl;
use OCA\DAV\CalDAV\CalDavBackend;
use Test\TestCase;
class CachedSubscriptionImplTest extends TestCase {
private CachedSubscription $cachedSubscription;
private array $cachedSubscriptionInfo;
private CachedSubscriptionImpl $cachedSubscriptionImpl;
private CalDavBackend $backend;
protected function setUp(): void {
parent::setUp();
$this->cachedSubscription = $this->createMock(CachedSubscription::class);
$this->cachedSubscriptionInfo = [
'id' => 'fancy_id_123',
'{DAV:}displayname' => 'user readable name 123',
'{http://apple.com/ns/ical/}calendar-color' => '#AABBCC',
'uri' => '/this/is/a/uri',
'source' => 'https://test.localhost/calendar1',
];
$this->backend = $this->createMock(CalDavBackend::class);
$this->cachedSubscriptionImpl = new CachedSubscriptionImpl(
$this->cachedSubscription,
$this->cachedSubscriptionInfo,
$this->backend
);
}
public function testGetKey(): void {
$this->assertEquals($this->cachedSubscriptionImpl->getKey(), 'fancy_id_123');
}
public function testGetDisplayname(): void {
$this->assertEquals($this->cachedSubscriptionImpl->getDisplayName(), 'user readable name 123');
}
public function testGetDisplayColor(): void {
$this->assertEquals($this->cachedSubscriptionImpl->getDisplayColor(), '#AABBCC');
}
public function testGetSource(): void {
$this->assertEquals($this->cachedSubscriptionImpl->getSource(), 'https://test.localhost/calendar1');
}
public function testSearch(): void {
$this->backend->expects($this->once())
->method('search')
->with($this->cachedSubscriptionInfo, 'abc', ['def'], ['ghi'], 42, 1337)
->willReturn(['SEARCHRESULTS']);
$result = $this->cachedSubscriptionImpl->search('abc', ['def'], ['ghi'], 42, 1337);
$this->assertEquals($result, ['SEARCHRESULTS']);
}
public function testGetPermissionRead(): void {
$this->cachedSubscription->expects($this->once())
->method('getACL')
->with()
->willReturn([
['privilege' => '{DAV:}read']
]);
$this->assertEquals(1, $this->cachedSubscriptionImpl->getPermissions());
}
}

@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
/**
* @copyright 2024 Daniel Kesselberg <mail@danielkesselberg.de>
*
* @author Daniel Kesselberg <mail@danielkesselberg.de>
*
* @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\CalDAV;
use OCA\DAV\CalDAV\CachedSubscriptionImpl;
use OCA\DAV\CalDAV\CachedSubscriptionProvider;
use OCA\DAV\CalDAV\CalDavBackend;
use Test\TestCase;
class CachedSubscriptionProviderTest extends TestCase {
private CalDavBackend $backend;
private CachedSubscriptionProvider $provider;
protected function setUp(): void {
parent::setUp();
$this->backend = $this->createMock(CalDavBackend::class);
$this->backend
->expects(self::once())
->method('getSubscriptionsForUser')
->with('user-principal-123')
->willReturn([
[
'id' => 'subscription-1',
'uri' => 'subscription-1',
'principaluris' => 'user-principal-123',
'source' => 'https://localhost/subscription-1',
// A subscription array has actually more properties.
],
[
'id' => 'subscription-2',
'uri' => 'subscription-2',
'principaluri' => 'user-principal-123',
'source' => 'https://localhost/subscription-2',
// A subscription array has actually more properties.
]
]);
$this->provider = new CachedSubscriptionProvider($this->backend);
}
public function testGetCalendars() {
$calendars = $this->provider->getCalendars(
'user-principal-123',
[]
);
$this->assertCount(2, $calendars);
$this->assertInstanceOf(CachedSubscriptionImpl::class, $calendars[0]);
$this->assertInstanceOf(CachedSubscriptionImpl::class, $calendars[1]);
}
public function testGetCalendarsFilterByUri() {
$calendars = $this->provider->getCalendars(
'user-principal-123',
['subscription-1']
);
$this->assertCount(1, $calendars);
$this->assertInstanceOf(CachedSubscriptionImpl::class, $calendars[0]);
$this->assertEquals('subscription-1', $calendars[0]->getUri());
}
}

@ -61,6 +61,11 @@ class CachedSubscriptionTest extends \Test\TestCase {
'principal' => '{DAV:}authenticated',
'protected' => true,
],
[
'privilege' => '{DAV:}write-properties',
'principal' => 'user1',
'protected' => 'true'
]
], $calendar->getACL());
}

@ -26,6 +26,7 @@
namespace OCA\DAV\Tests\unit\CalDAV;
use OCA\DAV\AppInfo\PluginManager;
use OCA\DAV\CalDAV\CachedSubscription;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\CalendarHome;
use OCA\DAV\CalDAV\Integration\ExternalCalendar;
@ -35,6 +36,7 @@ use OCA\DAV\CalDAV\Trashbin\TrashbinHome;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Sabre\CalDAV\Schedule\Inbox;
use Sabre\CalDAV\Subscriptions\Subscription;
use Sabre\DAV\MkCol;
use Test\TestCase;
@ -68,13 +70,13 @@ class CalendarHomeTest extends TestCase {
$this->calendarHome = new CalendarHome(
$this->backend,
$this->principalInfo,
$this->logger
$this->logger,
false
);
// Replace PluginManager with our mock
$reflection = new \ReflectionClass($this->calendarHome);
$reflectionProperty = $reflection->getProperty('pluginManager');
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue($this->calendarHome, $this->pluginManager);
}
@ -249,4 +251,124 @@ class CalendarHomeTest extends TestCase {
$actual = $this->calendarHome->getChild('app-generated--calendar_plugin_2--calendar-uri-from-backend');
$this->assertEquals($externalCalendarMock, $actual);
}
public function testGetChildrenSubscriptions(): void {
$this->backend
->expects(self::once())
->method('getCalendarsForUser')
->with('user-principal-123')
->willReturn([]);
$this->backend
->expects(self::once())
->method('getSubscriptionsForUser')
->with('user-principal-123')
->willReturn([
[
'id' => 'subscription-1',
'uri' => 'subscription-1',
'principaluri' => 'user-principal-123',
'source' => 'https://localhost/subscription-1',
// A subscription array has actually more properties.
],
[
'id' => 'subscription-2',
'uri' => 'subscription-2',
'principaluri' => 'user-principal-123',
'source' => 'https://localhost/subscription-2',
// A subscription array has actually more properties.
]
]);
/*
* @FIXME: PluginManager should be injected via constructor.
*/
$pluginManager = $this->createMock(PluginManager::class);
$pluginManager
->expects(self::once())
->method('getCalendarPlugins')
->with()
->willReturn([]);
$calendarHome = new CalendarHome(
$this->backend,
$this->principalInfo,
$this->logger,
false
);
$reflection = new \ReflectionClass($calendarHome);
$reflectionProperty = $reflection->getProperty('pluginManager');
$reflectionProperty->setValue($calendarHome, $pluginManager);
$actual = $calendarHome->getChildren();
$this->assertCount(5, $actual);
$this->assertInstanceOf(Inbox::class, $actual[0]);
$this->assertInstanceOf(Outbox::class, $actual[1]);
$this->assertInstanceOf(TrashbinHome::class, $actual[2]);
$this->assertInstanceOf(Subscription::class, $actual[3]);
$this->assertInstanceOf(Subscription::class, $actual[4]);
}
public function testGetChildrenCachedSubscriptions(): void {
$this->backend
->expects(self::once())
->method('getCalendarsForUser')
->with('user-principal-123')
->willReturn([]);
$this->backend
->expects(self::once())
->method('getSubscriptionsForUser')
->with('user-principal-123')
->willReturn([
[
'id' => 'subscription-1',
'uri' => 'subscription-1',
'principaluris' => 'user-principal-123',
'source' => 'https://localhost/subscription-1',
// A subscription array has actually more properties.
],
[
'id' => 'subscription-2',
'uri' => 'subscription-2',
'principaluri' => 'user-principal-123',
'source' => 'https://localhost/subscription-2',
// A subscription array has actually more properties.
]
]);
/*
* @FIXME: PluginManager should be injected via constructor.
*/
$pluginManager = $this->createMock(PluginManager::class);
$pluginManager
->expects(self::once())
->method('getCalendarPlugins')
->with()
->willReturn([]);
$calendarHome = new CalendarHome(
$this->backend,
$this->principalInfo,
$this->logger,
true
);
$reflection = new \ReflectionClass($calendarHome);
$reflectionProperty = $reflection->getProperty('pluginManager');
$reflectionProperty->setValue($calendarHome, $pluginManager);
$actual = $calendarHome->getChildren();
$this->assertCount(5, $actual);
$this->assertInstanceOf(Inbox::class, $actual[0]);
$this->assertInstanceOf(Outbox::class, $actual[1]);
$this->assertInstanceOf(TrashbinHome::class, $actual[2]);
$this->assertInstanceOf(CachedSubscription::class, $actual[3]);
$this->assertInstanceOf(CachedSubscription::class, $actual[4]);
}
}

@ -39,9 +39,6 @@ use Sabre\VObject\Component\VEvent;
use Sabre\VObject\ITip\Message;
use Sabre\VObject\Reader;
/**
* @group DB
*/
class CalendarImplTest extends \Test\TestCase {
/** @var CalendarImpl */
private $calendarImpl;

@ -44,17 +44,64 @@ class PluginTest extends \Test\TestCase {
$this->assertEquals(false, $plugin->isCachingEnabledForThisRequest());
}
public function testEnabled(): void {
public function testEnabledUserAgent(): void {
$request = $this->createMock(IRequest::class);
$request->expects($this->once())
->method('isUserAgent')
->with(Plugin::ENABLE_FOR_CLIENTS)
->willReturn(false);
->willReturn(true);
$request->expects($this->once())
->method('getHeader')
->with('X-NC-CalDAV-Webcal-Caching')
->willReturn('');
$request->expects($this->once())
->method('getMethod')
->willReturn('REPORT');
$request->expects($this->never())
->method('getParams');
$plugin = new Plugin($request);
$this->assertEquals(true, $plugin->isCachingEnabledForThisRequest());
}
public function testEnabledWebcalCachingHeader(): void {
$request = $this->createMock(IRequest::class);
$request->expects($this->once())
->method('isUserAgent')
->with(Plugin::ENABLE_FOR_CLIENTS)
->willReturn(false);
$request->expects($this->once())
->method('getHeader')
->with('X-NC-CalDAV-Webcal-Caching')
->willReturn('On');
$request->expects($this->once())
->method('getMethod')
->willReturn('REPORT');
$request->expects($this->never())
->method('getParams');
$plugin = new Plugin($request);
$this->assertEquals(true, $plugin->isCachingEnabledForThisRequest());
}
public function testEnabledExportRequest(): void {
$request = $this->createMock(IRequest::class);
$request->expects($this->once())
->method('isUserAgent')
->with(Plugin::ENABLE_FOR_CLIENTS)
->willReturn(false);
$request->expects($this->once())
->method('getHeader')
->with('X-NC-CalDAV-Webcal-Caching')
->willReturn('');
$request->expects($this->once())
->method('getMethod')
->willReturn('GET');
$request->expects($this->once())
->method('getParams')
->willReturn(['export' => '']);
$plugin = new Plugin($request);

@ -13,7 +13,7 @@ Feature: caldav
When "user0" requests calendar "admin/MyCalendar" on the endpoint "/remote.php/dav/calendars/"
Then The CalDAV HTTP status code should be "404"
And The exception is "Sabre\DAV\Exception\NotFound"
And The error message is "Node with name 'MyCalendar' could not be found"
And The error message is "Calendar with name 'MyCalendar' could not be found"
Scenario: Accessing a not shared calendar of another user via the legacy endpoint
Given user "user0" exists
@ -22,7 +22,7 @@ Feature: caldav
When "user0" requests calendar "admin/MyCalendar" on the endpoint "/remote.php/caldav/calendars/"
Then The CalDAV HTTP status code should be "404"
And The exception is "Sabre\DAV\Exception\NotFound"
And The error message is "Node with name 'MyCalendar' could not be found"
And The error message is "Calendar with name 'MyCalendar' could not be found"
Scenario: Accessing a not existing calendar of another user
Given user "user0" exists

Loading…
Cancel
Save