Merge pull request #24080 from owncloud/support-calendar-class-property

Extract CLASS property from calendar object and store it in the database
This commit is contained in:
Vincent Petry 2016-06-10 11:22:11 +02:00 committed by GitHub
commit 68c3b23e04
12 changed files with 753 additions and 154 deletions

View file

@ -272,6 +272,12 @@ CREATE TABLE calendarobjects (
<type>text</type>
<length>255</length>
</field>
<field>
<comments>0 - public, 1 - private, 2 - confidential</comments>
<name>classification</name>
<type>integer</type>
<default>0</default>
</field>
<index>
<name>calobjects_index</name>
<unique>true</unique>

View file

@ -5,7 +5,7 @@
<description>ownCloud WebDAV endpoint</description>
<licence>AGPL</licence>
<author>owncloud.org</author>
<version>0.2.4</version>
<version>0.2.5</version>
<default_enable/>
<types>
<filesystem/>
@ -20,4 +20,9 @@
<background-jobs>
<job>OCA\DAV\CardDAV\Sync\SyncJob</job>
</background-jobs>
<repair-steps>
<post-migration>
<job>OCA\DAV\Migration\Classification</job>
</post-migration>
</repair-steps>
</info>

View file

@ -31,10 +31,12 @@ use OCA\DAV\CardDAV\SyncService;
use OCA\DAV\Connector\Sabre\Principal;
use OCA\DAV\DAV\GroupPrincipalBackend;
use OCA\DAV\HookManager;
use OCA\DAV\Migration\Classification;
use \OCP\AppFramework\App;
use OCP\AppFramework\IAppContainer;
use OCP\Contacts\IManager;
use OCP\IUser;
use Sabre\VObject\Reader;
use Symfony\Component\EventDispatcher\GenericEvent;
class Application extends App {
@ -106,6 +108,14 @@ class Application extends App {
$g
);
});
$container->registerService('OCA\DAV\Migration\Classification', function ($c) {
/** @var IAppContainer $c */
return new Classification(
$c->query('CalDavBackend'),
$c->getServer()->getUserManager()
);
});
}
/**

View file

@ -37,10 +37,11 @@ use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp;
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
use Sabre\DAV;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\PropPatch;
use Sabre\HTTP\URLUtil;
use Sabre\VObject\DateTimeParser;
use Sabre\VObject\Reader;
use Sabre\VObject\RecurrenceIterator;
use Sabre\VObject\Recur\EventIterator;
/**
* Class CalDavBackend
@ -61,6 +62,10 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
*/
const MAX_DATE = '2038-01-01';
const CLASSIFICATION_PUBLIC = 0;
const CLASSIFICATION_PRIVATE = 1;
const CLASSIFICATION_CONFIDENTIAL = 2;
/**
* List of CalDAV properties, and how they map to database field names
* Add your own properties by simply adding on to this array.
@ -395,10 +400,10 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
*
* Read the PropPatch documentation for more info and examples.
*
* @param \Sabre\DAV\PropPatch $propPatch
* @param PropPatch $propPatch
* @return void
*/
function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) {
function updateCalendar($calendarId, PropPatch $propPatch) {
$supportedProperties = array_keys($this->propertyMap);
$supportedProperties[] = '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp';
@ -484,7 +489,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
*/
function getCalendarObjects($calendarId) {
$query = $this->db->getQueryBuilder();
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'componenttype'])
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'componenttype', 'classification'])
->from('calendarobjects')
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)));
$stmt = $query->execute();
@ -499,6 +504,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
'calendarid' => $row['calendarid'],
'size' => (int)$row['size'],
'component' => strtolower($row['componenttype']),
'classification'=> (int)$row['classification']
];
}
@ -524,7 +530,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
function getCalendarObject($calendarId, $objectUri) {
$query = $this->db->getQueryBuilder();
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype'])
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification'])
->from('calendarobjects')
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)));
@ -542,6 +548,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
'size' => (int)$row['size'],
'calendardata' => $this->readBlob($row['calendardata']),
'component' => strtolower($row['componenttype']),
'classification'=> (int)$row['classification']
];
}
@ -559,7 +566,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
*/
function getMultipleCalendarObjects($calendarId, array $uris) {
$query = $this->db->getQueryBuilder();
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype'])
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification'])
->from('calendarobjects')
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
->andWhere($query->expr()->in('uri', $query->createParameter('uri')))
@ -579,6 +586,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
'size' => (int)$row['size'],
'calendardata' => $this->readBlob($row['calendardata']),
'component' => strtolower($row['componenttype']),
'classification' => (int)$row['classification']
];
}
@ -618,6 +626,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
'componenttype' => $query->createNamedParameter($extraData['componentType']),
'firstoccurence' => $query->createNamedParameter($extraData['firstOccurence']),
'lastoccurence' => $query->createNamedParameter($extraData['lastOccurence']),
'classification' => $query->createNamedParameter($extraData['classification']),
'uid' => $query->createNamedParameter($extraData['uid']),
])
->execute();
@ -657,6 +666,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
->set('componenttype', $query->createNamedParameter($extraData['componentType']))
->set('firstoccurence', $query->createNamedParameter($extraData['firstOccurence']))
->set('lastoccurence', $query->createNamedParameter($extraData['lastOccurence']))
->set('classification', $query->createNamedParameter($extraData['classification']))
->set('uid', $query->createNamedParameter($extraData['uid']))
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
@ -667,6 +677,23 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
return '"' . $extraData['etag'] . '"';
}
/**
* @param int $calendarObjectId
* @param int $classification
*/
public function setClassification($calendarObjectId, $classification) {
if (!in_array($classification, [
self::CLASSIFICATION_PUBLIC, self::CLASSIFICATION_PRIVATE, self::CLASSIFICATION_CONFIDENTIAL
])) {
throw new \InvalidArgumentException();
}
$query = $this->db->getQueryBuilder();
$query->update('calendarobjects')
->set('classification', $query->createNamedParameter($classification))
->where($query->expr()->eq('id', $query->createNamedParameter($calendarObjectId)))
->execute();
}
/**
* Deletes an existing calendar object.
*
@ -1086,10 +1113,10 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
* Read the PropPatch documentation for more info and examples.
*
* @param mixed $subscriptionId
* @param \Sabre\DAV\PropPatch $propPatch
* @param PropPatch $propPatch
* @return void
*/
function updateSubscription($subscriptionId, DAV\PropPatch $propPatch) {
function updateSubscription($subscriptionId, PropPatch $propPatch) {
$supportedProperties = array_keys($this->subscriptionPropertyMap);
$supportedProperties[] = '{http://calendarserver.org/ns/}source';
@ -1280,14 +1307,15 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
* @param string $calendarData
* @return array
*/
protected function getDenormalizedData($calendarData) {
public function getDenormalizedData($calendarData) {
$vObject = Reader::read($calendarData);
$componentType = null;
$component = null;
$firstOccurence = null;
$lastOccurence = null;
$firstOccurrence = null;
$lastOccurrence = null;
$uid = null;
$classification = self::CLASSIFICATION_PUBLIC;
foreach($vObject->getComponents() as $component) {
if ($component->name!=='VTIMEZONE') {
$componentType = $component->name;
@ -1299,27 +1327,27 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
throw new \Sabre\DAV\Exception\BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component');
}
if ($componentType === 'VEVENT' && $component->DTSTART) {
$firstOccurence = $component->DTSTART->getDateTime()->getTimeStamp();
$firstOccurrence = $component->DTSTART->getDateTime()->getTimeStamp();
// Finding the last occurrence is a bit harder
if (!isset($component->RRULE)) {
if (isset($component->DTEND)) {
$lastOccurence = $component->DTEND->getDateTime()->getTimeStamp();
$lastOccurrence = $component->DTEND->getDateTime()->getTimeStamp();
} elseif (isset($component->DURATION)) {
$endDate = clone $component->DTSTART->getDateTime();
$endDate->add(DateTimeParser::parse($component->DURATION->getValue()));
$lastOccurence = $endDate->getTimeStamp();
$lastOccurrence = $endDate->getTimeStamp();
} elseif (!$component->DTSTART->hasTime()) {
$endDate = clone $component->DTSTART->getDateTime();
$endDate->modify('+1 day');
$lastOccurence = $endDate->getTimeStamp();
$lastOccurrence = $endDate->getTimeStamp();
} else {
$lastOccurence = $firstOccurence;
$lastOccurrence = $firstOccurrence;
}
} else {
$it = new RecurrenceIterator($vObject, (string)$component->UID);
$it = new EventIterator($vObject, (string)$component->UID);
$maxDate = new \DateTime(self::MAX_DATE);
if ($it->isInfinite()) {
$lastOccurence = $maxDate->getTimeStamp();
$lastOccurrence = $maxDate->getTimeStamp();
} else {
$end = $it->getDtEnd();
while($it->valid() && $end < $maxDate) {
@ -1327,19 +1355,31 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
$it->next();
}
$lastOccurence = $end->getTimeStamp();
$lastOccurrence = $end->getTimeStamp();
}
}
}
if ($component->CLASS) {
$classification = CalDavBackend::CLASSIFICATION_PRIVATE;
switch ($component->CLASS->getValue()) {
case 'PUBLIC':
$classification = CalDavBackend::CLASSIFICATION_PUBLIC;
break;
case 'CONFIDENTIAL':
$classification = CalDavBackend::CLASSIFICATION_CONFIDENTIAL;
break;
}
}
return [
'etag' => md5($calendarData),
'size' => strlen($calendarData),
'componentType' => $componentType,
'firstOccurence' => is_null($firstOccurence) ? null : max(0, $firstOccurence),
'lastOccurence' => $lastOccurence,
'uid' => $uid,
'etag' => md5($calendarData),
'size' => strlen($calendarData),
'componentType' => $componentType,
'firstOccurence' => is_null($firstOccurrence) ? null : max(0, $firstOccurrence),
'lastOccurence' => $lastOccurrence,
'uid' => $uid,
'classification' => $classification
];
}

View file

@ -26,6 +26,7 @@ use OCA\DAV\DAV\Sharing\IShareable;
use OCP\IL10N;
use Sabre\CalDAV\Backend\BackendInterface;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\PropPatch;
class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
@ -162,6 +163,78 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
parent::propPatch($propPatch);
}
function getChild($name) {
$obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $name);
if (!$obj) {
throw new NotFound('Calendar object not found');
}
if ($this->isShared() && $obj['classification'] === CalDavBackend::CLASSIFICATION_PRIVATE) {
throw new NotFound('Calendar object not found');
}
$obj['acl'] = $this->getChildACL();
return new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
}
function getChildren() {
$objs = $this->caldavBackend->getCalendarObjects($this->calendarInfo['id']);
$children = [];
foreach ($objs as $obj) {
if ($this->isShared() && $obj['classification'] === CalDavBackend::CLASSIFICATION_PRIVATE) {
continue;
}
$obj['acl'] = $this->getChildACL();
$children[] = new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
}
return $children;
}
function getMultipleChildren(array $paths) {
$objs = $this->caldavBackend->getMultipleCalendarObjects($this->calendarInfo['id'], $paths);
$children = [];
foreach ($objs as $obj) {
if ($this->isShared() && $obj['classification'] === CalDavBackend::CLASSIFICATION_PRIVATE) {
continue;
}
$obj['acl'] = $this->getChildACL();
$children[] = new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
}
return $children;
}
function childExists($name) {
$obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $name);
if (!$obj) {
return false;
}
if ($this->isShared() && $obj['classification'] === CalDavBackend::CLASSIFICATION_PRIVATE) {
return false;
}
return true;
}
function calendarQuery(array $filters) {
$uris = $this->caldavBackend->calendarQuery($this->calendarInfo['id'], $filters);
if ($this->isShared()) {
return array_filter($uris, function ($uri) {
return $this->childExists($uri);
});
}
return $uris;
}
private function canWrite() {
if (isset($this->calendarInfo['{http://owncloud.org/ns}read-only'])) {
return !$this->calendarInfo['{http://owncloud.org/ns}read-only'];
@ -169,4 +242,8 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
return true;
}
private function isShared() {
return isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal']);
}
}

View file

@ -0,0 +1,92 @@
<?php
/**
* @author Thomas Müller <thomas.mueller@tmit.eu>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\DAV\CalDAV;
use Sabre\VObject\Component;
use Sabre\VObject\Property;
use Sabre\VObject\Reader;
class CalendarObject extends \Sabre\CalDAV\CalendarObject {
/**
* @inheritdoc
*/
function get() {
$data = parent::get();
if ($this->isShared() && $this->objectData['classification'] === CalDavBackend::CLASSIFICATION_CONFIDENTIAL) {
return $this->createConfidentialObject($data);
}
return $data;
}
private function isShared() {
return isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal']);
}
/**
* @param string $calData
* @return string
*/
private static function createConfidentialObject($calData) {
$vObject = Reader::read($calData);
/** @var Component $vElement */
$vElement = null;
if(isset($vObject->VEVENT)) {
$vElement = $vObject->VEVENT;
}
if(isset($vObject->VJOURNAL)) {
$vElement = $vObject->VJOURNAL;
}
if(isset($vObject->VTODO)) {
$vElement = $vObject->VTODO;
}
if(!is_null($vElement)) {
foreach ($vElement->children as &$property) {
/** @var Property $property */
switch($property->name) {
case 'CREATED':
case 'DTSTART':
case 'RRULE':
case 'DURATION':
case 'DTEND':
case 'CLASS':
case 'UID':
break;
case 'SUMMARY':
$property->setValue('Busy');
break;
default:
$vElement->__unset($property->name);
unset($property);
break;
}
}
}
return $vObject->serialize();
}
}

View file

@ -0,0 +1,93 @@
<?php
/**
* @author Thomas Müller <thomas.mueller@tmit.eu>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\DAV\Migration;
use OCA\DAV\CalDAV\CalDavBackend;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
class Classification implements IRepairStep {
/** @var CalDavBackend */
private $calDavBackend;
/** @var IUserManager */
private $userManager;
/**
* Classification constructor.
*
* @param CalDavBackend $calDavBackend
*/
public function __construct(CalDavBackend $calDavBackend, IUserManager $userManager) {
$this->calDavBackend = $calDavBackend;
$this->userManager = $userManager;
}
/**
* @param IUser $user
*/
public function runForUser($user) {
$principal = 'principals/users/' . $user->getUID();
$calendars = $this->calDavBackend->getCalendarsForUser($principal);
foreach ($calendars as $calendar) {
$objects = $this->calDavBackend->getCalendarObjects($calendar['id']);
foreach ($objects as $object) {
$calObject = $this->calDavBackend->getCalendarObject($calendar['id'], $object['uri']);
$classification = $this->extractClassification($calObject['calendardata']);
$this->calDavBackend->setClassification($object['id'], $classification);
}
}
}
/**
* @param $calendarData
* @return integer
* @throws \Sabre\DAV\Exception\BadRequest
*/
protected function extractClassification($calendarData) {
return $this->calDavBackend->getDenormalizedData($calendarData)['classification'];
}
/**
* @inheritdoc
*/
public function getName() {
return 'Fix classification for calendar objects';
}
/**
* @inheritdoc
*/
public function run(IOutput $output) {
$output->startProgress();
$this->userManager->callForAllUsers(function($user) use ($output) {
/** @var IUser $user */
$output->advance(1, $user->getDisplayName());
$this->runForUser($user);
});
$output->finishProgress();
}
}

