Make user mentions great again

This commit is contained in:
Frederic Guillot 2016-12-01 22:52:58 -05:00
parent be83821ef7
commit f73d0d2ac9
No known key found for this signature in database
GPG Key ID: 92D77191BA7FBC99
22 changed files with 270 additions and 140 deletions

View File

@ -6,6 +6,7 @@ Improvements:
* Add button to close inline popups * Add button to close inline popups
* Simplify `.htaccess` to avoid potential issues with possible specific Apache configurations * Simplify `.htaccess` to avoid potential issues with possible specific Apache configurations
* Replace notifications Javascript code by CSS * Replace notifications Javascript code by CSS
* Refactoring of user mentions job
Breaking changes: Breaking changes:
@ -14,6 +15,7 @@ Breaking changes:
Bug fixes: Bug fixes:
* Fix link generation when user mention is followed by a punctuation mark * Fix link generation when user mention is followed by a punctuation mark
* Make user mentions works again
Version 1.0.34 Version 1.0.34
-------------- --------------

View File

@ -126,7 +126,6 @@ use Pimple\Container;
* @property \Kanboard\Model\TransitionModel $transitionModel * @property \Kanboard\Model\TransitionModel $transitionModel
* @property \Kanboard\Model\UserModel $userModel * @property \Kanboard\Model\UserModel $userModel
* @property \Kanboard\Model\UserLockingModel $userLockingModel * @property \Kanboard\Model\UserLockingModel $userLockingModel
* @property \Kanboard\Model\UserMentionModel $userMentionModel
* @property \Kanboard\Model\UserNotificationModel $userNotificationModel * @property \Kanboard\Model\UserNotificationModel $userNotificationModel
* @property \Kanboard\Model\UserNotificationTypeModel $userNotificationTypeModel * @property \Kanboard\Model\UserNotificationTypeModel $userNotificationTypeModel
* @property \Kanboard\Model\UserNotificationFilterModel $userNotificationFilterModel * @property \Kanboard\Model\UserNotificationFilterModel $userNotificationFilterModel
@ -178,6 +177,7 @@ use Pimple\Container;
* @property \Kanboard\Job\ProjectFileEventJob $projectFileEventJob * @property \Kanboard\Job\ProjectFileEventJob $projectFileEventJob
* @property \Kanboard\Job\NotificationJob $notificationJob * @property \Kanboard\Job\NotificationJob $notificationJob
* @property \Kanboard\Job\ProjectMetricJob $projectMetricJob * @property \Kanboard\Job\ProjectMetricJob $projectMetricJob
* @property \Kanboard\Job\UserMentionJob $userMentionJob
* @property \Psr\Log\LoggerInterface $logger * @property \Psr\Log\LoggerInterface $logger
* @property \PicoDb\Database $db * @property \PicoDb\Database $db
* @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher * @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher

View File

@ -90,7 +90,7 @@ class Markdown extends Parsedown
$user_id = $this->container['userModel']->getIdByUsername($matches[1]); $user_id = $this->container['userModel']->getIdByUsername($matches[1]);
if (! empty($user_id)) { if (! empty($user_id)) {
$url = $this->container['helper']->url->href('UserViewController', 'profile', array('user_id' => $user_id)); $url = $this->container['helper']->url->href('UserViewController', 'profile', array('user_id' => $user_id), false, '', true);
return array( return array(
'extent' => strlen($matches[0]), 'extent' => strlen($matches[0]),

View File

@ -14,6 +14,28 @@ class GenericEvent extends BaseEvent implements ArrayAccess
$this->container = $values; $this->container = $values;
} }
public function getTaskId()
{
if (isset($this->container['task']['id'])) {
return $this->container['task']['id'];
}
if (isset($this->container['task_id'])) {
return $this->container['task_id'];
}
return null;
}
public function getProjectId()
{
if (isset($this->container['task']['project_id'])) {
return $this->container['task']['project_id'];
}
return null;
}
public function getAll() public function getAll()
{ {
return $this->container; return $this->container;

View File

@ -4,4 +4,12 @@ namespace Kanboard\Event;
class ProjectFileEvent extends GenericEvent class ProjectFileEvent extends GenericEvent
{ {
public function getProjectId()
{
if (isset($this->container['file']['project_id'])) {
return $this->container['file']['project_id'];
}
return null;
}
} }

View File

@ -31,7 +31,6 @@ class CommentEventJob extends BaseJob
* *
* @param int $commentId * @param int $commentId
* @param string $eventName * @param string $eventName
* @return $this
*/ */
public function execute($commentId, $eventName) public function execute($commentId, $eventName)
{ {
@ -43,7 +42,8 @@ class CommentEventJob extends BaseJob
$this->dispatcher->dispatch($eventName, $event); $this->dispatcher->dispatch($eventName, $event);
if ($eventName === CommentModel::EVENT_CREATE) { if ($eventName === CommentModel::EVENT_CREATE) {
$this->userMentionModel->fireEvents($event['comment']['comment'], CommentModel::EVENT_USER_MENTION, $event); $userMentionJob = $this->userMentionJob->withParams($event['comment']['comment'], CommentModel::EVENT_USER_MENTION, $event);
$this->queueManager->push($userMentionJob);
} }
} }
} }

View File

@ -69,7 +69,8 @@ class TaskEventJob extends BaseJob
$this->dispatcher->dispatch($eventName, $event); $this->dispatcher->dispatch($eventName, $event);
if ($eventName === TaskModel::EVENT_CREATE) { if ($eventName === TaskModel::EVENT_CREATE) {
$this->userMentionModel->fireEvents($event['task']['description'], TaskModel::EVENT_USER_MENTION, $event); $userMentionJob = $this->userMentionJob->withParams($event['task']['description'], TaskModel::EVENT_USER_MENTION, $event);
$this->queueManager->push($userMentionJob);
} }
} }
} }

View File

@ -0,0 +1,71 @@
<?php
namespace Kanboard\Job;
use Kanboard\Event\GenericEvent;
use Kanboard\Model\UserModel;
/**
* Class UserMentionJob
*
* @package Kanboard\Job
* @author Frederic Guillot
*/
class UserMentionJob extends BaseJob
{
/**
* Set job parameters
*
* @param string $text
* @param string $eventName
* @param GenericEvent $event
* @return $this
*/
public function withParams($text, $eventName, GenericEvent $event)
{
$this->jobParams = array($text, $eventName, $event);
return $this;
}
/**
* Execute job
*
* @param string $text
* @param string $eventName
* @param GenericEvent $event
*/
public function execute($text, $eventName, GenericEvent $event)
{
$users = $this->getMentionedUsers($text);
foreach ($users as $user) {
if ($this->projectPermissionModel->isMember($event->getProjectId(), $user['id'])) {
$event['mention'] = $user;
$this->dispatcher->dispatch($eventName, $event);
}
}
}
/**
* Get list of mentioned users
*
* @access public
* @param string $text
* @return array
*/
public function getMentionedUsers($text)
{
$users = array();
if (preg_match_all('/@([^\s,!.:?]+)/', $text, $matches)) {
$users = $this->db->table(UserModel::TABLE)
->columns('id', 'username', 'name', 'email', 'language')
->eq('notifications_enabled', 1)
->neq('id', $this->userSession->getId())
->in('username', array_unique($matches[1]))
->findAll();
}
return $users;
}
}

View File

@ -1,62 +0,0 @@
<?php
namespace Kanboard\Model;
use Kanboard\Core\Base;
use Kanboard\Event\GenericEvent;
/**
* User Mention
*
* @package Kanboard\Model
* @author Frederic Guillot
*/
class UserMentionModel extends Base
{
/**
* Get list of mentioned users
*
* @access public
* @param string $content
* @return array
*/
public function getMentionedUsers($content)
{
$users = array();
if (preg_match_all('/@([^\s]+)/', $content, $matches)) {
$users = $this->db->table(UserModel::TABLE)
->columns('id', 'username', 'name', 'email', 'language')
->eq('notifications_enabled', 1)
->neq('id', $this->userSession->getId())
->in('username', array_unique($matches[1]))
->findAll();
}
return $users;
}
/**
* Fire events for user mentions
*
* @access public
* @param string $content
* @param string $eventName
* @param GenericEvent $event
*/
public function fireEvents($content, $eventName, GenericEvent $event)
{
if (empty($event['project_id'])) {
$event['project_id'] = $this->taskFinderModel->getProjectId($event['task_id']);
}
$users = $this->getMentionedUsers($content);
foreach ($users as $user) {
if ($this->projectPermissionModel->isMember($event['project_id'], $user['id'])) {
$event['mention'] = $user;
$this->dispatcher->dispatch($eventName, $event);
}
}
}
}

View File

@ -91,7 +91,6 @@ class ClassProvider implements ServiceProviderInterface
'TransitionModel', 'TransitionModel',
'UserModel', 'UserModel',
'UserLockingModel', 'UserLockingModel',
'UserMentionModel',
'UserNotificationModel', 'UserNotificationModel',
'UserNotificationFilterModel', 'UserNotificationFilterModel',
'UserUnreadNotificationModel', 'UserUnreadNotificationModel',

View File

@ -10,6 +10,7 @@ use Kanboard\Job\SubtaskEventJob;
use Kanboard\Job\TaskEventJob; use Kanboard\Job\TaskEventJob;
use Kanboard\Job\TaskFileEventJob; use Kanboard\Job\TaskFileEventJob;
use Kanboard\Job\TaskLinkEventJob; use Kanboard\Job\TaskLinkEventJob;
use Kanboard\Job\UserMentionJob;
use Pimple\Container; use Pimple\Container;
use Pimple\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
@ -62,6 +63,10 @@ class JobProvider implements ServiceProviderInterface
return new ProjectMetricJob($c); return new ProjectMetricJob($c);
}); });
$container['userMentionJob'] = $container->factory(function ($c) {
return new UserMentionJob($c);
});
return $container; return $container;
} }
} }

View File

@ -15,25 +15,25 @@ class NotificationSubscriber extends BaseSubscriber implements EventSubscriberIn
public static function getSubscribedEvents() public static function getSubscribedEvents()
{ {
return array( return array(
TaskModel::EVENT_USER_MENTION => 'handleEvent', TaskModel::EVENT_USER_MENTION => 'handleEvent',
TaskModel::EVENT_CREATE => 'handleEvent', TaskModel::EVENT_CREATE => 'handleEvent',
TaskModel::EVENT_UPDATE => 'handleEvent', TaskModel::EVENT_UPDATE => 'handleEvent',
TaskModel::EVENT_CLOSE => 'handleEvent', TaskModel::EVENT_CLOSE => 'handleEvent',
TaskModel::EVENT_OPEN => 'handleEvent', TaskModel::EVENT_OPEN => 'handleEvent',
TaskModel::EVENT_MOVE_COLUMN => 'handleEvent', TaskModel::EVENT_MOVE_COLUMN => 'handleEvent',
TaskModel::EVENT_MOVE_POSITION => 'handleEvent', TaskModel::EVENT_MOVE_POSITION => 'handleEvent',
TaskModel::EVENT_MOVE_SWIMLANE => 'handleEvent', TaskModel::EVENT_MOVE_SWIMLANE => 'handleEvent',
TaskModel::EVENT_ASSIGNEE_CHANGE => 'handleEvent', TaskModel::EVENT_ASSIGNEE_CHANGE => 'handleEvent',
SubtaskModel::EVENT_CREATE => 'handleEvent', SubtaskModel::EVENT_CREATE => 'handleEvent',
SubtaskModel::EVENT_UPDATE => 'handleEvent', SubtaskModel::EVENT_UPDATE => 'handleEvent',
SubtaskModel::EVENT_DELETE => 'handleEvent', SubtaskModel::EVENT_DELETE => 'handleEvent',
CommentModel::EVENT_CREATE => 'handleEvent', CommentModel::EVENT_CREATE => 'handleEvent',
CommentModel::EVENT_UPDATE => 'handleEvent', CommentModel::EVENT_UPDATE => 'handleEvent',
CommentModel::EVENT_DELETE => 'handleEvent', CommentModel::EVENT_DELETE => 'handleEvent',
CommentModel::EVENT_USER_MENTION => 'handleEvent', CommentModel::EVENT_USER_MENTION => 'handleEvent',
TaskFileModel::EVENT_CREATE => 'handleEvent', TaskFileModel::EVENT_CREATE => 'handleEvent',
TaskLinkModel::EVENT_CREATE_UPDATE => 'handleEvent', TaskLinkModel::EVENT_CREATE_UPDATE => 'handleEvent',
TaskLinkModel::EVENT_DELETE => 'handleEvent', TaskLinkModel::EVENT_DELETE => 'handleEvent',
); );
} }

