Browse Source
Notificacations for simple @-mentioning in comments
Notificacations for simple @-mentioning in comments
(WIP) notify user when mentioned in comments Fix doc, and create absolute URL for as notification link. PSR-4 compatibility changes also move notification creation to comments app Do not notify yourself unit test for controller and application smaller fixes - translatable app name - remove doubles in mention array - micro perf optimization - display name: special label for deleted users, keep user id for users that could not be fetched from userManager Comment Notification-Listener Unit Test fix email adresses remove notification when triggering comment was deleted add and adjust tests add missing @license tags simplify NotificationsController registration appinfo simplification, php docs make string easier to translate adjust test replace dispatcher-based listeners with a registration method and interface safer to not pass optional data parameter to setSubject for marking as processed. ID and mention suffices Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de> update comment Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>pull/1449/head
committed by
Arthur Schiwon
No known key found for this signature in database
GPG Key ID: 7424F1874854DF23
18 changed files with 1934 additions and 36 deletions
-
31apps/comments/appinfo/app.php
-
28apps/comments/appinfo/routes.php
-
35apps/comments/lib/AppInfo/Application.php
-
138apps/comments/lib/Controller/Notifications.php
-
78apps/comments/lib/EventHandler.php
-
130apps/comments/lib/Notification/Listener.php
-
115apps/comments/lib/Notification/Notifier.php
-
65apps/comments/tests/Unit/AppInfo/ApplicationTest.php
-
162apps/comments/tests/Unit/Controller/NotificationsTest.php
-
152apps/comments/tests/Unit/EventHandlerTest.php
-
360apps/comments/tests/Unit/Notification/ListenerTest.php
-
499apps/comments/tests/Unit/Notification/NotifierTest.php
-
4lib/private/AppFramework/DependencyInjection/DIContainer.php
-
79lib/private/Comments/Manager.php
-
39lib/public/Comments/ICommentsEventHandler.php
-
9lib/public/Comments/ICommentsManager.php
-
2tests/lib/Comments/FakeManager.php
-
44tests/lib/Comments/ManagerTest.php
@ -0,0 +1,28 @@ |
|||
<?php |
|||
|
|||
/** |
|||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @copyright Copyright (c) 2016, ownCloud, Inc. |
|||
* @license AGPL-3.0 |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
|
|||
use \OCA\Comments\AppInfo\Application; |
|||
|
|||
$application = new Application(); |
|||
$application->registerRoutes($this, ['routes' => [ |
|||
['name' => 'Notifications#view', 'url' => '/notifications/view/{id}', 'verb' => 'GET'], |
|||
]]); |
|||
@ -0,0 +1,35 @@ |
|||
<?php |
|||
|
|||
/** |
|||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @license GNU AGPL version 3 or any later version |
|||
* |
|||
* This library is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
* License as published by the Free Software Foundation; either |
|||
* version 3 of the License, or any later version. |
|||
* |
|||
* This library 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 library. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
namespace OCA\Comments\AppInfo; |
|||
|
|||
use OCA\Comments\Controller\Notifications; |
|||
use OCP\AppFramework\App; |
|||
|
|||
class Application extends App { |
|||
|
|||
public function __construct (array $urlParams = array()) { |
|||
parent::__construct('comments', $urlParams); |
|||
$container = $this->getContainer(); |
|||
|
|||
$container->registerAlias('NotificationsController', Notifications::class); |
|||
} |
|||
} |
|||
@ -0,0 +1,138 @@ |
|||
<?php |
|||
|
|||
/** |
|||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @license GNU AGPL version 3 or any later version |
|||
* |
|||
* This library is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
* License as published by the Free Software Foundation; either |
|||
* version 3 of the License, or any later version. |
|||
* |
|||
* This library 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 library. If not, see <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
|
|||
namespace OCA\Comments\Controller; |
|||
|
|||
use OCP\AppFramework\Controller; |
|||
use OCP\AppFramework\Http\NotFoundResponse; |
|||
use OCP\AppFramework\Http\RedirectResponse; |
|||
use OCP\AppFramework\Http\Response; |
|||
use OCP\Comments\IComment; |
|||
use OCP\Comments\ICommentsManager; |
|||
use OCP\Files\Folder; |
|||
use OCP\IRequest; |
|||
use OCP\IURLGenerator; |
|||
use OCP\IUserSession; |
|||
use OCP\Notification\IManager; |
|||
|
|||
/** |
|||
* Class Notifications |
|||
* |
|||
* @package OCA\Comments\Controller |
|||
*/ |
|||
class Notifications extends Controller { |
|||
/** @var Folder */ |
|||
protected $folder; |
|||
|
|||
/** @var ICommentsManager */ |
|||
protected $commentsManager; |
|||
|
|||
/** @var IURLGenerator */ |
|||
protected $urlGenerator; |
|||
|
|||
/** @var IManager */ |
|||
protected $notificationManager; |
|||
|
|||
/** @var IUserSession */ |
|||
protected $userSession; |
|||
|
|||
/** |
|||
* Notifications constructor. |
|||
* |
|||
* @param string $appName |
|||
* @param IRequest $request |
|||
* @param ICommentsManager $commentsManager |
|||
* @param Folder $folder |
|||
* @param IURLGenerator $urlGenerator |
|||
* @param IManager $notificationManager |
|||
* @param IUserSession $userSession |
|||
*/ |
|||
public function __construct( |
|||
$appName, |
|||
IRequest $request, |
|||
ICommentsManager $commentsManager, |
|||
Folder $folder, |
|||
IURLGenerator $urlGenerator, |
|||
IManager $notificationManager, |
|||
IUserSession $userSession |
|||
) { |
|||
parent::__construct($appName, $request); |
|||
$this->commentsManager = $commentsManager; |
|||
$this->folder = $folder; |
|||
$this->urlGenerator = $urlGenerator; |
|||
$this->notificationManager = $notificationManager; |
|||
$this->userSession = $userSession; |
|||
} |
|||
|
|||
/** |
|||
* @NoAdminRequired |
|||
* @NoCSRFRequired |
|||
* |
|||
* @param string $id the comment ID |
|||
* @return Response |
|||
*/ |
|||
public function view($id) { |
|||
try { |
|||
$comment = $this->commentsManager->get($id); |
|||
if($comment->getObjectType() !== 'files') { |
|||
return new NotFoundResponse(); |
|||
} |
|||
$files = $this->folder->getById($comment->getObjectId()); |
|||
if(count($files) === 0) { |
|||
$this->markProcessed($comment); |
|||
return new NotFoundResponse(); |
|||
} |
|||
|
|||
$dir = $this->folder->getRelativePath($files[0]->getParent()->getPath()); |
|||
$url = $this->urlGenerator->linkToRouteAbsolute( |
|||
'files.view.index', |
|||
[ |
|||
'dir' => $dir, |
|||
'scrollto' => $files[0]->getName() |
|||
] |
|||
); |
|||
|
|||
$this->markProcessed($comment); |
|||
|
|||
return new RedirectResponse($url); |
|||
} catch (\Exception $e) { |
|||
return new NotFoundResponse(); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Marks the notification about a comment as processed |
|||
* @param IComment $comment |
|||
*/ |
|||
protected function markProcessed(IComment $comment) { |
|||
$user = $this->userSession->getUser(); |
|||
if(is_null($user)) { |
|||
return; |
|||
} |
|||
$notification = $this->notificationManager->createNotification(); |
|||
$notification->setApp('comments') |
|||
->setObject('comment', $comment->getId()) |
|||
->setSubject('mention') |
|||
->setUser($user->getUID()); |
|||
$this->notificationManager->markProcessed($notification); |
|||
} |
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
<?php |
|||
|
|||
/** |
|||
* @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @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 <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
|
|||
namespace OCA\Comments; |
|||
|
|||
use OCA\Comments\Activity\Listener as ActivityListener; |
|||
use OCA\Comments\AppInfo\Application; |
|||
use OCA\Comments\Notification\Listener as NotificationListener; |
|||
use OCP\Comments\CommentsEvent; |
|||
use OCP\Comments\ICommentsEventHandler; |
|||
|
|||
/** |
|||
* Class EventHandler |
|||
* |
|||
* @package OCA\Comments |
|||
*/ |
|||
class EventHandler implements ICommentsEventHandler { |
|||
|
|||
/** @var Application */ |
|||
protected $app; |
|||
|
|||
public function __construct(Application $app) { |
|||
$this->app = $app; |
|||
} |
|||
|
|||
/** |
|||
* @param CommentsEvent $event |
|||
*/ |
|||
public function handle(CommentsEvent $event) { |
|||
if($event->getComment()->getObjectType() !== 'files') { |
|||
// this is a 'files'-specific Handler
|
|||
return; |
|||
} |
|||
|
|||
if( $event->getEvent() === CommentsEvent::EVENT_ADD |
|||
&& $event instanceof CommentsEvent |
|||
) { |
|||
$this->onAdd($event); |
|||
return; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @param CommentsEvent $event |
|||
*/ |
|||
private function onAdd(CommentsEvent $event) { |
|||
$c = $this->app->getContainer(); |
|||
|
|||
/** @var NotificationListener $notificationListener */ |
|||
$notificationListener = $c->query(NotificationListener::class); |
|||
$notificationListener->evaluate($event); |
|||
|
|||
/** @var ActivityListener $listener */ |
|||
$activityListener = $c->query(ActivityListener::class); |
|||
$activityListener->commentEvent($event); |
|||
} |
|||
} |
|||
@ -0,0 +1,130 @@ |
|||
<?php |
|||
/** |
|||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @copyright Copyright (c) 2016, ownCloud, Inc. |
|||
* @license AGPL-3.0 |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
|
|||
namespace OCA\Comments\Notification; |
|||
|
|||
use OCP\Comments\CommentsEvent; |
|||
use OCP\Comments\IComment; |
|||
use OCP\IURLGenerator; |
|||
use OCP\IUserManager; |
|||
use OCP\Notification\IManager; |
|||
|
|||
class Listener { |
|||
/** @var IManager */ |
|||
protected $notificationManager; |
|||
|
|||
/** @var IUserManager */ |
|||
protected $userManager; |
|||
|
|||
/** @var IURLGenerator */ |
|||
protected $urlGenerator; |
|||
|
|||
/** |
|||
* Listener constructor. |
|||
* |
|||
* @param IManager $notificationManager |
|||
* @param IUserManager $userManager |
|||
* @param IURLGenerator $urlGenerator |
|||
*/ |
|||
public function __construct( |
|||
IManager $notificationManager, |
|||
IUserManager $userManager, |
|||
IURLGenerator $urlGenerator |
|||
) { |
|||
|
|||
$this->notificationManager = $notificationManager; |
|||
$this->userManager = $userManager; |
|||
$this->urlGenerator = $urlGenerator; |
|||
} |
|||
|
|||
/** |
|||
* @param CommentsEvent $event |
|||
*/ |
|||
public function evaluate(CommentsEvent $event) { |
|||
$comment = $event->getComment(); |
|||
|
|||
if($comment->getObjectType() !== 'files') { |
|||
// comments App serves files only, other object types/apps need to
|
|||
// register their own ICommentsEventHandler and trigger notifications
|
|||
return; |
|||
} |
|||
|
|||
$mentions = $this->extractMentions($comment->getMessage()); |
|||
if(empty($mentions)) { |
|||
// no one to notify
|
|||
return; |
|||
} |
|||
|
|||
$notification = $this->instantiateNotification($comment); |
|||
|
|||
foreach($mentions as $mention) { |
|||
$user = substr($mention, 1); // @username → username
|
|||
if( ($comment->getActorType() === 'users' && $user === $comment->getActorId()) |
|||
|| !$this->userManager->userExists($user) |
|||
) { |
|||
// do not notify unknown users or yourself
|
|||
continue; |
|||
} |
|||
|
|||
$notification->setUser($user); |
|||
if($event->getEvent() === CommentsEvent::EVENT_DELETE) { |
|||
$this->notificationManager->markProcessed($notification); |
|||
} else { |
|||
$this->notificationManager->notify($notification); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* creates a notification instance and fills it with comment data |
|||
* |
|||
* @param IComment $comment |
|||
* @return \OCP\Notification\INotification |
|||
*/ |
|||
public function instantiateNotification(IComment $comment) { |
|||
$notification = $this->notificationManager->createNotification(); |
|||
$notification |
|||
->setApp('comments') |
|||
->setObject('comment', $comment->getId()) |
|||
->setSubject('mention', [ $comment->getObjectType(), $comment->getObjectId() ]) |
|||
->setDateTime($comment->getCreationDateTime()) |
|||
->setLink($this->urlGenerator->linkToRouteAbsolute( |
|||
'comments.Notifications.view', |
|||
['id' => $comment->getId()]) |
|||
); |
|||
|
|||
return $notification; |
|||
} |
|||
|
|||
/** |
|||
* extracts @-mentions out of a message body. |
|||
* |
|||
* @param string $message |
|||
* @return string[] containing the mentions, e.g. ['@alice', '@bob'] |
|||
*/ |
|||
public function extractMentions($message) { |
|||
$ok = preg_match_all('/\B@[a-z0-9_\-@\.\']+/i', $message, $mentions); |
|||
if(!$ok || !isset($mentions[0]) || !is_array($mentions[0])) { |
|||
return []; |
|||
} |
|||
return array_unique($mentions[0]); |
|||
} |
|||
} |
|||
@ -0,0 +1,115 @@ |
|||
<?php |
|||
/** |
|||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @copyright Copyright (c) 2016, ownCloud, Inc. |
|||
* @license AGPL-3.0 |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
|
|||
namespace OCA\Comments\Notification; |
|||
|
|||
use OCP\Comments\ICommentsManager; |
|||
use OCP\Comments\NotFoundException; |
|||
use OCP\Files\Folder; |
|||
use OCP\IUserManager; |
|||
use OCP\L10N\IFactory; |
|||
use OCP\Notification\INotification; |
|||
use OCP\Notification\INotifier; |
|||
|
|||
class Notifier implements INotifier { |
|||
|
|||
/** @var IFactory */ |
|||
protected $l10nFactory; |
|||
|
|||
/** @var Folder */ |
|||
protected $userFolder; |
|||
|
|||
/** @var ICommentsManager */ |
|||
protected $commentsManager; |
|||
|
|||
/** @var IUserManager */ |
|||
protected $userManager; |
|||
|
|||
public function __construct( |
|||
IFactory $l10nFactory, |
|||
Folder $userFolder, |
|||
ICommentsManager $commentsManager, |
|||
IUserManager $userManager |
|||
) { |
|||
$this->l10nFactory = $l10nFactory; |
|||
$this->userFolder = $userFolder; |
|||
$this->commentsManager = $commentsManager; |
|||
$this->userManager = $userManager; |
|||
} |
|||
|
|||
/** |
|||
* @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 |
|||
*/ |
|||
public function prepare(INotification $notification, $languageCode) { |
|||
if($notification->getApp() !== 'comments') { |
|||
throw new \InvalidArgumentException(); |
|||
} |
|||
try { |
|||
$comment = $this->commentsManager->get($notification->getObjectId()); |
|||
} catch(NotFoundException $e) { |
|||
// needs to be converted to InvalidArgumentException, otherwise none Notifications will be shown at all
|
|||
throw new \InvalidArgumentException('Comment not found', 0, $e); |
|||
} |
|||
$l = $this->l10nFactory->get('comments', $languageCode); |
|||
$displayName = $comment->getActorId(); |
|||
$isDeletedActor = $comment->getActorType() === ICommentsManager::DELETED_USER; |
|||
if($comment->getActorType() === 'users') { |
|||
$commenter = $this->userManager->get($comment->getActorId()); |
|||
if(!is_null($commenter)) { |
|||
$displayName = $commenter->getDisplayName(); |
|||
} |
|||
} |
|||
switch($notification->getSubject()) { |
|||
case 'mention': |
|||
$parameters = $notification->getSubjectParameters(); |
|||
if($parameters[0] !== 'files') { |
|||
throw new \InvalidArgumentException('Unsupported comment object'); |
|||
} |
|||
$nodes = $this->userFolder->getById($parameters[1]); |
|||
if(empty($nodes)) { |
|||
throw new \InvalidArgumentException('Cannot resolve file id to Node instance'); |
|||
} |
|||
$fileName = $nodes[0]->getName(); |
|||
if($isDeletedActor) { |
|||
$subject = (string) $l->t( |
|||
'You were mentioned in a comment on "%s" by a now deleted user.', |
|||
[ $fileName ] |
|||
); |
|||
} else { |
|||
$subject = (string) $l->t( |
|||
'You were mentioned in a comment on "%s" by %s.', |
|||
[ $fileName, $displayName ] |
|||
); |
|||
} |
|||
$notification->setParsedSubject($subject); |
|||
|
|||
return $notification; |
|||
break; |
|||
|
|||
default: |
|||
throw new \InvalidArgumentException('Invalid subject'); |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
<?php |
|||
/** |
|||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @copyright Copyright (c) 2016, ownCloud, Inc. |
|||
* @license AGPL-3.0 |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
|
|||
namespace OCA\Comments\Tests\Unit\AppInfo; |
|||
|
|||
use OCA\Comments\AppInfo\Application; |
|||
use Test\TestCase; |
|||
|
|||
/** |
|||
* Class ApplicationTest |
|||
* |
|||
* @group DB |
|||
* |
|||
* @package OCA\Comments\Tests\Unit\AppInfo |
|||
*/ |
|||
class ApplicationTest extends TestCase { |
|||
protected function setUp() { |
|||
parent::setUp(); |
|||
\OC::$server->getUserManager()->createUser('dummy', '456'); |
|||
\OC::$server->getUserSession()->setUser(\OC::$server->getUserManager()->get('dummy')); |
|||
} |
|||
|
|||
protected function tearDown() { |
|||
\OC::$server->getUserManager()->get('dummy')->delete(); |
|||
parent::tearDown(); |
|||
} |
|||
|
|||
public function test() { |
|||
$app = new Application(); |
|||
$c = $app->getContainer(); |
|||
|
|||
// assert service instances in the container are properly setup
|
|||
$s = $c->query('NotificationsController'); |
|||
$this->assertInstanceOf('OCA\Comments\Controller\Notifications', $s); |
|||
|
|||
$services = [ |
|||
'OCA\Comments\Activity\Extension', |
|||
'OCA\Comments\Activity\Listener', |
|||
'OCA\Comments\Notification\Listener' |
|||
]; |
|||
|
|||
foreach($services as $service) { |
|||
$s = $c->query($service); |
|||
$this->assertInstanceOf($service, $s); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,162 @@ |
|||
<?php |
|||
/** |
|||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @copyright Copyright (c) 2016, ownCloud, Inc. |
|||
* @license AGPL-3.0 |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
|
|||
namespace OCA\Comments\Tests\Unit\Controller; |
|||
|
|||
use OCA\Comments\Controller\Notifications; |
|||
use OCP\Comments\NotFoundException; |
|||
use Test\TestCase; |
|||
|
|||
class NotificationsTest extends TestCase { |
|||
/** @var \OCA\Comments\Controller\Notifications */ |
|||
protected $notificationsController; |
|||
|
|||
/** @var \OCP\Comments\ICommentsManager|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $commentsManager; |
|||
|
|||
/** @var \OCP\Files\Folder|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $folder; |
|||
|
|||
/** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $session; |
|||
|
|||
/** @var \OCP\Notification\IManager|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $notificationManager; |
|||
|
|||
protected function setUp() { |
|||
parent::setUp(); |
|||
|
|||
$this->commentsManager = $this->getMockBuilder('\OCP\Comments\ICommentsManager')->getMock(); |
|||
$this->folder = $this->getMockBuilder('\OCP\Files\Folder')->getMock(); |
|||
$this->session = $this->getMockBuilder('\OCP\IUserSession')->getMock(); |
|||
$this->notificationManager = $this->getMockBuilder('\OCP\Notification\IManager')->getMock(); |
|||
|
|||
$this->notificationsController = new Notifications( |
|||
'comments', |
|||
$this->getMockBuilder('\OCP\IRequest')->getMock(), |
|||
$this->commentsManager, |
|||
$this->folder, |
|||
$this->getMockBuilder('\OCP\IURLGenerator')->getMock(), |
|||
$this->notificationManager, |
|||
$this->session |
|||
); |
|||
} |
|||
|
|||
public function testViewSuccess() { |
|||
$comment = $this->getMockBuilder('\OCP\Comments\IComment')->getMock(); |
|||
$comment->expects($this->any()) |
|||
->method('getObjectType') |
|||
->will($this->returnValue('files')); |
|||
|
|||
$this->commentsManager->expects($this->any()) |
|||
->method('get') |
|||
->with('42') |
|||
->will($this->returnValue($comment)); |
|||
|
|||
$file = $this->getMockBuilder('\OCP\Files\Node')->getMock(); |
|||
$file->expects($this->once()) |
|||
->method('getParent') |
|||
->will($this->returnValue($this->getMockBuilder('\OCP\Files\Folder')->getMock())); |
|||
|
|||
$this->folder->expects($this->once()) |
|||
->method('getById') |
|||
->will($this->returnValue([$file])); |
|||
|
|||
$this->session->expects($this->once()) |
|||
->method('getUser') |
|||
->will($this->returnValue($this->getMockBuilder('\OCP\IUser')->getMock())); |
|||
|
|||
$notification = $this->getMockBuilder('\OCP\Notification\INotification')->getMock(); |
|||
$notification->expects($this->any()) |
|||
->method($this->anything()) |
|||
->will($this->returnValue($notification)); |
|||
|
|||
$this->notificationManager->expects($this->once()) |
|||
->method('createNotification') |
|||
->will($this->returnValue($notification)); |
|||
$this->notificationManager->expects($this->once()) |
|||
->method('markProcessed') |
|||
->with($notification); |
|||
|
|||
$response = $this->notificationsController->view('42'); |
|||
$this->assertInstanceOf('\OCP\AppFramework\Http\RedirectResponse', $response); |
|||
} |
|||
|
|||
public function testViewInvalidComment() { |
|||
$this->commentsManager->expects($this->any()) |
|||
->method('get') |
|||
->with('42') |
|||
->will($this->throwException(new NotFoundException())); |
|||
|
|||
$file = $this->getMockBuilder('\OCP\Files\Node')->getMock(); |
|||
$file->expects($this->never()) |
|||
->method('getParent'); |
|||
|
|||
$this->folder->expects($this->never()) |
|||
->method('getById'); |
|||
|
|||
$this->session->expects($this->never()) |
|||
->method('getUser'); |
|||
|
|||
$this->notificationManager->expects($this->never()) |
|||
->method('createNotification'); |
|||
$this->notificationManager->expects($this->never()) |
|||
->method('markProcessed'); |
|||
|
|||
$response = $this->notificationsController->view('42'); |
|||
$this->assertInstanceOf('\OCP\AppFramework\Http\NotFoundResponse', $response); |
|||
} |
|||
|
|||
public function testViewNoFile() { |
|||
$comment = $this->getMockBuilder('\OCP\Comments\IComment')->getMock(); |
|||
$comment->expects($this->any()) |
|||
->method('getObjectType') |
|||
->will($this->returnValue('files')); |
|||
|
|||
$this->commentsManager->expects($this->any()) |
|||
->method('get') |
|||
->with('42') |
|||
->will($this->returnValue($comment)); |
|||
|
|||
$this->folder->expects($this->once()) |
|||
->method('getById') |
|||
->will($this->returnValue([])); |
|||
|
|||
$this->session->expects($this->once()) |
|||
->method('getUser') |
|||
->will($this->returnValue($this->getMockBuilder('\OCP\IUser')->getMock())); |
|||
|
|||
$notification = $this->getMockBuilder('\OCP\Notification\INotification')->getMock(); |
|||
$notification->expects($this->any()) |
|||
->method($this->anything()) |
|||
->will($this->returnValue($notification)); |
|||
|
|||
$this->notificationManager->expects($this->once()) |
|||
->method('createNotification') |
|||
->will($this->returnValue($notification)); |
|||
$this->notificationManager->expects($this->once()) |
|||
->method('markProcessed') |
|||
->with($notification); |
|||
|
|||
$response = $this->notificationsController->view('42'); |
|||
$this->assertInstanceOf('\OCP\AppFramework\Http\NotFoundResponse', $response); |
|||
} |
|||
} |
|||
@ -0,0 +1,152 @@ |
|||
<?php |
|||
/** |
|||
* @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @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 <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
|
|||
namespace OCA\Comments\Tests\Unit\Notification; |
|||
|
|||
use OCA\Comments\AppInfo\Application; |
|||
use OCA\Comments\EventHandler; |
|||
use OCP\Comments\CommentsEvent; |
|||
use OCP\Comments\IComment; |
|||
use OCA\Comments\Activity\Listener as ActivityListener; |
|||
use OCA\Comments\Notification\Listener as NotificationListener; |
|||
use OCP\IContainer; |
|||
use Test\TestCase; |
|||
|
|||
class EventHandlerTest extends TestCase { |
|||
/** @var EventHandler */ |
|||
protected $eventHandler; |
|||
|
|||
/** @var Application|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $app; |
|||
|
|||
protected function setUp() { |
|||
parent::setUp(); |
|||
|
|||
$this->app = $this->getMockBuilder(Application::class) |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
|
|||
$this->eventHandler = new EventHandler($this->app); |
|||
} |
|||
|
|||
public function testNotFiles() { |
|||
/** @var IComment|\PHPUnit_Framework_MockObject_MockObject $comment */ |
|||
$comment = $this->getMockBuilder(IComment::class)->getMock(); |
|||
$comment->expects($this->once()) |
|||
->method('getObjectType') |
|||
->willReturn('smiles'); |
|||
|
|||
/** @var CommentsEvent|\PHPUnit_Framework_MockObject_MockObject $event */ |
|||
$event = $this->getMockBuilder(CommentsEvent::class) |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
$event->expects($this->once()) |
|||
->method('getComment') |
|||
->willReturn($comment); |
|||
$event->expects($this->never()) |
|||
->method('getEvent'); |
|||
|
|||
$this->eventHandler->handle($event); |
|||
} |
|||
|
|||
public function notHandledProvider() { |
|||
return [ |
|||
[CommentsEvent::EVENT_DELETE], |
|||
[CommentsEvent::EVENT_UPDATE] |
|||
]; |
|||
} |
|||
|
|||
/** |
|||
* @dataProvider notHandledProvider |
|||
* @param $eventType |
|||
*/ |
|||
public function testNotHandled($eventType) { |
|||
/** @var IComment|\PHPUnit_Framework_MockObject_MockObject $comment */ |
|||
$comment = $this->getMockBuilder(IComment::class)->getMock(); |
|||
$comment->expects($this->once()) |
|||
->method('getObjectType') |
|||
->willReturn('files'); |
|||
|
|||
/** @var CommentsEvent|\PHPUnit_Framework_MockObject_MockObject $event */ |
|||
$event = $this->getMockBuilder(CommentsEvent::class) |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
$event->expects($this->once()) |
|||
->method('getComment') |
|||
->willReturn($comment); |
|||
$event->expects($this->once()) |
|||
->method('getEvent') |
|||
->willReturn($eventType); |
|||
|
|||
// further processing does not happen, because $event methods cannot be
|
|||
// access more than once.
|
|||
$this->eventHandler->handle($event); |
|||
} |
|||
|
|||
public function testHandled() { |
|||
/** @var IComment|\PHPUnit_Framework_MockObject_MockObject $comment */ |
|||
$comment = $this->getMockBuilder(IComment::class)->getMock(); |
|||
$comment->expects($this->once()) |
|||
->method('getObjectType') |
|||
->willReturn('files'); |
|||
|
|||
/** @var CommentsEvent|\PHPUnit_Framework_MockObject_MockObject $event */ |
|||
$event = $this->getMockBuilder(CommentsEvent::class) |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
$event->expects($this->atLeastOnce()) |
|||
->method('getComment') |
|||
->willReturn($comment); |
|||
$event->expects($this->atLeastOnce()) |
|||
->method('getEvent') |
|||
->willReturn(CommentsEvent::EVENT_ADD); |
|||
|
|||
$notificationListener = $this->getMockBuilder(NotificationListener::class) |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
$notificationListener->expects($this->once()) |
|||
->method('evaluate') |
|||
->with($event); |
|||
|
|||
$activityListener = $this->getMockBuilder(ActivityListener::class) |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
$activityListener->expects($this->once()) |
|||
->method('commentEvent') |
|||
->with($event); |
|||
|
|||
/** @var IContainer|\PHPUnit_Framework_MockObject_MockObject $c */ |
|||
$c = $this->getMockBuilder(IContainer::class)->getMock(); |
|||
$c->expects($this->exactly(2)) |
|||
->method('query') |
|||
->withConsecutive([NotificationListener::class], [ActivityListener::class]) |
|||
->willReturnOnConsecutiveCalls($notificationListener, $activityListener); |
|||
|
|||
$this->app->expects($this->once()) |
|||
->method('getContainer') |
|||
->willReturn($c); |
|||
|
|||
$this->eventHandler->handle($event); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,360 @@ |
|||
<?php |
|||
/** |
|||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @copyright Copyright (c) 2016, ownCloud, Inc. |
|||
* @license AGPL-3.0 |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
|
|||
namespace OCA\Comments\Tests\Unit\Notification; |
|||
|
|||
use OCA\Comments\Notification\Listener; |
|||
use OCP\Comments\CommentsEvent; |
|||
use OCP\Comments\IComment; |
|||
use OCP\IURLGenerator; |
|||
use OCP\IUserManager; |
|||
use OCP\Notification\IManager; |
|||
use OCP\Notification\INotification; |
|||
use Test\TestCase; |
|||
|
|||
class ListenerTest extends TestCase { |
|||
/** @var IManager|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $notificationManager; |
|||
|
|||
/** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $userManager; |
|||
|
|||
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $urlGenerator; |
|||
|
|||
/** @var Listener */ |
|||
protected $listener; |
|||
|
|||
protected function setUp() { |
|||
parent::setUp(); |
|||
|
|||
$this->notificationManager = $this->getMockBuilder('\OCP\Notification\IManager')->getMock(); |
|||
$this->userManager = $this->getMockBuilder('\OCP\IUserManager')->getMock(); |
|||
$this->urlGenerator = $this->getMockBuilder('OCP\IURLGenerator')->getMock(); |
|||
|
|||
$this->listener = new Listener( |
|||
$this->notificationManager, |
|||
$this->userManager, |
|||
$this->urlGenerator |
|||
); |
|||
} |
|||
|
|||
public function eventProvider() { |
|||
return [ |
|||
[CommentsEvent::EVENT_ADD, 'notify'], |
|||
[CommentsEvent::EVENT_DELETE, 'markProcessed'] |
|||
]; |
|||
} |
|||
|
|||
/** |
|||
* @dataProvider eventProvider |
|||
* @param string $eventType |
|||
* @param string $notificationMethod |
|||
*/ |
|||
public function testEvaluate($eventType, $notificationMethod) { |
|||
$message = '@foobar and @barfoo you should know, @foo@bar.com is valid' . |
|||
' and so is @bar@foo.org@foobar.io I hope that clarifies everything.' . |
|||
' cc @23452-4333-54353-2342 @yolo!'; |
|||
|
|||
/** @var IComment|\PHPUnit_Framework_MockObject_MockObject $comment */ |
|||
$comment = $this->getMockBuilder('\OCP\Comments\IComment')->getMock(); |
|||
$comment->expects($this->any()) |
|||
->method('getObjectType') |
|||
->will($this->returnValue('files')); |
|||
$comment->expects($this->any()) |
|||
->method('getCreationDateTime') |
|||
->will($this->returnValue(new \DateTime())); |
|||
$comment->expects($this->once()) |
|||
->method('getMessage') |
|||
->will($this->returnValue($message)); |
|||
|
|||
/** @var CommentsEvent|\PHPUnit_Framework_MockObject_MockObject $event */ |
|||
$event = $this->getMockBuilder('\OCP\Comments\CommentsEvent') |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
$event->expects($this->once()) |
|||
->method('getComment') |
|||
->will($this->returnValue($comment)); |
|||
$event->expects(($this->any())) |
|||
->method(('getEvent')) |
|||
->will($this->returnValue($eventType)); |
|||
|
|||
/** @var INotification|\PHPUnit_Framework_MockObject_MockObject $notification */ |
|||
$notification = $this->getMockBuilder('\OCP\Notification\INotification')->getMock(); |
|||
$notification->expects($this->any()) |
|||
->method($this->anything()) |
|||
->will($this->returnValue($notification)); |
|||
$notification->expects($this->exactly(6)) |
|||
->method('setUser'); |
|||
|
|||
$this->notificationManager->expects($this->once()) |
|||
->method('createNotification') |
|||
->will($this->returnValue($notification)); |
|||
$this->notificationManager->expects($this->exactly(6)) |
|||
->method($notificationMethod) |
|||
->with($this->isInstanceOf('\OCP\Notification\INotification')); |
|||
|
|||
$this->userManager->expects($this->exactly(6)) |
|||
->method('userExists') |
|||
->withConsecutive( |
|||
['foobar'], |
|||
['barfoo'], |
|||
['foo@bar.com'], |
|||
['bar@foo.org@foobar.io'], |
|||
['23452-4333-54353-2342'], |
|||
['yolo'] |
|||
) |
|||
->will($this->returnValue(true)); |
|||
|
|||
$this->listener->evaluate($event); |
|||
} |
|||
|
|||
/** |
|||
* @dataProvider eventProvider |
|||
* @param string $eventType |
|||
*/ |
|||
public function testEvaluateNoMentions($eventType) { |
|||
$message = 'a boring comment without mentions'; |
|||
|
|||
/** @var IComment|\PHPUnit_Framework_MockObject_MockObject $comment */ |
|||
$comment = $this->getMockBuilder('\OCP\Comments\IComment')->getMock(); |
|||
$comment->expects($this->any()) |
|||
->method('getObjectType') |
|||
->will($this->returnValue('files')); |
|||
$comment->expects($this->any()) |
|||
->method('getCreationDateTime') |
|||
->will($this->returnValue(new \DateTime())); |
|||
$comment->expects($this->once()) |
|||
->method('getMessage') |
|||
->will($this->returnValue($message)); |
|||
|
|||
/** @var CommentsEvent|\PHPUnit_Framework_MockObject_MockObject $event */ |
|||
$event = $this->getMockBuilder('\OCP\Comments\CommentsEvent') |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
$event->expects($this->once()) |
|||
->method('getComment') |
|||
->will($this->returnValue($comment)); |
|||
$event->expects(($this->any())) |
|||
->method(('getEvent')) |
|||
->will($this->returnValue($eventType)); |
|||
|
|||
$this->notificationManager->expects($this->never()) |
|||
->method('createNotification'); |
|||
$this->notificationManager->expects($this->never()) |
|||
->method('notify'); |
|||
$this->notificationManager->expects($this->never()) |
|||
->method('markProcessed'); |
|||
|
|||
$this->userManager->expects($this->never()) |
|||
->method('userExists'); |
|||
|
|||
$this->listener->evaluate($event); |
|||
} |
|||
|
|||
public function testUnsupportedCommentObjectType() { |
|||
/** @var IComment|\PHPUnit_Framework_MockObject_MockObject $comment */ |
|||
$comment = $this->getMockBuilder('\OCP\Comments\IComment')->getMock(); |
|||
$comment->expects($this->once()) |
|||
->method('getObjectType') |
|||
->will($this->returnValue('vcards')); |
|||
$comment->expects($this->never()) |
|||
->method('getMessage'); |
|||
|
|||
/** @var CommentsEvent|\PHPUnit_Framework_MockObject_MockObject $event */ |
|||
$event = $this->getMockBuilder('\OCP\Comments\CommentsEvent') |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
$event->expects($this->once()) |
|||
->method('getComment') |
|||
->will($this->returnValue($comment)); |
|||
$event->expects(($this->any())) |
|||
->method(('getEvent')) |
|||
->will($this->returnValue(CommentsEvent::EVENT_ADD)); |
|||
|
|||
$this->listener->evaluate($event); |
|||
} |
|||
|
|||
public function testEvaluateUserDoesNotExist() { |
|||
$message = '@foobar bla bla bla'; |
|||
|
|||
/** @var IComment|\PHPUnit_Framework_MockObject_MockObject $comment */ |
|||
$comment = $this->getMockBuilder('\OCP\Comments\IComment')->getMock(); |
|||
$comment->expects($this->any()) |
|||
->method('getObjectType') |
|||
->will($this->returnValue('files')); |
|||
$comment->expects($this->any()) |
|||
->method('getCreationDateTime') |
|||
->will($this->returnValue(new \DateTime())); |
|||
$comment->expects($this->once()) |
|||
->method('getMessage') |
|||
->will($this->returnValue($message)); |
|||
|
|||
/** @var CommentsEvent|\PHPUnit_Framework_MockObject_MockObject $event */ |
|||
$event = $this->getMockBuilder('\OCP\Comments\CommentsEvent') |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
$event->expects($this->once()) |
|||
->method('getComment') |
|||
->will($this->returnValue($comment)); |
|||
$event->expects(($this->any())) |
|||
->method(('getEvent')) |
|||
->will($this->returnValue(CommentsEvent::EVENT_ADD)); |
|||
|
|||
/** @var INotification|\PHPUnit_Framework_MockObject_MockObject $notification */ |
|||
$notification = $this->getMockBuilder('\OCP\Notification\INotification')->getMock(); |
|||
$notification->expects($this->any()) |
|||
->method($this->anything()) |
|||
->will($this->returnValue($notification)); |
|||
$notification->expects($this->never()) |
|||
->method('setUser'); |
|||
|
|||
$this->notificationManager->expects($this->once()) |
|||
->method('createNotification') |
|||
->will($this->returnValue($notification)); |
|||
$this->notificationManager->expects($this->never()) |
|||
->method('notify'); |
|||
|
|||
$this->userManager->expects($this->once()) |
|||
->method('userExists') |
|||
->withConsecutive( |
|||
['foobar'] |
|||
) |
|||
->will($this->returnValue(false)); |
|||
|
|||
$this->listener->evaluate($event); |
|||
} |
|||
|
|||
/** |
|||
* @dataProvider eventProvider |
|||
* @param string $eventType |
|||
* @param string $notificationMethod |
|||
*/ |
|||
public function testEvaluateOneMentionPerUser($eventType, $notificationMethod) { |
|||
$message = '@foobar bla bla bla @foobar'; |
|||
|
|||
/** @var IComment|\PHPUnit_Framework_MockObject_MockObject $comment */ |
|||
$comment = $this->getMockBuilder('\OCP\Comments\IComment')->getMock(); |
|||
$comment->expects($this->any()) |
|||
->method('getObjectType') |
|||
->will($this->returnValue('files')); |
|||
$comment->expects($this->any()) |
|||
->method('getCreationDateTime') |
|||
->will($this->returnValue(new \DateTime())); |
|||
$comment->expects($this->once()) |
|||
->method('getMessage') |
|||
->will($this->returnValue($message)); |
|||
|
|||
/** @var CommentsEvent|\PHPUnit_Framework_MockObject_MockObject $event */ |
|||
$event = $this->getMockBuilder('\OCP\Comments\CommentsEvent') |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
$event->expects($this->once()) |
|||
->method('getComment') |
|||
->will($this->returnValue($comment)); |
|||
$event->expects(($this->any())) |
|||
->method(('getEvent')) |
|||
->will($this->returnValue($eventType)); |
|||
|
|||
/** @var INotification|\PHPUnit_Framework_MockObject_MockObject $notification */ |
|||
$notification = $this->getMockBuilder('\OCP\Notification\INotification')->getMock(); |
|||
$notification->expects($this->any()) |
|||
->method($this->anything()) |
|||
->will($this->returnValue($notification)); |
|||
$notification->expects($this->once()) |
|||
->method('setUser'); |
|||
|
|||
$this->notificationManager->expects($this->once()) |
|||
->method('createNotification') |
|||
->will($this->returnValue($notification)); |
|||
$this->notificationManager->expects($this->once()) |
|||
->method($notificationMethod) |
|||
->with($this->isInstanceOf('\OCP\Notification\INotification')); |
|||
|
|||
$this->userManager->expects($this->once()) |
|||
->method('userExists') |
|||
->withConsecutive( |
|||
['foobar'] |
|||
) |
|||
->will($this->returnValue(true)); |
|||
|
|||
$this->listener->evaluate($event); |
|||
} |
|||
|
|||
/** |
|||
* @dataProvider eventProvider |
|||
* @param string $eventType |
|||
*/ |
|||
public function testEvaluateNoSelfMention($eventType) { |
|||
$message = '@foobar bla bla bla'; |
|||
|
|||
/** @var IComment|\PHPUnit_Framework_MockObject_MockObject $comment */ |
|||
$comment = $this->getMockBuilder('\OCP\Comments\IComment')->getMock(); |
|||
$comment->expects($this->any()) |
|||
->method('getObjectType') |
|||
->will($this->returnValue('files')); |
|||
$comment->expects($this->any()) |
|||
->method('getActorType') |
|||
->will($this->returnValue('users')); |
|||
$comment->expects($this->any()) |
|||
->method('getActorId') |
|||
->will($this->returnValue('foobar')); |
|||
$comment->expects($this->any()) |
|||
->method('getCreationDateTime') |
|||
->will($this->returnValue(new \DateTime())); |
|||
$comment->expects($this->once()) |
|||
->method('getMessage') |
|||
->will($this->returnValue($message)); |
|||
|
|||
/** @var CommentsEvent|\PHPUnit_Framework_MockObject_MockObject $event */ |
|||
$event = $this->getMockBuilder('\OCP\Comments\CommentsEvent') |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
$event->expects($this->once()) |
|||
->method('getComment') |
|||
->will($this->returnValue($comment)); |
|||
$event->expects(($this->any())) |
|||
->method(('getEvent')) |
|||
->will($this->returnValue($eventType)); |
|||
|
|||
/** @var INotification|\PHPUnit_Framework_MockObject_MockObject $notification */ |
|||
$notification = $this->getMockBuilder('\OCP\Notification\INotification')->getMock(); |
|||
$notification->expects($this->any()) |
|||
->method($this->anything()) |
|||
->will($this->returnValue($notification)); |
|||
$notification->expects($this->never()) |
|||
->method('setUser'); |
|||
|
|||
$this->notificationManager->expects($this->once()) |
|||
->method('createNotification') |
|||
->will($this->returnValue($notification)); |
|||
$this->notificationManager->expects($this->never()) |
|||
->method('notify'); |
|||
$this->notificationManager->expects($this->never()) |
|||
->method('markProcessed'); |
|||
|
|||
$this->userManager->expects($this->never()) |
|||
->method('userExists'); |
|||
|
|||
$this->listener->evaluate($event); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,499 @@ |
|||
<?php |
|||
/** |
|||
* @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @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 <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
|
|||
namespace OCA\Comments\Tests\Unit\Notification; |
|||
|
|||
use OCA\Comments\Notification\Notifier; |
|||
use OCP\Comments\IComment; |
|||
use OCP\Comments\ICommentsManager; |
|||
use OCP\Comments\NotFoundException; |
|||
use OCP\Files\Folder; |
|||
use OCP\Files\Node; |
|||
use OCP\IL10N; |
|||
use OCP\IUser; |
|||
use OCP\IUserManager; |
|||
use OCP\L10N\IFactory; |
|||
use OCP\Notification\INotification; |
|||
use Test\TestCase; |
|||
|
|||
class NotifierTest extends TestCase { |
|||
|
|||
/** @var Notifier */ |
|||
protected $notifier; |
|||
|
|||
/** @var IFactory|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $l10nFactory; |
|||
|
|||
/** @var Folder|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $folder; |
|||
|
|||
/** @var ICommentsManager|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $commentsManager; |
|||
|
|||
/** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $userManager; |
|||
|
|||
|
|||
/** @var string */ |
|||
protected $lc = 'tlh_KX'; |
|||
|
|||
/** @var INotification|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $notification; |
|||
|
|||
/** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $l; |
|||
|
|||
/** @var IComment|\PHPUnit_Framework_MockObject_MockObject */ |
|||
protected $comment; |
|||
|
|||
protected function setUp() { |
|||
parent::setUp(); |
|||
|
|||
$this->l10nFactory = $this->getMockBuilder('OCP\L10N\IFactory')->getMock(); |
|||
$this->folder = $this->getMockBuilder('OCP\Files\Folder')->getMock(); |
|||
$this->commentsManager = $this->getMockBuilder('OCP\Comments\ICommentsManager')->getMock(); |
|||
$this->userManager = $this->getMockBuilder('OCP\IUserManager')->getMock(); |
|||
|
|||
$this->notifier = new Notifier( |
|||
$this->l10nFactory, |
|||
$this->folder, |
|||
$this->commentsManager, |
|||
$this->userManager |
|||
); |
|||
|
|||
$this->l = $this->getMockBuilder('OCP\IL10N')->getMock(); |
|||
$this->notification = $this->getMockBuilder('OCP\Notification\INotification')->getMock(); |
|||
$this->comment = $this->getMockBuilder('OCP\Comments\IComment')->getMock(); |
|||
} |
|||
|
|||
public function testPrepareSuccess() { |
|||
$fileName = 'Gre\'thor.odp'; |
|||
$displayName = 'Huraga'; |
|||
$message = 'You were mentioned in a comment on "Gre\'thor.odp" by Huraga.'; |
|||
|
|||
/** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */ |
|||
$user = $this->getMockBuilder('OCP\IUser')->getMock(); |
|||
$user->expects($this->once()) |
|||
->method('getDisplayName') |
|||
->willReturn($displayName); |
|||
|
|||
/** @var Node|\PHPUnit_Framework_MockObject_MockObject */ |
|||
$node = $this->getMockBuilder('OCP\Files\Node')->getMock(); |
|||
$node |
|||
->expects($this->once()) |
|||
->method('getName') |
|||
->willReturn($fileName); |
|||
|
|||
$this->folder |
|||
->expects($this->once()) |
|||
->method('getById') |
|||
->with('678') |
|||
->willReturn([$node]); |
|||
|
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getApp') |
|||
->willReturn('comments'); |
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getSubject') |
|||
->willReturn('mention'); |
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getSubjectParameters') |
|||
->willReturn(['files', '678']); |
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('setParsedSubject') |
|||
->with($message); |
|||
|
|||
$this->l |
|||
->expects($this->once()) |
|||
->method('t') |
|||
->with('You were mentioned in a comment on "%s" by %s.', [$fileName, $displayName]) |
|||
->willReturn($message); |
|||
|
|||
$this->l10nFactory |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->willReturn($this->l); |
|||
|
|||
$this->comment |
|||
->expects($this->any()) |
|||
->method('getActorId') |
|||
->willReturn('huraga'); |
|||
$this->comment |
|||
->expects($this->any()) |
|||
->method('getActorType') |
|||
->willReturn('users'); |
|||
|
|||
$this->commentsManager |
|||
->expects(($this->once())) |
|||
->method('get') |
|||
->willReturn($this->comment); |
|||
|
|||
$this->userManager |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->with('huraga') |
|||
->willReturn($user); |
|||
|
|||
$this->notifier->prepare($this->notification, $this->lc); |
|||
} |
|||
|
|||
public function testPrepareSuccessDeletedUser() { |
|||
$fileName = 'Gre\'thor.odp'; |
|||
$displayName = 'a now deleted user'; |
|||
$message = 'You were mentioned in a comment on "Gre\'thor.odp" by a now deleted user.'; |
|||
|
|||
/** @var Node|\PHPUnit_Framework_MockObject_MockObject */ |
|||
$node = $this->getMockBuilder('OCP\Files\Node')->getMock(); |
|||
$node |
|||
->expects($this->once()) |
|||
->method('getName') |
|||
->willReturn($fileName); |
|||
|
|||
$this->folder |
|||
->expects($this->once()) |
|||
->method('getById') |
|||
->with('678') |
|||
->willReturn([$node]); |
|||
|
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getApp') |
|||
->willReturn('comments'); |
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getSubject') |
|||
->willReturn('mention'); |
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getSubjectParameters') |
|||
->willReturn(['files', '678']); |
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('setParsedSubject') |
|||
->with($message); |
|||
|
|||
$this->l |
|||
->expects($this->once()) |
|||
->method('t') |
|||
->with('You were mentioned in a comment on "%s" by a now deleted user.', [ $fileName ]) |
|||
->willReturn($message); |
|||
|
|||
$this->l10nFactory |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->willReturn($this->l); |
|||
|
|||
$this->comment |
|||
->expects($this->any()) |
|||
->method('getActorId') |
|||
->willReturn('huraga'); |
|||
$this->comment |
|||
->expects($this->any()) |
|||
->method('getActorType') |
|||
->willReturn(ICommentsManager::DELETED_USER); |
|||
|
|||
$this->commentsManager |
|||
->expects(($this->once())) |
|||
->method('get') |
|||
->willReturn($this->comment); |
|||
|
|||
$this->userManager |
|||
->expects($this->never()) |
|||
->method('get'); |
|||
|
|||
$this->notifier->prepare($this->notification, $this->lc); |
|||
} |
|||
|
|||
/** |
|||
* @expectedException \InvalidArgumentException |
|||
*/ |
|||
public function testPrepareDifferentApp() { |
|||
$this->folder |
|||
->expects($this->never()) |
|||
->method('getById'); |
|||
|
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getApp') |
|||
->willReturn('constructions'); |
|||
$this->notification |
|||
->expects($this->never()) |
|||
->method('getSubject'); |
|||
$this->notification |
|||
->expects($this->never()) |
|||
->method('getSubjectParameters'); |
|||
$this->notification |
|||
->expects($this->never()) |
|||
->method('setParsedSubject'); |
|||
|
|||
$this->l10nFactory |
|||
->expects($this->never()) |
|||
->method('get'); |
|||
|
|||
$this->commentsManager |
|||
->expects(($this->never())) |
|||
->method('get'); |
|||
|
|||
$this->userManager |
|||
->expects($this->never()) |
|||
->method('get'); |
|||
|
|||
$this->notifier->prepare($this->notification, $this->lc); |
|||
} |
|||
|
|||
/** |
|||
* @expectedException \InvalidArgumentException |
|||
*/ |
|||
public function testPrepareNotFound() { |
|||
$this->folder |
|||
->expects($this->never()) |
|||
->method('getById'); |
|||
|
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getApp') |
|||
->willReturn('comments'); |
|||
$this->notification |
|||
->expects($this->never()) |
|||
->method('getSubject'); |
|||
$this->notification |
|||
->expects($this->never()) |
|||
->method('getSubjectParameters'); |
|||
$this->notification |
|||
->expects($this->never()) |
|||
->method('setParsedSubject'); |
|||
|
|||
$this->l10nFactory |
|||
->expects($this->never()) |
|||
->method('get'); |
|||
|
|||
$this->commentsManager |
|||
->expects(($this->once())) |
|||
->method('get') |
|||
->willThrowException(new NotFoundException()); |
|||
|
|||
$this->userManager |
|||
->expects($this->never()) |
|||
->method('get'); |
|||
|
|||
$this->notifier->prepare($this->notification, $this->lc); |
|||
} |
|||
|
|||
/** |
|||
* @expectedException \InvalidArgumentException |
|||
*/ |
|||
public function testPrepareDifferentSubject() { |
|||
$displayName = 'Huraga'; |
|||
|
|||
/** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */ |
|||
$user = $this->getMockBuilder('OCP\IUser')->getMock(); |
|||
$user->expects($this->once()) |
|||
->method('getDisplayName') |
|||
->willReturn($displayName); |
|||
|
|||
$this->folder |
|||
->expects($this->never()) |
|||
->method('getById'); |
|||
|
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getApp') |
|||
->willReturn('comments'); |
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getSubject') |
|||
->willReturn('unlike'); |
|||
$this->notification |
|||
->expects($this->never()) |
|||
->method('getSubjectParameters'); |
|||
$this->notification |
|||
->expects($this->never()) |
|||
->method('setParsedSubject'); |
|||
|
|||
$this->l |
|||
->expects($this->never()) |
|||
->method('t'); |
|||
|
|||
$this->l10nFactory |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->willReturn($this->l); |
|||
|
|||
$this->comment |
|||
->expects($this->any()) |
|||
->method('getActorId') |
|||
->willReturn('huraga'); |
|||
$this->comment |
|||
->expects($this->any()) |
|||
->method('getActorType') |
|||
->willReturn('users'); |
|||
|
|||
$this->commentsManager |
|||
->expects(($this->once())) |
|||
->method('get') |
|||
->willReturn($this->comment); |
|||
|
|||
$this->userManager |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->with('huraga') |
|||
->willReturn($user); |
|||
|
|||
$this->notifier->prepare($this->notification, $this->lc); |
|||
} |
|||
|
|||
/** |
|||
* @expectedException \InvalidArgumentException |
|||
*/ |
|||
public function testPrepareNotFiles() { |
|||
$displayName = 'Huraga'; |
|||
|
|||
/** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */ |
|||
$user = $this->getMockBuilder('OCP\IUser')->getMock(); |
|||
$user->expects($this->once()) |
|||
->method('getDisplayName') |
|||
->willReturn($displayName); |
|||
|
|||
$this->folder |
|||
->expects($this->never()) |
|||
->method('getById'); |
|||
|
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getApp') |
|||
->willReturn('comments'); |
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getSubject') |
|||
->willReturn('mention'); |
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getSubjectParameters') |
|||
->willReturn(['ships', '678']); |
|||
$this->notification |
|||
->expects($this->never()) |
|||
->method('setParsedSubject'); |
|||
|
|||
$this->l |
|||
->expects($this->never()) |
|||
->method('t'); |
|||
|
|||
$this->l10nFactory |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->willReturn($this->l); |
|||
|
|||
$this->comment |
|||
->expects($this->any()) |
|||
->method('getActorId') |
|||
->willReturn('huraga'); |
|||
$this->comment |
|||
->expects($this->any()) |
|||
->method('getActorType') |
|||
->willReturn('users'); |
|||
|
|||
$this->commentsManager |
|||
->expects(($this->once())) |
|||
->method('get') |
|||
->willReturn($this->comment); |
|||
|
|||
$this->userManager |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->with('huraga') |
|||
->willReturn($user); |
|||
|
|||
$this->notifier->prepare($this->notification, $this->lc); |
|||
} |
|||
|
|||
/** |
|||
* @expectedException \InvalidArgumentException |
|||
*/ |
|||
public function testPrepareUnresolvableFileID() { |
|||
$displayName = 'Huraga'; |
|||
|
|||
/** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */ |
|||
$user = $this->getMockBuilder('OCP\IUser')->getMock(); |
|||
$user->expects($this->once()) |
|||
->method('getDisplayName') |
|||
->willReturn($displayName); |
|||
|
|||
$this->folder |
|||
->expects($this->once()) |
|||
->method('getById') |
|||
->with('678') |
|||
->willReturn([]); |
|||
|
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getApp') |
|||
->willReturn('comments'); |
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getSubject') |
|||
->willReturn('mention'); |
|||
$this->notification |
|||
->expects($this->once()) |
|||
->method('getSubjectParameters') |
|||
->willReturn(['files', '678']); |
|||
$this->notification |
|||
->expects($this->never()) |
|||
->method('setParsedSubject'); |
|||
|
|||
$this->l |
|||
->expects($this->never()) |
|||
->method('t'); |
|||
|
|||
$this->l10nFactory |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->willReturn($this->l); |
|||
|
|||
$this->comment |
|||
->expects($this->any()) |
|||
->method('getActorId') |
|||
->willReturn('huraga'); |
|||
$this->comment |
|||
->expects($this->any()) |
|||
->method('getActorType') |
|||
->willReturn('users'); |
|||
|
|||
$this->commentsManager |
|||
->expects(($this->once())) |
|||
->method('get') |
|||
->willReturn($this->comment); |
|||
|
|||
$this->userManager |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->with('huraga') |
|||
->willReturn($user); |
|||
|
|||
$this->notifier->prepare($this->notification, $this->lc); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
<?php |
|||
/** |
|||
* @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de> |
|||
* |
|||
* @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 <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
|
|||
namespace OCP\Comments; |
|||
|
|||
/** |
|||
* Interface ICommentsEventHandler |
|||
* |
|||
* @package OCP\Comments |
|||
* @since 9.2.0 |
|||
*/ |
|||
interface ICommentsEventHandler { |
|||
|
|||
/** |
|||
* @param CommentsEvent $event |
|||
* @since 9.2.0 |
|||
*/ |
|||
public function handle(CommentsEvent $event); |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue