diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml index 0024e41e75..f362c882f9 100644 --- a/apps/dav/appinfo/info.xml +++ b/apps/dav/appinfo/info.xml @@ -31,4 +31,23 @@ OCA\DAV\Command\SyncBirthdayCalendar OCA\DAV\Command\SyncSystemAddressBook + + + + OCA\DAV\CalDAV\Activity\Filter\Calendar + OCA\DAV\CalDAV\Activity\Filter\Todo + + + + OCA\DAV\CalDAV\Activity\Setting\Calendar + OCA\DAV\CalDAV\Activity\Setting\Event + OCA\DAV\CalDAV\Activity\Setting\Todo + + + + OCA\DAV\CalDAV\Activity\Provider\Calendar + OCA\DAV\CalDAV\Activity\Provider\Event + OCA\DAV\CalDAV\Activity\Provider\Todo + + diff --git a/apps/dav/lib/AppInfo/Application.php b/apps/dav/lib/AppInfo/Application.php index 7c32fda8f5..669c52d148 100644 --- a/apps/dav/lib/AppInfo/Application.php +++ b/apps/dav/lib/AppInfo/Application.php @@ -26,6 +26,7 @@ namespace OCA\DAV\AppInfo; use OCA\DAV\CalDAV\Activity\Backend; use OCA\DAV\CalDAV\Activity\Extension; +use OCA\DAV\CalDAV\Activity\Provider\Event; use OCA\DAV\CalDAV\BirthdayService; use OCA\DAV\Capabilities; use OCA\DAV\CardDAV\ContactsManager; @@ -146,11 +147,11 @@ class Application extends App { /** @var Backend $backend */ $backend = $this->getContainer()->query(Backend::class); - $subject = Extension::SUBJECT_OBJECT_ADD; + $subject = Event::SUBJECT_OBJECT_ADD; if ($eventName === '\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject') { - $subject = Extension::SUBJECT_OBJECT_UPDATE; + $subject = Event::SUBJECT_OBJECT_UPDATE; } else if ($eventName === '\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject') { - $subject = Extension::SUBJECT_OBJECT_DELETE; + $subject = Event::SUBJECT_OBJECT_DELETE; } $backend->onTouchCalendarObject( $subject, @@ -162,11 +163,6 @@ class Application extends App { $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject', $listener); $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject', $listener); $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject', $listener); - - $aM = $this->getContainer()->getServer()->getActivityManager(); - $aM->registerExtension(function() { - return $this->getContainer()->query(Extension::class); - }); } public function getSyncService() { diff --git a/apps/dav/lib/CalDAV/Activity/Backend.php b/apps/dav/lib/CalDAV/Activity/Backend.php index 6a557fef7b..953fdcea83 100644 --- a/apps/dav/lib/CalDAV/Activity/Backend.php +++ b/apps/dav/lib/CalDAV/Activity/Backend.php @@ -22,6 +22,8 @@ namespace OCA\DAV\CalDAV\Activity; +use OCA\DAV\CalDAV\Activity\Provider\Calendar; +use OCA\DAV\CalDAV\Activity\Provider\Event; use OCP\Activity\IEvent; use OCP\Activity\IManager as IActivityManager; use OCP\IGroup; @@ -63,7 +65,7 @@ class Backend { * @param array $calendarData */ public function onCalendarAdd(array $calendarData) { - $this->triggerCalendarActivity(Extension::SUBJECT_ADD, $calendarData); + $this->triggerCalendarActivity(Calendar::SUBJECT_ADD, $calendarData); } /** @@ -74,7 +76,7 @@ class Backend { * @param array $properties */ public function onCalendarUpdate(array $calendarData, array $shares, array $properties) { - $this->triggerCalendarActivity(Extension::SUBJECT_UPDATE, $calendarData, $shares, $properties); + $this->triggerCalendarActivity(Calendar::SUBJECT_UPDATE, $calendarData, $shares, $properties); } /** @@ -84,7 +86,7 @@ class Backend { * @param array $shares */ public function onCalendarDelete(array $calendarData, array $shares) { - $this->triggerCalendarActivity(Extension::SUBJECT_DELETE, $calendarData, $shares); + $this->triggerCalendarActivity(Calendar::SUBJECT_DELETE, $calendarData, $shares); } /** @@ -112,8 +114,8 @@ class Backend { $event = $this->activityManager->generateEvent(); $event->setApp('dav') - ->setObject(Extension::CALENDAR, (int) $calendarData['id']) - ->setType(Extension::CALENDAR) + ->setObject('calendar', (int) $calendarData['id']) + ->setType('calendar') ->setAuthor($currentUser); $changedVisibleInformation = array_intersect([ @@ -121,7 +123,7 @@ class Backend { '{http://apple.com/ns/ical/}calendar-color' ], array_keys($changedProperties)); - if (empty($shares) || ($action === Extension::SUBJECT_UPDATE && empty($changedVisibleInformation))) { + if (empty($shares) || ($action === Calendar::SUBJECT_UPDATE && empty($changedVisibleInformation))) { $users = [$owner]; } else { $users = $this->getUsersForShares($shares); @@ -162,8 +164,8 @@ class Backend { $event = $this->activityManager->generateEvent(); $event->setApp('dav') - ->setObject(Extension::CALENDAR, (int) $calendarData['id']) - ->setType(Extension::CALENDAR) + ->setObject('calendar', (int) $calendarData['id']) + ->setType('calendar') ->setAuthor($currentUser); foreach ($remove as $principal) { @@ -179,8 +181,8 @@ class Backend { $principal[2], $event, $calendarData, - Extension::SUBJECT_UNSHARE_USER, - Extension::SUBJECT_DELETE . '_self' + Calendar::SUBJECT_UNSHARE_USER, + Calendar::SUBJECT_DELETE . '_self' ); if ($owner !== $principal[2]) { @@ -190,15 +192,15 @@ class Backend { ]; if ($owner === $event->getAuthor()) { - $subject = Extension::SUBJECT_UNSHARE_USER . '_you'; + $subject = Calendar::SUBJECT_UNSHARE_USER . '_you'; } else if ($principal[2] === $event->getAuthor()) { - $subject = Extension::SUBJECT_UNSHARE_USER . '_self'; + $subject = Calendar::SUBJECT_UNSHARE_USER . '_self'; } else { $event->setAffectedUser($event->getAuthor()) - ->setSubject(Extension::SUBJECT_UNSHARE_USER . '_you', $parameters); + ->setSubject(Calendar::SUBJECT_UNSHARE_USER . '_you', $parameters); $this->activityManager->publish($event); - $subject = Extension::SUBJECT_UNSHARE_USER . '_by'; + $subject = Calendar::SUBJECT_UNSHARE_USER . '_by'; $parameters[] = $event->getAuthor(); } @@ -207,7 +209,7 @@ class Backend { $this->activityManager->publish($event); } } else if ($principal[1] === 'groups') { - $this->triggerActivityGroup($principal[2], $event, $calendarData, Extension::SUBJECT_UNSHARE_USER); + $this->triggerActivityGroup($principal[2], $event, $calendarData, Calendar::SUBJECT_UNSHARE_USER); $parameters = [ $principal[2], @@ -215,13 +217,13 @@ class Backend { ]; if ($owner === $event->getAuthor()) { - $subject = Extension::SUBJECT_UNSHARE_GROUP . '_you'; + $subject = Calendar::SUBJECT_UNSHARE_GROUP . '_you'; } else { $event->setAffectedUser($event->getAuthor()) - ->setSubject(Extension::SUBJECT_UNSHARE_GROUP . '_you', $parameters); + ->setSubject(Calendar::SUBJECT_UNSHARE_GROUP . '_you', $parameters); $this->activityManager->publish($event); - $subject = Extension::SUBJECT_UNSHARE_GROUP . '_by'; + $subject = Calendar::SUBJECT_UNSHARE_GROUP . '_by'; $parameters[] = $event->getAuthor(); } @@ -244,7 +246,7 @@ class Backend { $principal = explode('/', $parts[1]); if ($principal[1] === 'users') { - $this->triggerActivityUser($principal[2], $event, $calendarData, Extension::SUBJECT_SHARE_USER); + $this->triggerActivityUser($principal[2], $event, $calendarData, Calendar::SUBJECT_SHARE_USER); if ($owner !== $principal[2]) { $parameters = [ @@ -253,13 +255,13 @@ class Backend { ]; if ($owner === $event->getAuthor()) { - $subject = Extension::SUBJECT_SHARE_USER . '_you'; + $subject = Calendar::SUBJECT_SHARE_USER . '_you'; } else { $event->setAffectedUser($event->getAuthor()) - ->setSubject(Extension::SUBJECT_SHARE_USER . '_you', $parameters); + ->setSubject(Calendar::SUBJECT_SHARE_USER . '_you', $parameters); $this->activityManager->publish($event); - $subject = Extension::SUBJECT_SHARE_USER . '_by'; + $subject = Calendar::SUBJECT_SHARE_USER . '_by'; $parameters[] = $event->getAuthor(); } @@ -268,7 +270,7 @@ class Backend { $this->activityManager->publish($event); } } else if ($principal[1] === 'groups') { - $this->triggerActivityGroup($principal[2], $event, $calendarData, Extension::SUBJECT_SHARE_USER); + $this->triggerActivityGroup($principal[2], $event, $calendarData, Calendar::SUBJECT_SHARE_USER); $parameters = [ $principal[2], @@ -276,13 +278,13 @@ class Backend { ]; if ($owner === $event->getAuthor()) { - $subject = Extension::SUBJECT_SHARE_GROUP . '_you'; + $subject = Calendar::SUBJECT_SHARE_GROUP . '_you'; } else { $event->setAffectedUser($event->getAuthor()) - ->setSubject(Extension::SUBJECT_SHARE_GROUP . '_you', $parameters); + ->setSubject(Calendar::SUBJECT_SHARE_GROUP . '_you', $parameters); $this->activityManager->publish($event); - $subject = Extension::SUBJECT_SHARE_GROUP . '_by'; + $subject = Calendar::SUBJECT_SHARE_GROUP . '_by'; $parameters[] = $event->getAuthor(); } @@ -379,16 +381,16 @@ class Backend { $object = $this->getObjectNameAndType($objectData); $action = $action . '_' . $object['type']; - if ($object['type'] === 'todo' && strpos($action, Extension::SUBJECT_OBJECT_UPDATE) === 0 && $object['status'] === 'COMPLETED') { + if ($object['type'] === 'todo' && strpos($action, Event::SUBJECT_OBJECT_UPDATE) === 0 && $object['status'] === 'COMPLETED') { $action .= '_completed'; - } else if ($object['type'] === 'todo' && strpos($action, Extension::SUBJECT_OBJECT_UPDATE) === 0 && $object['status'] === 'NEEDS-ACTION') { + } else if ($object['type'] === 'todo' && strpos($action, Event::SUBJECT_OBJECT_UPDATE) === 0 && $object['status'] === 'NEEDS-ACTION') { $action .= '_needs_action'; } $event = $this->activityManager->generateEvent(); $event->setApp('dav') - ->setObject(Extension::CALENDAR, (int) $calendarData['id']) - ->setType($object['type'] === 'event' ? Extension::CALENDAR_EVENT : Extension::CALENDAR_TODO) + ->setObject('calendar', (int) $calendarData['id']) + ->setType($object['type'] === 'event' ? 'calendar_event' : 'calendar_todo') ->setAuthor($currentUser); $users = $this->getUsersForShares($shares); @@ -401,7 +403,10 @@ class Backend { [ $currentUser, $calendarData['{DAV:}displayname'], - $object['name'], + [ + 'id' => $object['id'], + 'name' => $object['name'], + ], ] ); $this->activityManager->publish($event); @@ -428,9 +433,9 @@ class Backend { } if ($componentType === 'VEVENT') { - return ['name' => (string) $component->SUMMARY, 'type' => 'event']; + return ['id' => (string) $component->UID, 'name' => (string) $component->SUMMARY, 'type' => 'event']; } - return ['name' => (string) $component->SUMMARY, 'type' => 'todo', 'status' => (string) $component->STATUS]; + return ['id' => (string) $component->UID, 'name' => (string) $component->SUMMARY, 'type' => 'todo', 'status' => (string) $component->STATUS]; } /** diff --git a/apps/dav/lib/CalDAV/Activity/Extension.php b/apps/dav/lib/CalDAV/Activity/Extension.php deleted file mode 100644 index 29222b90ce..0000000000 --- a/apps/dav/lib/CalDAV/Activity/Extension.php +++ /dev/null @@ -1,378 +0,0 @@ - - * - * @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 . - * - */ - -namespace OCA\DAV\CalDAV\Activity; - -use OCP\Activity\IExtension; -use OCP\IURLGenerator; -use OCP\L10N\IFactory; - -class Extension implements IExtension { - const APP = 'dav'; - /** - * Filter with all sharing related activities - */ - const CALENDAR = 'calendar'; - const CALENDAR_EVENT = 'calendar_event'; - const CALENDAR_TODO = 'calendar_todo'; - - const SUBJECT_ADD = 'calendar_add'; - const SUBJECT_UPDATE = 'calendar_update'; - const SUBJECT_DELETE = 'calendar_delete'; - const SUBJECT_SHARE_USER = 'calendar_user_share'; - const SUBJECT_SHARE_GROUP = 'calendar_group_share'; - const SUBJECT_UNSHARE_USER = 'calendar_user_unshare'; - const SUBJECT_UNSHARE_GROUP = 'calendar_group_unshare'; - - const SUBJECT_OBJECT_ADD = 'object_add'; - const SUBJECT_OBJECT_UPDATE = 'object_update'; - const SUBJECT_OBJECT_DELETE = 'object_delete'; - - /** @var IFactory */ - protected $languageFactory; - - /** @var IURLGenerator */ - protected $URLGenerator; - - /** - * @param IFactory $languageFactory - * @param IURLGenerator $URLGenerator - */ - public function __construct(IFactory $languageFactory, IURLGenerator $URLGenerator) { - $this->languageFactory = $languageFactory; - $this->URLGenerator = $URLGenerator; - } - - protected function getL10N($languageCode = null) { - return $this->languageFactory->get(self::APP, $languageCode); - } - - /** - * The extension can return an array of additional notification types. - * If no additional types are to be added false is to be returned - * - * @param string $languageCode - * @return array|false - */ - public function getNotificationTypes($languageCode) { - $l = $this->getL10N($languageCode); - - return array( - self::CALENDAR => (string) $l->t('A calendar was modified'), - self::CALENDAR_EVENT => (string) $l->t('A calendar event was modified'), - self::CALENDAR_TODO => (string) $l->t('A calendar todo was modified'), - ); - } - - /** - * For a given method additional types to be displayed in the settings can be returned. - * In case no additional types are to be added false is to be returned. - * - * @param string $method - * @return array|false - */ - public function getDefaultTypes($method) { - $defaultTypes = []; - if ($method === self::METHOD_STREAM) { - $defaultTypes[] = self::CALENDAR; - $defaultTypes[] = self::CALENDAR_EVENT; - $defaultTypes[] = self::CALENDAR_TODO; - } - - return $defaultTypes; - } - - /** - * A string naming the css class for the icon to be used can be returned. - * If no icon is known for the given type false is to be returned. - * - * @param string $type - * @return string|false - */ - public function getTypeIcon($type) { - switch ($type) { - case self::CALENDAR: - case self::CALENDAR_EVENT: - return 'icon-calendar-dark'; - case self::CALENDAR_TODO: - return 'icon-checkmark'; - } - - return false; - } - - /** - * The extension can translate a given message to the requested languages. - * If no translation is available false is to be returned. - * - * @param string $app - * @param string $text - * @param array $params - * @param boolean $stripPath - * @param boolean $highlightParams - * @param string $languageCode - * @return string|false - */ - public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) { - if ($app !== self::APP) { - return false; - } - - $l = $this->getL10N($languageCode); - - switch ($text) { - case self::SUBJECT_ADD: - return (string) $l->t('%1$s created calendar %2$s', $params); - case self::SUBJECT_ADD . '_self': - return (string) $l->t('You created calendar %2$s', $params); - case self::SUBJECT_DELETE: - return (string) $l->t('%1$s deleted calendar %2$s', $params); - case self::SUBJECT_DELETE . '_self': - return (string) $l->t('You deleted calendar %2$s', $params); - case self::SUBJECT_UPDATE: - return (string) $l->t('%1$s updated calendar %2$s', $params); - case self::SUBJECT_UPDATE . '_self': - return (string) $l->t('You updated calendar %2$s', $params); - - case self::SUBJECT_SHARE_USER: - return (string) $l->t('%1$s shared calendar %2$s with you', $params); - case self::SUBJECT_SHARE_USER . '_you': - return (string) $l->t('You shared calendar %2$s with %1$s', $params); - case self::SUBJECT_SHARE_USER . '_by': - return (string) $l->t('%3$s shared calendar %2$s with %1$s', $params); - case self::SUBJECT_UNSHARE_USER: - return (string) $l->t('%1$s unshared calendar %2$s from you', $params); - case self::SUBJECT_UNSHARE_USER . '_you': - return (string) $l->t('You unshared calendar %2$s from %1$s', $params); - case self::SUBJECT_UNSHARE_USER . '_by': - return (string) $l->t('%3$s unshared calendar %2$s from %1$s', $params); - case self::SUBJECT_UNSHARE_USER . '_self': - return (string) $l->t('%1$s unshared calendar %2$s from themselves', $params); - - case self::SUBJECT_SHARE_GROUP . '_you': - return (string) $l->t('You shared calendar %2$s with group %1$s', $params); - case self::SUBJECT_SHARE_GROUP . '_by': - return (string) $l->t('%3$s shared calendar %2$s with group %1$s', $params); - case self::SUBJECT_UNSHARE_GROUP . '_you': - return (string) $l->t('You unshared calendar %2$s from group %1$s', $params); - case self::SUBJECT_UNSHARE_GROUP . '_by': - return (string) $l->t('%3$s unshared calendar %2$s from group %1$s', $params); - - case self::SUBJECT_OBJECT_ADD . '_event': - return (string) $l->t('%1$s created event %3$s in calendar %2$s', $params); - case self::SUBJECT_OBJECT_ADD . '_event_self': - return (string) $l->t('You created event %3$s in calendar %2$s', $params); - case self::SUBJECT_OBJECT_DELETE . '_event': - return (string) $l->t('%1$s deleted event %3$s from calendar %2$s', $params); - case self::SUBJECT_OBJECT_DELETE . '_event_self': - return (string) $l->t('You deleted event %3$s from calendar %2$s', $params); - case self::SUBJECT_OBJECT_UPDATE . '_event': - return (string) $l->t('%1$s updated event %3$s in calendar %2$s', $params); - case self::SUBJECT_OBJECT_UPDATE . '_event_self': - return (string) $l->t('You updated event %3$s in calendar %2$s', $params); - - case self::SUBJECT_OBJECT_ADD . '_todo': - return (string) $l->t('%1$s created todo %3$s in list %2$s', $params); - case self::SUBJECT_OBJECT_ADD . '_todo_self': - return (string) $l->t('You created todo %3$s in list %2$s', $params); - case self::SUBJECT_OBJECT_DELETE . '_todo': - return (string) $l->t('%1$s deleted todo %3$s from list %2$s', $params); - case self::SUBJECT_OBJECT_DELETE . '_todo_self': - return (string) $l->t('You deleted todo %3$s from list %2$s', $params); - case self::SUBJECT_OBJECT_UPDATE . '_todo': - return (string) $l->t('%1$s updated todo %3$s in list %2$s', $params); - case self::SUBJECT_OBJECT_UPDATE . '_todo_self': - return (string) $l->t('You updated todo %3$s in list %2$s', $params); - - case self::SUBJECT_OBJECT_UPDATE . '_todo_completed': - return (string) $l->t('%1$s solved todo %3$s in list %2$s', $params); - case self::SUBJECT_OBJECT_UPDATE . '_todo_completed_self': - return (string) $l->t('You solved todo %3$s in list %2$s', $params); - case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action': - return (string) $l->t('%1$s reopened todo %3$s in list %2$s', $params); - case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action_self': - return (string) $l->t('You reopened todo %3$s in list %2$s', $params); - - } - - return false; - } - - /** - * The extension can define the type of parameters for translation - * - * Currently known types are: - * * file => will strip away the path of the file and add a tooltip with it - * * username => will add the avatar of the user - * - * @param string $app - * @param string $text - * @return array|false - */ - public function getSpecialParameterList($app, $text) { - if ($app === self::APP) { - switch ($text) { - case self::SUBJECT_ADD: - case self::SUBJECT_ADD . '_self': - case self::SUBJECT_DELETE: - case self::SUBJECT_DELETE . '_self': - case self::SUBJECT_UPDATE: - case self::SUBJECT_UPDATE . '_self': - case self::SUBJECT_SHARE_USER: - case self::SUBJECT_SHARE_USER . '_you': - case self::SUBJECT_UNSHARE_USER: - case self::SUBJECT_UNSHARE_USER . '_you': - case self::SUBJECT_UNSHARE_USER . '_self': - return [ - 0 => 'username', - //1 => 'calendar', - ]; - case self::SUBJECT_SHARE_USER . '_by': - case self::SUBJECT_UNSHARE_USER . '_by': - return [ - 0 => 'username', - //1 => 'calendar', - 2 => 'username', - ]; - case self::SUBJECT_SHARE_GROUP . '_you': - case self::SUBJECT_UNSHARE_GROUP . '_you': - return [ - //0 => 'group', - //1 => 'calendar', - ]; - case self::SUBJECT_SHARE_GROUP . '_by': - case self::SUBJECT_UNSHARE_GROUP . '_by': - return [ - //0 => 'group', - //1 => 'calendar', - 2 => 'username', - ]; - - case self::SUBJECT_OBJECT_ADD . '_event': - case self::SUBJECT_OBJECT_ADD . '_event_self': - case self::SUBJECT_OBJECT_DELETE . '_event': - case self::SUBJECT_OBJECT_DELETE . '_event_self': - case self::SUBJECT_OBJECT_UPDATE . '_event': - case self::SUBJECT_OBJECT_UPDATE . '_event_self': - - case self::SUBJECT_OBJECT_ADD . '_todo': - case self::SUBJECT_OBJECT_ADD . '_todo_self': - case self::SUBJECT_OBJECT_DELETE . '_todo': - case self::SUBJECT_OBJECT_DELETE . '_todo_self': - case self::SUBJECT_OBJECT_UPDATE . '_todo': - case self::SUBJECT_OBJECT_UPDATE . '_todo_self': - - case self::SUBJECT_OBJECT_UPDATE . '_todo_completed': - case self::SUBJECT_OBJECT_UPDATE . '_todo_completed_self': - case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action': - case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action_self': - return [ - 0 => 'username', - //1 => 'calendar', - //2 => 'object', - ]; - } - } - - return false; - } - - /** - * The extension can define the parameter grouping by returning the index as integer. - * In case no grouping is required false is to be returned. - * - * @param array $activity - * @return integer|false - */ - public function getGroupParameter($activity) { - return false; - } - - /** - * The extension can define additional navigation entries. The array returned has to contain two keys 'top' - * and 'apps' which hold arrays with the relevant entries. - * If no further entries are to be added false is no be returned. - * - * @return array|false - */ - public function getNavigation() { - $l = $this->getL10N(); - return [ - 'apps' => [ - self::CALENDAR => [ - 'id' => self::CALENDAR, - 'icon' => 'icon-calendar-dark', - 'name' => (string) $l->t('Calendar'), - 'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::CALENDAR]), - ], - self::CALENDAR_TODO => [ - 'id' => self::CALENDAR_TODO, - 'icon' => 'icon-checkmark', - 'name' => (string) $l->t('Todos'), - 'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::CALENDAR_TODO]), - ], - ], - 'top' => [], - ]; - } - - /** - * The extension can check if a custom filter (given by a query string like filter=abc) is valid or not. - * - * @param string $filterValue - * @return boolean - */ - public function isFilterValid($filterValue) { - return in_array($filterValue, [self::CALENDAR, self::CALENDAR_TODO]); - } - - /** - * The extension can filter the types based on the filter if required. - * In case no filter is to be applied false is to be returned unchanged. - * - * @param array $types - * @param string $filter - * @return array|false - */ - public function filterNotificationTypes($types, $filter) { - switch ($filter) { - case self::CALENDAR: - return array_intersect([self::CALENDAR, self::CALENDAR_EVENT], $types); - case self::CALENDAR_TODO: - return array_intersect([self::CALENDAR_TODO], $types); - } - return false; - } - - /** - * For a given filter the extension can specify the sql query conditions including parameters for that query. - * In case the extension does not know the filter false is to be returned. - * The query condition and the parameters are to be returned as array with two elements. - * E.g. return array('`app` = ? and `message` like ?', array('mail', 'ownCloud%')); - * - * @param string $filter - * @return array|false - */ - public function getQueryForFilter($filter) { - return false; - } - -} diff --git a/apps/dav/lib/CalDAV/Activity/Filter/Calendar.php b/apps/dav/lib/CalDAV/Activity/Filter/Calendar.php new file mode 100644 index 0000000000..a20b8ad544 --- /dev/null +++ b/apps/dav/lib/CalDAV/Activity/Filter/Calendar.php @@ -0,0 +1,92 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\CalDAV\Activity\Filter; + + +use OCP\Activity\IFilter; +use OCP\IL10N; +use OCP\IURLGenerator; + +class Calendar implements IFilter { + + /** @var IL10N */ + protected $l; + + /** @var IURLGenerator */ + protected $url; + + public function __construct(IL10N $l, IURLGenerator $url) { + $this->l = $l; + $this->url = $url; + } + + /** + * @return string Lowercase a-z and underscore only identifier + * @since 11.0.0 + */ + public function getIdentifier() { + return 'calendar'; + } + + /** + * @return string A translated string + * @since 11.0.0 + */ + public function getName() { + return $this->l->t('Calendar'); + } + + /** + * @return int whether the filter should be rather on the top or bottom of + * the admin section. The filters are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * @since 11.0.0 + */ + public function getPriority() { + return 40; + } + + /** + * @return string Full URL to an icon, empty string when none is given + * @since 11.0.0 + */ + public function getIcon() { + return $this->url->getAbsoluteURL($this->url->imagePath('core', 'places/calendar-dark.svg')); + } + + /** + * @param string[] $types + * @return string[] An array of allowed apps from which activities should be displayed + * @since 11.0.0 + */ + public function filterTypes(array $types) { + return array_intersect(['calendar', 'calendar_event'], $types); + } + + /** + * @return string[] An array of allowed apps from which activities should be displayed + * @since 11.0.0 + */ + public function allowedApps() { + return []; + } +} diff --git a/apps/dav/lib/CalDAV/Activity/Filter/Todo.php b/apps/dav/lib/CalDAV/Activity/Filter/Todo.php new file mode 100644 index 0000000000..42ee074085 --- /dev/null +++ b/apps/dav/lib/CalDAV/Activity/Filter/Todo.php @@ -0,0 +1,92 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\CalDAV\Activity\Filter; + + +use OCP\Activity\IFilter; +use OCP\IL10N; +use OCP\IURLGenerator; + +class Todo implements IFilter { + + /** @var IL10N */ + protected $l; + + /** @var IURLGenerator */ + protected $url; + + public function __construct(IL10N $l, IURLGenerator $url) { + $this->l = $l; + $this->url = $url; + } + + /** + * @return string Lowercase a-z and underscore only identifier + * @since 11.0.0 + */ + public function getIdentifier() { + return 'calendar_todo'; + } + + /** + * @return string A translated string + * @since 11.0.0 + */ + public function getName() { + return $this->l->t('Todos'); + } + + /** + * @return int whether the filter should be rather on the top or bottom of + * the admin section. The filters are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * @since 11.0.0 + */ + public function getPriority() { + return 40; + } + + /** + * @return string Full URL to an icon, empty string when none is given + * @since 11.0.0 + */ + public function getIcon() { + return $this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/checkmark.svg')); + } + + /** + * @param string[] $types + * @return string[] An array of allowed apps from which activities should be displayed + * @since 11.0.0 + */ + public function filterTypes(array $types) { + return array_intersect(['calendar_todo'], $types); + } + + /** + * @return string[] An array of allowed apps from which activities should be displayed + * @since 11.0.0 + */ + public function allowedApps() { + return []; + } +} diff --git a/apps/dav/lib/CalDAV/Activity/Provider/Base.php b/apps/dav/lib/CalDAV/Activity/Provider/Base.php new file mode 100644 index 0000000000..72fdd681b8 --- /dev/null +++ b/apps/dav/lib/CalDAV/Activity/Provider/Base.php @@ -0,0 +1,129 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\CalDAV\Activity\Provider; + +use OCP\Activity\IEvent; +use OCP\Activity\IProvider; +use OCP\IUser; +use OCP\IUserManager; + +abstract class Base implements IProvider { + + /** @var IUserManager */ + protected $userManager; + + /** @var string[] cached displayNames - key is the UID and value the displayname */ + protected $displayNames = []; + + /** + * @param IUserManager $userManager + */ + public function __construct(IUserManager $userManager) { + $this->userManager = $userManager; + } + + /** + * @param IEvent $event + * @param string $subject + * @param array $parameters + */ + protected function setSubjects(IEvent $event, $subject, array $parameters) { + $placeholders = $replacements = []; + foreach ($parameters as $placeholder => $parameter) { + $placeholders[] = '{' . $placeholder . '}'; + $replacements[] = $parameter['name']; + } + + $event->setParsedSubject(str_replace($placeholders, $replacements, $subject)) + ->setRichSubject($subject, $parameters); + } + + /** + * @param array $eventData + * @return array + */ + protected function generateObjectParameter($eventData) { + if (!is_array($eventData) || !isset($eventData['id']) || !isset($eventData['name'])) { + throw new \InvalidArgumentException(); + }; + + return [ + 'type' => 'calendar-event', + 'id' => $eventData['id'], + 'name' => $eventData['name'], + ]; + } + + /** + * @param int $id + * @param string $name + * @return array + */ + protected function generateCalendarParameter($id, $name) { + return [ + 'type' => 'calendar', + 'id' => $id, + 'name' => $name, + ]; + } + + /** + * @param string $id + * @return array + */ + protected function generateGroupParameter($id) { + return [ + 'type' => 'group', + 'id' => $id, + 'name' => $id, + ]; + } + + /** + * @param string $uid + * @return array + */ + protected function generateUserParameter($uid) { + if (!isset($this->displayNames[$uid])) { + $this->displayNames[$uid] = $this->getDisplayName($uid); + } + + return [ + 'type' => 'user', + 'id' => $uid, + 'name' => $this->displayNames[$uid], + ]; + } + + /** + * @param string $uid + * @return string + */ + protected function getDisplayName($uid) { + $user = $this->userManager->get($uid); + if ($user instanceof IUser) { + return $user->getDisplayName(); + } else { + return $uid; + } + } +} diff --git a/apps/dav/lib/CalDAV/Activity/Provider/Calendar.php b/apps/dav/lib/CalDAV/Activity/Provider/Calendar.php new file mode 100644 index 0000000000..2e2ce5bc27 --- /dev/null +++ b/apps/dav/lib/CalDAV/Activity/Provider/Calendar.php @@ -0,0 +1,192 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\CalDAV\Activity\Provider; + +use OCP\Activity\IEvent; +use OCP\Activity\IEventMerger; +use OCP\Activity\IManager; +use OCP\IL10N; +use OCP\IURLGenerator; +use OCP\IUserManager; + +class Calendar extends Base { + + const SUBJECT_ADD = 'calendar_add'; + const SUBJECT_UPDATE = 'calendar_update'; + const SUBJECT_DELETE = 'calendar_delete'; + const SUBJECT_SHARE_USER = 'calendar_user_share'; + const SUBJECT_SHARE_GROUP = 'calendar_group_share'; + const SUBJECT_UNSHARE_USER = 'calendar_user_unshare'; + const SUBJECT_UNSHARE_GROUP = 'calendar_group_unshare'; + + /** @var IL10N */ + protected $l; + + /** @var IURLGenerator */ + protected $url; + + /** @var IManager */ + protected $activityManager; + + /** @var IEventMerger */ + protected $eventMerger; + + /** + * @param IL10N $l + * @param IURLGenerator $url + * @param IManager $activityManager + * @param IUserManager $userManager + * @param IEventMerger $eventMerger + */ + public function __construct(IL10N $l, IURLGenerator $url, IManager $activityManager, IUserManager $userManager, IEventMerger $eventMerger) { + parent::__construct($userManager); + $this->l = $l; + $this->url = $url; + $this->activityManager = $activityManager; + $this->eventMerger = $eventMerger; + } + + /** + * @param IEvent $event + * @param IEvent|null $previousEvent + * @return IEvent + * @throws \InvalidArgumentException + * @since 11.0.0 + */ + public function parse(IEvent $event, IEvent $previousEvent = null) { + if ($event->getApp() !== 'dav' || $event->getType() !== 'calendar') { + throw new \InvalidArgumentException(); + } + + $event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'places/calendar-dark.svg'))); + + if ($event->getSubject() === self::SUBJECT_ADD) { + $subject = $this->l->t('{actor} created calendar {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_ADD . '_self') { + $subject = $this->l->t('You created calendar {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_DELETE) { + $subject = $this->l->t('{actor} deleted calendar {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_DELETE . '_self') { + $subject = $this->l->t('You deleted calendar {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_UPDATE) { + $subject = $this->l->t('{actor} updated calendar {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_UPDATE . '_self') { + $subject = $this->l->t('You updated calendar {calendar}'); + + } else if ($event->getSubject() === self::SUBJECT_SHARE_USER) { + $subject = $this->l->t('{actor} shared calendar {calendar} with you'); + } else if ($event->getSubject() === self::SUBJECT_SHARE_USER . '_you') { + $subject = $this->l->t('You shared calendar {calendar} with {user}'); + } else if ($event->getSubject() === self::SUBJECT_SHARE_USER . '_by') { + $subject = $this->l->t('{actor} shared calendar {calendar} with {user}'); + } else if ($event->getSubject() === self::SUBJECT_UNSHARE_USER) { + $subject = $this->l->t('{actor} unshared calendar {calendar} from you'); + } else if ($event->getSubject() === self::SUBJECT_UNSHARE_USER . '_you') { + $subject = $this->l->t('You unshared calendar {calendar} from {user}'); + } else if ($event->getSubject() === self::SUBJECT_UNSHARE_USER . '_by') { + $subject = $this->l->t('{actor} unshared calendar {calendar} from {user}'); + } else if ($event->getSubject() === self::SUBJECT_UNSHARE_USER . '_self') { + $subject = $this->l->t('{actor} unshared calendar {calendar} from themselves'); + + } else if ($event->getSubject() === self::SUBJECT_SHARE_GROUP . '_you') { + $subject = $this->l->t('You shared calendar {calendar} with group {group}'); + } else if ($event->getSubject() === self::SUBJECT_SHARE_GROUP . '_by') { + $subject = $this->l->t('{actor} shared calendar {calendar} with group {group}'); + } else if ($event->getSubject() === self::SUBJECT_UNSHARE_GROUP . '_you') { + $subject = $this->l->t('You unshared calendar {calendar} from group {group}'); + } else if ($event->getSubject() === self::SUBJECT_UNSHARE_GROUP . '_by') { + $subject = $this->l->t('{actor} unshared calendar {calendar} from group {group}'); + } else { + throw new \InvalidArgumentException(); + } + + $parsedParameters = $this->getParameters($event); + $this->setSubjects($event, $subject, $parsedParameters); + + $event = $this->eventMerger->mergeEvents('calendar', $event, $previousEvent); + + if ($event->getChildEvent() === null) { + if (isset($parsedParameters['user'])) { + // Couldn't group by calendar, maybe we can group by users + $event = $this->eventMerger->mergeEvents('user', $event, $previousEvent); + } else if (isset($parsedParameters['group'])) { + // Couldn't group by calendar, maybe we can group by groups + $event = $this->eventMerger->mergeEvents('group', $event, $previousEvent); + } + } + + return $event; + } + + /** + * @param IEvent $event + * @return array + */ + protected function getParameters(IEvent $event) { + $subject = $event->getSubject(); + $parameters = $event->getSubjectParameters(); + + switch ($subject) { + case self::SUBJECT_ADD: + case self::SUBJECT_ADD . '_self': + case self::SUBJECT_DELETE: + case self::SUBJECT_DELETE . '_self': + case self::SUBJECT_UPDATE: + case self::SUBJECT_UPDATE . '_self': + case self::SUBJECT_SHARE_USER: + case self::SUBJECT_UNSHARE_USER: + case self::SUBJECT_UNSHARE_USER . '_self': + return [ + 'actor' => $this->generateUserParameter($parameters[0]), + 'calendar' => $this->generateCalendarParameter($event->getObjectId(), $parameters[1]), + ]; + case self::SUBJECT_SHARE_USER . '_you': + case self::SUBJECT_UNSHARE_USER . '_you': + return [ + 'user' => $this->generateUserParameter($parameters[0]), + 'calendar' => $this->generateCalendarParameter($event->getObjectId(), $parameters[1]), + ]; + case self::SUBJECT_SHARE_USER . '_by': + case self::SUBJECT_UNSHARE_USER . '_by': + return [ + 'user' => $this->generateUserParameter($parameters[0]), + 'calendar' => $this->generateCalendarParameter($event->getObjectId(), $parameters[1]), + 'actor' => $this->generateUserParameter($parameters[2]), + ]; + case self::SUBJECT_SHARE_GROUP . '_you': + case self::SUBJECT_UNSHARE_GROUP . '_you': + return [ + 'group' => $this->generateGroupParameter($parameters[0]), + 'calendar' => $this->generateCalendarParameter($event->getObjectId(), $parameters[1]), + ]; + case self::SUBJECT_SHARE_GROUP . '_by': + case self::SUBJECT_UNSHARE_GROUP . '_by': + return [ + 'group' => $this->generateGroupParameter($parameters[0]), + 'calendar' => $this->generateCalendarParameter($event->getObjectId(), $parameters[1]), + 'actor' => $this->generateUserParameter($parameters[2]), + ]; + } + + throw new \InvalidArgumentException(); + } +} diff --git a/apps/dav/lib/CalDAV/Activity/Provider/Event.php b/apps/dav/lib/CalDAV/Activity/Provider/Event.php new file mode 100644 index 0000000000..11c8d901ac --- /dev/null +++ b/apps/dav/lib/CalDAV/Activity/Provider/Event.php @@ -0,0 +1,130 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\CalDAV\Activity\Provider; + +use OCP\Activity\IEvent; +use OCP\Activity\IEventMerger; +use OCP\Activity\IManager; +use OCP\IL10N; +use OCP\IURLGenerator; +use OCP\IUserManager; + +class Event extends Base { + + const SUBJECT_OBJECT_ADD = 'object_add'; + const SUBJECT_OBJECT_UPDATE = 'object_update'; + const SUBJECT_OBJECT_DELETE = 'object_delete'; + + /** @var IL10N */ + protected $l; + + /** @var IURLGenerator */ + protected $url; + + /** @var IManager */ + protected $activityManager; + + /** @var IEventMerger */ + protected $eventMerger; + + /** + * @param IL10N $l + * @param IURLGenerator $url + * @param IManager $activityManager + * @param IUserManager $userManager + * @param IEventMerger $eventMerger + */ + public function __construct(IL10N $l, IURLGenerator $url, IManager $activityManager, IUserManager $userManager, IEventMerger $eventMerger) { + parent::__construct($userManager); + $this->l = $l; + $this->url = $url; + $this->activityManager = $activityManager; + $this->eventMerger = $eventMerger; + } + + /** + * @param IEvent $event + * @param IEvent|null $previousEvent + * @return IEvent + * @throws \InvalidArgumentException + * @since 11.0.0 + */ + public function parse(IEvent $event, IEvent $previousEvent = null) { + if ($event->getApp() !== 'dav' || $event->getType() !== 'calendar_event') { + throw new \InvalidArgumentException(); + } + + $event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'places/calendar-dark.svg'))); + + if ($event->getSubject() === self::SUBJECT_OBJECT_ADD . '_event') { + $subject = $this->l->t('{actor} created event {event} in calendar {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_OBJECT_ADD . '_event_self') { + $subject = $this->l->t('You created event {event} in calendar {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_OBJECT_DELETE . '_event') { + $subject = $this->l->t('{actor} deleted event {event} from calendar {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_OBJECT_DELETE . '_event_self') { + $subject = $this->l->t('You deleted event {event} from calendar {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_event') { + $subject = $this->l->t('{actor} updated event {event} in calendar {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_event_self') { + $subject = $this->l->t('You updated event {event} in calendar {calendar}'); + } else { + throw new \InvalidArgumentException(); + } + + $parsedParameters = $this->getParameters($event); + $this->setSubjects($event, $subject, $parsedParameters); + + $event = $this->eventMerger->mergeEvents('event', $event, $previousEvent); + + return $event; + } + + /** + * @param IEvent $event + * @return array + */ + protected function getParameters(IEvent $event) { + $subject = $event->getSubject(); + $parameters = $event->getSubjectParameters(); + + switch ($subject) { + case self::SUBJECT_OBJECT_ADD . '_event': + case self::SUBJECT_OBJECT_DELETE . '_event': + case self::SUBJECT_OBJECT_UPDATE . '_event': + return [ + 'actor' => $this->generateUserParameter($parameters[0]), + 'calendar' => $this->generateCalendarParameter($event->getObjectId(), $parameters[1]), + 'event' => $this->generateObjectParameter($parameters[2]), + ]; + case self::SUBJECT_OBJECT_ADD . '_event_self': + case self::SUBJECT_OBJECT_DELETE . '_event_self': + case self::SUBJECT_OBJECT_UPDATE . '_event_self': + return [ + 'calendar' => $this->generateCalendarParameter($event->getObjectId(), $parameters[1]), + 'event' => $this->generateObjectParameter($parameters[2]), + ]; + } + + throw new \InvalidArgumentException(); + } +} diff --git a/apps/dav/lib/CalDAV/Activity/Provider/Todo.php b/apps/dav/lib/CalDAV/Activity/Provider/Todo.php new file mode 100644 index 0000000000..43ab9e9c44 --- /dev/null +++ b/apps/dav/lib/CalDAV/Activity/Provider/Todo.php @@ -0,0 +1,107 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\CalDAV\Activity\Provider; + +use OCP\Activity\IEvent; + +class Todo extends Event { + + /** + * @param IEvent $event + * @param IEvent|null $previousEvent + * @return IEvent + * @throws \InvalidArgumentException + * @since 11.0.0 + */ + public function parse(IEvent $event, IEvent $previousEvent = null) { + if ($event->getApp() !== 'dav' || $event->getType() !== 'calendar_todo') { + throw new \InvalidArgumentException(); + } + + $event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/checkmark.svg'))); + + if ($event->getSubject() === self::SUBJECT_OBJECT_ADD . '_todo') { + $subject = $this->l->t('{actor} created todo {todo} in list {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_OBJECT_ADD . '_todo_self') { + $subject = $this->l->t('You created todo {todo} in list {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_OBJECT_DELETE . '_todo') { + $subject = $this->l->t('{actor} deleted todo {todo} from list {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_OBJECT_DELETE . '_todo_self') { + $subject = $this->l->t('You deleted todo {todo} from list {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo') { + $subject = $this->l->t('{actor} updated todo {todo} in list {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_self') { + $subject = $this->l->t('You updated todo {todo} in list {calendar}'); + + } else if ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_completed') { + $subject = $this->l->t('{actor} solved todo {todo} in list {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_completed_self') { + $subject = $this->l->t('You solved todo {todo} in list {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action') { + $subject = $this->l->t('{actor} reopened todo {todo} in list {calendar}'); + } else if ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action_self') { + $subject = $this->l->t('You reopened todo {todo} in list {calendar}'); + } else { + throw new \InvalidArgumentException(); + } + + $parsedParameters = $this->getParameters($event); + $this->setSubjects($event, $subject, $parsedParameters); + + $event = $this->eventMerger->mergeEvents('todo', $event, $previousEvent); + + return $event; + } + + /** + * @param IEvent $event + * @return array + */ + protected function getParameters(IEvent $event) { + $subject = $event->getSubject(); + $parameters = $event->getSubjectParameters(); + + switch ($subject) { + case self::SUBJECT_OBJECT_ADD . '_todo': + case self::SUBJECT_OBJECT_DELETE . '_todo': + case self::SUBJECT_OBJECT_UPDATE . '_todo': + case self::SUBJECT_OBJECT_UPDATE . '_todo_completed': + case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action': + return [ + 'actor' => $this->generateUserParameter($parameters[0]), + 'calendar' => $this->generateCalendarParameter($event->getObjectId(), $parameters[1]), + 'todo' => $this->generateObjectParameter($parameters[2]), + ]; + case self::SUBJECT_OBJECT_ADD . '_todo_self': + case self::SUBJECT_OBJECT_DELETE . '_todo_self': + case self::SUBJECT_OBJECT_UPDATE . '_todo_self': + case self::SUBJECT_OBJECT_UPDATE . '_todo_completed_self': + case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action_self': + return [ + 'calendar' => $this->generateCalendarParameter($event->getObjectId(), $parameters[1]), + 'todo' => $this->generateObjectParameter($parameters[2]), + ]; + } + + throw new \InvalidArgumentException(); + } +} diff --git a/apps/dav/lib/CalDAV/Activity/Setting/Calendar.php b/apps/dav/lib/CalDAV/Activity/Setting/Calendar.php new file mode 100644 index 0000000000..608ee266bb --- /dev/null +++ b/apps/dav/lib/CalDAV/Activity/Setting/Calendar.php @@ -0,0 +1,98 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\CalDAV\Activity\Setting; + + +use OCP\Activity\ISetting; +use OCP\IL10N; + +class Calendar implements ISetting { + + /** @var IL10N */ + protected $l; + + /** + * @param IL10N $l + */ + public function __construct(IL10N $l) { + $this->l = $l; + } + + /** + * @return string Lowercase a-z and underscore only identifier + * @since 11.0.0 + */ + public function getIdentifier() { + return 'calendar'; + } + + /** + * @return string A translated string + * @since 11.0.0 + */ + public function getName() { + return $this->l->t('A calendar was modified'); + } + + /** + * @return int whether the filter should be rather on the top or bottom of + * the admin section. The filters are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * @since 11.0.0 + */ + public function getPriority() { + return 50; + } + + /** + * @return bool True when the option can be changed for the stream + * @since 11.0.0 + */ + public function canChangeStream() { + return true; + } + + /** + * @return bool True when the option can be changed for the stream + * @since 11.0.0 + */ + public function isDefaultEnabledStream() { + return true; + } + + /** + * @return bool True when the option can be changed for the mail + * @since 11.0.0 + */ + public function canChangeMail() { + return true; + } + + /** + * @return bool True when the option can be changed for the stream + * @since 11.0.0 + */ + public function isDefaultEnabledMail() { + return false; + } +} + diff --git a/apps/dav/lib/CalDAV/Activity/Setting/Event.php b/apps/dav/lib/CalDAV/Activity/Setting/Event.php new file mode 100644 index 0000000000..887cd22afa --- /dev/null +++ b/apps/dav/lib/CalDAV/Activity/Setting/Event.php @@ -0,0 +1,98 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\CalDAV\Activity\Setting; + + +use OCP\Activity\ISetting; +use OCP\IL10N; + +class Event implements ISetting { + + /** @var IL10N */ + protected $l; + + /** + * @param IL10N $l + */ + public function __construct(IL10N $l) { + $this->l = $l; + } + + /** + * @return string Lowercase a-z and underscore only identifier + * @since 11.0.0 + */ + public function getIdentifier() { + return 'calendar_event'; + } + + /** + * @return string A translated string + * @since 11.0.0 + */ + public function getName() { + return $this->l->t('A calendar event was modified'); + } + + /** + * @return int whether the filter should be rather on the top or bottom of + * the admin section. The filters are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * @since 11.0.0 + */ + public function getPriority() { + return 50; + } + + /** + * @return bool True when the option can be changed for the stream + * @since 11.0.0 + */ + public function canChangeStream() { + return true; + } + + /** + * @return bool True when the option can be changed for the stream + * @since 11.0.0 + */ + public function isDefaultEnabledStream() { + return true; + } + + /** + * @return bool True when the option can be changed for the mail + * @since 11.0.0 + */ + public function canChangeMail() { + return true; + } + + /** + * @return bool True when the option can be changed for the stream + * @since 11.0.0 + */ + public function isDefaultEnabledMail() { + return false; + } +} + diff --git a/apps/dav/lib/CalDAV/Activity/Setting/Todo.php b/apps/dav/lib/CalDAV/Activity/Setting/Todo.php new file mode 100644 index 0000000000..0c8215f484 --- /dev/null +++ b/apps/dav/lib/CalDAV/Activity/Setting/Todo.php @@ -0,0 +1,98 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\CalDAV\Activity\Setting; + + +use OCP\Activity\ISetting; +use OCP\IL10N; + +class Todo implements ISetting { + + /** @var IL10N */ + protected $l; + + /** + * @param IL10N $l + */ + public function __construct(IL10N $l) { + $this->l = $l; + } + + /** + * @return string Lowercase a-z and underscore only identifier + * @since 11.0.0 + */ + public function getIdentifier() { + return 'calendar_todos'; + } + + /** + * @return string A translated string + * @since 11.0.0 + */ + public function getName() { + return $this->l->t('A calendar todo was modified'); + } + + /** + * @return int whether the filter should be rather on the top or bottom of + * the admin section. The filters are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * @since 11.0.0 + */ + public function getPriority() { + return 50; + } + + /** + * @return bool True when the option can be changed for the stream + * @since 11.0.0 + */ + public function canChangeStream() { + return true; + } + + /** + * @return bool True when the option can be changed for the stream + * @since 11.0.0 + */ + public function isDefaultEnabledStream() { + return true; + } + + /** + * @return bool True when the option can be changed for the mail + * @since 11.0.0 + */ + public function canChangeMail() { + return true; + } + + /** + * @return bool True when the option can be changed for the stream + * @since 11.0.0 + */ + public function isDefaultEnabledMail() { + return false; + } +} + diff --git a/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php b/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php index 3585d69bad..d8d15e8f1f 100644 --- a/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php +++ b/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php @@ -22,7 +22,7 @@ namespace OCA\DAV\Tests\unit\CalDAV\Activity; use OCA\DAV\CalDAV\Activity\Backend; -use OCA\DAV\CalDAV\Activity\Extension; +use OCA\DAV\CalDAV\Activity\Provider\Calendar; use OCP\Activity\IEvent; use OCP\Activity\IManager; use OCP\IGroup; @@ -74,9 +74,9 @@ class BackendTest extends TestCase { public function dataCallTriggerCalendarActivity() { return [ - ['onCalendarAdd', [['data']], Extension::SUBJECT_ADD, [['data'], [], []]], - ['onCalendarUpdate', [['data'], ['shares'], ['changed-properties']], Extension::SUBJECT_UPDATE, [['data'], ['shares'], ['changed-properties']]], - ['onCalendarDelete', [['data'], ['shares']], Extension::SUBJECT_DELETE, [['data'], ['shares'], []]], + ['onCalendarAdd', [['data']], Calendar::SUBJECT_ADD, [['data'], [], []]], + ['onCalendarUpdate', [['data'], ['shares'], ['changed-properties']], Calendar::SUBJECT_UPDATE, [['data'], ['shares'], ['changed-properties']]], + ['onCalendarDelete', [['data'], ['shares']], Calendar::SUBJECT_DELETE, [['data'], ['shares'], []]], ]; } @@ -104,51 +104,51 @@ class BackendTest extends TestCase { public function dataTriggerCalendarActivity() { return [ // Add calendar - [Extension::SUBJECT_ADD, [], [], [], '', '', null, []], - [Extension::SUBJECT_ADD, [ + [Calendar::SUBJECT_ADD, [], [], [], '', '', null, []], + [Calendar::SUBJECT_ADD, [ 'principaluri' => 'principal/user/admin', 'id' => 42, '{DAV:}displayname' => 'Name of calendar', ], [], [], '', 'admin', null, ['admin']], - [Extension::SUBJECT_ADD, [ + [Calendar::SUBJECT_ADD, [ 'principaluri' => 'principal/user/admin', 'id' => 42, '{DAV:}displayname' => 'Name of calendar', ], [], [], 'test2', 'test2', null, ['admin']], // Update calendar - [Extension::SUBJECT_UPDATE, [], [], [], '', '', null, []], + [Calendar::SUBJECT_UPDATE, [], [], [], '', '', null, []], // No visible change - owner only - [Extension::SUBJECT_UPDATE, [ + [Calendar::SUBJECT_UPDATE, [ 'principaluri' => 'principal/user/admin', 'id' => 42, '{DAV:}displayname' => 'Name of calendar', ], ['shares'], [], '', 'admin', null, ['admin']], // Visible change - [Extension::SUBJECT_UPDATE, [ + [Calendar::SUBJECT_UPDATE, [ 'principaluri' => 'principal/user/admin', 'id' => 42, '{DAV:}displayname' => 'Name of calendar', ], ['shares'], ['{DAV:}displayname' => 'Name'], '', 'admin', ['user1'], ['user1', 'admin']], - [Extension::SUBJECT_UPDATE, [ + [Calendar::SUBJECT_UPDATE, [ 'principaluri' => 'principal/user/admin', 'id' => 42, '{DAV:}displayname' => 'Name of calendar', ], ['shares'], ['{DAV:}displayname' => 'Name'], 'test2', 'test2', ['user1'], ['user1', 'admin']], // Delete calendar - [Extension::SUBJECT_DELETE, [], [], [], '', '', null, []], - [Extension::SUBJECT_DELETE, [ + [Calendar::SUBJECT_DELETE, [], [], [], '', '', null, []], + [Calendar::SUBJECT_DELETE, [ 'principaluri' => 'principal/user/admin', 'id' => 42, '{DAV:}displayname' => 'Name of calendar', ], ['shares'], [], '', 'admin', [], ['admin']], - [Extension::SUBJECT_DELETE, [ + [Calendar::SUBJECT_DELETE, [ 'principaluri' => 'principal/user/admin', 'id' => 42, '{DAV:}displayname' => 'Name of calendar', ], ['shares'], [], '', 'admin', ['user1'], ['user1', 'admin']], - [Extension::SUBJECT_DELETE, [ + [Calendar::SUBJECT_DELETE, [ 'principaluri' => 'principal/user/admin', 'id' => 42, '{DAV:}displayname' => 'Name of calendar', @@ -202,11 +202,11 @@ class BackendTest extends TestCase { ->willReturnSelf(); $event->expects($this->once()) ->method('setObject') - ->with(Extension::CALENDAR, $data['id']) + ->with('calendar', $data['id']) ->willReturnSelf(); $event->expects($this->once()) ->method('setType') - ->with(Extension::CALENDAR) + ->with('calendar') ->willReturnSelf(); $event->expects($this->once()) ->method('setAuthor') diff --git a/apps/dav/tests/unit/CalDAV/Activity/Filter/CalendarTest.php b/apps/dav/tests/unit/CalDAV/Activity/Filter/CalendarTest.php new file mode 100644 index 0000000000..895a404acf --- /dev/null +++ b/apps/dav/tests/unit/CalDAV/Activity/Filter/CalendarTest.php @@ -0,0 +1,84 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\Tests\unit\CalDAV\Activity\Filter; + +use OCA\DAV\CalDAV\Activity\Filter\Calendar; +use OCP\Activity\IFilter; +use OCP\IL10N; +use OCP\IURLGenerator; +use Test\TestCase; + +class CalendarTest extends TestCase { + + /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */ + protected $url; + + /** @var IFilter|\PHPUnit_Framework_MockObject_MockObject */ + protected $filter; + + protected function setUp() { + parent::setUp(); + $this->url = $this->createMock(IURLGenerator::class); + $l = $this->createMock(IL10N::class); + $l->expects($this->any()) + ->method('t') + ->willReturnCallback(function($string, $args) { + return vsprintf($string, $args); + }); + + $this->filter = new Calendar( + $l, $this->url + ); + } + + public function testGetIcon() { + $this->url->expects($this->once()) + ->method('imagePath') + ->with('core', 'places/calendar-dark.svg') + ->willReturn('path-to-icon'); + + $this->url->expects($this->once()) + ->method('getAbsoluteURL') + ->with('path-to-icon') + ->willReturn('absolute-path-to-icon'); + + $this->assertEquals('absolute-path-to-icon', $this->filter->getIcon()); + } + + public function dataFilterTypes() { + return [ + [[], []], + [['calendar', 'calendar_event'], ['calendar', 'calendar_event']], + [['calendar', 'calendar_event', 'calendar_todo'], ['calendar', 'calendar_event']], + [['calendar', 'calendar_event', 'files'], ['calendar', 'calendar_event']], + ]; + } + + /** + * @dataProvider dataFilterTypes + * @param string[] $types + * @param string[] $expected + */ + public function testFilterTypes($types, $expected) { + $this->assertEquals($expected, $this->filter->filterTypes($types)); + } +} diff --git a/apps/dav/tests/unit/CalDAV/Activity/Filter/GenericTest.php b/apps/dav/tests/unit/CalDAV/Activity/Filter/GenericTest.php new file mode 100644 index 0000000000..533f88747c --- /dev/null +++ b/apps/dav/tests/unit/CalDAV/Activity/Filter/GenericTest.php @@ -0,0 +1,110 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\Tests\unit\CalDAV\Activity\Filter; + +use OCA\DAV\CalDAV\Activity\Filter\Calendar; +use OCA\DAV\CalDAV\Activity\Filter\Todo; +use OCP\Activity\IFilter; +use Test\TestCase; + +class GenericTest extends TestCase { + + public function dataFilters() { + return [ + [Calendar::class], + [Todo::class], + ]; + } + + /** + * @dataProvider dataFilters + * @param string $filterClass + */ + public function testImplementsInterface($filterClass) { + $filter = \OC::$server->query($filterClass); + $this->assertInstanceOf(IFilter::class, $filter); + } + + /** + * @dataProvider dataFilters + * @param string $filterClass + */ + public function testGetIdentifier($filterClass) { + /** @var IFilter $filter */ + $filter = \OC::$server->query($filterClass); + $this->assertInternalType('string', $filter->getIdentifier()); + } + + /** + * @dataProvider dataFilters + * @param string $filterClass + */ + public function testGetName($filterClass) { + /** @var IFilter $filter */ + $filter = \OC::$server->query($filterClass); + $this->assertInternalType('string', $filter->getName()); + } + + /** + * @dataProvider dataFilters + * @param string $filterClass + */ + public function testGetPriority($filterClass) { + /** @var IFilter $filter */ + $filter = \OC::$server->query($filterClass); + $priority = $filter->getPriority(); + $this->assertInternalType('int', $filter->getPriority()); + $this->assertGreaterThanOrEqual(0, $priority); + $this->assertLessThanOrEqual(100, $priority); + } + + /** + * @dataProvider dataFilters + * @param string $filterClass + */ + public function testGetIcon($filterClass) { + /** @var IFilter $filter */ + $filter = \OC::$server->query($filterClass); + $this->assertInternalType('string', $filter->getIcon()); + $this->assertStringStartsWith('http', $filter->getIcon()); + } + + /** + * @dataProvider dataFilters + * @param string $filterClass + */ + public function testFilterTypes($filterClass) { + /** @var IFilter $filter */ + $filter = \OC::$server->query($filterClass); + $this->assertInternalType('array', $filter->filterTypes([])); + } + + /** + * @dataProvider dataFilters + * @param string $filterClass + */ + public function testAllowedApps($filterClass) { + /** @var IFilter $filter */ + $filter = \OC::$server->query($filterClass); + $this->assertInternalType('array', $filter->allowedApps()); + } +} diff --git a/apps/dav/tests/unit/CalDAV/Activity/Filter/TodoTest.php b/apps/dav/tests/unit/CalDAV/Activity/Filter/TodoTest.php new file mode 100644 index 0000000000..54a5a6f5f9 --- /dev/null +++ b/apps/dav/tests/unit/CalDAV/Activity/Filter/TodoTest.php @@ -0,0 +1,84 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\Tests\unit\CalDAV\Activity\Filter; + +use OCA\DAV\CalDAV\Activity\Filter\Todo; +use OCP\Activity\IFilter; +use OCP\IL10N; +use OCP\IURLGenerator; +use Test\TestCase; + +class TodoTest extends TestCase { + + /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */ + protected $url; + + /** @var IFilter|\PHPUnit_Framework_MockObject_MockObject */ + protected $filter; + + protected function setUp() { + parent::setUp(); + $this->url = $this->createMock(IURLGenerator::class); + $l = $this->createMock(IL10N::class); + $l->expects($this->any()) + ->method('t') + ->willReturnCallback(function($string, $args) { + return vsprintf($string, $args); + }); + + $this->filter = new Todo( + $l, $this->url + ); + } + + public function testGetIcon() { + $this->url->expects($this->once()) + ->method('imagePath') + ->with('core', 'actions/checkmark.svg') + ->willReturn('path-to-icon'); + + $this->url->expects($this->once()) + ->method('getAbsoluteURL') + ->with('path-to-icon') + ->willReturn('absolute-path-to-icon'); + + $this->assertEquals('absolute-path-to-icon', $this->filter->getIcon()); + } + + public function dataFilterTypes() { + return [ + [[], []], + [['calendar_todo'], ['calendar_todo']], + [['calendar', 'calendar_event', 'calendar_todo'], ['calendar_todo']], + [['calendar', 'calendar_todo', 'files'], ['calendar_todo']], + ]; + } + + /** + * @dataProvider dataFilterTypes + * @param string[] $types + * @param string[] $expected + */ + public function testFilterTypes($types, $expected) { + $this->assertEquals($expected, $this->filter->filterTypes($types)); + } +} diff --git a/apps/dav/tests/unit/CalDAV/Activity/Provider/BaseTest.php b/apps/dav/tests/unit/CalDAV/Activity/Provider/BaseTest.php new file mode 100644 index 0000000000..85eb439f10 --- /dev/null +++ b/apps/dav/tests/unit/CalDAV/Activity/Provider/BaseTest.php @@ -0,0 +1,189 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\Tests\unit\CalDAV\Activity\Provider; + +use OCA\DAV\CalDAV\Activity\Provider\Base; +use OCP\Activity\IEvent; +use OCP\Activity\IProvider; +use OCP\IUser; +use OCP\IUserManager; +use Test\TestCase; + +class BaseTest extends TestCase { + + /** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */ + protected $userManager; + + /** @var IProvider|Base|\PHPUnit_Framework_MockObject_MockObject */ + protected $provider; + + protected function setUp() { + parent::setUp(); + $this->userManager = $this->createMock(IUserManager::class); + $this->provider = $this->getMockBuilder(Base::class) + ->setConstructorArgs([ + $this->userManager + ]) + ->setMethods(['parse']) + ->getMock(); + } + + public function dataSetSubjects() { + return [ + ['abc', [], 'abc'], + ['{actor} created {calendar}', ['actor' => ['name' => 'abc'], 'calendar' => ['name' => 'xyz']], 'abc created xyz'], + ]; + } + + /** + * @dataProvider dataSetSubjects + * @param string $subject + * @param array $parameters + * @param string $parsedSubject + */ + public function testSetSubjects($subject, array $parameters, $parsedSubject) { + $event = $this->createMock(IEvent::class); + $event->expects($this->once()) + ->method('setRichSubject') + ->with($subject, $parameters) + ->willReturnSelf(); + $event->expects($this->once()) + ->method('setParsedSubject') + ->with($parsedSubject) + ->willReturnSelf(); + + $this->invokePrivate($this->provider, 'setSubjects', [$event, $subject, $parameters]); + } + + public function dataGenerateObjectParameter() { + return [ + [23, 'c1'], + [42, 'c2'], + ]; + } + + /** + * @dataProvider dataGenerateObjectParameter + * @param int $id + * @param string $name + */ + public function testGenerateObjectParameter($id, $name) { + $this->assertEquals([ + 'type' => 'calendar-event', + 'id' => $id, + 'name' => $name, + ], $this->invokePrivate($this->provider, 'generateObjectParameter', [['id' => $id, 'name' => $name]])); + } + + public function dataGenerateObjectParameterThrows() { + return [ + ['event'], + [['name' => 'event']], + [['id' => 42]], + ]; + } + + /** + * @dataProvider dataGenerateObjectParameterThrows + * @expectedException \InvalidArgumentException + * @param mixed $eventData + */ + public function testGenerateObjectParameterThrows($eventData) { + $this->invokePrivate($this->provider, 'generateObjectParameter', [$eventData]); + } + + public function dataGenerateCalendarParameter() { + return [ + [23, 'c1'], + [42, 'c2'], + ]; + } + + /** + * @dataProvider dataGenerateCalendarParameter + * @param int $id + * @param string $name + */ + public function testGenerateCalendarParameter($id, $name) { + $this->assertEquals([ + 'type' => 'calendar', + 'id' => $id, + 'name' => $name, + ], $this->invokePrivate($this->provider, 'generateCalendarParameter', [$id, $name])); + } + + public function dataGenerateGroupParameter() { + return [ + ['g1'], + ['g2'], + ]; + } + + /** + * @dataProvider dataGenerateGroupParameter + * @param string $gid + */ + public function testGenerateGroupParameter($gid) { + $this->assertEquals([ + 'type' => 'group', + 'id' => $gid, + 'name' => $gid, + ], $this->invokePrivate($this->provider, 'generateGroupParameter', [$gid])); + } + + public function dataGenerateUserParameter() { + $u1 = $this->createMock(IUser::class); + $u1->expects($this->any()) + ->method('getDisplayName') + ->willReturn('User 1'); + return [ + ['u1', 'User 1', $u1], + ['u2', 'u2', null], + ]; + } + + /** + * @dataProvider dataGenerateUserParameter + * @param string $uid + * @param string $displayName + * @param IUser|null $user + */ + public function testGenerateUserParameter($uid, $displayName, $user) { + $this->userManager->expects($this->once()) + ->method('get') + ->with($uid) + ->willReturn($user); + + $this->assertEquals([ + 'type' => 'user', + 'id' => $uid, + 'name' => $displayName, + ], $this->invokePrivate($this->provider, 'generateUserParameter', [$uid])); + + // Test caching (only 1 user manager invocation allowed) + $this->assertEquals([ + 'type' => 'user', + 'id' => $uid, + 'name' => $displayName, + ], $this->invokePrivate($this->provider, 'generateUserParameter', [$uid])); + } +} diff --git a/apps/dav/tests/unit/CalDAV/Activity/Setting/GenericTest.php b/apps/dav/tests/unit/CalDAV/Activity/Setting/GenericTest.php new file mode 100644 index 0000000000..54c7a54baf --- /dev/null +++ b/apps/dav/tests/unit/CalDAV/Activity/Setting/GenericTest.php @@ -0,0 +1,121 @@ + + * + * @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 . + * + */ + +namespace OCA\DAV\Tests\unit\CalDAV\Activity\Setting; + +use OCA\DAV\CalDAV\Activity\Setting\Calendar; +use OCA\DAV\CalDAV\Activity\Setting\Event; +use OCA\DAV\CalDAV\Activity\Setting\Todo; +use OCP\Activity\ISetting; +use Test\TestCase; + +class GenericTest extends TestCase { + + public function dataSettings() { + return [ + [Calendar::class], + [Event::class], + [Todo::class], + ]; + } + + /** + * @dataProvider dataSettings + * @param string $settingClass + */ + public function testImplementsInterface($settingClass) { + $setting = \OC::$server->query($settingClass); + $this->assertInstanceOf(ISetting::class, $setting); + } + + /** + * @dataProvider dataSettings + * @param string $settingClass + */ + public function testGetIdentifier($settingClass) { + /** @var ISetting $setting */ + $setting = \OC::$server->query($settingClass); + $this->assertInternalType('string', $setting->getIdentifier()); + } + + /** + * @dataProvider dataSettings + * @param string $settingClass + */ + public function testGetName($settingClass) { + /** @var ISetting $setting */ + $setting = \OC::$server->query($settingClass); + $this->assertInternalType('string', $setting->getName()); + } + + /** + * @dataProvider dataSettings + * @param string $settingClass + */ + public function testGetPriority($settingClass) { + /** @var ISetting $setting */ + $setting = \OC::$server->query($settingClass); + $priority = $setting->getPriority(); + $this->assertInternalType('int', $setting->getPriority()); + $this->assertGreaterThanOrEqual(0, $priority); + $this->assertLessThanOrEqual(100, $priority); + } + + /** + * @dataProvider dataSettings + * @param string $settingClass + */ + public function testCanChangeStream($settingClass) { + /** @var ISetting $setting */ + $setting = \OC::$server->query($settingClass); + $this->assertInternalType('bool', $setting->canChangeStream()); + } + + /** + * @dataProvider dataSettings + * @param string $settingClass + */ + public function testIsDefaultEnabledStream($settingClass) { + /** @var ISetting $setting */ + $setting = \OC::$server->query($settingClass); + $this->assertInternalType('bool', $setting->isDefaultEnabledStream()); + } + + /** + * @dataProvider dataSettings + * @param string $settingClass + */ + public function testCanChangeMail($settingClass) { + /** @var ISetting $setting */ + $setting = \OC::$server->query($settingClass); + $this->assertInternalType('bool', $setting->canChangeMail()); + } + + /** + * @dataProvider dataSettings + * @param string $settingClass + */ + public function testIsDefaultEnabledMail($settingClass) { + /** @var ISetting $setting */ + $setting = \OC::$server->query($settingClass); + $this->assertInternalType('bool', $setting->isDefaultEnabledMail()); + } +} diff --git a/core/img/places/calendar-dark.svg b/core/img/places/calendar-dark.svg index 06d2a8efca..9290ef60f6 100644 --- a/core/img/places/calendar-dark.svg +++ b/core/img/places/calendar-dark.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/core/img/places/contacts-dark.svg b/core/img/places/contacts-dark.svg index c819521a25..714cfef1db 100644 --- a/core/img/places/contacts-dark.svg +++ b/core/img/places/contacts-dark.svg @@ -1 +1 @@ - \ No newline at end of file +