View File

@ -33,5 +33,7 @@ class CommentEventBuilderTest extends Base
$this->assertInstanceOf('Kanboard\Event\CommentEvent', $event); $this->assertInstanceOf('Kanboard\Event\CommentEvent', $event);
$this->assertNotEmpty($event['comment']); $this->assertNotEmpty($event['comment']);
$this->assertNotEmpty($event['task']); $this->assertNotEmpty($event['task']);
$this->assertEquals(1, $event->getTaskId());
$this->assertEquals(1, $event->getProjectId());
} }
} }

View File

@ -29,5 +29,7 @@ class ProjectFileEventBuilderTest extends Base
$this->assertInstanceOf('Kanboard\Event\ProjectFileEvent', $event); $this->assertInstanceOf('Kanboard\Event\ProjectFileEvent', $event);
$this->assertNotEmpty($event['file']); $this->assertNotEmpty($event['file']);
$this->assertNotEmpty($event['project']); $this->assertNotEmpty($event['project']);
$this->assertNull($event->getTaskId());
$this->assertEquals(1, $event->getProjectId());
} }
} }

View File

@ -58,5 +58,7 @@ class SubtaskEventBuilderTest extends Base
$this->assertCount(2, $event['changes']); $this->assertCount(2, $event['changes']);
$this->assertEquals('new title', $event['changes']['title']); $this->assertEquals('new title', $event['changes']['title']);
$this->assertEquals(1, $event['changes']['user_id']); $this->assertEquals(1, $event['changes']['user_id']);
$this->assertEquals(1, $event->getTaskId());
$this->assertEquals(1, $event->getProjectId());
} }
} }

View File

@ -33,6 +33,8 @@ class TaskEventBuilderTest extends Base
$this->assertInstanceOf('Kanboard\Event\TaskEvent', $event); $this->assertInstanceOf('Kanboard\Event\TaskEvent', $event);
$this->assertNotEmpty($event['task']); $this->assertNotEmpty($event['task']);
$this->assertEquals(1, $event['task_id']); $this->assertEquals(1, $event['task_id']);
$this->assertEquals(1, $event->getTaskId());
$this->assertEquals(1, $event->getProjectId());
$this->assertEquals(array('title' => 'after'), $event['changes']); $this->assertEquals(array('title' => 'after'), $event['changes']);
} }

View File

@ -32,5 +32,7 @@ class TaskFileEventBuilderTest extends Base
$this->assertInstanceOf('Kanboard\Event\TaskFileEvent', $event); $this->assertInstanceOf('Kanboard\Event\TaskFileEvent', $event);
$this->assertNotEmpty($event['file']); $this->assertNotEmpty($event['file']);
$this->assertNotEmpty($event['task']); $this->assertNotEmpty($event['task']);
$this->assertEquals(1, $event->getTaskId());
$this->assertEquals(1, $event->getProjectId());
} }
} }

View File

@ -33,6 +33,8 @@ class TaskLinkEventBuilderTest extends Base
$this->assertInstanceOf('Kanboard\Event\TaskLinkEvent', $event); $this->assertInstanceOf('Kanboard\Event\TaskLinkEvent', $event);
$this->assertNotEmpty($event['task_link']); $this->assertNotEmpty($event['task_link']);
$this->assertNotEmpty($event['task']); $this->assertNotEmpty($event['task']);
$this->assertEquals(1, $event->getTaskId());
$this->assertEquals(1, $event->getProjectId());
} }
public function testBuildTitle() public function testBuildTitle()

View File

@ -47,12 +47,12 @@ class TextHelperTest extends Base
public function testMarkdownUserLink() public function testMarkdownUserLink()
{ {
$h = new TextHelper($this->container); $h = new TextHelper($this->container);
$this->assertEquals('<p>Text <a href="?controller=UserViewController&amp;action=profile&amp;user_id=1" class="user-mention-link">@admin</a> @notfound</p>', $h->markdown('Text @admin @notfound')); $this->assertEquals('<p>Text <a href="http://localhost/?controller=UserViewController&amp;action=profile&amp;user_id=1" class="user-mention-link">@admin</a> @notfound</p>', $h->markdown('Text @admin @notfound'));
$this->assertEquals('<p>Text <a href="?controller=UserViewController&amp;action=profile&amp;user_id=1" class="user-mention-link">@admin</a>,</p>', $h->markdown('Text @admin,')); $this->assertEquals('<p>Text <a href="http://localhost/?controller=UserViewController&amp;action=profile&amp;user_id=1" class="user-mention-link">@admin</a>,</p>', $h->markdown('Text @admin,'));
$this->assertEquals('<p>Text <a href="?controller=UserViewController&amp;action=profile&amp;user_id=1" class="user-mention-link">@admin</a>!</p>', $h->markdown('Text @admin!')); $this->assertEquals('<p>Text <a href="http://localhost/?controller=UserViewController&amp;action=profile&amp;user_id=1" class="user-mention-link">@admin</a>!</p>', $h->markdown('Text @admin!'));
$this->assertEquals('<p>Text <a href="?controller=UserViewController&amp;action=profile&amp;user_id=1" class="user-mention-link">@admin</a>? </p>', $h->markdown('Text @admin? ')); $this->assertEquals('<p>Text <a href="http://localhost/?controller=UserViewController&amp;action=profile&amp;user_id=1" class="user-mention-link">@admin</a>? </p>', $h->markdown('Text @admin? '));
$this->assertEquals('<p>Text <a href="?controller=UserViewController&amp;action=profile&amp;user_id=1" class="user-mention-link">@admin</a>.</p>', $h->markdown('Text @admin.')); $this->assertEquals('<p>Text <a href="http://localhost/?controller=UserViewController&amp;action=profile&amp;user_id=1" class="user-mention-link">@admin</a>.</p>', $h->markdown('Text @admin.'));
$this->assertEquals('<p>Text <a href="?controller=UserViewController&amp;action=profile&amp;user_id=1" class="user-mention-link">@admin</a>: test</p>', $h->markdown('Text @admin: test')); $this->assertEquals('<p>Text <a href="http://localhost/?controller=UserViewController&amp;action=profile&amp;user_id=1" class="user-mention-link">@admin</a>: test</p>', $h->markdown('Text @admin: test'));
$this->assertEquals('<p>Text @admin @notfound</p>', $h->markdown('Text @admin @notfound', true)); $this->assertEquals('<p>Text @admin @notfound</p>', $h->markdown('Text @admin @notfound', true));
} }

View File

@ -49,4 +49,46 @@ class CommentEventJobTest extends Base
$this->assertArrayHasKey(CommentModel::EVENT_UPDATE.'.closure', $called); $this->assertArrayHasKey(CommentModel::EVENT_UPDATE.'.closure', $called);
$this->assertArrayHasKey(CommentModel::EVENT_DELETE.'.closure', $called); $this->assertArrayHasKey(CommentModel::EVENT_DELETE.'.closure', $called);
} }
public function testThatUserMentionJobIsCalled()
{
$comment = 'some comment';
$this->container['queueManager'] = $this
->getMockBuilder('\Kanboard\Core\Queue\QueueManager')
->setConstructorArgs(array($this->container))
->setMethods(array(
'push',
))
->getMock();
$this->container['userMentionJob'] = $this
->getMockBuilder('\Kanboard\Job\UserMentionJob')
->setConstructorArgs(array($this->container))
->setMethods(array(
'withParams',
))
->getMock();
$this->container['queueManager']
->expects($this->any())
->method('push');
$this->container['userMentionJob']
->expects($this->once())
->method('withParams')
->with($comment, CommentModel::EVENT_USER_MENTION, $this->anything())
->will($this->returnValue($this->container['userMentionJob']));
$commentModel = new CommentModel($this->container);
$taskCreationModel = new TaskCreationModel($this->container);
$projectModel = new ProjectModel($this->container);
$commentEventJob = new CommentEventJob($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1)));
$this->assertEquals(1, $commentModel->create(array('task_id' => 1, 'comment' => $comment, 'user_id' => 1)));
$commentEventJob->execute(1, CommentModel::EVENT_CREATE);
}
} }

View File

@ -186,4 +186,44 @@ class TaskEventJobTest extends Base
$called = $this->container['dispatcher']->getCalledListeners(); $called = $this->container['dispatcher']->getCalledListeners();
$this->assertArrayHasKey(TaskModel::EVENT_MOVE_PROJECT.'.closure', $called); $this->assertArrayHasKey(TaskModel::EVENT_MOVE_PROJECT.'.closure', $called);
} }
public function testThatUserMentionJobIsCalled()
{
$description = 'something';
$this->container['queueManager'] = $this
->getMockBuilder('\Kanboard\Core\Queue\QueueManager')
->setConstructorArgs(array($this->container))
->setMethods(array(
'push',
))
->getMock();
$this->container['userMentionJob'] = $this
->getMockBuilder('\Kanboard\Job\UserMentionJob')
->setConstructorArgs(array($this->container))
->setMethods(array(
'withParams',
))
->getMock();
$this->container['queueManager']
->expects($this->any())
->method('push');
$this->container['userMentionJob']
->expects($this->once())
->method('withParams')
->with($description, TaskModel::EVENT_USER_MENTION, $this->anything())
->will($this->returnValue($this->container['userMentionJob']));
$taskCreationModel = new TaskCreationModel($this->container);
$projectModel = new ProjectModel($this->container);
$taskEventJob = new TaskEventJob($this->container);
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'description' => $description, 'project_id' => 1)));
$taskEventJob->execute(1, array(TaskModel::EVENT_CREATE));
}
} }

View File

