Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>pull/44752/head
@@ -46,7 +46,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', |
@@ -61,7 +61,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', |
@@ -34,6 +34,7 @@ namespace OCA\DAV\AppInfo; | |||
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; | |||
@@ -207,6 +208,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); |
@@ -68,7 +68,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; | |||
} | |||
} |
@@ -1882,12 +1882,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); | |||
} | |||
/** | |||
@@ -107,16 +112,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,7 @@ | |||
*/ | |||
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; | |||
@@ -61,6 +62,7 @@ class DavAclPlugin extends \Sabre\DAVACL\Plugin { | |||
$type = 'Addressbook'; | |||
break; | |||
case Calendar::class: | |||
case CachedSubscription::class: | |||
$type = 'Calendar'; | |||
break; | |||
default: |
@@ -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; |
@@ -48,17 +48,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); | |||