summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Reschke <lukas@owncloud.com>2015-09-10 15:26:36 +0200
committerLukas Reschke <lukas@owncloud.com>2015-09-10 15:26:36 +0200
commitfb717f254fe81065912c13e0907ba374c8167f98 (patch)
tree1a34b7c8bed92bb5686d73a1521998b2057276cf
parent89cd9295600f6707579240f3f010d4b75a2d85cd (diff)
parent38001d824b142ca9c47f2afafce91ab8b76f1a9a (diff)
downloadnextcloud-server-fb717f254fe81065912c13e0907ba374c8167f98.tar.gz
nextcloud-server-fb717f254fe81065912c13e0907ba374c8167f98.zip
Merge pull request #18699 from owncloud/notification-manager
Notification manager
-rw-r--r--apps/files_sharing/ajax/external.php1
-rw-r--r--apps/files_sharing/api/remote.php4
-rw-r--r--apps/files_sharing/api/server2server.php23
-rw-r--r--apps/files_sharing/appinfo/app.php7
-rw-r--r--apps/files_sharing/appinfo/application.php1
-rw-r--r--apps/files_sharing/lib/external/manager.php24
-rw-r--r--apps/files_sharing/lib/hooks.php1
-rw-r--r--apps/files_sharing/lib/notifier.php86
-rw-r--r--apps/files_sharing/tests/external/managertest.php1
-rw-r--r--apps/files_sharing/tests/server2server.php1
-rw-r--r--lib/private/notification/action.php167
-rw-r--r--lib/private/notification/iaction.php109
-rw-r--r--lib/private/notification/iapp.php56
-rw-r--r--lib/private/notification/imanager.php56
-rw-r--r--lib/private/notification/inotification.php241
-rw-r--r--lib/private/notification/inotifier.php43
-rw-r--r--lib/private/notification/manager.php191
-rw-r--r--lib/private/notification/notification.php446
-rw-r--r--lib/private/server.php14
-rw-r--r--lib/public/iservercontainer.php9
-rw-r--r--tests/lib/notification/actiontest.php236
-rw-r--r--tests/lib/notification/managertest.php345
-rw-r--r--tests/lib/notification/notificationtest.php601
-rw-r--r--tests/lib/server.php2
24 files changed, 2662 insertions, 3 deletions
diff --git a/apps/files_sharing/ajax/external.php b/apps/files_sharing/ajax/external.php
index d26a64d3aec..66cfd8e9d1a 100644
--- a/apps/files_sharing/ajax/external.php
+++ b/apps/files_sharing/ajax/external.php
@@ -52,6 +52,7 @@ $externalManager = new \OCA\Files_Sharing\External\Manager(
\OC\Files\Filesystem::getMountManager(),
\OC\Files\Filesystem::getLoader(),
\OC::$server->getHTTPHelper(),
+ \OC::$server->getNotificationManager(),
\OC::$server->getUserSession()->getUser()->getUID()
);
diff --git a/apps/files_sharing/api/remote.php b/apps/files_sharing/api/remote.php
index f6cb0a29d8b..0f6d2dc265a 100644
--- a/apps/files_sharing/api/remote.php
+++ b/apps/files_sharing/api/remote.php
@@ -38,6 +38,7 @@ class Remote {
Filesystem::getMountManager(),
Filesystem::getLoader(),
\OC::$server->getHTTPHelper(),
+ \OC::$server->getNotificationManager(),
\OC_User::getUser()
);
@@ -56,6 +57,7 @@ class Remote {
Filesystem::getMountManager(),
Filesystem::getLoader(),
\OC::$server->getHTTPHelper(),
+ \OC::$server->getNotificationManager(),
\OC_User::getUser()
);
@@ -78,6 +80,7 @@ class Remote {
Filesystem::getMountManager(),
Filesystem::getLoader(),
\OC::$server->getHTTPHelper(),
+ \OC::$server->getNotificationManager(),
\OC_User::getUser()
);
@@ -87,5 +90,4 @@ class Remote {
return new \OC_OCS_Result(null, 404, "wrong share ID, share doesn't exist.");
}
-
}
diff --git a/apps/files_sharing/api/server2server.php b/apps/files_sharing/api/server2server.php
index 4328e3830ba..6ecaea20535 100644
--- a/apps/files_sharing/api/server2server.php
+++ b/apps/files_sharing/api/server2server.php
@@ -70,6 +70,7 @@ class Server2Server {
\OC\Files\Filesystem::getMountManager(),
\OC\Files\Filesystem::getLoader(),
\OC::$server->getHTTPHelper(),
+ \OC::$server->getNotificationManager(),
$shareWith
);
@@ -82,6 +83,28 @@ class Server2Server {
Activity::FILES_SHARING_APP, Activity::SUBJECT_REMOTE_SHARE_RECEIVED, array($user, trim($name, '/')), '', array(),
'', '', $shareWith, Activity::TYPE_REMOTE_SHARE, Activity::PRIORITY_LOW);
+ $urlGenerator = \OC::$server->getURLGenerator();
+
+ $notificationManager = \OC::$server->getNotificationManager();
+ $notification = $notificationManager->createNotification();
+ $notification->setApp('files_sharing')
+ ->setUser($shareWith)
+ ->setTimestamp(time())
+ ->setObject('remote_share', $remoteId)
+ ->setSubject('remote_share', [$user, trim($name, '/')]);
+
+ $acceptAction = $notification->createAction();
+ $acceptAction->setLabel('accept')
+ ->setLink($urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/remote_shares/' . $remoteId), 'POST');
+ $declineAction = $notification->createAction();
+ $declineAction->setLabel('decline')
+ ->setLink($urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/remote_shares/' . $remoteId), 'DELETE');
+
+ $notification->addAction($acceptAction)
+ ->addAction($declineAction);
+
+ $notificationManager->notify($notification);
+
return new \OC_OCS_Result();
} catch (\Exception $e) {
\OCP\Util::writeLog('files_sharing', 'server can not add remote share, ' . $e->getMessage(), \OCP\Util::ERROR);
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index 295d013beff..20f1b046d35 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -103,3 +103,10 @@ if ($config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes') {
}
}
}
+
+$manager = \OC::$server->getNotificationManager();
+$manager->registerNotifier(function() {
+ return new \OCA\Files_Sharing\Notifier(
+ \OC::$server->getL10NFactory()
+ );
+});
diff --git a/apps/files_sharing/appinfo/application.php b/apps/files_sharing/appinfo/application.php
index 530195c65fa..d0dcadb77e8 100644
--- a/apps/files_sharing/appinfo/application.php
+++ b/apps/files_sharing/appinfo/application.php
@@ -93,6 +93,7 @@ class Application extends App {
\OC\Files\Filesystem::getMountManager(),
\OC\Files\Filesystem::getLoader(),
$server->getHTTPHelper(),
+ $server->getNotificationManager(),
$uid
);
});
diff --git a/apps/files_sharing/lib/external/manager.php b/apps/files_sharing/lib/external/manager.php
index 67a26c096c2..17142e95099 100644
--- a/apps/files_sharing/lib/external/manager.php
+++ b/apps/files_sharing/lib/external/manager.php
@@ -28,6 +28,7 @@ namespace OCA\Files_Sharing\External;
use OC\Files\Filesystem;
use OCP\Files;
+use OC\Notification\IManager;
class Manager {
const STORAGE = '\OCA\Files_Sharing\External\Storage';
@@ -58,19 +59,26 @@ class Manager {
private $httpHelper;
/**
+ * @var IManager
+ */
+ private $notificationManager;
+
+ /**
* @param \OCP\IDBConnection $connection
* @param \OC\Files\Mount\Manager $mountManager
* @param \OCP\Files\Storage\IStorageFactory $storageLoader
* @param \OC\HTTPHelper $httpHelper
+ * @param IManager $notificationManager
* @param string $uid
*/
public function __construct(\OCP\IDBConnection $connection, \OC\Files\Mount\Manager $mountManager,
- \OCP\Files\Storage\IStorageFactory $storageLoader, \OC\HTTPHelper $httpHelper, $uid) {
+ \OCP\Files\Storage\IStorageFactory $storageLoader, \OC\HTTPHelper $httpHelper, IManager $notificationManager, $uid) {
$this->connection = $connection;
$this->mountManager = $mountManager;
$this->storageLoader = $storageLoader;
$this->httpHelper = $httpHelper;
$this->uid = $uid;
+ $this->notificationManager = $notificationManager;
}
/**
@@ -206,6 +214,7 @@ class Manager {
$acceptShare->execute(array(1, $mountPoint, $hash, $id, $this->uid));
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'accept');
+ $this->scrapNotification($share['remote_id']);
return true;
}
@@ -228,6 +237,7 @@ class Manager {
$removeShare->execute(array($id, $this->uid));
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline');
+ $this->scrapNotification($share['remote_id']);
return true;
}
@@ -235,6 +245,17 @@ class Manager {
}
/**
+ * @param int $remoteShare
+ */
+ protected function scrapNotification($remoteShare) {
+ $filter = $this->notificationManager->createNotification();
+ $filter->setApp('files_sharing')
+ ->setUser($this->uid)
+ ->setObject('remote_share', (int) $remoteShare);
+ $this->notificationManager->markProcessed($filter);
+ }
+
+ /**
* inform remote server whether server-to-server share was accepted/declined
*
* @param string $remote
@@ -265,6 +286,7 @@ class Manager {
\OC\Files\Filesystem::getMountManager(),
\OC\Files\Filesystem::getLoader(),
\OC::$server->getHTTPHelper(),
+ \OC::$server->getNotificationManager(),
$params['user']
);
diff --git a/apps/files_sharing/lib/hooks.php b/apps/files_sharing/lib/hooks.php
index 7dd04f2f4a0..1937010f390 100644
--- a/apps/files_sharing/lib/hooks.php
+++ b/apps/files_sharing/lib/hooks.php
@@ -33,6 +33,7 @@ class Hooks {
\OC\Files\Filesystem::getMountManager(),
\OC\Files\Filesystem::getLoader(),
\OC::$server->getHTTPHelper(),
+ \OC::$server->getNotificationManager(),
$params['uid']);
$manager->removeUserShares($params['uid']);
diff --git a/apps/files_sharing/lib/notifier.php b/apps/files_sharing/lib/notifier.php
new file mode 100644
index 00000000000..cc2deb3f439
--- /dev/null
+++ b/apps/files_sharing/lib/notifier.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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\Files_Sharing;
+
+
+use OC\Notification\INotification;
+use OC\Notification\INotifier;
+
+class Notifier implements INotifier {
+ /** @var \OCP\L10N\IFactory */
+ protected $factory;
+
+ /**
+ * @param \OCP\L10N\IFactory $factory
+ */
+ public function __construct(\OCP\L10N\IFactory $factory) {
+ $this->factory = $factory;
+ }
+
+ /**
+ * @param INotification $notification
+ * @param string $languageCode The code of the language that should be used to prepare the notification
+ * @return INotification
+ */
+ public function prepare(INotification $notification, $languageCode) {
+ if ($notification->getApp() !== 'files_sharing') {
+ // Not my app => throw
+ throw new \InvalidArgumentException();
+ }
+
+ // Read the language from the notification
+ $l = $this->factory->get('files_sharing', $languageCode);
+
+ switch ($notification->getSubject()) {
+ // Deal with known subjects
+ case 'remote_share':
+ $params = $notification->getSubjectParameters();
+ $notification->setParsedSubject(
+ (string) $l->t('You received %s as a remote share from %s', $params)
+ );
+
+ // Deal with the actions for a known subject
+ foreach ($notification->getActions() as $action) {
+ switch ($action->getLabel()) {
+ case 'accept':
+ $action->setParsedLabel(
+ (string) $l->t('Accept')
+ );
+ break;
+
+ case 'decline':
+ $action->setParsedLabel(
+ (string) $l->t('Decline')
+ );
+ break;
+ }
+
+ $notification->addParsedAction($action);
+ }
+ return $notification;
+
+ default:
+ // Unknown subject => Unknown notification => throw
+ throw new \InvalidArgumentException();
+ }
+ }
+}
diff --git a/apps/files_sharing/tests/external/managertest.php b/apps/files_sharing/tests/external/managertest.php
index df01ea0f738..8e03c67a9a3 100644
--- a/apps/files_sharing/tests/external/managertest.php
+++ b/apps/files_sharing/tests/external/managertest.php
@@ -50,6 +50,7 @@ class ManagerTest extends TestCase {
$this->mountManager,
new StorageFactory(),
$httpHelper,
+ \OC::$server->getNotificationManager(),
$this->uid
);
}
diff --git a/apps/files_sharing/tests/server2server.php b/apps/files_sharing/tests/server2server.php
index a1c87d73393..a4cc8209a8e 100644
--- a/apps/files_sharing/tests/server2server.php
+++ b/apps/files_sharing/tests/server2server.php
@@ -154,6 +154,7 @@ class Test_Files_Sharing_S2S_OCS_API extends TestCase {
\OC\Files\Filesystem::getMountManager(),
\OC\Files\Filesystem::getLoader(),
\OC::$server->getHTTPHelper(),
+ \OC::$server->getNotificationManager(),
$toDelete
);
diff --git a/lib/private/notification/action.php b/lib/private/notification/action.php
new file mode 100644
index 00000000000..6de8a1a4bbc
--- /dev/null
+++ b/lib/private/notification/action.php
@@ -0,0 +1,167 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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 OC\Notification;
+
+
+class Action implements IAction {
+
+ /** @var string */
+ protected $label;
+
+ /** @var string */
+ protected $labelParsed;
+
+ /** @var string */
+ protected $link;
+
+ /** @var string */
+ protected $requestType;
+
+ /** @var string */
+ protected $icon;
+
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ $this->label = '';
+ $this->labelParsed = '';
+ $this->link = '';
+ $this->requestType = '';
+ $this->icon = '';
+ }
+
+ /**
+ * @param string $label
+ * @return $this
+ * @throws \InvalidArgumentException if the label is invalid
+ * @since 8.2.0
+ */
+ public function setLabel($label) {
+ if (!is_string($label) || $label === '' || isset($label[32])) {
+ throw new \InvalidArgumentException('The given label is invalid');
+ }
+ $this->label = $label;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getLabel() {
+ return $this->label;
+ }
+
+ /**
+ * @param string $label
+ * @return $this
+ * @throws \InvalidArgumentException if the label is invalid
+ * @since 8.2.0
+ */
+ public function setParsedLabel($label) {
+ if (!is_string($label) || $label === '') {
+ throw new \InvalidArgumentException('The given parsed label is invalid');
+ }
+ $this->labelParsed = $label;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getParsedLabel() {
+ return $this->labelParsed;
+ }
+
+ /**
+ * @param string $link
+ * @param string $requestType
+ * @return $this
+ * @throws \InvalidArgumentException if the link is invalid
+ * @since 8.2.0
+ */
+ public function setLink($link, $requestType) {
+ if (!is_string($link) || $link === '' || isset($link[256])) {
+ throw new \InvalidArgumentException('The given link is invalid');
+ }
+ if (!in_array($requestType, ['GET', 'POST', 'PUT', 'DELETE'], true)) {
+ throw new \InvalidArgumentException('The given request type is invalid');
+ }
+ $this->link = $link;
+ $this->requestType = $requestType;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getLink() {
+ return $this->link;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getRequestType() {
+ return $this->requestType;
+ }
+
+ /**
+ * @param string $icon
+ * @return $this
+ * @throws \InvalidArgumentException if the icon is invalid
+ * @since 8.2.0
+ */
+ public function setIcon($icon) {
+ if (!is_string($icon) || $icon === '' || isset($icon[64])) {
+ throw new \InvalidArgumentException('The given icon is invalid');
+ }
+ $this->icon = $icon;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getIcon() {
+ return $this->icon;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isValid() {
+ return $this->label !== '' && $this->link !== '';
+ }
+
+ /**
+ * @return bool
+ */
+ public function isValidParsed() {
+ return $this->labelParsed !== '' && $this->link !== '';
+ }
+}
diff --git a/lib/private/notification/iaction.php b/lib/private/notification/iaction.php
new file mode 100644
index 00000000000..da6728f5c52
--- /dev/null
+++ b/lib/private/notification/iaction.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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 OC\Notification;
+
+/**
+ * Interface IAction
+ *
+ * @package OC\Notification
+ * @since 8.2.0
+ *
+ * DEVELOPER NOTE:
+ * The notification api is experimental only in 8.2.0! Do not start using it,
+ * if you can not prepare an update for the next version afterwards.
+ */
+interface IAction {
+ /**
+ * @param string $label
+ * @return $this
+ * @throws \InvalidArgumentException if the label is invalid
+ * @since 8.2.0
+ */
+ public function setLabel($label);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getLabel();
+
+ /**
+ * @param string $label
+ * @return $this
+ * @throws \InvalidArgumentException if the label is invalid
+ * @since 8.2.0
+ */
+ public function setParsedLabel($label);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getParsedLabel();
+
+ /**
+ * @param string $link
+ * @param string $requestType
+ * @return $this
+ * @throws \InvalidArgumentException if the link is invalid
+ * @since 8.2.0
+ */
+ public function setLink($link, $requestType);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getLink();
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getRequestType();
+
+ /**
+ * @param string $icon
+ * @return $this
+ * @throws \InvalidArgumentException if the icon is invalid
+ * @since 8.2.0
+ */
+ public function setIcon($icon);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getIcon();
+
+ /**
+ * @return bool
+ * @since 8.2.0
+ */
+ public function isValid();
+
+ /**
+ * @return bool
+ * @since 8.2.0
+ */
+ public function isValidParsed();
+}
diff --git a/lib/private/notification/iapp.php b/lib/private/notification/iapp.php
new file mode 100644
index 00000000000..eda66423f3a
--- /dev/null
+++ b/lib/private/notification/iapp.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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 OC\Notification;
+
+/**
+ * Interface IApp
+ *
+ * @package OC\Notification
+ * @since 8.2.0
+ *
+ * DEVELOPER NOTE:
+ * The notification api is experimental only in 8.2.0! Do not start using it,
+ * if you can not prepare an update for the next version afterwards.
+ */
+interface IApp {
+ /**
+ * @param INotification $notification
+ * @return null
+ * @throws \InvalidArgumentException When the notification is not valid
+ * @since 8.2.0
+ */
+ public function notify(INotification $notification);
+
+ /**
+ * @param INotification $notification
+ * @return null
+ * @since 8.2.0
+ */
+ public function markProcessed(INotification $notification);
+
+ /**
+ * @param INotification $notification
+ * @return int
+ * @since 8.2.0
+ */
+ public function getCount(INotification $notification);
+}
diff --git a/lib/private/notification/imanager.php b/lib/private/notification/imanager.php
new file mode 100644
index 00000000000..0cd92b33251
--- /dev/null
+++ b/lib/private/notification/imanager.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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 OC\Notification;
+
+/**
+ * Interface IManager
+ *
+ * @package OC\Notification
+ * @since 8.2.0
+ *
+ * DEVELOPER NOTE:
+ * The notification api is experimental only in 8.2.0! Do not start using it,
+ * if you can not prepare an update for the next version afterwards.
+ */
+interface IManager extends IApp, INotifier {
+ /**
+ * @param \Closure $service The service must implement IApp, otherwise a
+ * \InvalidArgumentException is thrown later
+ * @return null
+ * @since 8.2.0
+ */
+ public function registerApp(\Closure $service);
+
+ /**
+ * @param \Closure $service The service must implement INotifier, otherwise a
+ * \InvalidArgumentException is thrown later
+ * @return null
+ * @since 8.2.0
+ */
+ public function registerNotifier(\Closure $service);
+
+ /**
+ * @return INotification
+ * @since 8.2.0
+ */
+ public function createNotification();
+}
diff --git a/lib/private/notification/inotification.php b/lib/private/notification/inotification.php
new file mode 100644
index 00000000000..faf5db1d24c
--- /dev/null
+++ b/lib/private/notification/inotification.php
@@ -0,0 +1,241 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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 OC\Notification;
+
+/**
+ * Interface INotification
+ *
+ * @package OC\Notification
+ * @since 8.2.0
+ *
+ * DEVELOPER NOTE:
+ * The notification api is experimental only in 8.2.0! Do not start using it,
+ * if you can not prepare an update for the next version afterwards.
+ */
+interface INotification {
+ /**
+ * @param string $app
+ * @return $this
+ * @throws \InvalidArgumentException if the app id are invalid
+ * @since 8.2.0
+ */
+ public function setApp($app);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getApp();
+
+ /**
+ * @param string $user
+ * @return $this
+ * @throws \InvalidArgumentException if the user id are invalid
+ * @since 8.2.0
+ */
+ public function setUser($user);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getUser();
+
+ /**
+ * @param int $timestamp
+ * @return $this
+ * @throws \InvalidArgumentException if the timestamp are invalid
+ * @since 8.2.0
+ */
+ public function setTimestamp($timestamp);
+
+ /**
+ * @return int
+ * @since 8.2.0
+ */
+ public function getTimestamp();
+
+ /**
+ * @param string $type
+ * @param int $id
+ * @return $this
+ * @throws \InvalidArgumentException if the object type or id are invalid
+ * @since 8.2.0
+ */
+ public function setObject($type, $id);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getObjectType();
+
+ /**
+ * @return int
+ * @since 8.2.0
+ */
+ public function getObjectId();
+
+ /**
+ * @param string $subject
+ * @param array $parameters
+ * @return $this
+ * @throws \InvalidArgumentException if the subject or parameters are invalid
+ * @since 8.2.0
+ */
+ public function setSubject($subject, array $parameters = []);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getSubject();
+
+ /**
+ * @return string[]
+ * @since 8.2.0
+ */
+ public function getSubjectParameters();
+
+ /**
+ * @param string $subject
+ * @return $this
+ * @throws \InvalidArgumentException if the subject are invalid
+ * @since 8.2.0
+ */
+ public function setParsedSubject($subject);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getParsedSubject();
+
+ /**
+ * @param string $message
+ * @param array $parameters
+ * @return $this
+ * @throws \InvalidArgumentException if the message or parameters are invalid
+ * @since 8.2.0
+ */
+ public function setMessage($message, array $parameters = []);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getMessage();
+
+ /**
+ * @return string[]
+ * @since 8.2.0
+ */
+ public function getMessageParameters();
+
+ /**
+ * @param string $message
+ * @return $this
+ * @throws \InvalidArgumentException if the message are invalid
+ * @since 8.2.0
+ */
+ public function setParsedMessage($message);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getParsedMessage();
+
+ /**
+ * @param string $link
+ * @return $this
+ * @throws \InvalidArgumentException if the link are invalid
+ * @since 8.2.0
+ */
+ public function setLink($link);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getLink();
+
+ /**
+ * @param string $icon
+ * @return $this
+ * @throws \InvalidArgumentException if the icon are invalid
+ * @since 8.2.0
+ */
+ public function setIcon($icon);
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getIcon();
+
+ /**
+ * @return IAction
+ * @since 8.2.0
+ */
+ public function createAction();
+
+ /**
+ * @param IAction $action
+ * @return $this
+ * @throws \InvalidArgumentException if the action are invalid
+ * @since 8.2.0
+ */
+ public function addAction(IAction $action);
+
+ /**
+ * @return IAction[]
+ * @since 8.2.0
+ */
+ public function getActions();
+
+ /**
+ * @param IAction $action
+ * @return $this
+ * @throws \InvalidArgumentException if the action are invalid
+ * @since 8.2.0
+ */
+ public function addParsedAction(IAction $action);
+
+ /**
+ * @return IAction[]
+ * @since 8.2.0
+ */
+ public function getParsedActions();
+
+ /**
+ * @return bool
+ * @since 8.2.0
+ */
+ public function isValid();
+
+ /**
+ * @return bool
+ * @since 8.2.0
+ */
+ public function isValidParsed();
+}
diff --git a/lib/private/notification/inotifier.php b/lib/private/notification/inotifier.php
new file mode 100644
index 00000000000..22531229e3f
--- /dev/null
+++ b/lib/private/notification/inotifier.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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 OC\Notification;
+
+/**
+ * Interface INotifier
+ *
+ * @package OC\Notification
+ * @since 8.2.0
+ *
+ * DEVELOPER NOTE:
+ * The notification api is experimental only in 8.2.0! Do not start using it,
+ * if you can not prepare an update for the next version afterwards.
+ */
+interface INotifier {
+ /**
+ * @param INotification $notification
+ * @param string $languageCode The code of the language that should be used to prepare the notification
+ * @return INotification
+ * @throws \InvalidArgumentException When the notification was not prepared by a notifier
+ * @since 8.2.0
+ */
+ public function prepare(INotification $notification, $languageCode);
+}
diff --git a/lib/private/notification/manager.php b/lib/private/notification/manager.php
new file mode 100644
index 00000000000..9635925e38e
--- /dev/null
+++ b/lib/private/notification/manager.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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 OC\Notification;
+
+
+class Manager implements IManager {
+ /** @var IApp */
+ protected $apps;
+
+ /** @var INotifier */
+ protected $notifiers;
+
+ /** @var \Closure */
+ protected $appsClosures;
+
+ /** @var \Closure */
+ protected $notifiersClosures;
+
+ public function __construct() {
+ $this->apps = [];
+ $this->notifiers = [];
+ $this->appsClosures = [];
+ $this->notifiersClosures = [];
+ }
+
+ /**
+ * @param \Closure $service The service must implement IApp, otherwise a
+ * \InvalidArgumentException is thrown later
+ * @return null
+ * @since 8.2.0
+ */
+ public function registerApp(\Closure $service) {
+ $this->appsClosures[] = $service;
+ $this->apps = [];
+ }
+
+ /**
+ * @param \Closure $service The service must implement INotifier, otherwise a
+ * \InvalidArgumentException is thrown later
+ * @return null
+ * @since 8.2.0
+ */
+ public function registerNotifier(\Closure $service) {
+ $this->notifiersClosures[] = $service;
+ $this->notifiers = [];
+ }
+
+ /**
+ * @return IApp[]
+ */
+ protected function getApps() {
+ if (!empty($this->apps)) {
+ return $this->apps;
+ }
+
+ $this->apps = [];
+ foreach ($this->appsClosures as $closure) {
+ $app = $closure();
+ if (!($app instanceof IApp)) {
+ throw new \InvalidArgumentException('The given notification app does not implement the IApp interface');
+ }
+ $this->apps[] = $app;
+ }
+
+ return $this->apps;
+ }
+
+ /**
+ * @return INotifier[]
+ */
+ protected function getNotifiers() {
+ if (!empty($this->notifiers)) {
+ return $this->notifiers;
+ }
+
+ $this->notifiers = [];
+ foreach ($this->notifiersClosures as $closure) {
+ $notifier = $closure();
+ if (!($notifier instanceof INotifier)) {
+ throw new \InvalidArgumentException('The given notification app does not implement the INotifier interface');
+ }
+ $this->notifiers[] = $notifier;
+ }
+
+ return $this->notifiers;
+ }
+
+ /**
+ * @return INotification
+ * @since 8.2.0
+ */
+ public function createNotification() {
+ return new Notification();
+ }
+
+ /**
+ * @param INotification $notification
+ * @return null
+ * @throws \InvalidArgumentException When the notification is not valid
+ * @since 8.2.0
+ */
+ public function notify(INotification $notification) {
+ if (!$notification->isValid()) {
+ throw new \InvalidArgumentException('The given notification is invalid');
+ }
+
+ $apps = $this->getApps();
+
+ foreach ($apps as $app) {
+ try {
+ $app->notify($notification);
+ } catch (\InvalidArgumentException $e) {
+ }
+ }
+ }
+
+ /**
+ * @param INotification $notification
+ * @param string $languageCode The code of the language that should be used to prepare the notification
+ * @return INotification
+ * @throws \InvalidArgumentException When the notification was not prepared by a notifier
+ * @since 8.2.0
+ */
+ public function prepare(INotification $notification, $languageCode) {
+ $notifiers = $this->getNotifiers();
+
+ foreach ($notifiers as $notifier) {
+ try {
+ $notification = $notifier->prepare($notification, $languageCode);
+ } catch (\InvalidArgumentException $e) {
+ continue;
+ }
+
+ if (!($notification instanceof INotification) || !$notification->isValidParsed()) {
+ throw new \InvalidArgumentException('The given notification has not been handled');
+ }
+ }
+
+ if (!($notification instanceof INotification) || !$notification->isValidParsed()) {
+ throw new \InvalidArgumentException('The given notification has not been handled');
+ }
+
+ return $notification;
+ }
+
+ /**
+ * @param INotification $notification
+ * @return null
+ */
+ public function markProcessed(INotification $notification) {
+ $apps = $this->getApps();
+
+ foreach ($apps as $app) {
+ $app->markProcessed($notification);
+ }
+ }
+
+ /**
+ * @param INotification $notification
+ * @return int
+ */
+ public function getCount(INotification $notification) {
+ $apps = $this->getApps();
+
+ $count = 0;
+ foreach ($apps as $app) {
+ $count += $app->getCount($notification);
+ }
+
+ return $count;
+ }
+}
diff --git a/lib/private/notification/notification.php b/lib/private/notification/notification.php
new file mode 100644
index 00000000000..40fe39a956e
--- /dev/null
+++ b/lib/private/notification/notification.php
@@ -0,0 +1,446 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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 OC\Notification;
+
+
+class Notification implements INotification {
+ /** @var string */
+ protected $app;
+
+ /** @var string */
+ protected $user;
+
+ /** @var int */
+ protected $timestamp;
+
+ /** @var string */
+ protected $objectType;
+
+ /** @var int */
+ protected $objectId;
+
+ /** @var string */
+ protected $subject;
+
+ /** @var array */
+ protected $subjectParameters;
+
+ /** @var string */
+ protected $subjectParsed;
+
+ /** @var string */
+ protected $message;
+
+ /** @var array */
+ protected $messageParameters;
+
+ /** @var string */
+ protected $messageParsed;
+
+ /** @var string */
+ protected $link;
+
+ /** @var string */
+ protected $icon;
+
+ /** @var array */
+ protected $actions;
+
+ /** @var array */
+ protected $actionsParsed;
+
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ $this->app = '';
+ $this->user = '';
+ $this->timestamp = 0;
+ $this->objectType = '';
+ $this->objectId = 0;
+ $this->subject = '';
+ $this->subjectParameters = [];
+ $this->subjectParsed = '';
+ $this->message = '';
+ $this->messageParameters = [];
+ $this->messageParsed = '';
+ $this->link = '';
+ $this->icon = '';
+ $this->actions = [];
+ $this->actionsParsed = [];
+ }
+
+ /**
+ * @param string $app
+ * @return $this
+ * @throws \InvalidArgumentException if the app id is invalid
+ * @since 8.2.0
+ */
+ public function setApp($app) {
+ if (!is_string($app) || $app === '' || isset($app[32])) {
+ throw new \InvalidArgumentException('The given app name is invalid');
+ }
+ $this->app = $app;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getApp() {
+ return $this->app;
+ }
+
+ /**
+ * @param string $user
+ * @return $this
+ * @throws \InvalidArgumentException if the user id is invalid
+ * @since 8.2.0
+ */
+ public function setUser($user) {
+ if (!is_string($user) || $user === '' || isset($user[64])) {
+ throw new \InvalidArgumentException('The given user id is invalid');
+ }
+ $this->user = $user;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getUser() {
+ return $this->user;
+ }
+
+ /**
+ * @param int $timestamp
+ * @return $this
+ * @throws \InvalidArgumentException if the timestamp is invalid
+ * @since 8.2.0
+ */
+ public function setTimestamp($timestamp) {
+ if (!is_int($timestamp)) {
+ throw new \InvalidArgumentException('The given timestamp is invalid');
+ }
+ $this->timestamp = $timestamp;
+ return $this;
+ }
+
+ /**
+ * @return int
+ * @since 8.2.0
+ */
+ public function getTimestamp() {
+ return $this->timestamp;
+ }
+
+ /**
+ * @param string $type
+ * @param int $id
+ * @return $this
+ * @throws \InvalidArgumentException if the object type or id is invalid
+ * @since 8.2.0
+ */
+ public function setObject($type, $id) {
+ if (!is_string($type) || $type === '' || isset($type[64])) {
+ throw new \InvalidArgumentException('The given object type is invalid');
+ }
+ $this->objectType = $type;
+
+ if (!is_int($id)) {
+ throw new \InvalidArgumentException('The given object id is invalid');
+ }
+ $this->objectId = $id;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getObjectType() {
+ return $this->objectType;
+ }
+
+ /**
+ * @return int
+ * @since 8.2.0
+ */
+ public function getObjectId() {
+ return $this->objectId;
+ }
+
+ /**
+ * @param string $subject
+ * @param array $parameters
+ * @return $this
+ * @throws \InvalidArgumentException if the subject or parameters are invalid
+ * @since 8.2.0
+ */
+ public function setSubject($subject, array $parameters = []) {
+ if (!is_string($subject) || $subject === '' || isset($subject[64])) {
+ throw new \InvalidArgumentException('The given subject is invalid');
+ }
+ $this->subject = $subject;
+
+ if (!is_array($parameters)) {
+ throw new \InvalidArgumentException('The given subject parameters are invalid');
+ }
+ $this->subjectParameters = $parameters;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getSubject() {
+ return $this->subject;
+ }
+
+ /**
+ * @return string[]
+ * @since 8.2.0
+ */
+ public function getSubjectParameters() {
+ return $this->subjectParameters;
+ }
+
+ /**
+ * @param string $subject
+ * @return $this
+ * @throws \InvalidArgumentException if the subject are invalid
+ * @since 8.2.0
+ */
+ public function setParsedSubject($subject) {
+ if (!is_string($subject) || $subject === '') {
+ throw new \InvalidArgumentException('The given parsed subject is invalid');
+ }
+ $this->subjectParsed = $subject;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getParsedSubject() {
+ return $this->subjectParsed;
+ }
+
+ /**
+ * @param string $message
+ * @param array $parameters
+ * @return $this
+ * @throws \InvalidArgumentException if the message or parameters are invalid
+ * @since 8.2.0
+ */
+ public function setMessage($message, array $parameters = []) {
+ if (!is_string($message) || $message === '' || isset($message[64])) {
+ throw new \InvalidArgumentException('The given message is invalid');
+ }
+ $this->message = $message;
+
+ if (!is_array($parameters)) {
+ throw new \InvalidArgumentException('The given message parameters are invalid');
+ }
+ $this->messageParameters = $parameters;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getMessage() {
+ return $this->message;
+ }
+
+ /**
+ * @return string[]
+ * @since 8.2.0
+ */
+ public function getMessageParameters() {
+ return $this->messageParameters;
+ }
+
+ /**
+ * @param string $message
+ * @return $this
+ * @throws \InvalidArgumentException if the message are invalid
+ * @since 8.2.0
+ */
+ public function setParsedMessage($message) {
+ if (!is_string($message) || $message === '') {
+ throw new \InvalidArgumentException('The given parsed message is invalid');
+ }
+ $this->messageParsed = $message;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getParsedMessage() {
+ return $this->messageParsed;
+ }
+
+ /**
+ * @param string $link
+ * @return $this
+ * @throws \InvalidArgumentException if the link are invalid
+ * @since 8.2.0
+ */
+ public function setLink($link) {
+ if (!is_string($link) || $link === '' || isset($link[4000])) {
+ throw new \InvalidArgumentException('The given link is invalid');
+ }
+ $this->link = $link;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getLink() {
+ return $this->link;
+ }
+
+ /**
+ * @param string $icon
+ * @return $this
+ * @throws \InvalidArgumentException if the icon are invalid
+ * @since 8.2.0
+ */
+ public function setIcon($icon) {
+ if (!is_string($icon) || $icon === '' || isset($icon[64])) {
+ throw new \InvalidArgumentException('The given icon is invalid');
+ }
+ $this->icon = $icon;
+ return $this;
+ }
+
+ /**
+ * @return string
+ * @since 8.2.0
+ */
+ public function getIcon() {
+ return $this->icon;
+ }
+
+ /**
+ * @return IAction
+ * @since 8.2.0
+ */
+ public function createAction() {
+ return new Action();
+ }
+
+ /**
+ * @param IAction $action
+ * @return $this
+ * @throws \InvalidArgumentException if the action are invalid
+ * @since 8.2.0
+ */
+ public function addAction(IAction $action) {
+ if (!$action->isValid()) {
+ throw new \InvalidArgumentException('The given action is invalid');
+ }
+ $this->actions[] = $action;
+ return $this;
+ }
+
+ /**
+ * @return IAction[]
+ * @since 8.2.0
+ */
+ public function getActions() {
+ return $this->actions;
+ }
+
+ /**
+ * @param IAction $action
+ * @return $this
+ * @throws \InvalidArgumentException if the action are invalid
+ * @since 8.2.0
+ */
+ public function addParsedAction(IAction $action) {
+ if (!$action->isValidParsed()) {
+ throw new \InvalidArgumentException('The given parsed action is invalid');
+ }
+ $this->actionsParsed[] = $action;
+ return $this;
+ }
+
+ /**
+ * @return IAction[]
+ * @since 8.2.0
+ */
+ public function getParsedActions() {
+ return $this->actionsParsed;
+ }
+
+ /**
+ * @return bool
+ * @since 8.2.0
+ */
+ public function isValid() {
+ return
+ $this->isValidCommon()
+ &&
+ $this->getSubject() !== ''
+ ;
+ }
+
+ /**
+ * @return bool
+ * @since 8.2.0
+ */
+ public function isValidParsed() {
+ return
+ $this->isValidCommon()
+ &&
+ $this->getParsedSubject() !== ''
+ ;
+ }
+
+ /**
+ * @return bool
+ */
+ protected function isValidCommon() {
+ return
+ $this->getApp() !== ''
+ &&
+ $this->getUser() !== ''
+ &&
+ $this->getTimestamp() !== 0
+ &&
+ $this->getObjectType() !== ''
+ &&
+ $this->getObjectId() !== 0
+ ;
+ }
+}
diff --git a/lib/private/server.php b/lib/private/server.php
index 346761840d6..bbf060a47b7 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -53,6 +53,7 @@ use OC\Lock\DBLockingProvider;
use OC\Lock\MemcacheLockingProvider;
use OC\Lock\NoopLockingProvider;
use OC\Mail\Mailer;
+use OC\Notification\Manager;
use OC\Security\CertificateManager;
use OC\Security\Crypto;
use OC\Security\Hasher;
@@ -473,6 +474,9 @@ class Server extends SimpleContainer implements IServerContainer {
$c->getDatabaseConnection()
);
});
+ $this->registerService('NotificationManager', function() {
+ return new Manager();
+ });
$this->registerService('CapabilitiesManager', function (Server $c) {
$manager = new \OC\CapabilitiesManager();
$manager->registerCapability(function() use ($c) {
@@ -1042,6 +1046,16 @@ class Server extends SimpleContainer implements IServerContainer {
}
/**
+ * Get the Notification Manager
+ *
+ * @return \OC\Notification\IManager
+ * @since 8.2.0
+ */
+ public function getNotificationManager() {
+ return $this->query('NotificationManager');
+ }
+
+ /**
* @return \OC\Session\CryptoWrapper
*/
public function getSessionCryptoWrapper() {
diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php
index 81724cb4967..8be23dff214 100644
--- a/lib/public/iservercontainer.php
+++ b/lib/public/iservercontainer.php
@@ -448,7 +448,6 @@ interface IServerContainer {
*/
public function getMimeTypeLoader();
-
/**
* Get the EventDispatcher
*
@@ -456,4 +455,12 @@ interface IServerContainer {
* @since 8.2.0
*/
public function getEventDispatcher();
+
+ /**
+ * Get the Notification Manager
+ *
+ * @return \OC\Notification\IManager
+ * @since 8.2.0
+ */
+ public function getNotificationManager();
}
diff --git a/tests/lib/notification/actiontest.php b/tests/lib/notification/actiontest.php
new file mode 100644
index 00000000000..e319c250cc7
--- /dev/null
+++ b/tests/lib/notification/actiontest.php
@@ -0,0 +1,236 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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 Test\Notification;
+
+
+use OC\Notification\Action;
+use OC\Notification\IAction;
+use Test\TestCase;
+
+class ActionTest extends TestCase {
+ /** @var IAction */
+ protected $action;
+
+ public function setUp() {
+ parent::setUp();
+ $this->action = new Action();
+ }
+
+ public function dataSetLabel() {
+ return [
+ ['test1'],
+ [str_repeat('a', 1)],
+ [str_repeat('a', 32)],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSetLabel
+ * @param string $label
+ */
+ public function testSetLabel($label) {
+ $this->assertSame('', $this->action->getLabel());
+ $this->action->setLabel($label);
+ $this->assertSame($label, $this->action->getLabel());
+ }
+
+ public function dataSetLabelInvalid() {
+ return [
+ [true],
+ [false],
+ [0],
+ [1],
+ [''],
+ [str_repeat('a', 33)],
+ [[]],
+ [[str_repeat('a', 33)]],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSetLabelInvalid
+ * @param string $label
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetLabelInvalid($label) {
+ $this->action->setLabel($label);
+ }
+
+ public function dataSetParsedLabel() {
+ return [
+ ['test1'],
+ [str_repeat('a', 1)],
+ [str_repeat('a', 32)],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSetParsedLabel
+ * @param string $label
+ */
+ public function testSetParsedLabel($label) {
+ $this->assertSame('', $this->action->getParsedLabel());
+ $this->action->setParsedLabel($label);
+ $this->assertSame($label, $this->action->getParsedLabel());
+ }
+
+ public function dataSetParsedLabelInvalid() {
+ return [
+ [true],
+ [false],
+ [0],
+ [1],
+ [''],
+ [[]],
+ [[str_repeat('a', 33)]],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSetParsedLabelInvalid
+ * @param string $label
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetParsedLabelInvalid($label) {
+ $this->action->setParsedLabel($label);
+ }
+
+ public function dataSetLink() {
+ return [
+ ['test1', 'GET'],
+ ['test2', 'POST'],
+ [str_repeat('a', 1), 'PUT'],
+ [str_repeat('a', 256), 'DELETE'],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSetLink
+ * @param string $link
+ * @param string $type
+ */
+ public function testSetLink($link, $type) {
+ $this->assertSame('', $this->action->getLink());
+ $this->action->setLink($link, $type);
+ $this->assertSame($link, $this->action->getLink());
+ $this->assertSame($type, $this->action->getRequestType());
+ }
+
+ public function dataSetLinkInvalid() {
+ return [
+ // Invalid link
+ [true, 'GET'],
+ [false, 'GET'],
+ [0, 'GET'],
+ [1, 'GET'],
+ ['', 'GET'],
+ [str_repeat('a', 257), 'GET'],
+ [[], 'GET'],
+ [[str_repeat('a', 257)], 'GET'],
+
+ // Invalid type
+ ['url', 'notGET'],
+ ['url', true],
+ ['url', false],
+ ['url', 0],
+ ['url', 1],
+ ['url', []],
+ ['url', ['GET']],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSetLinkInvalid
+ * @param string $link
+ * @param string $type
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetLinkInvalid($link, $type) {
+ $this->action->setLink($link, $type);
+ }
+
+ public function dataSetIcon() {
+ return [
+ ['test1'],
+ [str_repeat('a', 1)],
+ [str_repeat('a', 64)],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSetIcon
+ * @param string $icon
+ */
+ public function testSetIcon($icon) {
+ $this->assertSame('', $this->action->getIcon());
+ $this->action->setIcon($icon);
+ $this->assertSame($icon, $this->action->getIcon());
+ }
+
+ public function dataSetIconInvalid() {
+ return [
+ [true],
+ [false],
+ [0],
+ [1],
+ [''],
+ [str_repeat('a', 65)],
+ [[]],
+ [[str_repeat('a', 65)]],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSetIconInvalid
+ * @param string $icon
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetIconInvalid($icon) {
+ $this->action->setIcon($icon);
+ }
+
+ public function testIsValid() {
+ $this->assertFalse($this->action->isValid());
+ $this->assertFalse($this->action->isValidParsed());
+ $this->action->setLabel('label');
+ $this->assertFalse($this->action->isValid());
+ $this->assertFalse($this->action->isValidParsed());
+ $this->action->setLink('link', 'GET');
+ $this->assertTrue($this->action->isValid());
+ $this->assertFalse($this->action->isValidParsed());
+ }
+
+ public function testIsValidParsed() {
+ $this->assertFalse($this->action->isValid());
+ $this->assertFalse($this->action->isValidParsed());
+ $this->action->setParsedLabel('label');
+ $this->assertFalse($this->action->isValid());
+ $this->assertFalse($this->action->isValidParsed());
+ $this->action->setLink('link', 'GET');
+ $this->assertFalse($this->action->isValid());
+ $this->assertTrue($this->action->isValidParsed());
+ }
+}
diff --git a/tests/lib/notification/managertest.php b/tests/lib/notification/managertest.php
new file mode 100644
index 00000000000..fa2a0586f90
--- /dev/null
+++ b/tests/lib/notification/managertest.php
@@ -0,0 +1,345 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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 Test\Notification;
+
+use OC\Notification\Manager;
+use OC\Notification\IManager;
+use Test\TestCase;
+
+class ManagerTest extends TestCase {
+ /** @var IManager */
+ protected $manager;
+
+ public function setUp() {
+ parent::setUp();
+ $this->manager = new Manager();
+ }
+
+ public function testRegisterApp() {
+ $app = $this->getMockBuilder('OC\Notification\IApp')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $closure = function() use ($app) {
+ return $app;
+ };
+
+ $this->assertEquals([], $this->invokePrivate($this->manager, 'getApps'));
+
+ $this->manager->registerApp($closure);
+
+ $this->assertEquals([$app], $this->invokePrivate($this->manager, 'getApps'));
+ $this->assertEquals([$app], $this->invokePrivate($this->manager, 'getApps'));
+
+ $this->manager->registerApp($closure);
+
+ $this->assertEquals([$app, $app], $this->invokePrivate($this->manager, 'getApps'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testRegisterAppInvalid() {
+ $notifier = $this->getMockBuilder('OC\Notification\INotifier')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $closure = function() use ($notifier) {
+ return $notifier;
+ };
+
+ $this->manager->registerApp($closure);
+
+ $this->invokePrivate($this->manager, 'getApps');
+ }
+
+ public function testRegisterNotifier() {
+ $notifier = $this->getMockBuilder('OC\Notification\INotifier')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $closure = function() use ($notifier) {
+ return $notifier;
+ };
+
+ $this->assertEquals([], $this->invokePrivate($this->manager, 'getNotifiers'));
+
+ $this->manager->registerNotifier($closure);
+
+ $this->assertEquals([$notifier], $this->invokePrivate($this->manager, 'getNotifiers'));
+ $this->assertEquals([$notifier], $this->invokePrivate($this->manager, 'getNotifiers'));
+
+ $this->manager->registerNotifier($closure);
+
+ $this->assertEquals([$notifier, $notifier], $this->invokePrivate($this->manager, 'getNotifiers'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testRegisterNotifierInvalid() {
+ $app = $this->getMockBuilder('OC\Notification\IApp')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $closure = function() use ($app) {
+ return $app;
+ };
+
+ $this->manager->registerNotifier($closure);
+
+ $this->invokePrivate($this->manager, 'getNotifiers');
+ }
+
+ public function testCreateNotification() {
+ $action = $this->manager->createNotification();
+ $this->assertInstanceOf('OC\Notification\INotification', $action);
+ }
+
+ public function testNotify() {
+ /** @var \OC\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
+ $notification = $this->getMockBuilder('OC\Notification\INotification')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $notification->expects($this->once())
+ ->method('isValid')
+ ->willReturn(true);
+
+ /** @var \OC\Notification\IApp|\PHPUnit_Framework_MockObject_MockObject $app */
+ $app = $this->getMockBuilder('OC\Notification\IApp')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $app->expects($this->once())
+ ->method('notify')
+ ->with($notification);
+
+ /** @var \OC\Notification\IApp|\PHPUnit_Framework_MockObject_MockObject $app2 */
+ $app2 = $this->getMockBuilder('OC\Notification\IApp')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $app2->expects($this->once())
+ ->method('notify')
+ ->with($notification);
+
+ $this->manager->registerApp(function() use ($app) {
+ return $app;
+ });
+ $this->manager->registerApp(function() use ($app2) {
+ return $app2;
+ });
+
+ $this->manager->notify($notification);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testNotifyInvalid() {
+ /** @var \OC\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
+ $notification = $this->getMockBuilder('OC\Notification\INotification')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $notification->expects($this->once())
+ ->method('isValid')
+ ->willReturn(false);
+
+ $this->manager->notify($notification);
+ }
+
+ public function testPrepare() {
+ /** @var \OC\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
+ $notification = $this->getMockBuilder('OC\Notification\INotification')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $notification->expects($this->once())
+ ->method('isValidParsed')
+ ->willReturn(true);
+ /** @var \OC\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification2 */
+ $notification2 = $this->getMockBuilder('OC\Notification\INotification')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $notification2->expects($this->exactly(2))
+ ->method('isValidParsed')
+ ->willReturn(true);
+
+ /** @var \OC\Notification\IApp|\PHPUnit_Framework_MockObject_MockObject $notifier */
+ $notifier = $this->getMockBuilder('OC\Notification\INotifier')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $notifier->expects($this->once())
+ ->method('prepare')
+ ->with($notification, 'en')
+ ->willReturnArgument(0);
+
+ /** @var \OC\Notification\IApp|\PHPUnit_Framework_MockObject_MockObject $notifier2 */
+ $notifier2 = $this->getMockBuilder('OC\Notification\INotifier')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $notifier2->expects($this->once())
+ ->method('prepare')
+ ->with($notification, 'en')
+ ->willReturn($notification2);
+
+ $this->manager->registerNotifier(function() use ($notifier) {
+ return $notifier;
+ });
+ $this->manager->registerNotifier(function() use ($notifier2) {
+ return $notifier2;
+ });
+
+ $this->assertEquals($notification2, $this->manager->prepare($notification, 'en'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testPrepareInvalid() {
+ /** @var \OC\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
+ $notification = $this->getMockBuilder('OC\Notification\INotification')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $notification->expects($this->once())
+ ->method('isValidParsed')
+ ->willReturn(false);
+
+ /** @var \OC\Notification\IApp|\PHPUnit_Framework_MockObject_MockObject $notifier */
+ $notifier = $this->getMockBuilder('OC\Notification\INotifier')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $notifier->expects($this->once())
+ ->method('prepare')
+ ->with($notification, 'de')
+ ->willReturnArgument(0);
+
+ $this->manager->registerNotifier(function() use ($notifier) {
+ return $notifier;
+ });
+
+ $this->manager->prepare($notification, 'de');
+ }
+
+ public function testPrepareNotifierThrows() {
+ /** @var \OC\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
+ $notification = $this->getMockBuilder('OC\Notification\INotification')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $notification->expects($this->once())
+ ->method('isValidParsed')
+ ->willReturn(true);
+
+ /** @var \OC\Notification\IApp|\PHPUnit_Framework_MockObject_MockObject $notifier */
+ $notifier = $this->getMockBuilder('OC\Notification\INotifier')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $notifier->expects($this->once())
+ ->method('prepare')
+ ->with($notification, 'de')
+ ->willThrowException(new \InvalidArgumentException);
+
+ $this->manager->registerNotifier(function() use ($notifier) {
+ return $notifier;
+ });
+
+ $this->assertEquals($notification, $this->manager->prepare($notification, 'de'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testPrepareNoNotifier() {
+ /** @var \OC\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
+ $notification = $this->getMockBuilder('OC\Notification\INotification')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $notification->expects($this->once())
+ ->method('isValidParsed')
+ ->willReturn(false);
+
+ $this->manager->prepare($notification, 'en');
+ }
+
+ public function testMarkProcessed() {
+ /** @var \OC\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
+ $notification = $this->getMockBuilder('OC\Notification\INotification')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ /** @var \OC\Notification\IApp|\PHPUnit_Framework_MockObject_MockObject $app */
+ $app = $this->getMockBuilder('OC\Notification\IApp')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $app->expects($this->once())
+ ->method('markProcessed')
+ ->with($notification);
+
+ /** @var \OC\Notification\IApp|\PHPUnit_Framework_MockObject_MockObject $app2 */
+ $app2 = $this->getMockBuilder('OC\Notification\IApp')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $app2->expects($this->once())
+ ->method('markProcessed')
+ ->with($notification);
+
+ $this->manager->registerApp(function() use ($app) {
+ return $app;
+ });
+ $this->manager->registerApp(function() use ($app2) {
+ return $app2;
+ });
+
+ $this->manager->markProcessed($notification);
+ }
+
+ public function testGetCount() {
+ /** @var \OC\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
+ $notification = $this->getMockBuilder('OC\Notification\INotification')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ /** @var \OC\Notification\IApp|\PHPUnit_Framework_MockObject_MockObject $app */
+ $app = $this->getMockBuilder('OC\Notification\IApp')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $app->expects($this->once())
+ ->method('getCount')
+ ->with($notification)
+ ->willReturn(21);
+
+ /** @var \OC\Notification\IApp|\PHPUnit_Framework_MockObject_MockObject $app2 */
+ $app2 = $this->getMockBuilder('OC\Notification\IApp')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $app2->expects($this->once())
+ ->method('getCount')
+ ->with($notification)
+ ->willReturn(42);
+
+ $this->manager->registerApp(function() use ($app) {
+ return $app;
+ });
+ $this->manager->registerApp(function() use ($app2) {
+ return $app2;
+ });
+
+ $this->assertSame(63, $this->manager->getCount($notification));
+ }
+}
diff --git a/tests/lib/notification/notificationtest.php b/tests/lib/notification/notificationtest.php
new file mode 100644
index 00000000000..a790a53eaa7
--- /dev/null
+++ b/tests/lib/notification/notificationtest.php
@@ -0,0 +1,601 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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 Test\Notification;
+
+
+use OC\Notification\Notification;
+use OC\Notification\INotification;
+use Test\TestCase;
+
+class NotificationTest extends TestCase {
+ /** @var INotification */
+ protected $notification;
+
+ public function setUp() {
+ parent::setUp();
+ $this->notification = new Notification();
+ }
+
+ protected function dataValidString($maxLength) {
+ $dataSets = [
+ ['test1'],
+ [str_repeat('a', 1)],
+ ];
+ if ($maxLength !== false) {
+ $dataSets[] = [str_repeat('a', $maxLength)];
+ }
+ return $dataSets;
+ }
+
+ protected function dataInvalidString($maxLength) {
+ $dataSets = [
+ [true],
+ [false],
+ [0],
+ [1],
+ [''],
+ [[]],
+ ];
+ if ($maxLength !== false) {
+ $dataSets[] = [str_repeat('a', $maxLength + 1)];
+ $dataSets[] = [[str_repeat('a', $maxLength + 1)]];
+ }
+ return $dataSets;
+ }
+
+ protected function dataValidInt() {
+ return [
+ [0],
+ [1],
+ [time()],
+ ];
+ }
+
+ protected function dataInvalidInt() {
+ return [
+ [true],
+ [false],
+ [''],
+ ['a'],
+ [str_repeat('a', 256)],
+ [[]],
+ [['a']],
+ [[str_repeat('a', 256)]],
+ ];
+ }
+
+ public function dataSetApp() {
+ return $this->dataValidString(32);
+ }
+
+ /**
+ * @dataProvider dataSetApp
+ * @param string $app
+ */
+ public function testSetApp($app) {
+ $this->assertSame('', $this->notification->getApp());
+ $this->notification->setApp($app);
+ $this->assertSame($app, $this->notification->getApp());
+ }
+
+ public function dataSetAppInvalid() {
+ return $this->dataInvalidString(32);
+ }
+
+ /**
+ * @dataProvider dataSetAppInvalid
+ * @param mixed $app
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetAppInvalid($app) {
+ $this->notification->setApp($app);
+ }
+
+ public function dataSetUser() {
+ return $this->dataValidString(64);
+ }
+
+ /**
+ * @dataProvider dataSetUser
+ * @param string $user
+ */
+ public function testSetUser($user) {
+ $this->assertSame('', $this->notification->getUser());
+ $this->notification->setUser($user);
+ $this->assertSame($user, $this->notification->getUser());
+ }
+
+ public function dataSetUserInvalid() {
+ return $this->dataInvalidString(64);
+ }
+
+ /**
+ * @dataProvider dataSetUserInvalid
+ * @param mixed $user
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetUserInvalid($user) {
+ $this->notification->setUser($user);
+ }
+
+ public function dataSetTimestamp() {
+ return $this->dataValidInt();
+ }
+
+ /**
+ * @dataProvider dataSetTimestamp
+ * @param int $timestamp
+ */
+ public function testSetTimestamp($timestamp) {
+ $this->assertSame(0, $this->notification->getTimestamp());
+ $this->notification->setTimestamp($timestamp);
+ $this->assertSame($timestamp, $this->notification->getTimestamp());
+ }
+
+ public function dataSetTimestampInvalid() {
+ return $this->dataInvalidInt();
+ }
+
+ /**
+ * @dataProvider dataSetTimestampInvalid
+ * @param mixed $timestamp
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetTimestampInvalid($timestamp) {
+ $this->notification->setTimestamp($timestamp);
+ }
+
+ public function dataSetObject() {
+ return [
+ ['a', 1],
+ [str_repeat('a', 64), time()],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSetObject
+ * @param string $type
+ * @param int $id
+ */
+ public function testSetObject($type, $id) {
+ $this->assertSame('', $this->notification->getObjectType());
+ $this->assertSame(0, $this->notification->getObjectId());
+ $this->notification->setObject($type, $id);
+ $this->assertSame($type, $this->notification->getObjectType());
+ $this->assertSame($id, $this->notification->getObjectId());
+ }
+
+ public function dataSetObjectTypeInvalid() {
+ return $this->dataInvalidString(64);
+ }
+
+ /**
+ * @dataProvider dataSetObjectTypeInvalid
+ * @param mixed $type
+ *
+ * @expectedException \InvalidArgumentException
+ * @expectedMessage 'The given object type is invalid'
+ */
+ public function testSetObjectTypeInvalid($type) {
+ $this->notification->setObject($type, 1337);
+ }
+
+ public function dataSetObjectIdInvalid() {
+ return $this->dataInvalidInt();
+ }
+
+ /**
+ * @dataProvider dataSetObjectIdInvalid
+ * @param mixed $id
+ *
+ * @expectedException \InvalidArgumentException
+ * @expectedMessage 'The given object id is invalid'
+ */
+ public function testSetObjectIdInvalid($id) {
+ $this->notification->setObject('object', $id);
+ }
+
+ public function dataSetSubject() {
+ return [
+ ['a', []],
+ [str_repeat('a', 64), [str_repeat('a', 160)]],
+ [str_repeat('a', 64), array_fill(0, 160, 'a')],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSetSubject
+ * @param string $subject
+ * @param array $parameters
+ */
+ public function testSetSubject($subject, $parameters) {
+ $this->assertSame('', $this->notification->getSubject());
+ $this->assertSame([], $this->notification->getSubjectParameters());
+ $this->notification->setSubject($subject, $parameters);
+ $this->assertSame($subject, $this->notification->getSubject());
+ $this->assertSame($parameters, $this->notification->getSubjectParameters());
+ }
+
+ public function dataSetSubjectInvalidSubject() {
+ return $this->dataInvalidString(64);
+ }
+
+ /**
+ * @dataProvider dataSetSubjectInvalidSubject
+ * @param mixed $subject
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetSubjectInvalidSubject($subject) {
+ $this->notification->setSubject($subject, []);
+ }
+
+ public function dataSetParsedSubject() {
+ return $this->dataValidString(false);
+ }
+
+ /**
+ * @dataProvider dataSetParsedSubject
+ * @param string $subject
+ */
+ public function testSetParsedSubject($subject) {
+ $this->assertSame('', $this->notification->getParsedSubject());
+ $this->notification->setParsedSubject($subject);
+ $this->assertSame($subject, $this->notification->getParsedSubject());
+ }
+
+ public function dataSetParsedSubjectInvalid() {
+ return $this->dataInvalidString(false);
+ }
+
+ /**
+ * @dataProvider dataSetParsedSubjectInvalid
+ * @param mixed $subject
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetParsedSubjectInvalid($subject) {
+ $this->notification->setParsedSubject($subject);
+ }
+
+ public function dataSetMessage() {
+ return [
+ ['a', []],
+ [str_repeat('a', 64), [str_repeat('a', 160)]],
+ [str_repeat('a', 64), array_fill(0, 160, 'a')],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSetMessage
+ * @param string $message
+ * @param array $parameters
+ */
+ public function testSetMessage($message, $parameters) {
+ $this->assertSame('', $this->notification->getMessage());
+ $this->assertSame([], $this->notification->getMessageParameters());
+ $this->notification->setMessage($message, $parameters);
+ $this->assertSame($message, $this->notification->getMessage());
+ $this->assertSame($parameters, $this->notification->getMessageParameters());
+ }
+
+ public function dataSetMessageInvalidMessage() {
+ return $this->dataInvalidString(64);
+ }
+
+ /**
+ * @dataProvider dataSetMessageInvalidMessage
+ * @param mixed $message
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetMessageInvalidMessage($message) {
+ $this->notification->setMessage($message, []);
+ }
+
+ public function dataSetParsedMessage() {
+ return $this->dataValidString(false);
+ }
+
+ /**
+ * @dataProvider dataSetParsedMessage
+ * @param string $message
+ */
+ public function testSetParsedMessage($message) {
+ $this->assertSame('', $this->notification->getParsedMessage());
+ $this->notification->setParsedMessage($message);
+ $this->assertSame($message, $this->notification->getParsedMessage());
+ }
+
+ public function dataSetParsedMessageInvalid() {
+ return $this->dataInvalidString(false);
+ }
+
+ /**
+ * @dataProvider dataSetParsedMessageInvalid
+ * @param mixed $message
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetParsedMessageInvalid($message) {
+ $this->notification->setParsedMessage($message);
+ }
+
+ public function dataSetLink() {
+ return $this->dataValidString(4000);
+ }
+
+ /**
+ * @dataProvider dataSetLink
+ * @param string $link
+ */
+ public function testSetLink($link) {
+ $this->assertSame('', $this->notification->getLink());
+ $this->notification->setLink($link);
+ $this->assertSame($link, $this->notification->getLink());
+ }
+
+ public function dataSetLinkInvalid() {
+ return $this->dataInvalidString(4000);
+ }
+
+ /**
+ * @dataProvider dataSetLinkInvalid
+ * @param mixed $link
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetLinkInvalid($link) {
+ $this->notification->setLink($link);
+ }
+
+ public function dataSetIcon() {
+ return $this->dataValidString(64);
+ }
+
+ /**
+ * @dataProvider dataSetIcon
+ * @param string $icon
+ */
+ public function testSetIcon($icon) {
+ $this->assertSame('', $this->notification->getIcon());
+ $this->notification->setIcon($icon);
+ $this->assertSame($icon, $this->notification->getIcon());
+ }
+
+ public function dataSetIconInvalid() {
+ return $this->dataInvalidString(64);
+ }
+
+ /**
+ * @dataProvider dataSetIconInvalid
+ * @param mixed $icon
+ *
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSetIconInvalid($icon) {
+ $this->notification->setIcon($icon);
+ }
+
+ public function testCreateAction() {
+ $action = $this->notification->createAction();
+ $this->assertInstanceOf('OC\Notification\IAction', $action);
+ }
+
+ public function testAddAction() {
+ /** @var \OC\Notification\IAction|\PHPUnit_Framework_MockObject_MockObject $action */
+ $action = $this->getMockBuilder('OC\Notification\IAction')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $action->expects($this->once())
+ ->method('isValid')
+ ->willReturn(true);
+ $action->expects($this->never())
+ ->method('isValidParsed');
+
+ $this->notification->addAction($action);
+
+ $this->assertEquals([$action], $this->notification->getActions());
+ $this->assertEquals([], $this->notification->getParsedActions());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testAddActionInvalid() {
+ /** @var \OC\Notification\IAction|\PHPUnit_Framework_MockObject_MockObject $action */
+ $action = $this->getMockBuilder('OC\Notification\IAction')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $action->expects($this->once())
+ ->method('isValid')
+ ->willReturn(false);
+ $action->expects($this->never())
+ ->method('isValidParsed');
+
+ $this->notification->addAction($action);
+ }
+
+ public function testAddParsedAction() {
+ /** @var \OC\Notification\IAction|\PHPUnit_Framework_MockObject_MockObject $action */
+ $action = $this->getMockBuilder('OC\Notification\IAction')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $action->expects($this->once())
+ ->method('isValidParsed')
+ ->willReturn(true);
+ $action->expects($this->never())
+ ->method('isValid');
+
+ $this->notification->addParsedAction($action);
+
+ $this->assertEquals([$action], $this->notification->getParsedActions());
+ $this->assertEquals([], $this->notification->getActions());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testAddParsedActionInvalid() {
+ /** @var \OC\Notification\IAction|\PHPUnit_Framework_MockObject_MockObject $action */
+ $action = $this->getMockBuilder('OC\Notification\IAction')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $action->expects($this->once())
+ ->method('isValidParsed')
+ ->willReturn(false);
+ $action->expects($this->never())
+ ->method('isValid');
+
+ $this->notification->addParsedAction($action);
+ }
+
+ public function dataIsValid() {
+ return [
+ [false, '', false],
+ [true, '', false],
+ [false, 'a', false],
+ [true, 'a', true],
+ ];
+ }
+
+ /**
+ * @dataProvider dataIsValid
+ *
+ * @param bool $isValidCommon
+ * @param string $subject
+ * @param bool $expected
+ */
+ public function testIsValid($isValidCommon, $subject, $expected) {
+ /** @var \OC\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
+ $notification = $this->getMockBuilder('\OC\Notification\Notification')
+ ->setMethods([
+ 'isValidCommon',
+ 'getSubject',
+ ])
+ ->getMock();
+
+ $notification->expects($this->once())
+ ->method('isValidCommon')
+ ->willReturn($isValidCommon);
+
+ $notification->expects(!$isValidCommon ? $this->never() : $this->once())
+ ->method('getSubject')
+ ->willReturn($subject);
+
+ $notification->expects($this->never())
+ ->method('getParsedSubject')
+ ->willReturn($subject);
+
+ $this->assertEquals($expected, $notification->isValid());
+ }
+
+ /**
+ * @dataProvider dataIsValid
+ *
+ * @param bool $isValidCommon
+ * @param string $subject
+ * @param bool $expected
+ */
+ public function testIsParsedValid($isValidCommon, $subject, $expected) {
+ /** @var \OC\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
+ $notification = $this->getMockBuilder('\OC\Notification\Notification')
+ ->setMethods([
+ 'isValidCommon',
+ 'getParsedSubject',
+ ])
+ ->getMock();
+
+ $notification->expects($this->once())
+ ->method('isValidCommon')
+ ->willReturn($isValidCommon);
+
+ $notification->expects(!$isValidCommon ? $this->never() : $this->once())
+ ->method('getParsedSubject')
+ ->willReturn($subject);
+
+ $notification->expects($this->never())
+ ->method('getSubject')
+ ->willReturn($subject);
+
+ $this->assertEquals($expected, $notification->isValidParsed());
+ }
+
+ public function dataIsValidCommon() {
+ return [
+ ['', '', 0, '', 0, false],
+ ['app', '', 0, '', 0, false],
+ ['app', 'user', 0, '', 0, false],
+ ['app', 'user', time(), '', 0, false],
+ ['app', 'user', time(), 'type', 0, false],
+ ['app', 'user', time(), 'type', 42, true],
+ ];
+ }
+
+ /**
+ * @dataProvider dataIsValidCommon
+ *
+ * @param string $app
+ * @param string $user
+ * @param int $timestamp
+ * @param string $objectType
+ * @param int $objectId
+ * @param bool $expected
+ */
+ public function testIsValidCommon($app, $user, $timestamp, $objectType, $objectId, $expected) {
+ /** @var \OC\Notification\INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
+ $notification = $this->getMockBuilder('\OC\Notification\Notification')
+ ->setMethods([
+ 'getApp',
+ 'getUser',
+ 'getTimestamp',
+ 'getObjectType',
+ 'getObjectId',
+ ])
+ ->getMock();
+
+ $notification->expects($this->any())
+ ->method('getApp')
+ ->willReturn($app);
+
+ $notification->expects($this->any())
+ ->method('getUser')
+ ->willReturn($user);
+
+ $notification->expects($this->any())
+ ->method('getTimestamp')
+ ->willReturn($timestamp);
+
+ $notification->expects($this->any())
+ ->method('getObjectType')
+ ->willReturn($objectType);
+
+ $notification->expects($this->any())
+ ->method('getObjectId')
+ ->willReturn($objectId);
+
+ $this->assertEquals($expected, $this->invokePrivate($notification, 'isValidCommon'));
+ }
+}
diff --git a/tests/lib/server.php b/tests/lib/server.php
index e73fc8b3ab1..96a476bd4d1 100644
--- a/tests/lib/server.php
+++ b/tests/lib/server.php
@@ -104,6 +104,8 @@ class Server extends \Test\TestCase {
['NavigationManager', '\OC\NavigationManager'],
['NavigationManager', '\OCP\INavigationManager'],
+ ['NotificationManager', '\OC\Notification\Manager'],
+ ['NotificationManager', '\OC\Notification\IManager'],
['UserCache', '\OC\Cache\File'],
['UserCache', '\OCP\ICache'],