View file

@ -0,0 +1,163 @@
<?php
/**
* @author Joas Schilling <nickvergessen@owncloud.com>
* @author Thomas Müller <thomas.mueller@tmit.eu>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\DAV\Tests\unit\CalDAV;
use DateTime;
use DateTimeZone;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\Calendar;
use OCA\DAV\Connector\Sabre\Principal;
use OCP\IL10N;
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
use Sabre\DAV\PropPatch;
use Sabre\DAV\Xml\Property\Href;
use Sabre\DAVACL\IACL;
use Test\TestCase;
/**
* Class CalDavBackendTest
*
* @group DB
*
* @package OCA\DAV\Tests\unit\CalDAV
*/
abstract class AbstractCalDavBackendTest extends TestCase {
/** @var CalDavBackend */
protected $backend;
/** @var Principal | \PHPUnit_Framework_MockObject_MockObject */
protected $principal;
const UNIT_TEST_USER = 'principals/users/caldav-unit-test';
const UNIT_TEST_USER1 = 'principals/users/caldav-unit-test1';
const UNIT_TEST_GROUP = 'principals/groups/caldav-unit-test-group';
public function setUp() {
parent::setUp();
$this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal')
->disableOriginalConstructor()
->setMethods(['getPrincipalByPath', 'getGroupMembership'])
->getMock();
$this->principal->expects($this->any())->method('getPrincipalByPath')
->willReturn([
'uri' => 'principals/best-friend'
]);
$this->principal->expects($this->any())->method('getGroupMembership')
->withAnyParameters()
->willReturn([self::UNIT_TEST_GROUP]);
$db = \OC::$server->getDatabaseConnection();
$this->backend = new CalDavBackend($db, $this->principal);
$this->tearDown();
}
public function tearDown() {
parent::tearDown();
if (is_null($this->backend)) {
return;
}
$books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
foreach ($books as $book) {
$this->backend->deleteCalendar($book['id']);
}
$subscriptions = $this->backend->getSubscriptionsForUser(self::UNIT_TEST_USER);
foreach ($subscriptions as $subscription) {
$this->backend->deleteSubscription($subscription['id']);
}
}
protected function createTestCalendar() {
$this->backend->createCalendar(self::UNIT_TEST_USER, 'Example', [
'{http://apple.com/ns/ical/}calendar-color' => '#1C4587FF'
]);
$calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
$this->assertEquals(1, count($calendars));
$this->assertEquals(self::UNIT_TEST_USER, $calendars[0]['principaluri']);
/** @var SupportedCalendarComponentSet $components */
$components = $calendars[0]['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'];
$this->assertEquals(['VEVENT','VTODO'], $components->getValue());
$color = $calendars[0]['{http://apple.com/ns/ical/}calendar-color'];
$this->assertEquals('#1C4587FF', $color);
$this->assertEquals('Example', $calendars[0]['uri']);
$this->assertEquals('Example', $calendars[0]['{DAV:}displayname']);
$calendarId = $calendars[0]['id'];
return $calendarId;
}
protected function createEvent($calendarId, $start = '20130912T130000Z', $end = '20130912T140000Z') {
$calData = <<<EOD
BEGIN:VCALENDAR
VERSION:2.0
PRODID:ownCloud Calendar
BEGIN:VEVENT
CREATED;VALUE=DATE-TIME:20130910T125139Z
UID:47d15e3ec8
LAST-MODIFIED;VALUE=DATE-TIME:20130910T125139Z
DTSTAMP;VALUE=DATE-TIME:20130910T125139Z
SUMMARY:Test Event
DTSTART;VALUE=DATE-TIME:$start
DTEND;VALUE=DATE-TIME:$end
CLASS:PUBLIC
END:VEVENT
END:VCALENDAR
EOD;
$uri0 = $this->getUniqueID('event');
$this->backend->createCalendarObject($calendarId, $uri0, $calData);
return $uri0;
}
protected function assertAcl($principal, $privilege, $acl) {
foreach($acl as $a) {
if ($a['principal'] === $principal && $a['privilege'] === $privilege) {
$this->assertTrue(true);
return;
}
}
$this->fail("ACL does not contain $principal / $privilege");
}
protected function assertNotAcl($principal, $privilege, $acl) {
foreach($acl as $a) {
if ($a['principal'] === $principal && $a['privilege'] === $privilege) {
$this->fail("ACL contains $principal / $privilege");
return;
}
}
$this->assertTrue(true);
}
protected function assertAccess($shouldHaveAcl, $principal, $privilege, $acl) {
if ($shouldHaveAcl) {
$this->assertAcl($principal, $privilege, $acl);
} else {
$this->assertNotAcl($principal, $privilege, $acl);
}
}
}

