diff options
author | Thomas Müller <thomas.mueller@tmit.eu> | 2016-01-25 17:18:47 +0100 |
---|---|---|
committer | Thomas Müller <thomas.mueller@tmit.eu> | 2016-02-09 11:20:31 +0100 |
commit | bf3a843e892e39e6c4d12b632da31d5718bc45c7 (patch) | |
tree | 7e65e9cd5baf4b46c2f10cce1be4f2cc7ab5b668 /apps/dav | |
parent | 254e0fa71a31d0ee77136ba0fee95fe7b136a4a0 (diff) | |
download | nextcloud-server-bf3a843e892e39e6c4d12b632da31d5718bc45c7.tar.gz nextcloud-server-bf3a843e892e39e6c4d12b632da31d5718bc45c7.zip |
Migration of calendars
Diffstat (limited to 'apps/dav')
-rw-r--r-- | apps/dav/appinfo/application.php | 42 | ||||
-rw-r--r-- | apps/dav/appinfo/install.php | 1 | ||||
-rw-r--r-- | apps/dav/appinfo/register_command.php | 3 | ||||
-rw-r--r-- | apps/dav/command/migrateaddressbooks.php | 1 | ||||
-rw-r--r-- | apps/dav/command/migratecalendars.php | 66 | ||||
-rw-r--r-- | apps/dav/lib/caldav/caldavbackend.php | 124 | ||||
-rw-r--r-- | apps/dav/lib/migration/calendaradapter.php | 83 | ||||
-rw-r--r-- | apps/dav/lib/migration/migratecalendars.php | 94 | ||||
-rw-r--r-- | apps/dav/tests/unit/migration/calendar_schema.xml | 191 | ||||
-rw-r--r-- | apps/dav/tests/unit/migration/calendaradaptertest.php | 131 | ||||
-rw-r--r-- | apps/dav/tests/unit/migration/migratecalendartest.php | 76 |
11 files changed, 801 insertions, 11 deletions
diff --git a/apps/dav/appinfo/application.php b/apps/dav/appinfo/application.php index 07905db7368..11ab384d75d 100644 --- a/apps/dav/appinfo/application.php +++ b/apps/dav/appinfo/application.php @@ -20,12 +20,16 @@ */ namespace OCA\Dav\AppInfo; +use OCA\DAV\CalDAV\CalDavBackend; +use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\CardDAV\ContactsManager; use OCA\DAV\CardDAV\SyncJob; use OCA\DAV\CardDAV\SyncService; use OCA\DAV\HookManager; use OCA\Dav\Migration\AddressBookAdapter; +use OCA\Dav\Migration\CalendarAdapter; use OCA\Dav\Migration\MigrateAddressbooks; +use OCA\Dav\Migration\MigrateCalendars; use \OCP\AppFramework\App; use OCP\AppFramework\IAppContainer; use OCP\Contacts\IManager; @@ -73,7 +77,17 @@ class Application extends App { $c->getServer()->getUserManager(), $c->getServer()->getGroupManager() ); - return new \OCA\DAV\CardDAV\CardDavBackend($db, $principal, $logger); + return new CardDavBackend($db, $principal, $logger); + }); + + $container->registerService('CalDavBackend', function($c) { + /** @var IAppContainer $c */ + $db = $c->getServer()->getDatabaseConnection(); + $principal = new \OCA\DAV\Connector\Sabre\Principal( + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager() + ); + return new CalDavBackend($db, $principal); }); $container->registerService('MigrateAddressbooks', function($c) { @@ -84,6 +98,15 @@ class Application extends App { $c->query('CardDavBackend') ); }); + + $container->registerService('MigrateCalendars', function($c) { + /** @var IAppContainer $c */ + $db = $c->getServer()->getDatabaseConnection(); + return new MigrateCalendars( + new CalendarAdapter($db), + $c->query('CalDavBackend') + ); + }); } /** @@ -112,8 +135,8 @@ class Application extends App { } public function migrateAddressbooks() { - try { + /** @var MigrateAddressbooks $migration */ $migration = $this->getContainer()->query('MigrateAddressbooks'); $migration->setup(); $userManager = $this->getContainer()->getServer()->getUserManager(); @@ -127,4 +150,19 @@ class Application extends App { } } + public function migrateCalendars() { + try { + /** @var MigrateCalendars $migration */ + $migration = $this->getContainer()->query('MigrateCalendars'); + $migration->setup(); + $userManager = $this->getContainer()->getServer()->getUserManager(); + + $userManager->callForAllUsers(function($user) use($migration) { + /** @var IUser $user */ + $migration->migrateForUser($user->getUID()); + }); + } catch (\Exception $ex) { + $this->getContainer()->getServer()->getLogger()->logException($ex); + } + } } diff --git a/apps/dav/appinfo/install.php b/apps/dav/appinfo/install.php index f6ef533958e..a7a3220b90f 100644 --- a/apps/dav/appinfo/install.php +++ b/apps/dav/appinfo/install.php @@ -24,3 +24,4 @@ use OCA\Dav\AppInfo\Application; $app = new Application(); $app->setupCron(); $app->migrateAddressbooks(); +$app->migrateCalendars(); diff --git a/apps/dav/appinfo/register_command.php b/apps/dav/appinfo/register_command.php index e8ca370f84f..4981cab9264 100644 --- a/apps/dav/appinfo/register_command.php +++ b/apps/dav/appinfo/register_command.php @@ -23,6 +23,7 @@ use OCA\Dav\AppInfo\Application; use OCA\DAV\Command\CreateAddressBook; use OCA\DAV\Command\CreateCalendar; use OCA\Dav\Command\MigrateAddressbooks; +use OCA\Dav\Command\MigrateCalendars; use OCA\DAV\Command\SyncSystemAddressBook; $config = \OC::$server->getConfig(); @@ -44,4 +45,6 @@ if ($config->getSystemValue('debug', false)){ $app = new \OCA\Dav\AppInfo\Application(); $migration = $app->getContainer()->query('MigrateAddressbooks'); $application->add(new MigrateAddressbooks($userManager, $migration)); + $migration = $app->getContainer()->query('MigrateCalendars'); + $application->add(new MigrateCalendars($userManager, $migration)); } diff --git a/apps/dav/command/migrateaddressbooks.php b/apps/dav/command/migrateaddressbooks.php index 2ab7113ab1f..f37c29e7ab3 100644 --- a/apps/dav/command/migrateaddressbooks.php +++ b/apps/dav/command/migrateaddressbooks.php @@ -68,6 +68,7 @@ class MigrateAddressbooks extends Command { } $output->writeln("Start migration for $user"); $this->service->migrateForUser($user); + return; } $output->writeln("Start migration of all known users ..."); $p = new ProgressBar($output); diff --git a/apps/dav/command/migratecalendars.php b/apps/dav/command/migratecalendars.php new file mode 100644 index 00000000000..eda4f5fb417 --- /dev/null +++ b/apps/dav/command/migratecalendars.php @@ -0,0 +1,66 @@ +<?php + +namespace OCA\Dav\Command; + +use OCP\IUser; +use OCP\IUserManager; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\ProgressBar; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class MigrateCalendars extends Command { + + /** @var IUserManager */ + protected $userManager; + + /** @var \OCA\Dav\Migration\MigrateCalendars */ + private $service; + + /** + * @param IUserManager $userManager + * @param \OCA\Dav\Migration\MigrateCalendars $service + */ + function __construct(IUserManager $userManager, + \OCA\Dav\Migration\MigrateCalendars $service + ) { + parent::__construct(); + $this->userManager = $userManager; + $this->service = $service; + } + + protected function configure() { + $this + ->setName('dav:migrate-calendars') + ->setDescription('Migrate calendars from the calendar app to core') + ->addArgument('user', + InputArgument::OPTIONAL, + 'User for whom all calendars will be migrated'); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + $this->service->setup(); + + if ($input->hasArgument('user')) { + $user = $input->getArgument('user'); + if (!$this->userManager->userExists($user)) { + throw new \InvalidArgumentException("User <$user> in unknown."); + } + $output->writeln("Start migration for $user"); + $this->service->migrateForUser($user); + return; + } + $output->writeln("Start migration of all known users ..."); + $p = new ProgressBar($output); + $p->start(); + $this->userManager->callForAllUsers(function($user) use ($p) { + $p->advance(); + /** @var IUser $user */ + $this->service->migrateForUser($user->getUID()); + }); + + $p->finish(); + $output->writeln(''); + } +} diff --git a/apps/dav/lib/caldav/caldavbackend.php b/apps/dav/lib/caldav/caldavbackend.php index 52b4812b05b..775612487f9 100644 --- a/apps/dav/lib/caldav/caldavbackend.php +++ b/apps/dav/lib/caldav/caldavbackend.php @@ -22,9 +22,11 @@ namespace OCA\DAV\CalDAV; +use OCA\DAV\DAV\Sharing\IShareable; use OCP\DB\QueryBuilder\IQueryBuilder; use OCA\DAV\Connector\Sabre\Principal; use OCA\DAV\DAV\Sharing\Backend; +use OCP\IDBConnection; use Sabre\CalDAV\Backend\AbstractBackend; use Sabre\CalDAV\Backend\SchedulingSupport; use Sabre\CalDAV\Backend\SubscriptionSupport; @@ -59,7 +61,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription const MAX_DATE = '2038-01-01'; /** - * List of CalDAV properties, and how they map to database fieldnames + * List of CalDAV properties, and how they map to database field names * Add your own properties by simply adding on to this array. * * Note that only string-based properties are supported here. @@ -75,7 +77,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription ]; /** - * List of subscription properties, and how they map to database fieldnames. + * List of subscription properties, and how they map to database field names. * * @var array */ @@ -89,7 +91,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription '{http://calendarserver.org/ns/}subscribed-strip-attachments' => 'stripattachments', ]; - /** @var \OCP\IDBConnection */ + /** @var IDBConnection */ private $db; /** @var Backend */ @@ -101,9 +103,10 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription /** * CalDavBackend constructor. * - * @param \OCP\IDBConnection $db + * @param IDBConnection $db + * @param Principal $principalBackend */ - public function __construct(\OCP\IDBConnection $db, Principal $principalBackend) { + public function __construct(IDBConnection $db, Principal $principalBackend) { $this->db = $db; $this->principalBackend = $principalBackend; $this->sharingBackend = new Backend($this->db, $principalBackend, 'calendar'); @@ -232,6 +235,95 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription return array_values($calendars); } + public function getCalendarByUri($principal, $uri) { + $fields = array_values($this->propertyMap); + $fields[] = 'id'; + $fields[] = 'uri'; + $fields[] = 'synctoken'; + $fields[] = 'components'; + $fields[] = 'principaluri'; + $fields[] = 'transparent'; + + // Making fields a comma-delimited list + $query = $this->db->getQueryBuilder(); + $query->select($fields)->from('calendars') + ->where($query->expr()->eq('uri', $query->createNamedParameter($uri))) + ->andWhere($query->expr()->eq('principaluri', $query->createNamedParameter($principal))) + ->setMaxResults(1); + $stmt = $query->execute(); + + $row = $stmt->fetch(\PDO::FETCH_ASSOC); + $stmt->closeCursor(); + if ($row === false) { + return null; + } + + $components = []; + if ($row['components']) { + $components = explode(',',$row['components']); + } + + $calendar = [ + 'id' => $row['id'], + 'uri' => $row['uri'], + 'principaluri' => $row['principaluri'], + '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'), + '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', + '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components), + '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), + ]; + + foreach($this->propertyMap as $xmlName=>$dbName) { + $calendar[$xmlName] = $row[$dbName]; + } + + return $calendar; + } + + public function getCalendarById($calendarId) { + $fields = array_values($this->propertyMap); + $fields[] = 'id'; + $fields[] = 'uri'; + $fields[] = 'synctoken'; + $fields[] = 'components'; + $fields[] = 'principaluri'; + $fields[] = 'transparent'; + + // Making fields a comma-delimited list + $query = $this->db->getQueryBuilder(); + $query->select($fields)->from('calendars') + ->where($query->expr()->eq('id', $query->createNamedParameter($calendarId))) + ->setMaxResults(1); + $stmt = $query->execute(); + + $row = $stmt->fetch(\PDO::FETCH_ASSOC); + $stmt->closeCursor(); + if ($row === false) { + return null; + } + + $components = []; + if ($row['components']) { + $components = explode(',',$row['components']); + } + + $calendar = [ + 'id' => $row['id'], + 'uri' => $row['uri'], + 'principaluri' => $row['principaluri'], + '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'), + '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', + '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components), + '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), + ]; + + foreach($this->propertyMap as $xmlName=>$dbName) { + $calendar[$xmlName] = $row[$dbName]; + } + + return $calendar; + } + /** * Creates a new calendar for a principal. * @@ -241,7 +333,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * @param string $principalUri * @param string $calendarUri * @param array $properties - * @return void + * @return int */ function createCalendar($principalUri, $calendarUri, array $properties) { $values = [ @@ -278,6 +370,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $query->setValue($column, $query->createNamedParameter($value)); } $query->execute(); + return $query->getLastInsertId(); } /** @@ -1249,16 +1342,29 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription return $cardData; } + /** + * @param IShareable $shareable + * @param array $add + * @param array $remove + */ public function updateShares($shareable, $add, $remove) { $this->sharingBackend->updateShares($shareable, $add, $remove); } + /** + * @param int $resourceId + * @return array + */ public function getShares($resourceId) { return $this->sharingBackend->getShares($resourceId); } - public function applyShareAcl($addressBookId, $acl) { - return $this->sharingBackend->applyShareAcl($addressBookId, $acl); + /** + * @param int $resourceId + * @param array $acl + * @return array + */ + public function applyShareAcl($resourceId, $acl) { + return $this->sharingBackend->applyShareAcl($resourceId, $acl); } - } diff --git a/apps/dav/lib/migration/calendaradapter.php b/apps/dav/lib/migration/calendaradapter.php new file mode 100644 index 00000000000..39faf2cec37 --- /dev/null +++ b/apps/dav/lib/migration/calendaradapter.php @@ -0,0 +1,83 @@ +<?php + +namespace OCA\Dav\Migration; + +use OCP\IDBConnection; + +class CalendarAdapter { + + /** @var \OCP\IDBConnection */ + protected $dbConnection; + + /** @var string */ + private $sourceCalendarTable; + + /** @var string */ + private $sourceCalObjTable; + + /** + * @param IDBConnection $dbConnection + * @param string $sourceCalendarTable + * @param string $sourceCalObjTable + */ + function __construct(IDBConnection $dbConnection, + $sourceCalendarTable = 'clndr_calendars', + $sourceCalObjTable = 'clndr_objects') { + $this->dbConnection = $dbConnection; + $this->sourceCalendarTable = $sourceCalendarTable; + $this->sourceCalObjTable = $sourceCalObjTable; + } + + /** + * @param string $user + * @param \Closure $callBack + */ + public function foreachCalendar($user, \Closure $callBack) { + // get all calendars of that user + $query = $this->dbConnection->getQueryBuilder(); + $stmt = $query->select('*')->from($this->sourceCalendarTable) + ->where($query->expr()->eq('userid', $query->createNamedParameter($user))) + ->execute(); + + while($row = $stmt->fetch()) { + $callBack($row); + } + } + + public function setup() { + if (!$this->dbConnection->tableExists($this->sourceCalendarTable)) { + throw new \DomainException('Calendar tables are missing. Nothing to do.'); + } + } + + /** + * @param int $calendarId + * @param \Closure $callBack + */ + public function foreachCalendarObject($calendarId, \Closure $callBack) { + $query = $this->dbConnection->getQueryBuilder(); + $stmt = $query->select('*')->from($this->sourceCalObjTable) + ->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId))) + ->execute(); + + while($row = $stmt->fetch()) { + $callBack($row); + } + } + + /** + * @param int $addressBookId + * @return array + */ + public function getShares($addressBookId) { + $query = $this->dbConnection->getQueryBuilder(); + $shares = $query->select('*')->from('share') + ->where($query->expr()->eq('item_source', $query->createNamedParameter($addressBookId))) + ->andWhere($query->expr()->eq('item_type', $query->expr()->literal('calendar'))) + ->andWhere($query->expr()->in('share_type', [ $query->expr()->literal(0), $query->expr()->literal(1)])) + ->execute() + ->fetchAll(); + + return $shares; + } +} diff --git a/apps/dav/lib/migration/migratecalendars.php b/apps/dav/lib/migration/migratecalendars.php new file mode 100644 index 00000000000..33f8a105180 --- /dev/null +++ b/apps/dav/lib/migration/migratecalendars.php @@ -0,0 +1,94 @@ +<?php + +namespace OCA\Dav\Migration; + +use OCA\DAV\CalDAV\CalDavBackend; +use OCA\DAV\CalDAV\Calendar; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class MigrateCalendars { + + /** @var CalendarAdapter */ + protected $adapter; + + /** @var CalDavBackend */ + private $backend; + + /** + * @param CalendarAdapter $adapter + * @param CalDavBackend $backend + */ + function __construct(CalendarAdapter $adapter, + CalDavBackend $backend + ) { + $this->adapter = $adapter; + $this->backend = $backend; + } + + /** + * @param string $user + */ + public function migrateForUser($user) { + + $this->adapter->foreachCalendar($user, function($calendar) use ($user) { + $principal = "principals/users/$user"; + $calendarByUri = $this->backend->getCalendarByUri($principal, $calendar['uri']); + if (!is_null($calendarByUri)) { + return; + } + + $newId = $this->backend->createCalendar($principal, $calendar['uri'], [ + '{DAV:}displayname' => $calendar['displayname'], + '{urn:ietf:params:xml:ns:caldav}calendar-description' => $calendar['displayname'], + '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => $calendar['timezone'], + '{http://apple.com/ns/ical/}calendar-order' => $calendar['calendarorder'], + '{http://apple.com/ns/ical/}calendar-color' => $calendar['calendarcolor'], + ]); + + $this->migrateCalendar($calendar['id'], $newId); + $this->migrateShares($calendar['id'], $newId); + }); + } + + public function setup() { + $this->adapter->setup(); + } + + /** + * @param int $calendarId + * @param int $newCalendarId + */ + private function migrateCalendar($calendarId, $newCalendarId) { + $this->adapter->foreachCalendarObject($calendarId, function($calObject) use ($newCalendarId) { + $this->backend->createCalendarObject($newCalendarId, $calObject['uri'], $calObject['calendardata']); + }); + } + + /** + * @param int $calendarId + * @param int $newCalendarId + */ + private function migrateShares($calendarId, $newCalendarId) { + $shares =$this->adapter->getShares($calendarId); + if (empty($shares)) { + return; + } + + $add = array_map(function($s) { + $prefix = 'principal:principals/users/'; + if ($s['share_type'] === 1) { + $prefix = 'principal:principals/groups/'; + } + return [ + 'href' => $prefix . $s['share_with'] + ]; + }, $shares); + + $newCalendar = $this->backend->getCalendarById($newCalendarId); + $calendar = new Calendar($this->backend, $newCalendar); + $this->backend->updateShares($calendar, $add, []); + } +} diff --git a/apps/dav/tests/unit/migration/calendar_schema.xml b/apps/dav/tests/unit/migration/calendar_schema.xml new file mode 100644 index 00000000000..6c88b596a3f --- /dev/null +++ b/apps/dav/tests/unit/migration/calendar_schema.xml @@ -0,0 +1,191 @@ +<?xml version="1.0" encoding="ISO-8859-1" ?> +<database> + + <name>*dbname*</name> + <create>true</create> + <overwrite>false</overwrite> + + <charset>utf8</charset> + + <table> + + <name>*dbprefix*clndr_objects</name> + + <declaration> + + <field> + <name>id</name> + <type>integer</type> + <default>0</default> + <notnull>true</notnull> + <autoincrement>1</autoincrement> + <unsigned>true</unsigned> + <length>4</length> + </field> + + <field> + <name>calendarid</name> + <type>integer</type> + <default></default> + <notnull>true</notnull> + <unsigned>true</unsigned> + <length>4</length> + </field> + + <field> + <name>objecttype</name> + <type>text</type> + <default></default> + <notnull>true</notnull> + <length>40</length> + </field> + + <field> + <name>startdate</name> + <type>timestamp</type> + <default>1970-01-01 00:00:00</default> + <notnull>false</notnull> + </field> + + <field> + <name>enddate</name> + <type>timestamp</type> + <default>1970-01-01 00:00:00</default> + <notnull>false</notnull> + </field> + + <field> + <name>repeating</name> + <type>integer</type> + <default></default> + <notnull>false</notnull> + <length>4</length> + </field> + + <field> + <name>summary</name> + <type>text</type> + <default></default> + <notnull>false</notnull> + <length>255</length> + </field> + + <field> + <name>calendardata</name> + <type>clob</type> + <notnull>false</notnull> + </field> + + <field> + <name>uri</name> + <type>text</type> + <default></default> + <notnull>false</notnull> + <length>255</length> + </field> + + <field> + <name>lastmodified</name> + <type>integer</type> + <default></default> + <notnull>false</notnull> + <length>4</length> + </field> + + </declaration> + + </table> + + <table> + + <name>*dbprefix*clndr_calendars</name> + + <declaration> + + <field> + <name>id</name> + <type>integer</type> + <default>0</default> + <notnull>true</notnull> + <autoincrement>1</autoincrement> + <unsigned>true</unsigned> + <length>4</length> + </field> + + <field> + <name>userid</name> + <type>text</type> + <default></default> + <notnull>false</notnull> + <length>255</length> + </field> + + <field> + <name>displayname</name> + <type>text</type> + <default></default> + <notnull>false</notnull> + <length>100</length> + </field> + + <field> + <name>uri</name> + <type>text</type> + <default></default> + <notnull>false</notnull> + <length>255</length> + </field> + + <field> + <name>active</name> + <type>integer</type> + <default>1</default> + <notnull>true</notnull> + <length>4</length> + </field> + + <field> + <name>ctag</name> + <type>integer</type> + <default>0</default> + <notnull>true</notnull> + <unsigned>true</unsigned> + <length>4</length> + </field> + + <field> + <name>calendarorder</name> + <type>integer</type> + <default>0</default> + <notnull>true</notnull> + <unsigned>true</unsigned> + <length>4</length> + </field> + + <field> + <name>calendarcolor</name> + <type>text</type> + <default></default> + <notnull>false</notnull> + <length>10</length> + </field> + + <field> + <name>timezone</name> + <type>clob</type> + <notnull>false</notnull> + </field> + + <field> + <name>components</name> + <type>text</type> + <default></default> + <notnull>false</notnull> + <length>100</length> + </field> + + </declaration> + + </table> + +</database> diff --git a/apps/dav/tests/unit/migration/calendaradaptertest.php b/apps/dav/tests/unit/migration/calendaradaptertest.php new file mode 100644 index 00000000000..f92774ef6ad --- /dev/null +++ b/apps/dav/tests/unit/migration/calendaradaptertest.php @@ -0,0 +1,131 @@ +<?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\Migration; + +use DomainException; +use OCA\Dav\Migration\AddressBookAdapter; +use OCA\Dav\Migration\CalendarAdapter; +use OCP\IDBConnection; +use Test\TestCase; + +/** + * Class CalendarAdapterTest + * + * @group DB + * + * @package OCA\DAV\Tests\Unit\Migration + */ +class CalendarAdapterTest extends TestCase { + + /** @var IDBConnection */ + private $db; + /** @var CalendarAdapter */ + private $adapter; + /** @var array */ + private $cals = []; + /** @var array */ + private $calObjs = []; + + public function setUp() { + parent::setUp(); + $this->db = \OC::$server->getDatabaseConnection(); + + $manager = new \OC\DB\MDB2SchemaManager($this->db); + $manager->createDbFromStructure(__DIR__ . '/calendar_schema.xml'); + + $this->adapter = new CalendarAdapter($this->db); + } + + public function tearDown() { + $this->db->dropTable('clndr_calendars'); + $this->db->dropTable('clndr_objects'); + parent::tearDown(); + } + + /** + * @expectedException DomainException + */ + public function testOldTablesDoNotExist() { + $adapter = new AddressBookAdapter(\OC::$server->getDatabaseConnection(), 'crazy_table_that_does_no_exist'); + $adapter->setup(); + } + + public function test() { + + // insert test data + $builder = $this->db->getQueryBuilder(); + $builder->insert('clndr_calendars') + ->values([ + 'userid' => $builder->createNamedParameter('test-user-666'), + 'displayname' => $builder->createNamedParameter('Display Name'), + 'uri' => $builder->createNamedParameter('events'), + 'ctag' => $builder->createNamedParameter('112233'), + 'active' => $builder->createNamedParameter('1') + ]) + ->execute(); + $builder = $this->db->getQueryBuilder(); + $builder->insert('clndr_objects') + ->values([ + 'calendarid' => $builder->createNamedParameter(6666), + 'objecttype' => $builder->createNamedParameter('VEVENT'), + 'startdate' => $builder->createNamedParameter(new \DateTime(), 'datetime'), + 'enddate' => $builder->createNamedParameter(new \DateTime(), 'datetime'), + 'repeating' => $builder->createNamedParameter(0), + 'summary' => $builder->createNamedParameter('Something crazy will happen'), + 'uri' => $builder->createNamedParameter('event.ics'), + 'lastmodified' => $builder->createNamedParameter('112233'), + ]) + ->execute(); + $builder = $this->db->getQueryBuilder(); + $builder->insert('share') + ->values([ + 'share_type' => $builder->createNamedParameter(1), + 'share_with' => $builder->createNamedParameter('user01'), + 'uid_owner' => $builder->createNamedParameter('user02'), + 'item_type' => $builder->createNamedParameter('calendar'), + 'item_source' => $builder->createNamedParameter(6666), + 'item_target' => $builder->createNamedParameter('Contacts (user02)'), + ]) + ->execute(); + + // test the adapter + $this->adapter->foreachCalendar('test-user-666', function($row) { + $this->cals[] = $row; + }); + $this->assertArrayHasKey('id', $this->cals[0]); + $this->assertEquals('test-user-666', $this->cals[0]['userid']); + $this->assertEquals('Display Name', $this->cals[0]['displayname']); + $this->assertEquals('events', $this->cals[0]['uri']); + $this->assertEquals('112233', $this->cals[0]['ctag']); + + $this->adapter->foreachCalendarObject(6666, function($row) { + $this->calObjs[]= $row; + }); + $this->assertArrayHasKey('id', $this->calObjs[0]); + $this->assertEquals(6666, $this->calObjs[0]['calendarid']); + + // test getShares + $shares = $this->adapter->getShares(6666); + $this->assertEquals(1, count($shares)); + + } + +} diff --git a/apps/dav/tests/unit/migration/migratecalendartest.php b/apps/dav/tests/unit/migration/migratecalendartest.php new file mode 100644 index 00000000000..1058773ffff --- /dev/null +++ b/apps/dav/tests/unit/migration/migratecalendartest.php @@ -0,0 +1,76 @@ +<?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\Migration; + +use OCA\DAV\CalDAV\CalDavBackend; +use OCA\Dav\Migration\CalendarAdapter; +use Test\TestCase; + +class MigrateCalendarTest extends TestCase { + + public function testMigration() { + /** @var CalendarAdapter | \PHPUnit_Framework_MockObject_MockObject $adapter */ + $adapter = $this->mockAdapter(); + + /** @var CalDavBackend | \PHPUnit_Framework_MockObject_MockObject $cardDav */ + $cardDav = $this->getMockBuilder('\OCA\Dav\CalDAV\CalDAVBackend')->disableOriginalConstructor()->getMock(); + $cardDav->method('createCalendar')->willReturn(666); + $cardDav->expects($this->once())->method('createCalendar')->with('principals/users/test01', 'test_contacts'); + $cardDav->expects($this->once())->method('createCalendarObject')->with(666, '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.ics', 'BEGIN:VCARD'); + + $m = new \OCA\Dav\Migration\MigrateCalendars($adapter, $cardDav); + $m->migrateForUser('test01'); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function mockAdapter($shares = []) { + $adapter = $this->getMockBuilder('\OCA\Dav\Migration\CalendarAdapter') + ->disableOriginalConstructor() + ->getMock(); + $adapter->method('foreachCalendar')->willReturnCallback(function ($user, \Closure $callBack) { + $callBack([ + // calendarorder | calendarcolor | timezone | components + 'id' => 0, + 'userid' => $user, + 'displayname' => 'Test Contacts', + 'uri' => 'test_contacts', + 'ctag' => 1234567890, + 'active' => 1, + 'calendarorder' => '0', + 'calendarcolor' => '#b3dc6c', + 'timezone' => null, + 'components' => 'VEVENT,VTODO,VJOURNAL' + ]); + }); + $adapter->method('foreachCalendarObject')->willReturnCallback(function ($addressBookId, \Closure $callBack) { + $callBack([ + 'userid' => $addressBookId, + 'uri' => '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.ics', + 'calendardata' => 'BEGIN:VCARD' + ]); + }); + $adapter->method('getShares')->willReturn($shares); + return $adapter; + } + +} |