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
parent
9e7824f3ed
commit
e1073cf442
@ -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); |
||||
} |
Loading…
Reference in new issue