View file

@ -26,13 +26,10 @@ use DateTime;
use DateTimeZone;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\Calendar;
use OCA\DAV\Connector\Sabre\Principal;
use OCP\IL10N;
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
use Sabre\DAV\PropPatch;
use Sabre\DAV\Xml\Property\Href;
use Sabre\DAVACL\IACL;
use Test\TestCase;
/**
* Class CalDavBackendTest
@ -41,54 +38,7 @@ use Test\TestCase;
*
* @package OCA\DAV\Tests\unit\CalDAV
*/
class CalDavBackendTest extends TestCase {
/** @var CalDavBackend */
private $backend;
/** @var Principal | \PHPUnit_Framework_MockObject_MockObject */
private $principal;
const UNIT_TEST_USER = 'principals/users/caldav-unit-test';
const UNIT_TEST_USER1 = 'principals/users/caldav-unit-test1';
const UNIT_TEST_GROUP = 'principals/groups/caldav-unit-test-group';
public function setUp() {
parent::setUp();
$this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal')
->disableOriginalConstructor()
->setMethods(['getPrincipalByPath', 'getGroupMembership'])
->getMock();
$this->principal->expects($this->any())->method('getPrincipalByPath')
->willReturn([
'uri' => 'principals/best-friend'
]);
$this->principal->expects($this->any())->method('getGroupMembership')
->withAnyParameters()
->willReturn([self::UNIT_TEST_GROUP]);
$db = \OC::$server->getDatabaseConnection();
$this->backend = new CalDavBackend($db, $this->principal);
$this->tearDown();
}
public function tearDown() {
parent::tearDown();
if (is_null($this->backend)) {
return;
}
$books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
foreach ($books as $book) {
$this->backend->deleteCalendar($book['id']);
}
$subscriptions = $this->backend->getSubscriptionsForUser(self::UNIT_TEST_USER);
foreach ($subscriptions as $subscription) {
$this->backend->deleteSubscription($subscription['id']);
}
}
class CalDavBackendTest extends AbstractCalDavBackendTest {
public function testCalendarOperations() {
@ -232,6 +182,7 @@ EOD;
$calendarObjects = $this->backend->getCalendarObjects($calendarId);
$this->assertEquals(1, count($calendarObjects));
$this->assertEquals($calendarId, $calendarObjects[0]['calendarid']);
$this->assertArrayHasKey('classification', $calendarObjects[0]);
// get the cards
$calendarObject = $this->backend->getCalendarObject($calendarId, $uri);
@ -241,6 +192,7 @@ EOD;
$this->assertArrayHasKey('lastmodified', $calendarObject);
$this->assertArrayHasKey('etag', $calendarObject);
$this->assertArrayHasKey('size', $calendarObject);
$this->assertArrayHasKey('classification', $calendarObject);
$this->assertEquals($calData, $calendarObject['calendardata']);
// update the card
@ -310,6 +262,7 @@ EOD;
$this->assertArrayHasKey('lastmodified', $card);
$this->assertArrayHasKey('etag', $card);
$this->assertArrayHasKey('size', $card);
$this->assertArrayHasKey('classification', $card);
$this->assertEquals($calData, $card['calendardata']);
}
@ -363,49 +316,6 @@ EOD;
];
}
private function createTestCalendar() {
$this->backend->createCalendar(self::UNIT_TEST_USER, 'Example', [
'{http://apple.com/ns/ical/}calendar-color' => '#1C4587FF'
]);
$calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
$this->assertEquals(1, count($calendars));
$this->assertEquals(self::UNIT_TEST_USER, $calendars[0]['principaluri']);
/** @var SupportedCalendarComponentSet $components */
$components = $calendars[0]['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'];
$this->assertEquals(['VEVENT','VTODO'], $components->getValue());
$color = $calendars[0]['{http://apple.com/ns/ical/}calendar-color'];
$this->assertEquals('#1C4587FF', $color);
$this->assertEquals('Example', $calendars[0]['uri']);
$this->assertEquals('Example', $calendars[0]['{DAV:}displayname']);
$calendarId = $calendars[0]['id'];
return $calendarId;
}
private function createEvent($calendarId, $start = '20130912T130000Z', $end = '20130912T140000Z') {
$calData = <<<EOD
BEGIN:VCALENDAR
VERSION:2.0
PRODID:ownCloud Calendar
BEGIN:VEVENT
CREATED;VALUE=DATE-TIME:20130910T125139Z
UID:47d15e3ec8
LAST-MODIFIED;VALUE=DATE-TIME:20130910T125139Z
DTSTAMP;VALUE=DATE-TIME:20130910T125139Z
SUMMARY:Test Event
DTSTART;VALUE=DATE-TIME:$start
DTEND;VALUE=DATE-TIME:$end
CLASS:PUBLIC
END:VEVENT
END:VCALENDAR
EOD;
$uri0 = $this->getUniqueID('event');
$this->backend->createCalendarObject($calendarId, $uri0, $calData);
return $uri0;
}
public function testSyncSupport() {
$calendarId = $this->createTestCalendar();
@ -464,43 +374,20 @@ EOD;
/**
* @dataProvider providesCalDataForGetDenormalizedData
*/
public function testGetDenormalizedData($expectedFirstOccurance, $calData) {
$actual = $this->invokePrivate($this->backend, 'getDenormalizedData', [$calData]);
$this->assertEquals($expectedFirstOccurance, $actual['firstOccurence']);
public function testGetDenormalizedData($expected, $key, $calData) {
$actual = $this->backend->getDenormalizedData($calData);
$this->assertEquals($expected, $actual[$key]);
}
public function providesCalDataForGetDenormalizedData() {
return [
[0, "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nDTSTART;VALUE=DATE:16040222\r\nDTEND;VALUE=DATE:16040223\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
[null, "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"]
'first occurrence before unix epoch starts' => [0, 'firstOccurence', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nDTSTART;VALUE=DATE:16040222\r\nDTEND;VALUE=DATE:16040223\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
'no first occurrence because yearly' => [null, 'firstOccurence', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
'CLASS:PRIVATE' => [CalDavBackend::CLASSIFICATION_PRIVATE, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:PRIVATE\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
'CLASS:PUBLIC' => [CalDavBackend::CLASSIFICATION_PUBLIC, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:PUBLIC\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
'CLASS:CONFIDENTIAL' => [CalDavBackend::CLASSIFICATION_CONFIDENTIAL, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:CONFIDENTIAL\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
'no class set -> public' => [CalDavBackend::CLASSIFICATION_PUBLIC, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nTRANSP:OPAQUE\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
'unknown class -> private' => [CalDavBackend::CLASSIFICATION_PRIVATE, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:VERTRAULICH\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
];
}
private function assertAcl($principal, $privilege, $acl) {
foreach($acl as $a) {
if ($a['principal'] === $principal && $a['privilege'] === $privilege) {
$this->assertTrue(true);
return;
}
}
$this->fail("ACL does not contain $principal / $privilege");
}
private function assertNotAcl($principal, $privilege, $acl) {
foreach($acl as $a) {
if ($a['principal'] === $principal && $a['privilege'] === $privilege) {
$this->fail("ACL contains $principal / $privilege");
return;
}
}
$this->assertTrue(true);
}
private function assertAccess($shouldHaveAcl, $principal, $privilege, $acl) {
if ($shouldHaveAcl) {
$this->assertAcl($principal, $privilege, $acl);
} else {
$this->assertNotAcl($principal, $privilege, $acl);
}
}
}

View file

@ -27,6 +27,7 @@ use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\Calendar;
use OCP\IL10N;
use Sabre\DAV\PropPatch;
use Sabre\VObject\Reader;
use Test\TestCase;
class CalendarTest extends TestCase {
@ -189,4 +190,153 @@ class CalendarTest extends TestCase {
'birthday calendar' => [false, false, false, BirthdayService::BIRTHDAY_CALENDAR_URI]
];
}
/**
* @dataProvider providesConfidentialClassificationData
* @param $expectedChildren
* @param $isShared
*/
public function testPrivateClassification($expectedChildren, $isShared) {
$calObject0 = ['uri' => 'event-0', 'classification' => CalDavBackend::CLASSIFICATION_PUBLIC];
$calObject1 = ['uri' => 'event-1', 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL];
$calObject2 = ['uri' => 'event-2', 'classification' => CalDavBackend::CLASSIFICATION_PRIVATE];
/** @var \PHPUnit_Framework_MockObject_MockObject | CalDavBackend $backend */
$backend = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock();
$backend->expects($this->any())->method('getCalendarObjects')->willReturn([
$calObject0, $calObject1, $calObject2
]);
$backend->expects($this->any())->method('getMultipleCalendarObjects')
->with(666, ['event-0', 'event-1', 'event-2'])
->willReturn([
$calObject0, $calObject1, $calObject2
]);
$backend->expects($this->any())->method('getCalendarObject')
->willReturn($calObject2)->with(666, 'event-2');
$calendarInfo = [
'principaluri' => 'user2',
'id' => 666,
'uri' => 'cal',
];
if ($isShared) {
$calendarInfo['{http://owncloud.org/ns}owner-principal'] = 'user1';
}
$c = new Calendar($backend, $calendarInfo, $this->l10n);
$children = $c->getChildren();
$this->assertEquals($expectedChildren, count($children));
$children = $c->getMultipleChildren(['event-0', 'event-1', 'event-2']);
$this->assertEquals($expectedChildren, count($children));
$this->assertEquals(!$isShared, $c->childExists('event-2'));
}
/**
* @dataProvider providesConfidentialClassificationData
* @param $expectedChildren
* @param $isShared
*/
public function testConfidentialClassification($expectedChildren, $isShared) {
$start = '20160609';
$end = '20160610';
$calData = <<<EOD
BEGIN:VCALENDAR
PRODID:-//ownCloud calendar v1.2.2
BEGIN:VEVENT
CREATED:20160602T133732
DTSTAMP:20160602T133732
LAST-MODIFIED:20160602T133732
UID:wej2z68l9h
SUMMARY:Test Event
LOCATION:Somewhere ...
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CUTYPE=INDIVIDUAL;CN=de
epdiver:MAILTO:thomas.mueller@tmit.eu
ORGANIZER;CN=deepdiver:MAILTO:thomas.mueller@tmit.eu
DESCRIPTION:maybe ....
DTSTART;TZID=Europe/Berlin;VALUE=DATE:$start
DTEND;TZID=Europe/Berlin;VALUE=DATE:$end
RRULE:FREQ=DAILY
BEGIN:VALARM
ACTION:AUDIO
TRIGGER:-PT15M
END:VALARM
END:VEVENT
BEGIN:VTIMEZONE
TZID:Europe/Berlin
BEGIN:DAYLIGHT
DTSTART:19810329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
TZNAME:MESZ
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
END:DAYLIGHT
BEGIN:STANDARD
DTSTART:19961027T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
TZNAME:MEZ
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
END:STANDARD
END:VTIMEZONE
END:VCALENDAR
EOD;
$calObject0 = ['uri' => 'event-0', 'classification' => CalDavBackend::CLASSIFICATION_PUBLIC];
$calObject1 = ['uri' => 'event-1', 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL, 'calendardata' => $calData];
$calObject2 = ['uri' => 'event-2', 'classification' => CalDavBackend::CLASSIFICATION_PRIVATE];
/** @var \PHPUnit_Framework_MockObject_MockObject | CalDavBackend $backend */
$backend = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock();
$backend->expects($this->any())->method('getCalendarObjects')->willReturn([
$calObject0, $calObject1, $calObject2
]);
$backend->expects($this->any())->method('getMultipleCalendarObjects')
->with(666, ['event-0', 'event-1', 'event-2'])
->willReturn([
$calObject0, $calObject1, $calObject2
]);
$backend->expects($this->any())->method('getCalendarObject')
->willReturn($calObject1)->with(666, 'event-1');
$calendarInfo = [
'principaluri' => 'user2',
'id' => 666,
'uri' => 'cal',
];
if ($isShared) {
$calendarInfo['{http://owncloud.org/ns}owner-principal'] = 'user1';
}
$c = new Calendar($backend, $calendarInfo, $this->l10n);
// test private event
$privateEvent = $c->getChild('event-1');
$calData = $privateEvent->get();
$event = Reader::read($calData);
$this->assertEquals($start, $event->VEVENT->DTSTART->getValue());
$this->assertEquals($end, $event->VEVENT->DTEND->getValue());
if ($isShared) {
$this->assertEquals('Busy', $event->VEVENT->SUMMARY->getValue());
$this->assertArrayNotHasKey('ATTENDEE', $event->VEVENT);
$this->assertArrayNotHasKey('LOCATION', $event->VEVENT);
$this->assertArrayNotHasKey('DESCRIPTION', $event->VEVENT);
$this->assertArrayNotHasKey('ORGANIZER', $event->VEVENT);
} else {
$this->assertEquals('Test Event', $event->VEVENT->SUMMARY->getValue());
}
}
public function providesConfidentialClassificationData() {
return [
[3, false],
[2, true]
];
}
}

View file

@ -0,0 +1,75 @@
<?php
/**
* @author Thomas Müller <thomas.mueller@tmit.eu>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\DAV\Tests\unit\DAV\Migration;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\Migration\Classification;
use OCA\DAV\Tests\unit\CalDAV\AbstractCalDavBackendTest;
use OCP\IUser;
/**
* Class ClassificationTest
*
* @group DB
*
* @package OCA\DAV\Tests\unit\DAV
*/
class ClassificationTest extends AbstractCalDavBackendTest {
/** @var \PHPUnit_Framework_MockObject_MockObject | \OCP\IUserManager */
private $userManager;
public function setUp() {
parent::setUp();
$this->userManager = $this->getMockBuilder('OCP\IUserManager')
->disableOriginalConstructor()->getMock();
}
public function test() {
// setup data
$calendarId = $this->createTestCalendar();
$eventUri = $this->createEvent($calendarId, '20130912T130000Z', '20130912T140000Z');
$object = $this->backend->getCalendarObject($calendarId, $eventUri);
// assert proper classification
$this->assertEquals(CalDavBackend::CLASSIFICATION_PUBLIC, $object['classification']);
$this->backend->setClassification($object['id'], CalDavBackend::CLASSIFICATION_CONFIDENTIAL);
$object = $this->backend->getCalendarObject($calendarId, $eventUri);
$this->assertEquals(CalDavBackend::CLASSIFICATION_CONFIDENTIAL, $object['classification']);
// run migration
$c = new Classification($this->backend, $this->userManager);
/** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */
$user = $this->getMockBuilder('OCP\IUser')
->disableOriginalConstructor()
->getMock();
$user->expects($this->once())->method('getUID')->willReturn('caldav-unit-test');
$c->runForUser($user);
// assert classification after migration
$object = $this->backend->getCalendarObject($calendarId, $eventUri);
$this->assertEquals(CalDavBackend::CLASSIFICATION_PUBLIC, $object['classification']);
}
}

View file

@ -39,8 +39,9 @@ interface IRepairStep {
* Run repair step.
* Must throw exception on error.
*
* @since 9.1.0
* @param IOutput $output
* @throws \Exception in case of failure
* @since 9.1.0
*/
public function run(IOutput $output);