@ -1,45 +1,60 @@
<?php <?php
use Kanboard\Core\Security\Role;
use Kanboard\Event\TaskEvent;
use Kanboard\Job\UserMentionJob;
use Kanboard\Model\ProjectModel;
use Kanboard\Model\ProjectUserRoleModel;
use Kanboard\Model\TaskModel;
use Kanboard\Model\UserModel;
require_once __DIR__.'/../Base.php'; require_once __DIR__.'/../Base.php';
use Kanboard\Core\Security\Role; class UserMentionJobTest extends Base
use Kanboard\Event\GenericEvent;
use Kanboard\Model\UserModel;
use Kanboard\Model\TaskModel;
use Kanboard\Model\TaskCreationModel;
use Kanboard\Model\ProjectModel;
use Kanboard\Model\ProjectUserRoleModel;
use Kanboard\Model\UserMentionModel;
class UserMentionTest extends Base
{ {
public function testGetMentionedUsersWithNoMentions() public function testGetMentionedUsersWithNoMentions()
{ {
$userModel = new UserModel($this->container); $userModel = new UserModel($this->container);
$userMentionModel = new UserMentionModel($this->container); $userMentionJob = new UserMentionJob($this->container);
$this->assertNotFalse($userModel->create(array('username' => 'user1'))); $this->assertNotFalse($userModel->create(array('username' => 'user1')));
$this->assertEmpty($userMentionModel->getMentionedUsers('test')); $this->assertEmpty($userMentionJob->getMentionedUsers('test'));
} }
public function testGetMentionedUsersWithNotficationDisabled() public function testGetMentionedUsersWithNotficationDisabled()
{ {
$userModel = new UserModel($this->container); $userModel = new UserModel($this->container);
$userMentionModel = new UserMentionModel($this->container); $userMentionJob = new UserMentionJob($this->container);
$this->assertNotFalse($userModel->create(array('username' => 'user1'))); $this->assertNotFalse($userModel->create(array('username' => 'user1')));
$this->assertEmpty($userMentionModel->getMentionedUsers('test @user1')); $this->assertEmpty($userMentionJob->getMentionedUsers('test @user1'));
} }
public function testGetMentionedUsersWithNotficationEnabled() public function testGetMentionedUsersWithNotficationEnabled()
{ {
$userModel = new UserModel($this->container); $userModel = new UserModel($this->container);
$userMentionModel = new UserMentionModel($this->container); $userMentionJob = new UserMentionJob($this->container);
$this->assertNotFalse($userModel->create(array('username' => 'user1'))); $this->assertNotFalse($userModel->create(array('username' => 'user1')));
$this->assertNotFalse($userModel->create(array('username' => 'user2', 'name' => 'Foobar', 'notifications_enabled' => 1))); $this->assertNotFalse($userModel->create(array('username' => 'user2', 'name' => 'Foobar', 'notifications_enabled' => 1)));
$users = $userMentionModel->getMentionedUsers('test @user2'); $users = $userMentionJob->getMentionedUsers('test @user2');
$this->assertCount(1, $users);
$this->assertEquals('user2', $users[0]['username']);
$this->assertEquals('Foobar', $users[0]['name']);
$this->assertEquals('', $users[0]['email']);
$this->assertEquals('', $users[0]['language']);
}
public function testGetMentionedUsersWithNotficationEnabledAndPunctuationMarks()
{
$userModel = new UserModel($this->container);
$userMentionJob = new UserMentionJob($this->container);
$this->assertNotFalse($userModel->create(array('username' => 'user1')));
$this->assertNotFalse($userModel->create(array('username' => 'user2', 'name' => 'Foobar', 'notifications_enabled' => 1)));
$users = $userMentionJob->getMentionedUsers('test @user2, test');
$this->assertCount(1, $users); $this->assertCount(1, $users);
$this->assertEquals('user2', $users[0]['username']); $this->assertEquals('user2', $users[0]['username']);
$this->assertEquals('Foobar', $users[0]['name']); $this->assertEquals('Foobar', $users[0]['name']);
@ -51,12 +66,12 @@ class UserMentionTest extends Base
{ {
$this->container['sessionStorage']->user = array('id' => 3); $this->container['sessionStorage']->user = array('id' => 3);
$userModel = new UserModel($this->container); $userModel = new UserModel($this->container);
$userMentionModel = new UserMentionModel($this->container); $userMentionJob = new UserMentionJob($this->container);
$this->assertNotFalse($userModel->create(array('username' => 'user1'))); $this->assertNotFalse($userModel->create(array('username' => 'user1')));
$this->assertNotFalse($userModel->create(array('username' => 'user2', 'name' => 'Foobar', 'notifications_enabled' => 1))); $this->assertNotFalse($userModel->create(array('username' => 'user2', 'name' => 'Foobar', 'notifications_enabled' => 1)));
$this->assertEmpty($userMentionModel->getMentionedUsers('test @user2')); $this->assertEmpty($userMentionJob->getMentionedUsers('test @user2'));
} }
public function testFireEventsWithMultipleMentions() public function testFireEventsWithMultipleMentions()
@ -64,8 +79,8 @@ class UserMentionTest extends Base
$projectUserRoleModel = new ProjectUserRoleModel($this->container); $projectUserRoleModel = new ProjectUserRoleModel($this->container);
$projectModel = new ProjectModel($this->container); $projectModel = new ProjectModel($this->container);
$userModel = new UserModel($this->container); $userModel = new UserModel($this->container);
$userMentionModel = new UserMentionModel($this->container); $userMentionJob = new UserMentionJob($this->container);
$event = new GenericEvent(array('project_id' => 1)); $event = new TaskEvent(array('task' => array('project_id' => 1)));
$this->assertEquals(2, $userModel->create(array('username' => 'user1', 'name' => 'User 1', 'notifications_enabled' => 1))); $this->assertEquals(2, $userModel->create(array('username' => 'user1', 'name' => 'User 1', 'notifications_enabled' => 1)));
$this->assertEquals(3, $userModel->create(array('username' => 'user2', 'name' => 'User 2', 'notifications_enabled' => 1))); $this->assertEquals(3, $userModel->create(array('username' => 'user2', 'name' => 'User 2', 'notifications_enabled' => 1)));
@ -75,35 +90,10 @@ class UserMentionTest extends Base
$this->container['dispatcher']->addListener(TaskModel::EVENT_USER_MENTION, array($this, 'onUserMention')); $this->container['dispatcher']->addListener(TaskModel::EVENT_USER_MENTION, array($this, 'onUserMention'));
$userMentionModel->fireEvents('test @user1 @user2', TaskModel::EVENT_USER_MENTION, $event); $userMentionJob->execute('test @user1 @user2', TaskModel::EVENT_USER_MENTION, $event);
$called = $this->container['dispatcher']->getCalledListeners(); $called = $this->container['dispatcher']->getCalledListeners();
$this->assertArrayHasKey(TaskModel::EVENT_USER_MENTION.'.UserMentionTest::onUserMention', $called); $this->assertArrayHasKey(TaskModel::EVENT_USER_MENTION.'.UserMentionJobTest::onUserMention', $called);
}
public function testFireEventsWithNoProjectId()
{
$projectUserRoleModel = new ProjectUserRoleModel($this->container);
$projectModel = new ProjectModel($this->container);
$taskCreationModel = new TaskCreationModel($this->container);
$userModel = new UserModel($this->container);
$userMentionModel = new UserMentionModel($this->container);
$event = new GenericEvent(array('task_id' => 1));
$this->assertEquals(2, $userModel->create(array('username' => 'user1', 'name' => 'User 1', 'notifications_enabled' => 1)));
$this->assertEquals(3, $userModel->create(array('username' => 'user2', 'name' => 'User 2', 'notifications_enabled' => 1)));
$this->assertEquals(1, $projectModel->create(array('name' => 'P1')));
$this->assertTrue($projectUserRoleModel->addUser(1, 3, Role::PROJECT_MEMBER));
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'Task 1')));
$this->container['dispatcher']->addListener(TaskModel::EVENT_USER_MENTION, array($this, 'onUserMention'));
$userMentionModel->fireEvents('test @user1 @user2', TaskModel::EVENT_USER_MENTION, $event);
$called = $this->container['dispatcher']->getCalledListeners();
$this->assertArrayHasKey(TaskModel::EVENT_USER_MENTION.'.UserMentionTest::onUserMention', $called);
} }
public function onUserMention($event) public function onUserMention($event)