Merge pull request #1449 from nextcloud/comments-user-mention
Notifications for simple @-mentioning in comments
This commit is contained in:
commit
96f8f209b9
22 changed files with 1890 additions and 40 deletions
|
@ -41,22 +41,33 @@ $activityManager = \OC::$server->getActivityManager();
|
|||
$activityManager->registerExtension(function() {
|
||||
$application = new \OCP\AppFramework\App('comments');
|
||||
/** @var \OCA\Comments\Activity\Extension $extension */
|
||||
$extension = $application->getContainer()->query('OCA\Comments\Activity\Extension');
|
||||
$extension = $application->getContainer()->query(\OCA\Comments\Activity\Extension::class);
|
||||
return $extension;
|
||||
});
|
||||
|
||||
$managerListener = function(\OCP\Comments\CommentsEvent $event) use ($activityManager) {
|
||||
$application = new \OCP\AppFramework\App('comments');
|
||||
/** @var \OCA\Comments\Activity\Listener $listener */
|
||||
$listener = $application->getContainer()->query('OCA\Comments\Activity\Listener');
|
||||
$listener->commentEvent($event);
|
||||
};
|
||||
|
||||
$eventDispatcher->addListener(\OCP\Comments\CommentsEvent::EVENT_ADD, $managerListener);
|
||||
|
||||
$eventDispatcher->addListener(\OCP\Comments\CommentsEntityEvent::EVENT_ENTITY, function(\OCP\Comments\CommentsEntityEvent $event) {
|
||||
$event->addEntityCollection('files', function($name) {
|
||||
$nodes = \OC::$server->getUserFolder()->getById(intval($name));
|
||||
return !empty($nodes);
|
||||
});
|
||||
});
|
||||
|
||||
$notificationManager = \OC::$server->getNotificationManager();
|
||||
$notificationManager->registerNotifier(
|
||||
function() {
|
||||
$application = new \OCP\AppFramework\App('comments');
|
||||
return $application->getContainer()->query(\OCA\Comments\Notification\Notifier::class);
|
||||
},
|
||||
function () {
|
||||
$l = \OC::$server->getL10N('comments');
|
||||
return ['id' => 'comments', 'name' => $l->t('Comments')];
|
||||
}
|
||||
);
|
||||
|
||||
$commentsManager = \OC::$server->getCommentsManager();
|
||||
$commentsManager->registerEventHandler(function () {
|
||||
$application = new \OCP\AppFramework\App('comments');
|
||||
/** @var \OCA\Comments\Activity\Extension $extension */
|
||||
$handler = $application->getContainer()->query(\OCA\Comments\EventHandler::class);
|
||||
return $handler;
|
||||
});
|
||||
|
|
28
apps/comments/appinfo/routes.php
Normal file
28
apps/comments/appinfo/routes.php
Normal file
|
@ -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'],
|
||||
]]);
|
35
apps/comments/lib/AppInfo/Application.php
Normal file
35
apps/comments/lib/AppInfo/Application.php
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
134
apps/comments/lib/Controller/Notifications.php
Normal file
134
apps/comments/lib/Controller/Notifications.php
Normal file
|
@ -0,0 +1,134 @@
|
|||
<?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();
|
||||
}
|
||||
|
||||
$url = $this->urlGenerator->linkToRouteAbsolute(
|
||||
'files.viewcontroller.showFile',
|
||||
[ 'fileid' => $comment->getObjectId() ]
|
||||
);
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
91
apps/comments/lib/EventHandler.php
Normal file
91
apps/comments/lib/EventHandler.php
Normal file
|
@ -0,0 +1,91 @@
|
|||
<?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 ActivityListener */
|
||||
private $activityListener;
|
||||
|
||||
/** @var NotificationListener */
|
||||
private $notificationListener;
|
||||
|
||||
public function __construct(ActivityListener $activityListener, NotificationListener $notificationListener) {
|
||||
$this->activityListener = $activityListener;
|
||||
$this->notificationListener = $notificationListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommentsEvent $event
|
||||
*/
|
||||
public function handle(CommentsEvent $event) {
|
||||
if($event->getComment()->getObjectType() !== 'files') {
|
||||
// this is a 'files'-specific Handler
|
||||
return;
|
||||
}
|
||||
|
||||
$eventType = $event->getEvent();
|
||||
if( $eventType === CommentsEvent::EVENT_ADD
|
||||
) {
|
||||
$this->notificationHandler($event);
|
||||
$this->activityHandler($event);
|
||||
return;
|
||||
}
|
||||
|
||||
$applicableEvents = [
|
||||
CommentsEvent::EVENT_PRE_UPDATE,
|
||||
CommentsEvent::EVENT_UPDATE,
|
||||
CommentsEvent::EVENT_DELETE,
|
||||
];
|
||||
if(in_array($eventType, $applicableEvents)) {
|
||||
$this->notificationHandler($event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommentsEvent $event
|
||||
*/
|
||||
private function activityHandler(CommentsEvent $event) {
|
||||
$this->activityListener->commentEvent($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommentsEvent $event
|
||||
*/
|
||||
private function notificationHandler(CommentsEvent $event) {
|
||||
$this->notificationListener->evaluate($event);
|
||||
}
|
||||
}
|
126
apps/comments/lib/Notification/Listener.php
Normal file
126
apps/comments/lib/Notification/Listener.php
Normal file
|
@ -0,0 +1,126 @@
|
|||
<?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();
|
||||
|
||||
$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
|
||||
|| $event->getEvent() === CommentsEvent::EVENT_PRE_UPDATE)
|
||||
{
|
||||
$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]);
|
||||
}
|
||||
}
|
115
apps/comments/lib/Notification/Notifier.php
Normal file
115
apps/comments/lib/Notification/Notifier.php
Normal file
|
@ -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(
|
||||
'A (now) deleted user mentioned you in a comment on "%s".',
|
||||
[ $fileName ]
|
||||
);
|
||||
} else {
|
||||
$subject = (string) $l->t(
|
||||
'%s mentioned you in a comment on "%s".',
|
||||
[ $displayName, $fileName ]
|
||||
);
|
||||
}
|
||||
$notification->setParsedSubject($subject);
|
||||
|
||||
return $notification;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \InvalidArgumentException('Invalid subject');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
65
apps/comments/tests/Unit/AppInfo/ApplicationTest.php
Normal file
65
apps/comments/tests/Unit/AppInfo/ApplicationTest.php
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
155
apps/comments/tests/Unit/Controller/NotificationsTest.php
Normal file
155
apps/comments/tests/Unit/Controller/NotificationsTest.php
Normal file
|
@ -0,0 +1,155 @@
|
|||
<?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();
|
||||
|
||||
$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()));
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
119
apps/comments/tests/Unit/EventHandlerTest.php
Normal file
119
apps/comments/tests/Unit/EventHandlerTest.php
Normal file
|
@ -0,0 +1,119 @@
|
|||
<?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\EventHandler;
|
||||
use OCP\Comments\CommentsEvent;
|
||||
use OCP\Comments\IComment;
|
||||
use OCA\Comments\Activity\Listener as ActivityListener;
|
||||
use OCA\Comments\Notification\Listener as NotificationListener;
|
||||
use Test\TestCase;
|
||||
|
||||
class EventHandlerTest extends TestCase {
|
||||
/** @var EventHandler */
|
||||
protected $eventHandler;
|
||||
|
||||
/** @var ActivityListener|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $activityListener;
|
||||
|
||||
/** @var NotificationListener|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $notificationListener;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->activityListener = $this->getMockBuilder(ActivityListener::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->notificationListener = $this->getMockBuilder(NotificationListener::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->eventHandler = new EventHandler($this->activityListener, $this->notificationListener);
|
||||
}
|
||||
|
||||
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 handledProvider() {
|
||||
return [
|
||||
[CommentsEvent::EVENT_DELETE],
|
||||
[CommentsEvent::EVENT_UPDATE],
|
||||
[CommentsEvent::EVENT_PRE_UPDATE],
|
||||
[CommentsEvent::EVENT_ADD]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider handledProvider
|
||||
* @param string $eventType
|
||||
*/
|
||||
public function testHandled($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->atLeastOnce())
|
||||
->method('getComment')
|
||||
->willReturn($comment);
|
||||
$event->expects($this->atLeastOnce())
|
||||
->method('getEvent')
|
||||
->willReturn($eventType);
|
||||
|
||||
$this->notificationListener->expects($this->once())
|
||||
->method('evaluate')
|
||||
->with($event);
|
||||
|
||||
$this->activityListener->expects($this->any())
|
||||
->method('commentEvent')
|
||||
->with($event);
|
||||
|
||||
$this->eventHandler->handle($event);
|
||||
}
|
||||
|
||||
}
|
339
apps/comments/tests/Unit/Notification/ListenerTest.php
Normal file
339
apps/comments/tests/Unit/Notification/ListenerTest.php
Normal file
|
@ -0,0 +1,339 @@
|
|||
<?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_UPDATE, 'notify'],
|
||||
[CommentsEvent::EVENT_PRE_UPDATE, 'markProcessed'],
|
||||
[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 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);
|
||||
}
|
||||
|
||||
}
|
498
apps/comments/tests/Unit/Notification/NotifierTest.php
Normal file
498
apps/comments/tests/Unit/Notification/NotifierTest.php
Normal file
|
@ -0,0 +1,498 @@
|
|||
<?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 = 'Hurage mentioned you in a comment on "Gre\'thor.odp".';
|
||||
|
||||
/** @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('%s mentioned you in a comment on "%s".', [$displayName, $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('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';
|
||||
$message = 'A (now) deleted user mentioned you in a comment on "Gre\'thor.odp".';
|
||||
|
||||
/** @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('A (now) deleted user mentioned you in a comment on "%s".', [ $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);
|
||||
}
|
||||
|
||||
}
|
|
@ -173,7 +173,7 @@ class CommentNode implements \Sabre\DAV\INode, \Sabre\DAV\IProperties {
|
|||
* @param $propertyValue
|
||||
* @return bool
|
||||
* @throws BadRequest
|
||||
* @throws Forbidden
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function updateComment($propertyValue) {
|
||||
$this->checkWriteAccessOnComment();
|
||||
|
|
|
@ -61,6 +61,7 @@ return array(
|
|||
'OCP\\Comments\\CommentsEntityEvent' => $baseDir . '/lib/public/Comments/CommentsEntityEvent.php',
|
||||
'OCP\\Comments\\CommentsEvent' => $baseDir . '/lib/public/Comments/CommentsEvent.php',
|
||||
'OCP\\Comments\\IComment' => $baseDir . '/lib/public/Comments/IComment.php',
|
||||
'OCP\\Comments\\ICommentsEventHandler' => $baseDir . '/lib/public/Comments/ICommentsEventHandler.php',
|
||||
'OCP\\Comments\\ICommentsManager' => $baseDir . '/lib/public/Comments/ICommentsManager.php',
|
||||
'OCP\\Comments\\ICommentsManagerFactory' => $baseDir . '/lib/public/Comments/ICommentsManagerFactory.php',
|
||||
'OCP\\Comments\\IllegalIDChangeException' => $baseDir . '/lib/public/Comments/IllegalIDChangeException.php',
|
||||
|
|
|
@ -91,6 +91,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
|
|||
'OCP\\Comments\\CommentsEntityEvent' => __DIR__ . '/../../..' . '/lib/public/Comments/CommentsEntityEvent.php',
|
||||
'OCP\\Comments\\CommentsEvent' => __DIR__ . '/../../..' . '/lib/public/Comments/CommentsEvent.php',
|
||||
'OCP\\Comments\\IComment' => __DIR__ . '/../../..' . '/lib/public/Comments/IComment.php',
|
||||
'OCP\\Comments\\ICommentsEventHandler' => __DIR__ . '/../../..' . '/lib/public/Comments/ICommentsEventHandler.php',
|
||||
'OCP\\Comments\\ICommentsManager' => __DIR__ . '/../../..' . '/lib/public/Comments/ICommentsManager.php',
|
||||
'OCP\\Comments\\ICommentsManagerFactory' => __DIR__ . '/../../..' . '/lib/public/Comments/ICommentsManagerFactory.php',
|
||||
'OCP\\Comments\\IllegalIDChangeException' => __DIR__ . '/../../..' . '/lib/public/Comments/IllegalIDChangeException.php',
|
||||
|
|
|
@ -161,6 +161,10 @@ class DIContainer extends SimpleContainer implements IAppContainer {
|
|||
return $this->getServer()->getRootFolder();
|
||||
});
|
||||
|
||||
$this->registerService('OCP\\Files\\Folder', function() {
|
||||
return $this->getServer()->getUserFolder();
|
||||
});
|
||||
|
||||
$this->registerService('OCP\\Http\\Client\\IClientService', function($c) {
|
||||
return $this->getServer()->getHTTPClientService();
|
||||
});
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace OC\Comments;
|
|||
use Doctrine\DBAL\Exception\DriverException;
|
||||
use OCP\Comments\CommentsEvent;
|
||||
use OCP\Comments\IComment;
|
||||
use OCP\Comments\ICommentsEventHandler;
|
||||
use OCP\Comments\ICommentsManager;
|
||||
use OCP\Comments\NotFoundException;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
|
@ -33,7 +34,6 @@ use OCP\IDBConnection;
|
|||
use OCP\IConfig;
|
||||
use OCP\ILogger;
|
||||
use OCP\IUser;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
class Manager implements ICommentsManager {
|
||||
|
||||
|
@ -46,30 +46,30 @@ class Manager implements ICommentsManager {
|
|||
/** @var IConfig */
|
||||
protected $config;
|
||||
|
||||
/** @var EventDispatcherInterface */
|
||||
protected $dispatcher;
|
||||
|
||||
/** @var IComment[] */
|
||||
protected $commentsCache = [];
|
||||
|
||||
/** @var \Closure[] */
|
||||
protected $eventHandlerClosures = [];
|
||||
|
||||
/** @var ICommentsEventHandler[] */
|
||||
protected $eventHandlers = [];
|
||||
|
||||
/**
|
||||
* Manager constructor.
|
||||
*
|
||||
* @param IDBConnection $dbConn
|
||||
* @param ILogger $logger
|
||||
* @param IConfig $config
|
||||
* @param EventDispatcherInterface $dispatcher
|
||||
*/
|
||||
public function __construct(
|
||||
IDBConnection $dbConn,
|
||||
ILogger $logger,
|
||||
IConfig $config,
|
||||
EventDispatcherInterface $dispatcher
|
||||
IConfig $config
|
||||
) {
|
||||
$this->dbConn = $dbConn;
|
||||
$this->logger = $logger;
|
||||
$this->config = $config;
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -455,10 +455,7 @@ class Manager implements ICommentsManager {
|
|||
}
|
||||
|
||||
if ($affectedRows > 0 && $comment instanceof IComment) {
|
||||
$this->dispatcher->dispatch(CommentsEvent::EVENT_DELETE, new CommentsEvent(
|
||||
CommentsEvent::EVENT_DELETE,
|
||||
$comment
|
||||
));
|
||||
$this->sendEvent(CommentsEvent::EVENT_DELETE, $comment);
|
||||
}
|
||||
|
||||
return ($affectedRows > 0);
|
||||
|
@ -525,13 +522,9 @@ class Manager implements ICommentsManager {
|
|||
|
||||
if ($affectedRows > 0) {
|
||||
$comment->setId(strval($qb->getLastInsertId()));
|
||||
$this->sendEvent(CommentsEvent::EVENT_ADD, $comment);
|
||||
}
|
||||
|
||||
$this->dispatcher->dispatch(CommentsEvent::EVENT_ADD, new CommentsEvent(
|
||||
CommentsEvent::EVENT_ADD,
|
||||
$comment
|
||||
));
|
||||
|
||||
return $affectedRows > 0;
|
||||
}
|
||||
|
||||
|
@ -543,6 +536,12 @@ class Manager implements ICommentsManager {
|
|||
* @throws NotFoundException
|
||||
*/
|
||||
protected function update(IComment $comment) {
|
||||
// for properly working preUpdate Events we need the old comments as is
|
||||
// in the DB and overcome caching. Also avoid that outdated information stays.
|
||||
$this->uncache($comment->getId());
|
||||
$this->sendEvent(CommentsEvent::EVENT_PRE_UPDATE, $this->get($comment->getId()));
|
||||
$this->uncache($comment->getId());
|
||||
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
$affectedRows = $qb
|
||||
->update('comments')
|
||||
|
@ -565,10 +564,7 @@ class Manager implements ICommentsManager {
|
|||
throw new NotFoundException('Comment to update does ceased to exist');
|
||||
}
|
||||
|
||||
$this->dispatcher->dispatch(CommentsEvent::EVENT_UPDATE, new CommentsEvent(
|
||||
CommentsEvent::EVENT_UPDATE,
|
||||
$comment
|
||||
));
|
||||
$this->sendEvent(CommentsEvent::EVENT_UPDATE, $comment);
|
||||
|
||||
return $affectedRows > 0;
|
||||
}
|
||||
|
@ -751,4 +747,51 @@ class Manager implements ICommentsManager {
|
|||
}
|
||||
return ($affectedRows > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* registers an Entity to the manager, so event notifications can be send
|
||||
* to consumers of the comments infrastructure
|
||||
*
|
||||
* @param \Closure $closure
|
||||
*/
|
||||
public function registerEventHandler(\Closure $closure) {
|
||||
$this->eventHandlerClosures[] = $closure;
|
||||
$this->eventHandlers = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* returns valid, registered entities
|
||||
*
|
||||
* @return \OCP\Comments\ICommentsEventHandler[]
|
||||
*/
|
||||
private function getEventHandlers() {
|
||||
if(!empty($this->eventHandlers)) {
|
||||
return $this->eventHandlers;
|
||||
}
|
||||
|
||||
$this->eventHandlers = [];
|
||||
foreach ($this->eventHandlerClosures as $name => $closure) {
|
||||
$entity = $closure();
|
||||
if (!($entity instanceof ICommentsEventHandler)) {
|
||||
throw new \InvalidArgumentException('The given entity does not implement the ICommentsEntity interface');
|
||||
}
|
||||
$this->eventHandlers[$name] = $entity;
|
||||
}
|
||||
|
||||
return $this->eventHandlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* sends notifications to the registered entities
|
||||
*
|
||||
* @param $eventType
|
||||
* @param IComment $comment
|
||||
*/
|
||||
private function sendEvent($eventType, IComment $comment) {
|
||||
$entities = $this->getEventHandlers();
|
||||
$event = new CommentsEvent($eventType, $comment);
|
||||
foreach ($entities as $entity) {
|
||||
$entity->handle($event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,9 +32,10 @@ use Symfony\Component\EventDispatcher\Event;
|
|||
*/
|
||||
class CommentsEvent extends Event {
|
||||
|
||||
const EVENT_ADD = 'OCP\Comments\ICommentsManager::addComment';
|
||||
const EVENT_UPDATE = 'OCP\Comments\ICommentsManager::updateComment';
|
||||
const EVENT_DELETE = 'OCP\Comments\ICommentsManager::deleteComment';
|
||||
const EVENT_ADD = 'OCP\Comments\ICommentsManager::addComment';
|
||||
const EVENT_PRE_UPDATE = 'OCP\Comments\ICommentsManager::preUpdateComment';
|
||||
const EVENT_UPDATE = 'OCP\Comments\ICommentsManager::updateComment';
|
||||
const EVENT_DELETE = 'OCP\Comments\ICommentsManager::deleteComment';
|
||||
|
||||
/** @var string */
|
||||
protected $event;
|
||||
|
|
39
lib/public/Comments/ICommentsEventHandler.php
Normal file
39
lib/public/Comments/ICommentsEventHandler.php
Normal file
|
@ -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);
|
||||
}
|
|
@ -237,4 +237,13 @@ interface ICommentsManager {
|
|||
*/
|
||||
public function deleteReadMarksOnObject($objectType, $objectId);
|
||||
|
||||
/**
|
||||
* registers an Entity to the manager, so event notifications can be send
|
||||
* to consumers of the comments infrastructure
|
||||
*
|
||||
* @param \Closure $closure
|
||||
* @since 9.2.0
|
||||
*/
|
||||
public function registerEventHandler(\Closure $closure);
|
||||
|
||||
}
|
||||
|
|
|
@ -38,4 +38,6 @@ class FakeManager implements \OCP\Comments\ICommentsManager {
|
|||
public function deleteReadMarksFromUser(\OCP\IUser $user) {}
|
||||
|
||||
public function deleteReadMarksOnObject($objectType, $objectId) {}
|
||||
|
||||
public function registerEventHandler(\Closure $closure) {}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
namespace Test\Comments;
|
||||
|
||||
use OC\Comments\Comment;
|
||||
use OCP\Comments\CommentsEvent;
|
||||
use OCP\Comments\ICommentsEventHandler;
|
||||
use OCP\Comments\ICommentsManager;
|
||||
use OCP\IUser;
|
||||
use Test\TestCase;
|
||||
|
@ -355,7 +358,7 @@ class ManagerTest extends TestCase {
|
|||
|
||||
public function testSaveNew() {
|
||||
$manager = $this->getManager();
|
||||
$comment = new \OC\Comments\Comment();
|
||||
$comment = new Comment();
|
||||
$comment
|
||||
->setActor('users', 'alice')
|
||||
->setObject('files', 'file64')
|
||||
|
@ -375,7 +378,7 @@ class ManagerTest extends TestCase {
|
|||
|
||||
public function testSaveUpdate() {
|
||||
$manager = $this->getManager();
|
||||
$comment = new \OC\Comments\Comment();
|
||||
$comment = new Comment();
|
||||
$comment
|
||||
->setActor('users', 'alice')
|
||||
->setObject('files', 'file64')
|
||||
|
@ -396,7 +399,7 @@ class ManagerTest extends TestCase {
|
|||
*/
|
||||
public function testSaveUpdateException() {
|
||||
$manager = $this->getManager();
|
||||
$comment = new \OC\Comments\Comment();
|
||||
$comment = new Comment();
|
||||
$comment
|
||||
->setActor('users', 'alice')
|
||||
->setObject('files', 'file64')
|
||||
|
@ -415,7 +418,7 @@ class ManagerTest extends TestCase {
|
|||
*/
|
||||
public function testSaveIncomplete() {
|
||||
$manager = $this->getManager();
|
||||
$comment = new \OC\Comments\Comment();
|
||||
$comment = new Comment();
|
||||
$comment->setMessage('from no one to nothing');
|
||||
$manager->save($comment);
|
||||
}
|
||||
|
@ -426,7 +429,7 @@ class ManagerTest extends TestCase {
|
|||
$manager = $this->getManager();
|
||||
|
||||
for($i = 0; $i < 3; $i++) {
|
||||
$comment = new \OC\Comments\Comment();
|
||||
$comment = new Comment();
|
||||
$comment
|
||||
->setActor('users', 'alice')
|
||||
->setObject('files', 'file64')
|
||||
|
@ -630,4 +633,35 @@ class ManagerTest extends TestCase {
|
|||
$this->assertNull($dateTimeGet);
|
||||
}
|
||||
|
||||
public function testSendEvent() {
|
||||
$handler1 = $this->getMockBuilder(ICommentsEventHandler::class)->getMock();
|
||||
$handler1->expects($this->exactly(4))
|
||||
->method('handle');
|
||||
|
||||
$handler2 = $this->getMockBuilder(ICommentsEventHandler::class)->getMock();
|
||||
$handler1->expects($this->exactly(4))
|
||||
->method('handle');
|
||||
|
||||
$manager = $this->getManager();
|
||||
$manager->registerEventHandler(function () use ($handler1) {return $handler1; });
|
||||
$manager->registerEventHandler(function () use ($handler2) {return $handler2; });
|
||||
|
||||
$comment = new Comment();
|
||||
$comment
|
||||
->setActor('users', 'alice')
|
||||
->setObject('files', 'file64')
|
||||
->setMessage('very beautiful, I am impressed!')
|
||||
->setVerb('comment');
|
||||
|
||||
// Add event
|
||||
$manager->save($comment);
|
||||
|
||||
// Update event
|
||||
$comment->setMessage('Different topic');
|
||||
$manager->save($comment);
|
||||
|
||||
// Delete event
|
||||
$manager->delete($comment->getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue