From 3cca8498cbbd4f04fea3db06976707fbfa13c7aa Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 21 Jan 2016 09:49:37 +0100 Subject: [PATCH] Make it possible to get a list of notifiers for a potential settings page --- lib/private/notification/imanager.php | 12 +++- lib/private/notification/manager.php | 45 +++++++++++++-- tests/lib/notification/managertest.php | 79 +++++++++++++++++++++++++- 3 files changed, 126 insertions(+), 10 deletions(-) diff --git a/lib/private/notification/imanager.php b/lib/private/notification/imanager.php index 0e9504a1f6..2f8e3ba39f 100644 --- a/lib/private/notification/imanager.php +++ b/lib/private/notification/imanager.php @@ -43,10 +43,18 @@ interface IManager extends IApp, INotifier { /** * @param \Closure $service The service must implement INotifier, otherwise a * \InvalidArgumentException is thrown later + * @param \Closure $info An array with the keys 'id' and 'name' containing + * the app id and the app name * @return null - * @since 8.2.0 + * @since 8.2.0 - Parameter $info was added in 9.0.0 */ - public function registerNotifier(\Closure $service); + public function registerNotifier(\Closure $service, \Closure $info); + + /** + * @return array App ID => App Name + * @since 9.0.0 + */ + public function listNotifiers(); /** * @return INotification diff --git a/lib/private/notification/manager.php b/lib/private/notification/manager.php index a8f1ec349c..239b5bfe5c 100644 --- a/lib/private/notification/manager.php +++ b/lib/private/notification/manager.php @@ -29,17 +29,25 @@ class Manager implements IManager { /** @var INotifier */ protected $notifiers; - /** @var \Closure */ + /** @var array[] */ + protected $notifiersInfo; + + /** @var \Closure[] */ protected $appsClosures; - /** @var \Closure */ + /** @var \Closure[] */ protected $notifiersClosures; + /** @var \Closure[] */ + protected $notifiersInfoClosures; + public function __construct() { $this->apps = []; $this->notifiers = []; + $this->notifiersInfo = []; $this->appsClosures = []; $this->notifiersClosures = []; + $this->notifiersInfoClosures = []; } /** @@ -56,12 +64,16 @@ class Manager implements IManager { /** * @param \Closure $service The service must implement INotifier, otherwise a * \InvalidArgumentException is thrown later + * @param \Closure $info An array with the keys 'id' and 'name' containing + * the app id and the app name * @return null - * @since 8.2.0 + * @since 8.2.0 - Parameter $info was added in 9.0.0 */ - public function registerNotifier(\Closure $service) { + public function registerNotifier(\Closure $service, \Closure $info) { $this->notifiersClosures[] = $service; + $this->notifiersInfoClosures[] = $info; $this->notifiers = []; + $this->notifiersInfo = []; } /** @@ -96,7 +108,7 @@ class Manager implements IManager { foreach ($this->notifiersClosures as $closure) { $notifier = $closure(); if (!($notifier instanceof INotifier)) { - throw new \InvalidArgumentException('The given notification app does not implement the INotifier interface'); + throw new \InvalidArgumentException('The given notifier does not implement the INotifier interface'); } $this->notifiers[] = $notifier; } @@ -104,6 +116,29 @@ class Manager implements IManager { return $this->notifiers; } + /** + * @return array[] + */ + public function listNotifiers() { + if (!empty($this->notifiersInfo)) { + return $this->notifiersInfo; + } + + $this->notifiersInfo = []; + foreach ($this->notifiersInfoClosures as $closure) { + $notifier = $closure(); + if (!is_array($notifier) || sizeof($notifier) !== 2 || !isset($notifier['id']) || !isset($notifier['name'])) { + throw new \InvalidArgumentException('The given notifier information is invalid'); + } + if (isset($this->notifiersInfo[$notifier['id']])) { + throw new \InvalidArgumentException('The given notifier ID ' . $notifier['id'] . ' is already in use'); + } + $this->notifiersInfo[$notifier['id']] = $notifier['name']; + } + + return $this->notifiersInfo; + } + /** * @return INotification * @since 8.2.0 diff --git a/tests/lib/notification/managertest.php b/tests/lib/notification/managertest.php index fa2a0586f9..1f411bc74e 100644 --- a/tests/lib/notification/managertest.php +++ b/tests/lib/notification/managertest.php @@ -82,15 +82,23 @@ class ManagerTest extends TestCase { }; $this->assertEquals([], $this->invokePrivate($this->manager, 'getNotifiers')); + $this->assertEquals([], $this->invokePrivate($this->manager, 'listNotifiers')); - $this->manager->registerNotifier($closure); + $this->manager->registerNotifier($closure, function() { + return ['id' => 'test1', 'name' => 'Test One']; + }); $this->assertEquals([$notifier], $this->invokePrivate($this->manager, 'getNotifiers')); + $this->assertEquals(['test1' => 'Test One'], $this->invokePrivate($this->manager, 'listNotifiers')); $this->assertEquals([$notifier], $this->invokePrivate($this->manager, 'getNotifiers')); + $this->assertEquals(['test1' => 'Test One'], $this->invokePrivate($this->manager, 'listNotifiers')); - $this->manager->registerNotifier($closure); + $this->manager->registerNotifier($closure, function() { + return ['id' => 'test2', 'name' => 'Test Two']; + }); $this->assertEquals([$notifier, $notifier], $this->invokePrivate($this->manager, 'getNotifiers')); + $this->assertEquals(['test1' => 'Test One', 'test2' => 'Test Two'], $this->invokePrivate($this->manager, 'listNotifiers')); } /** @@ -105,11 +113,68 @@ class ManagerTest extends TestCase { return $app; }; - $this->manager->registerNotifier($closure); + $this->manager->registerNotifier($closure, function() { + return ['id' => 'test1', 'name' => 'Test One']; + }); $this->invokePrivate($this->manager, 'getNotifiers'); } + public function dataRegisterNotifierInfoInvalid() { + return [ + [null], + ['No array'], + [['id' => 'test1', 'name' => 'Test One', 'size' => 'Invalid']], + [['no-id' => 'test1', 'name' => 'Test One']], + [['id' => 'test1', 'no-name' => 'Test One']], + ]; + } + + /** + * @dataProvider dataRegisterNotifierInfoInvalid + * @expectedException \InvalidArgumentException + * @param mixed $data + */ + public function testRegisterNotifierInfoInvalid($data) { + $app = $this->getMockBuilder('OC\Notification\IApp') + ->disableOriginalConstructor() + ->getMock(); + + $closure = function() use ($app) { + return $app; + }; + + $this->manager->registerNotifier($closure, function() use ($data) { + return $data; + }); + + $this->manager->listNotifiers(); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The given notifier ID test1 is already in use + */ + public function testRegisterNotifierInfoDuplicate() { + $app = $this->getMockBuilder('OC\Notification\IApp') + ->disableOriginalConstructor() + ->getMock(); + + $closure = function() use ($app) { + return $app; + }; + + $this->manager->registerNotifier($closure, function() { + return ['id' => 'test1', 'name' => 'Test One']; + }); + + $this->manager->registerNotifier($closure, function() { + return ['id' => 'test1', 'name' => 'Test One']; + }); + + $this->manager->listNotifiers(); + } + public function testCreateNotification() { $action = $this->manager->createNotification(); $this->assertInstanceOf('OC\Notification\INotification', $action); @@ -201,9 +266,13 @@ class ManagerTest extends TestCase { $this->manager->registerNotifier(function() use ($notifier) { return $notifier; + }, function() { + return ['id' => 'test1', 'name' => 'Test One']; }); $this->manager->registerNotifier(function() use ($notifier2) { return $notifier2; + }, function() { + return ['id' => 'test2', 'name' => 'Test Two']; }); $this->assertEquals($notification2, $this->manager->prepare($notification, 'en')); @@ -232,6 +301,8 @@ class ManagerTest extends TestCase { $this->manager->registerNotifier(function() use ($notifier) { return $notifier; + }, function() { + return ['id' => 'test1', 'name' => 'Test One']; }); $this->manager->prepare($notification, 'de'); @@ -257,6 +328,8 @@ class ManagerTest extends TestCase { $this->manager->registerNotifier(function() use ($notifier) { return $notifier; + }, function() { + return ['id' => 'test1', 'name' => 'Test One']; }); $this->assertEquals($notification, $this->manager->prepare($notification, 'de'));