From 59367d5450ce3607ee7a6c56849e7b5f67b7e42b Mon Sep 17 00:00:00 2001 From: Eskiso Date: Thu, 17 Dec 2015 09:36:38 +0000 Subject: Added MaxLenght to 50 for use with API/Comment new parameter --- app/Model/Comment.php | 1 + 1 file changed, 1 insertion(+) (limited to 'app/Model/Comment.php') diff --git a/app/Model/Comment.php b/app/Model/Comment.php index c7125a25..f60a96e3 100644 --- a/app/Model/Comment.php +++ b/app/Model/Comment.php @@ -203,6 +203,7 @@ class Comment extends Base new Validators\Integer('id', t('This value must be an integer')), new Validators\Integer('task_id', t('This value must be an integer')), new Validators\Integer('user_id', t('This value must be an integer')), + new Validators\MaxLength('reference', t('The maximum length is %d characters', 50), 50), new Validators\Required('comment', t('Comment is required')) ); } -- cgit v1.2.3 From ded63d21a84811c9e082c0fea0110a1b498265d6 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Tue, 29 Dec 2015 09:30:36 +0100 Subject: Send notifications on user mentions --- app/Api/Task.php | 4 +- app/Integration/BitbucketWebhook.php | 4 +- app/Integration/GithubWebhook.php | 4 +- app/Integration/GitlabWebhook.php | 2 +- app/Model/Action.php | 2 +- app/Model/Comment.php | 9 +- app/Model/Notification.php | 54 +++++----- app/Model/ProjectPermission.php | 15 ++- app/Model/Task.php | 1 + app/Model/TaskCreation.php | 11 +- app/Model/UserMention.php | 61 +++++++++++ app/Model/UserNotification.php | 19 ++-- app/Notification/Mail.php | 4 + app/ServiceProvider/ClassProvider.php | 1 + app/Subscriber/NotificationSubscriber.php | 41 +++++--- app/Template/notification/comment_user_mention.php | 7 ++ app/Template/notification/task_user_mention.php | 7 ++ tests/units/Model/ProjectPermissionTest.php | 39 ++++++- tests/units/Model/UserMentionTest.php | 114 +++++++++++++++++++++ 19 files changed, 324 insertions(+), 75 deletions(-) create mode 100644 app/Model/UserMention.php create mode 100644 app/Template/notification/comment_user_mention.php create mode 100644 app/Template/notification/task_user_mention.php create mode 100644 tests/units/Model/UserMentionTest.php (limited to 'app/Model/Comment.php') diff --git a/app/Api/Task.php b/app/Api/Task.php index 4a7ee932..1491cd35 100644 --- a/app/Api/Task.php +++ b/app/Api/Task.php @@ -71,7 +71,7 @@ class Task extends Base { $this->checkProjectPermission($project_id); - if ($owner_id !== 0 && ! $this->projectPermission->isMember($project_id, $owner_id)) { + if ($owner_id !== 0 && ! $this->projectPermission->isAssignable($project_id, $owner_id)) { return false; } @@ -117,7 +117,7 @@ class Task extends Base return false; } - if ($owner_id !== null && ! $this->projectPermission->isMember($project_id, $owner_id)) { + if ($owner_id !== null && ! $this->projectPermission->isAssignable($project_id, $owner_id)) { return false; } diff --git a/app/Integration/BitbucketWebhook.php b/app/Integration/BitbucketWebhook.php index 97a39437..3814e35c 100644 --- a/app/Integration/BitbucketWebhook.php +++ b/app/Integration/BitbucketWebhook.php @@ -81,7 +81,7 @@ class BitbucketWebhook extends \Kanboard\Core\Base if (! empty($task)) { $user = $this->user->getByUsername($payload['actor']['username']); - if (! empty($user) && ! $this->projectPermission->isMember($this->project_id, $user['id'])) { + if (! empty($user) && ! $this->projectPermission->isAssignable($this->project_id, $user['id'])) { $user = array(); } @@ -213,7 +213,7 @@ class BitbucketWebhook extends \Kanboard\Core\Base return false; } - if (! $this->projectPermission->isMember($this->project_id, $user['id'])) { + if (! $this->projectPermission->isAssignable($this->project_id, $user['id'])) { return false; } diff --git a/app/Integration/GithubWebhook.php b/app/Integration/GithubWebhook.php index c8b53e37..6dd7a8d9 100644 --- a/app/Integration/GithubWebhook.php +++ b/app/Integration/GithubWebhook.php @@ -149,7 +149,7 @@ class GithubWebhook extends \Kanboard\Core\Base if (! empty($task)) { $user = $this->user->getByUsername($payload['comment']['user']['login']); - if (! empty($user) && ! $this->projectPermission->isMember($this->project_id, $user['id'])) { + if (! empty($user) && ! $this->projectPermission->isAssignable($this->project_id, $user['id'])) { $user = array(); } @@ -266,7 +266,7 @@ class GithubWebhook extends \Kanboard\Core\Base $user = $this->user->getByUsername($issue['assignee']['login']); $task = $this->taskFinder->getByReference($this->project_id, $issue['number']); - if (! empty($user) && ! empty($task) && $this->projectPermission->isMember($this->project_id, $user['id'])) { + if (! empty($user) && ! empty($task) && $this->projectPermission->isAssignable($this->project_id, $user['id'])) { $event = array( 'project_id' => $this->project_id, 'task_id' => $task['id'], diff --git a/app/Integration/GitlabWebhook.php b/app/Integration/GitlabWebhook.php index 17b6da70..7ab4cedf 100644 --- a/app/Integration/GitlabWebhook.php +++ b/app/Integration/GitlabWebhook.php @@ -273,7 +273,7 @@ class GitlabWebhook extends \Kanboard\Core\Base if (! empty($task)) { $user = $this->user->getByUsername($payload['user']['username']); - if (! empty($user) && ! $this->projectPermission->isMember($this->project_id, $user['id'])) { + if (! empty($user) && ! $this->projectPermission->isAssignable($this->project_id, $user['id'])) { $user = array(); } diff --git a/app/Model/Action.php b/app/Model/Action.php index 289471f4..d3d18edb 100644 --- a/app/Model/Action.php +++ b/app/Model/Action.php @@ -427,7 +427,7 @@ class Action extends Base return $this->board->getColumnIdByTitle($project_id, $column['title']) ?: false; case 'user_id': case 'owner_id': - return $this->projectPermission->isMember($project_id, $param['value']) ? $param['value'] : false; + return $this->projectPermission->isAssignable($project_id, $param['value']) ? $param['value'] : false; default: return $param['value']; } diff --git a/app/Model/Comment.php b/app/Model/Comment.php index f60a96e3..71e964dc 100644 --- a/app/Model/Comment.php +++ b/app/Model/Comment.php @@ -26,8 +26,9 @@ class Comment extends Base * * @var string */ - const EVENT_UPDATE = 'comment.update'; - const EVENT_CREATE = 'comment.create'; + const EVENT_UPDATE = 'comment.update'; + const EVENT_CREATE = 'comment.create'; + const EVENT_USER_MENTION = 'comment.user.mention'; /** * Get all comments for a given task @@ -110,7 +111,9 @@ class Comment extends Base $comment_id = $this->persist(self::TABLE, $values); if ($comment_id) { - $this->container['dispatcher']->dispatch(self::EVENT_CREATE, new CommentEvent(array('id' => $comment_id) + $values)); + $event = new CommentEvent(array('id' => $comment_id) + $values); + $this->dispatcher->dispatch(self::EVENT_CREATE, $event); + $this->userMention->fireEvents($values['comment'], self::EVENT_USER_MENTION, $event); } return $comment_id; diff --git a/app/Model/Notification.php b/app/Model/Notification.php index f1122993..87c1a796 100644 --- a/app/Model/Notification.php +++ b/app/Model/Notification.php @@ -74,6 +74,10 @@ class Notification extends Base return e('%s commented on the task #%d', $event_author, $event_data['task']['id']); case File::EVENT_CREATE: return e('%s attached a file to the task #%d', $event_author, $event_data['task']['id']); + case Task::EVENT_USER_MENTION: + return e('%s mentioned you in the task #%d', $event_author, $event_data['task']['id']); + case Comment::EVENT_USER_MENTION: + return e('%s mentioned you in a comment on the task #%d', $event_author, $event_data['task']['id']); default: return e('Notification'); } @@ -91,52 +95,40 @@ class Notification extends Base { switch ($event_name) { case File::EVENT_CREATE: - $title = e('New attachment on task #%d: %s', $event_data['file']['task_id'], $event_data['file']['name']); - break; + return e('New attachment on task #%d: %s', $event_data['file']['task_id'], $event_data['file']['name']); case Comment::EVENT_CREATE: - $title = e('New comment on task #%d', $event_data['comment']['task_id']); - break; + return e('New comment on task #%d', $event_data['comment']['task_id']); case Comment::EVENT_UPDATE: - $title = e('Comment updated on task #%d', $event_data['comment']['task_id']); - break; + return e('Comment updated on task #%d', $event_data['comment']['task_id']); case Subtask::EVENT_CREATE: - $title = e('New subtask on task #%d', $event_data['subtask']['task_id']); - break; + return e('New subtask on task #%d', $event_data['subtask']['task_id']); case Subtask::EVENT_UPDATE: - $title = e('Subtask updated on task #%d', $event_data['subtask']['task_id']); - break; + return e('Subtask updated on task #%d', $event_data['subtask']['task_id']); case Task::EVENT_CREATE: - $title = e('New task #%d: %s', $event_data['task']['id'], $event_data['task']['title']); - break; + return e('New task #%d: %s', $event_data['task']['id'], $event_data['task']['title']); case Task::EVENT_UPDATE: - $title = e('Task updated #%d', $event_data['task']['id']); - break; + return e('Task updated #%d', $event_data['task']['id']); case Task::EVENT_CLOSE: - $title = e('Task #%d closed', $event_data['task']['id']); - break; + return e('Task #%d closed', $event_data['task']['id']); case Task::EVENT_OPEN: - $title = e('Task #%d opened', $event_data['task']['id']); - break; + return e('Task #%d opened', $event_data['task']['id']); case Task::EVENT_MOVE_COLUMN: - $title = e('Column changed for task #%d', $event_data['task']['id']); - break; + return e('Column changed for task #%d', $event_data['task']['id']); case Task::EVENT_MOVE_POSITION: - $title = e('New position for task #%d', $event_data['task']['id']); - break; + return e('New position for task #%d', $event_data['task']['id']); case Task::EVENT_MOVE_SWIMLANE: - $title = e('Swimlane changed for task #%d', $event_data['task']['id']); - break; + return e('Swimlane changed for task #%d', $event_data['task']['id']); case Task::EVENT_ASSIGNEE_CHANGE: - $title = e('Assignee changed on task #%d', $event_data['task']['id']); - break; + return e('Assignee changed on task #%d', $event_data['task']['id']); case Task::EVENT_OVERDUE: $nb = count($event_data['tasks']); - $title = $nb > 1 ? e('%d overdue tasks', $nb) : e('Task #%d is overdue', $event_data['tasks'][0]['id']); - break; + return $nb > 1 ? e('%d overdue tasks', $nb) : e('Task #%d is overdue', $event_data['tasks'][0]['id']); + case Task::EVENT_USER_MENTION: + return e('You were mentioned in the task #%d', $event_data['task']['id']); + case Comment::EVENT_USER_MENTION: + return e('You were mentioned in a comment on the task #%d', $event_data['task']['id']); default: - $title = e('Notification'); + return e('Notification'); } - - return $title; } } diff --git a/app/Model/ProjectPermission.php b/app/Model/ProjectPermission.php index 4ad9bbf1..66f4091d 100644 --- a/app/Model/ProjectPermission.php +++ b/app/Model/ProjectPermission.php @@ -86,11 +86,24 @@ class ProjectPermission extends Base * @param integer $user_id * @return boolean */ - public function isMember($project_id, $user_id) + public function isAssignable($project_id, $user_id) { return in_array($this->projectUserRole->getUserRole($project_id, $user_id), array(Role::PROJECT_MEMBER, Role::PROJECT_MANAGER)); } + /** + * Return true if the user is member + * + * @access public + * @param integer $project_id + * @param integer $user_id + * @return boolean + */ + public function isMember($project_id, $user_id) + { + return in_array($this->projectUserRole->getUserRole($project_id, $user_id), array(Role::PROJECT_MEMBER, Role::PROJECT_MANAGER, Role::PROJECT_VIEWER)); + } + /** * Get active project ids by user * diff --git a/app/Model/Task.php b/app/Model/Task.php index f1cd094f..7aa9e312 100644 --- a/app/Model/Task.php +++ b/app/Model/Task.php @@ -41,6 +41,7 @@ class Task extends Base const EVENT_CREATE_UPDATE = 'task.create_update'; const EVENT_ASSIGNEE_CHANGE = 'task.assignee_change'; const EVENT_OVERDUE = 'task.overdue'; + const EVENT_USER_MENTION = 'task.user.mention'; /** * Recurrence: status diff --git a/app/Model/TaskCreation.php b/app/Model/TaskCreation.php index 5ef1a04b..88912d4d 100644 --- a/app/Model/TaskCreation.php +++ b/app/Model/TaskCreation.php @@ -86,8 +86,13 @@ class TaskCreation extends Base */ private function fireEvents($task_id, array $values) { - $values['task_id'] = $task_id; - $this->container['dispatcher']->dispatch(Task::EVENT_CREATE_UPDATE, new TaskEvent($values)); - $this->container['dispatcher']->dispatch(Task::EVENT_CREATE, new TaskEvent($values)); + $event = new TaskEvent(array('task_id' => $task_id) + $values); + + $this->dispatcher->dispatch(Task::EVENT_CREATE_UPDATE, $event); + $this->dispatcher->dispatch(Task::EVENT_CREATE, $event); + + if (! empty($values['description'])) { + $this->userMention->fireEvents($values['description'], Task::EVENT_USER_MENTION, $event); + } } } diff --git a/app/Model/UserMention.php b/app/Model/UserMention.php new file mode 100644 index 00000000..97a4e419 --- /dev/null +++ b/app/Model/UserMention.php @@ -0,0 +1,61 @@ +db->table(User::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->taskFinder->getProjectId($event['task_id']); + } + + $users = $this->getMentionedUsers($content); + + foreach ($users as $user) { + if ($this->projectPermission->isMember($event['project_id'], $user['id'])) { + $event['mention'] = $user; + $this->dispatcher->dispatch($eventName, $event); + } + } + } +} diff --git a/app/Model/UserNotification.php b/app/Model/UserNotification.php index e00f23c5..8161288c 100644 --- a/app/Model/UserNotification.php +++ b/app/Model/UserNotification.php @@ -21,18 +21,12 @@ class UserNotification extends Base */ public function sendNotifications($event_name, array $event_data) { - $logged_user_id = $this->userSession->isLogged() ? $this->userSession->getId() : 0; - $users = $this->getUsersWithNotificationEnabled($event_data['task']['project_id'], $logged_user_id); - - if (! empty($users)) { - foreach ($users as $user) { - if ($this->userNotificationFilter->shouldReceiveNotification($user, $event_data)) { - $this->sendUserNotification($user, $event_name, $event_data); - } - } + $users = $this->getUsersWithNotificationEnabled($event_data['task']['project_id'], $this->userSession->getId()); - // Restore locales - $this->config->setupTranslations(); + foreach ($users as $user) { + if ($this->userNotificationFilter->shouldReceiveNotification($user, $event_data)) { + $this->sendUserNotification($user, $event_name, $event_data); + } } } @@ -58,6 +52,9 @@ class UserNotification extends Base foreach ($this->userNotificationType->getSelectedTypes($user['id']) as $type) { $this->userNotificationType->getType($type)->notifyUser($user, $event_name, $event_data); } + + // Restore locales + $this->config->setupTranslations(); } /** diff --git a/app/Notification/Mail.php b/app/Notification/Mail.php index 98bffef2..d05dbdf2 100644 --- a/app/Notification/Mail.php +++ b/app/Notification/Mail.php @@ -121,6 +121,10 @@ class Mail extends Base implements NotificationInterface case Task::EVENT_ASSIGNEE_CHANGE: $subject = $this->getStandardMailSubject(e('Assignee change'), $event_data); break; + case Task::EVENT_USER_MENTION: + case Comment::EVENT_USER_MENTION: + $subject = $this->getStandardMailSubject(e('Mentioned'), $event_data); + break; case Task::EVENT_OVERDUE: $subject = e('[%s] Overdue tasks', $event_data['project_name']); break; diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php index fad73047..03257c07 100644 --- a/app/ServiceProvider/ClassProvider.php +++ b/app/ServiceProvider/ClassProvider.php @@ -67,6 +67,7 @@ class ClassProvider implements ServiceProviderInterface 'User', 'UserImport', 'UserLocking', + 'UserMention', 'UserNotification', 'UserNotificationFilter', 'UserUnreadNotification', diff --git a/app/Subscriber/NotificationSubscriber.php b/app/Subscriber/NotificationSubscriber.php index 394573e4..1bde24dd 100644 --- a/app/Subscriber/NotificationSubscriber.php +++ b/app/Subscriber/NotificationSubscriber.php @@ -2,6 +2,7 @@ namespace Kanboard\Subscriber; +use Kanboard\Core\Base; use Kanboard\Event\GenericEvent; use Kanboard\Model\Task; use Kanboard\Model\Comment; @@ -9,34 +10,40 @@ use Kanboard\Model\Subtask; use Kanboard\Model\File; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -class NotificationSubscriber extends \Kanboard\Core\Base implements EventSubscriberInterface +class NotificationSubscriber extends Base implements EventSubscriberInterface { public static function getSubscribedEvents() { return array( - Task::EVENT_CREATE => array('execute', 0), - Task::EVENT_UPDATE => array('execute', 0), - Task::EVENT_CLOSE => array('execute', 0), - Task::EVENT_OPEN => array('execute', 0), - Task::EVENT_MOVE_COLUMN => array('execute', 0), - Task::EVENT_MOVE_POSITION => array('execute', 0), - Task::EVENT_MOVE_SWIMLANE => array('execute', 0), - Task::EVENT_ASSIGNEE_CHANGE => array('execute', 0), - Subtask::EVENT_CREATE => array('execute', 0), - Subtask::EVENT_UPDATE => array('execute', 0), - Comment::EVENT_CREATE => array('execute', 0), - Comment::EVENT_UPDATE => array('execute', 0), - File::EVENT_CREATE => array('execute', 0), + Task::EVENT_USER_MENTION => 'handleEvent', + Task::EVENT_CREATE => 'handleEvent', + Task::EVENT_UPDATE => 'handleEvent', + Task::EVENT_CLOSE => 'handleEvent', + Task::EVENT_OPEN => 'handleEvent', + Task::EVENT_MOVE_COLUMN => 'handleEvent', + Task::EVENT_MOVE_POSITION => 'handleEvent', + Task::EVENT_MOVE_SWIMLANE => 'handleEvent', + Task::EVENT_ASSIGNEE_CHANGE => 'handleEvent', + Subtask::EVENT_CREATE => 'handleEvent', + Subtask::EVENT_UPDATE => 'handleEvent', + Comment::EVENT_CREATE => 'handleEvent', + Comment::EVENT_UPDATE => 'handleEvent', + Comment::EVENT_USER_MENTION => 'handleEvent', + File::EVENT_CREATE => 'handleEvent', ); } - public function execute(GenericEvent $event, $event_name) + public function handleEvent(GenericEvent $event, $event_name) { $event_data = $this->getEventData($event); if (! empty($event_data)) { - $this->userNotification->sendNotifications($event_name, $event_data); - $this->projectNotification->sendNotifications($event_data['task']['project_id'], $event_name, $event_data); + if (! empty($event['mention'])) { + $this->userNotification->sendUserNotification($event['mention'], $event_name, $event_data); + } else { + $this->userNotification->sendNotifications($event_name, $event_data); + $this->projectNotification->sendNotifications($event_data['task']['project_id'], $event_name, $event_data); + } } } diff --git a/app/Template/notification/comment_user_mention.php b/app/Template/notification/comment_user_mention.php new file mode 100644 index 00000000..59f5127e --- /dev/null +++ b/app/Template/notification/comment_user_mention.php @@ -0,0 +1,7 @@ +

+ +

e($task['title']) ?>

+ +text->markdown($comment['comment']) ?> + +render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/app/Template/notification/task_user_mention.php b/app/Template/notification/task_user_mention.php new file mode 100644 index 00000000..40ddddca --- /dev/null +++ b/app/Template/notification/task_user_mention.php @@ -0,0 +1,7 @@ +

+

e($task['title']) ?>

+ +

+text->markdown($task['description']) ?> + +render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/tests/units/Model/ProjectPermissionTest.php b/tests/units/Model/ProjectPermissionTest.php index 77419bec..6e8bbde9 100644 --- a/tests/units/Model/ProjectPermissionTest.php +++ b/tests/units/Model/ProjectPermissionTest.php @@ -128,6 +128,43 @@ class ProjectPermissionTest extends Base $this->assertFalse($projectPermission->isUserAllowed(2, 5)); } + public function testIsAssignable() + { + $userModel = new User($this->container); + $projectModel = new Project($this->container); + $groupModel = new Group($this->container); + $groupRoleModel = new ProjectGroupRole($this->container); + $groupMemberModel = new GroupMember($this->container); + $userRoleModel = new ProjectUserRole($this->container); + $projectPermission = new ProjectPermission($this->container); + + $this->assertEquals(2, $userModel->create(array('username' => 'user 1'))); + $this->assertEquals(3, $userModel->create(array('username' => 'user 2'))); + $this->assertEquals(4, $userModel->create(array('username' => 'user 3'))); + $this->assertEquals(5, $userModel->create(array('username' => 'user 4'))); + + $this->assertEquals(1, $projectModel->create(array('name' => 'Project 1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'Project 2'))); + + $this->assertEquals(1, $groupModel->create('Group A')); + + $this->assertTrue($groupMemberModel->addUser(1, 2)); + $this->assertTrue($groupRoleModel->addGroup(1, 1, Role::PROJECT_VIEWER)); + + $this->assertTrue($userRoleModel->addUser(1, 3, Role::PROJECT_MEMBER)); + $this->assertTrue($userRoleModel->addUser(1, 4, Role::PROJECT_MANAGER)); + + $this->assertFalse($projectPermission->isAssignable(1, 2)); + $this->assertTrue($projectPermission->isAssignable(1, 3)); + $this->assertTrue($projectPermission->isAssignable(1, 4)); + $this->assertFalse($projectPermission->isAssignable(1, 5)); + + $this->assertFalse($projectPermission->isAssignable(2, 2)); + $this->assertFalse($projectPermission->isAssignable(2, 3)); + $this->assertFalse($projectPermission->isAssignable(2, 4)); + $this->assertFalse($projectPermission->isAssignable(2, 5)); + } + public function testIsMember() { $userModel = new User($this->container); @@ -154,7 +191,7 @@ class ProjectPermissionTest extends Base $this->assertTrue($userRoleModel->addUser(1, 3, Role::PROJECT_MEMBER)); $this->assertTrue($userRoleModel->addUser(1, 4, Role::PROJECT_MANAGER)); - $this->assertFalse($projectPermission->isMember(1, 2)); + $this->assertTrue($projectPermission->isMember(1, 2)); $this->assertTrue($projectPermission->isMember(1, 3)); $this->assertTrue($projectPermission->isMember(1, 4)); $this->assertFalse($projectPermission->isMember(1, 5)); diff --git a/tests/units/Model/UserMentionTest.php b/tests/units/Model/UserMentionTest.php new file mode 100644 index 00000000..d50c9285 --- /dev/null +++ b/tests/units/Model/UserMentionTest.php @@ -0,0 +1,114 @@ +container); + $userMentionModel = new UserMention($this->container); + + $this->assertNotFalse($userModel->create(array('username' => 'user1'))); + $this->assertEmpty($userMentionModel->getMentionedUsers('test')); + } + + public function testGetMentionedUsersWithNotficationDisabled() + { + $userModel = new User($this->container); + $userMentionModel = new UserMention($this->container); + + $this->assertNotFalse($userModel->create(array('username' => 'user1'))); + $this->assertEmpty($userMentionModel->getMentionedUsers('test @user1')); + } + + public function testGetMentionedUsersWithNotficationEnabled() + { + $userModel = new User($this->container); + $userMentionModel = new UserMention($this->container); + + $this->assertNotFalse($userModel->create(array('username' => 'user1'))); + $this->assertNotFalse($userModel->create(array('username' => 'user2', 'name' => 'Foobar', 'notifications_enabled' => 1))); + + $users = $userMentionModel->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 testGetMentionedUsersWithNotficationEnabledAndUserLoggedIn() + { + $this->container['sessionStorage']->user = array('id' => 3); + $userModel = new User($this->container); + $userMentionModel = new UserMention($this->container); + + $this->assertNotFalse($userModel->create(array('username' => 'user1'))); + $this->assertNotFalse($userModel->create(array('username' => 'user2', 'name' => 'Foobar', 'notifications_enabled' => 1))); + + $this->assertEmpty($userMentionModel->getMentionedUsers('test @user2')); + } + + public function testFireEventsWithMultipleMentions() + { + $projectUserRoleModel = new ProjectUserRole($this->container); + $projectModel = new Project($this->container); + $userModel = new User($this->container); + $userMentionModel = new UserMention($this->container); + $event = new GenericEvent(array('project_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->container['dispatcher']->addListener(Task::EVENT_USER_MENTION, array($this, 'onUserMention')); + + $userMentionModel->fireEvents('test @user1 @user2', Task::EVENT_USER_MENTION, $event); + + $called = $this->container['dispatcher']->getCalledListeners(); + $this->assertArrayHasKey(Task::EVENT_USER_MENTION.'.UserMentionTest::onUserMention', $called); + } + + public function testFireEventsWithNoProjectId() + { + $projectUserRoleModel = new ProjectUserRole($this->container); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $userModel = new User($this->container); + $userMentionModel = new UserMention($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(Task::EVENT_USER_MENTION, array($this, 'onUserMention')); + + $userMentionModel->fireEvents('test @user1 @user2', Task::EVENT_USER_MENTION, $event); + + $called = $this->container['dispatcher']->getCalledListeners(); + $this->assertArrayHasKey(Task::EVENT_USER_MENTION.'.UserMentionTest::onUserMention', $called); + } + + public function onUserMention($event) + { + $this->assertInstanceOf('Kanboard\Event\GenericEvent', $event); + $this->assertEquals(array('id' => '3', 'username' => 'user2', 'name' => 'User 2', 'email' => null, 'language' => null), $event['mention']); + } +} -- cgit v1.2.3 From a296ba5b18487d312acca2513d461a210a460fae Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sun, 3 Jan 2016 16:43:13 -0500 Subject: Improve Automatic Actions plugin api --- ChangeLog | 27 +- app/Action/Base.php | 118 ++-- app/Action/CommentCreation.php | 17 +- app/Action/CommentCreationMoveTaskColumn.php | 94 +++ app/Action/TaskAssignCategoryColor.php | 11 + app/Action/TaskAssignCategoryLabel.php | 15 +- app/Action/TaskAssignCategoryLink.php | 13 +- app/Action/TaskAssignColorCategory.php | 11 + app/Action/TaskAssignColorColumn.php | 11 + app/Action/TaskAssignColorLink.php | 11 + app/Action/TaskAssignColorUser.php | 11 + app/Action/TaskAssignCurrentUser.php | 19 +- app/Action/TaskAssignCurrentUserColumn.php | 98 +++ app/Action/TaskAssignSpecificUser.php | 11 + app/Action/TaskAssignUser.php | 13 +- app/Action/TaskClose.php | 48 +- app/Action/TaskCloseColumn.php | 84 +++ app/Action/TaskCreation.php | 11 + app/Action/TaskDuplicateAnotherProject.php | 13 +- app/Action/TaskEmail.php | 11 + app/Action/TaskLogMoveAnotherColumn.php | 83 --- app/Action/TaskMoveAnotherProject.php | 11 + app/Action/TaskMoveColumnAssigned.php | 12 +- app/Action/TaskMoveColumnCategoryChange.php | 15 +- app/Action/TaskMoveColumnUnAssigned.php | 12 +- app/Action/TaskOpen.php | 11 + app/Action/TaskUpdateStartDate.php | 11 + app/Api/Action.php | 28 +- app/Controller/Action.php | 21 +- app/Core/Action/ActionManager.php | 141 +++++ app/Core/Base.php | 3 + app/Core/Event/EventManager.php | 83 +++ app/Core/Mail/Client.php | 20 +- app/Integration/BitbucketWebhook.php | 2 +- app/Integration/GithubWebhook.php | 2 +- app/Integration/GitlabWebhook.php | 2 +- app/Model/Action.php | 301 +-------- app/Model/ActionParameter.php | 122 ++++ app/Model/Comment.php | 1 + app/Model/ProjectUserRole.php | 6 +- app/Schema/Sqlite.php | 25 +- app/ServiceProvider/ActionProvider.php | 78 +++ app/ServiceProvider/ClassProvider.php | 4 + app/ServiceProvider/EventDispatcherProvider.php | 3 - app/Subscriber/BootstrapSubscriber.php | 13 +- app/Template/action/index.php | 30 +- app/common.php | 1 + doc/api-action-procedures.markdown | 42 +- doc/automatic-actions.markdown | 66 +- doc/plugin-registration.markdown | 37 -- tests/functionals/ApiTest.php | 6 +- tests/units/Action/BaseActionTest.php | 144 +++++ .../Action/CommentCreationMoveTaskColumnTest.php | 58 ++ tests/units/Action/CommentCreationTest.php | 165 ++--- tests/units/Action/TaskAssignCategoryColorTest.php | 60 ++ tests/units/Action/TaskAssignCategoryLabelTest.php | 85 +++ tests/units/Action/TaskAssignCategoryLinkTest.php | 32 +- tests/units/Action/TaskAssignColorCategoryTest.php | 90 +-- tests/units/Action/TaskAssignColorColumnTest.php | 55 +- tests/units/Action/TaskAssignColorLinkTest.php | 67 +- tests/units/Action/TaskAssignColorUserTest.php | 78 +-- .../Action/TaskAssignCurrentUserColumnTest.php | 75 +++ tests/units/Action/TaskAssignCurrentUserTest.php | 74 +-- tests/units/Action/TaskAssignSpecificUserTest.php | 72 +-- tests/units/Action/TaskAssignUserTest.php | 62 ++ tests/units/Action/TaskCloseColumnTest.php | 53 ++ tests/units/Action/TaskCloseTest.php | 106 +--- tests/units/Action/TaskCreationTest.php | 49 ++ .../Action/TaskDuplicateAnotherProjectTest.php | 95 +-- tests/units/Action/TaskEmailTest.php | 133 +--- tests/units/Action/TaskMoveAnotherProjectTest.php | 90 +-- tests/units/Action/TaskMoveColumnAssignedTest.php | 56 ++ .../Action/TaskMoveColumnCategoryChangeTest.php | 108 ++-- .../units/Action/TaskMoveColumnUnAssignedTest.php | 74 +++ tests/units/Action/TaskOpenTest.php | 51 ++ tests/units/Action/TaskUpdateStartDateTest.php | 54 +- tests/units/Core/Action/ActionManagerTest.php | 157 +++++ tests/units/Core/Event/EventManagerTest.php | 18 + tests/units/Integration/BitbucketWebhookTest.php | 2 +- tests/units/Integration/GithubWebhookTest.php | 2 +- tests/units/Integration/GitlabWebhookTest.php | 2 +- tests/units/Model/ActionTest.php | 698 ++++++++++++--------- tests/units/Model/ProjectDuplicationTest.php | 6 +- 83 files changed, 3028 insertions(+), 1682 deletions(-) create mode 100644 app/Action/CommentCreationMoveTaskColumn.php create mode 100644 app/Action/TaskAssignCurrentUserColumn.php create mode 100644 app/Action/TaskCloseColumn.php delete mode 100644 app/Action/TaskLogMoveAnotherColumn.php create mode 100644 app/Core/Action/ActionManager.php create mode 100644 app/Core/Event/EventManager.php create mode 100644 app/Model/ActionParameter.php create mode 100644 app/ServiceProvider/ActionProvider.php create mode 100644 tests/units/Action/BaseActionTest.php create mode 100644 tests/units/Action/CommentCreationMoveTaskColumnTest.php create mode 100644 tests/units/Action/TaskAssignCategoryColorTest.php create mode 100644 tests/units/Action/TaskAssignCategoryLabelTest.php create mode 100644 tests/units/Action/TaskAssignCurrentUserColumnTest.php create mode 100644 tests/units/Action/TaskAssignUserTest.php create mode 100644 tests/units/Action/TaskCloseColumnTest.php create mode 100644 tests/units/Action/TaskCreationTest.php create mode 100644 tests/units/Action/TaskMoveColumnAssignedTest.php create mode 100644 tests/units/Action/TaskMoveColumnUnAssignedTest.php create mode 100644 tests/units/Action/TaskOpenTest.php create mode 100644 tests/units/Core/Action/ActionManagerTest.php create mode 100644 tests/units/Core/Event/EventManagerTest.php (limited to 'app/Model/Comment.php') diff --git a/ChangeLog b/ChangeLog index 3b261700..54518b34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,24 +1,31 @@ Version 1.0.23 (unreleased) --------------------------- +Breaking changes: + +* Plugin API changes for Automatic Actions +* Automatic Action to close a task doesn't have the column parameter anymore (use the action "Close a task in a specific column") +* Action name stored in the database is now the absolute class name + New features: -- Added support of user mentions (@username) -- Added report to compare working hours between open and closed tasks -- Added the possiblity to define custom routes from plugins -- Added new method to remove metadata +* Added support of user mentions (@username) +* Added report to compare working hours between open and closed tasks +* Added the possiblity to define custom routes from plugins +* Added new method to remove metadata Improvements: -- Improving performance during task position change (SQL queries are 3 times faster than before) -- Do not show window scrollbars when individual column scrolling is enabled +* Improving performance during task position change (SQL queries are 3 times faster than before) +* Do not show window scrollbars when individual column scrolling is enabled +* Automatic Actions code improvements and unit tests Bug fixes: -- Fix compatiblity issue with FreeBSD for session.hash_function parameter -- Fix wrong constant name that cause a PHP error in project management section -- Fix pagination in group members listing -- Avoid PHP error when enabling LDAP group provider with PHP < 5.5 +* Fix compatiblity issue with FreeBSD for session.hash_function parameter +* Fix wrong constant name that cause a PHP error in project management section +* Fix pagination in group members listing +* Avoid PHP error when enabling LDAP group provider with PHP < 5.5 Version 1.0.22 -------------- diff --git a/app/Action/Base.php b/app/Action/Base.php index 81e2ccc6..febd6cfc 100644 --- a/app/Action/Base.php +++ b/app/Action/Base.php @@ -3,7 +3,6 @@ namespace Kanboard\Action; use Kanboard\Event\GenericEvent; -use Pimple\Container; /** * Base class for automatic actions @@ -13,6 +12,14 @@ use Pimple\Container; */ abstract class Base extends \Kanboard\Core\Base { + /** + * Extended events + * + * @access private + * @var array + */ + private $compatibleEvents = array(); + /** * Flag for called listener * @@ -27,7 +34,7 @@ abstract class Base extends \Kanboard\Core\Base * @access private * @var integer */ - private $project_id = 0; + private $projectId = 0; /** * User parameters @@ -38,20 +45,25 @@ abstract class Base extends \Kanboard\Core\Base private $params = array(); /** - * Attached event name + * Get automatic action name * - * @access protected - * @var string + * @final + * @access public + * @return string */ - protected $event_name = ''; + final public function getName() + { + return '\\'.get_called_class(); + } /** - * Container instance + * Get automatic action description * - * @access protected - * @var \Pimple\Container + * @abstract + * @access public + * @return string */ - protected $container; + abstract public function getDescription(); /** * Execute the action @@ -100,30 +112,26 @@ abstract class Base extends \Kanboard\Core\Base abstract public function hasRequiredCondition(array $data); /** - * Constructor + * Return class information * * @access public - * @param \Pimple\Container $container Container - * @param integer $project_id Project id - * @param string $event_name Attached event name + * @return string */ - public function __construct(Container $container, $project_id, $event_name) + public function __toString() { - $this->container = $container; - $this->project_id = $project_id; - $this->event_name = $event_name; - $this->called = false; + return $this->getName(); } /** - * Return class information + * Set project id * * @access public - * @return string + * @return Base */ - public function __toString() + public function setProjectId($project_id) { - return get_called_class(); + $this->projectId = $project_id; + return $this; } /** @@ -134,7 +142,7 @@ abstract class Base extends \Kanboard\Core\Base */ public function getProjectId() { - return $this->project_id; + return $this->projectId; } /** @@ -143,10 +151,12 @@ abstract class Base extends \Kanboard\Core\Base * @access public * @param string $name Parameter name * @param mixed $value Value + * @param Base */ public function setParam($name, $value) { $this->params[$name] = $value; + return $this; } /** @@ -154,24 +164,25 @@ abstract class Base extends \Kanboard\Core\Base * * @access public * @param string $name Parameter name - * @param mixed $default_value Default value + * @param mixed $default Default value * @return mixed */ - public function getParam($name, $default_value = null) + public function getParam($name, $default = null) { - return isset($this->params[$name]) ? $this->params[$name] : $default_value; + return isset($this->params[$name]) ? $this->params[$name] : $default; } /** * Check if an action is executable (right project and required parameters) * * @access public - * @param array $data Event data dictionary - * @return bool True if the action is executable + * @param array $data + * @param string $eventName + * @return bool */ - public function isExecutable(array $data) + public function isExecutable(array $data, $eventName) { - return $this->hasCompatibleEvent() && + return $this->hasCompatibleEvent($eventName) && $this->hasRequiredProject($data) && $this->hasRequiredParameters($data) && $this->hasRequiredCondition($data); @@ -181,11 +192,12 @@ abstract class Base extends \Kanboard\Core\Base * Check if the event is compatible with the action * * @access public + * @param string $eventName * @return bool */ - public function hasCompatibleEvent() + public function hasCompatibleEvent($eventName) { - return in_array($this->event_name, $this->getCompatibleEvents()); + return in_array($eventName, $this->getEvents()); } /** @@ -197,7 +209,7 @@ abstract class Base extends \Kanboard\Core\Base */ public function hasRequiredProject(array $data) { - return isset($data['project_id']) && $data['project_id'] == $this->project_id; + return isset($data['project_id']) && $data['project_id'] == $this->getProjectId(); } /** @@ -222,10 +234,11 @@ abstract class Base extends \Kanboard\Core\Base * Execute the action * * @access public - * @param \Event\GenericEvent $event Event data dictionary - * @return bool True if the action was executed or false when not executed + * @param \Kanboard\Event\GenericEvent $event + * @param string $eventName + * @return bool */ - public function execute(GenericEvent $event) + public function execute(GenericEvent $event, $eventName) { // Avoid infinite loop, a listener instance can be called only one time if ($this->called) { @@ -235,15 +248,38 @@ abstract class Base extends \Kanboard\Core\Base $data = $event->getAll(); $result = false; - if ($this->isExecutable($data)) { + if ($this->isExecutable($data, $eventName)) { $this->called = true; $result = $this->doAction($data); } - if (DEBUG) { - $this->logger->debug(get_called_class().' => '.($result ? 'true' : 'false')); - } + $this->logger->debug('AutomaticAction '.$this->getName().' => '.($result ? 'true' : 'false')); return $result; } + + /** + * Register a new event for the automatic action + * + * @access public + * @param string $event + * @param string $description + */ + public function addEvent($event, $description) + { + $this->eventManager->register($event, $description); + $this->compatibleEvents[] = $event; + return $this; + } + + /** + * Get all compatible events of an automatic action + * + * @access public + * @return array + */ + public function getEvents() + { + return array_unique(array_merge($this->getCompatibleEvents(), $this->compatibleEvents)); + } } diff --git a/app/Action/CommentCreation.php b/app/Action/CommentCreation.php index 73fedc3b..d6ea2074 100644 --- a/app/Action/CommentCreation.php +++ b/app/Action/CommentCreation.php @@ -14,6 +14,17 @@ use Kanboard\Integration\GitlabWebhook; */ class CommentCreation extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Create a comment from an external provider'); + } + /** * Get the list of compatible events * @@ -67,9 +78,9 @@ class CommentCreation extends Base { return (bool) $this->comment->create(array( 'reference' => isset($data['reference']) ? $data['reference'] : '', - 'comment' => empty($data['comment']) ? $data['commit_comment'] : $data['comment'], + 'comment' => $data['comment'], 'task_id' => $data['task_id'], - 'user_id' => empty($data['user_id']) ? 0 : $data['user_id'], + 'user_id' => isset($data['user_id']) && $this->projectPermission->isAssignable($this->getProjectId(), $data['user_id']) ? $data['user_id'] : 0, )); } @@ -82,6 +93,6 @@ class CommentCreation extends Base */ public function hasRequiredCondition(array $data) { - return ! empty($data['comment']) || ! empty($data['commit_comment']); + return ! empty($data['comment']); } } diff --git a/app/Action/CommentCreationMoveTaskColumn.php b/app/Action/CommentCreationMoveTaskColumn.php new file mode 100644 index 00000000..4473cf91 --- /dev/null +++ b/app/Action/CommentCreationMoveTaskColumn.php @@ -0,0 +1,94 @@ + t('Column')); + } + + /** + * Get the required parameter for the event + * + * @access public + * @return string[] + */ + public function getEventRequiredParameters() + { + return array('task_id', 'column_id'); + } + + /** + * Execute the action (append to the task description). + * + * @access public + * @param array $data Event data dictionary + * @return bool True if the action was executed or false when not executed + */ + public function doAction(array $data) + { + if (! $this->userSession->isLogged()) { + return false; + } + + $column = $this->board->getColumn($data['column_id']); + + return (bool) $this->comment->create(array( + 'comment' => t('Moved to column %s', $column['title']), + 'task_id' => $data['task_id'], + 'user_id' => $this->userSession->getId(), + )); + } + + /** + * Check if the event data meet the action condition + * + * @access public + * @param array $data Event data dictionary + * @return bool + */ + public function hasRequiredCondition(array $data) + { + return $data['column_id'] == $this->getParam('column_id'); + } +} diff --git a/app/Action/TaskAssignCategoryColor.php b/app/Action/TaskAssignCategoryColor.php index ffa1ac2a..f5085cb0 100644 --- a/app/Action/TaskAssignCategoryColor.php +++ b/app/Action/TaskAssignCategoryColor.php @@ -12,6 +12,17 @@ use Kanboard\Model\Task; */ class TaskAssignCategoryColor extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign automatically a category based on a color'); + } + /** * Get the list of compatible events * diff --git a/app/Action/TaskAssignCategoryLabel.php b/app/Action/TaskAssignCategoryLabel.php index 0ef474b6..8d291e89 100644 --- a/app/Action/TaskAssignCategoryLabel.php +++ b/app/Action/TaskAssignCategoryLabel.php @@ -12,6 +12,17 @@ use Kanboard\Integration\GithubWebhook; */ class TaskAssignCategoryLabel extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Change the category based on an external label'); + } + /** * Get the list of compatible events * @@ -64,7 +75,7 @@ class TaskAssignCategoryLabel extends Base { $values = array( 'id' => $data['task_id'], - 'category_id' => isset($data['category_id']) ? $data['category_id'] : $this->getParam('category_id'), + 'category_id' => $this->getParam('category_id'), ); return $this->taskModification->update($values); @@ -79,6 +90,6 @@ class TaskAssignCategoryLabel extends Base */ public function hasRequiredCondition(array $data) { - return $data['label'] == $this->getParam('label'); + return $data['label'] == $this->getParam('label') && empty($data['category_id']); } } diff --git a/app/Action/TaskAssignCategoryLink.php b/app/Action/TaskAssignCategoryLink.php index 3d00e8d3..b39e41b4 100644 --- a/app/Action/TaskAssignCategoryLink.php +++ b/app/Action/TaskAssignCategoryLink.php @@ -13,6 +13,17 @@ use Kanboard\Model\TaskLink; */ class TaskAssignCategoryLink extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign automatically a category based on a link'); + } + /** * Get the list of compatible events * @@ -65,7 +76,7 @@ class TaskAssignCategoryLink extends Base { $values = array( 'id' => $data['task_id'], - 'category_id' => isset($data['category_id']) ? $data['category_id'] : $this->getParam('category_id'), + 'category_id' => $this->getParam('category_id'), ); return $this->taskModification->update($values); diff --git a/app/Action/TaskAssignColorCategory.php b/app/Action/TaskAssignColorCategory.php index a2332f78..3a15b15f 100644 --- a/app/Action/TaskAssignColorCategory.php +++ b/app/Action/TaskAssignColorCategory.php @@ -12,6 +12,17 @@ use Kanboard\Model\Task; */ class TaskAssignColorCategory extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign automatically a color based on a category'); + } + /** * Get the list of compatible events * diff --git a/app/Action/TaskAssignColorColumn.php b/app/Action/TaskAssignColorColumn.php index 53140733..7474045b 100644 --- a/app/Action/TaskAssignColorColumn.php +++ b/app/Action/TaskAssignColorColumn.php @@ -12,6 +12,17 @@ use Kanboard\Model\Task; */ class TaskAssignColorColumn extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign a color when the task is moved to a specific column'); + } + /** * Get the list of compatible events * diff --git a/app/Action/TaskAssignColorLink.php b/app/Action/TaskAssignColorLink.php index 67b2ef62..f71df70e 100644 --- a/app/Action/TaskAssignColorLink.php +++ b/app/Action/TaskAssignColorLink.php @@ -12,6 +12,17 @@ use Kanboard\Model\TaskLink; */ class TaskAssignColorLink extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Change task color when using a specific task link'); + } + /** * Get the list of compatible events * diff --git a/app/Action/TaskAssignColorUser.php b/app/Action/TaskAssignColorUser.php index 6bf02c36..6e56bdc5 100644 --- a/app/Action/TaskAssignColorUser.php +++ b/app/Action/TaskAssignColorUser.php @@ -12,6 +12,17 @@ use Kanboard\Model\Task; */ class TaskAssignColorUser extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign a color to a specific user'); + } + /** * Get the list of compatible events * diff --git a/app/Action/TaskAssignCurrentUser.php b/app/Action/TaskAssignCurrentUser.php index f34c4f36..192a120c 100644 --- a/app/Action/TaskAssignCurrentUser.php +++ b/app/Action/TaskAssignCurrentUser.php @@ -12,6 +12,17 @@ use Kanboard\Model\Task; */ class TaskAssignCurrentUser extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign the task to the person who does the action'); + } + /** * Get the list of compatible events * @@ -22,7 +33,6 @@ class TaskAssignCurrentUser extends Base { return array( Task::EVENT_CREATE, - Task::EVENT_MOVE_COLUMN, ); } @@ -34,9 +44,7 @@ class TaskAssignCurrentUser extends Base */ public function getActionRequiredParameters() { - return array( - 'column_id' => t('Column'), - ); + return array(); } /** @@ -49,7 +57,6 @@ class TaskAssignCurrentUser extends Base { return array( 'task_id', - 'column_id', ); } @@ -83,6 +90,6 @@ class TaskAssignCurrentUser extends Base */ public function hasRequiredCondition(array $data) { - return $data['column_id'] == $this->getParam('column_id'); + return true; } } diff --git a/app/Action/TaskAssignCurrentUserColumn.php b/app/Action/TaskAssignCurrentUserColumn.php new file mode 100644 index 00000000..05d08dd3 --- /dev/null +++ b/app/Action/TaskAssignCurrentUserColumn.php @@ -0,0 +1,98 @@ + t('Column'), + ); + } + + /** + * Get the required parameter for the event + * + * @access public + * @return string[] + */ + public function getEventRequiredParameters() + { + return array( + 'task_id', + 'column_id', + ); + } + + /** + * Execute the action + * + * @access public + * @param array $data Event data dictionary + * @return bool True if the action was executed or false when not executed + */ + public function doAction(array $data) + { + if (! $this->userSession->isLogged()) { + return false; + } + + $values = array( + 'id' => $data['task_id'], + 'owner_id' => $this->userSession->getId(), + ); + + return $this->taskModification->update($values); + } + + /** + * Check if the event data meet the action condition + * + * @access public + * @param array $data Event data dictionary + * @return bool + */ + public function hasRequiredCondition(array $data) + { + return $data['column_id'] == $this->getParam('column_id'); + } +} diff --git a/app/Action/TaskAssignSpecificUser.php b/app/Action/TaskAssignSpecificUser.php index dfcb281b..2dc3e966 100644 --- a/app/Action/TaskAssignSpecificUser.php +++ b/app/Action/TaskAssignSpecificUser.php @@ -12,6 +12,17 @@ use Kanboard\Model\Task; */ class TaskAssignSpecificUser extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign the task to a specific user'); + } + /** * Get the list of compatible events * diff --git a/app/Action/TaskAssignUser.php b/app/Action/TaskAssignUser.php index a5821729..bb3a83c2 100644 --- a/app/Action/TaskAssignUser.php +++ b/app/Action/TaskAssignUser.php @@ -13,6 +13,17 @@ use Kanboard\Integration\BitbucketWebhook; */ class TaskAssignUser extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Change the assignee based on an external username'); + } + /** * Get the list of compatible events * @@ -78,6 +89,6 @@ class TaskAssignUser extends Base */ public function hasRequiredCondition(array $data) { - return true; + return $this->projectPermission->isAssignable($this->getProjectId(), $data['owner_id']); } } diff --git a/app/Action/TaskClose.php b/app/Action/TaskClose.php index d80bd023..a4b093a4 100644 --- a/app/Action/TaskClose.php +++ b/app/Action/TaskClose.php @@ -15,6 +15,17 @@ use Kanboard\Model\Task; */ class TaskClose extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Close a task'); + } + /** * Get the list of compatible events * @@ -24,7 +35,6 @@ class TaskClose extends Base public function getCompatibleEvents() { return array( - Task::EVENT_MOVE_COLUMN, GithubWebhook::EVENT_COMMIT, GithubWebhook::EVENT_ISSUE_CLOSED, GitlabWebhook::EVENT_COMMIT, @@ -42,17 +52,7 @@ class TaskClose extends Base */ public function getActionRequiredParameters() { - switch ($this->event_name) { - case GithubWebhook::EVENT_COMMIT: - case GithubWebhook::EVENT_ISSUE_CLOSED: - case GitlabWebhook::EVENT_COMMIT: - case GitlabWebhook::EVENT_ISSUE_CLOSED: - case BitbucketWebhook::EVENT_COMMIT: - case BitbucketWebhook::EVENT_ISSUE_CLOSED: - return array(); - default: - return array('column_id' => t('Column')); - } + return array(); } /** @@ -63,17 +63,7 @@ class TaskClose extends Base */ public function getEventRequiredParameters() { - switch ($this->event_name) { - case GithubWebhook::EVENT_COMMIT: - case GithubWebhook::EVENT_ISSUE_CLOSED: - case GitlabWebhook::EVENT_COMMIT: - case GitlabWebhook::EVENT_ISSUE_CLOSED: - case BitbucketWebhook::EVENT_COMMIT: - case BitbucketWebhook::EVENT_ISSUE_CLOSED: - return array('task_id'); - default: - return array('task_id', 'column_id'); - } + return array('task_id'); } /** @@ -97,16 +87,6 @@ class TaskClose extends Base */ public function hasRequiredCondition(array $data) { - switch ($this->event_name) { - case GithubWebhook::EVENT_COMMIT: - case GithubWebhook::EVENT_ISSUE_CLOSED: - case GitlabWebhook::EVENT_COMMIT: - case GitlabWebhook::EVENT_ISSUE_CLOSED: - case BitbucketWebhook::EVENT_COMMIT: - case BitbucketWebhook::EVENT_ISSUE_CLOSED: - return true; - default: - return $data['column_id'] == $this->getParam('column_id'); - } + return true; } } diff --git a/app/Action/TaskCloseColumn.php b/app/Action/TaskCloseColumn.php new file mode 100644 index 00000000..09af3b96 --- /dev/null +++ b/app/Action/TaskCloseColumn.php @@ -0,0 +1,84 @@ + t('Column')); + } + + /** + * Get the required parameter for the event + * + * @access public + * @return string[] + */ + public function getEventRequiredParameters() + { + return array('task_id', 'column_id'); + } + + /** + * Execute the action (close the task) + * + * @access public + * @param array $data Event data dictionary + * @return bool True if the action was executed or false when not executed + */ + public function doAction(array $data) + { + return $this->taskStatus->close($data['task_id']); + } + + /** + * Check if the event data meet the action condition + * + * @access public + * @param array $data Event data dictionary + * @return bool + */ + public function hasRequiredCondition(array $data) + { + return $data['column_id'] == $this->getParam('column_id'); + } +} diff --git a/app/Action/TaskCreation.php b/app/Action/TaskCreation.php index af1403f0..23ff4592 100644 --- a/app/Action/TaskCreation.php +++ b/app/Action/TaskCreation.php @@ -14,6 +14,17 @@ use Kanboard\Integration\BitbucketWebhook; */ class TaskCreation extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Create a task from an external provider'); + } + /** * Get the list of compatible events * diff --git a/app/Action/TaskDuplicateAnotherProject.php b/app/Action/TaskDuplicateAnotherProject.php index 1f6684dd..5bcdce08 100644 --- a/app/Action/TaskDuplicateAnotherProject.php +++ b/app/Action/TaskDuplicateAnotherProject.php @@ -12,6 +12,17 @@ use Kanboard\Model\Task; */ class TaskDuplicateAnotherProject extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Duplicate the task to another project'); + } + /** * Get the list of compatible events * @@ -51,7 +62,6 @@ class TaskDuplicateAnotherProject extends Base return array( 'task_id', 'column_id', - 'project_id', ); } @@ -65,7 +75,6 @@ class TaskDuplicateAnotherProject extends Base public function doAction(array $data) { $destination_column_id = $this->board->getFirstColumn($this->getParam('project_id')); - return (bool) $this->taskDuplication->duplicateToProject($data['task_id'], $this->getParam('project_id'), null, $destination_column_id); } diff --git a/app/Action/TaskEmail.php b/app/Action/TaskEmail.php index 7fb76c4c..4e0e06a6 100644 --- a/app/Action/TaskEmail.php +++ b/app/Action/TaskEmail.php @@ -12,6 +12,17 @@ use Kanboard\Model\Task; */ class TaskEmail extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Send a task by email to someone'); + } + /** * Get the list of compatible events * diff --git a/app/Action/TaskLogMoveAnotherColumn.php b/app/Action/TaskLogMoveAnotherColumn.php deleted file mode 100644 index a699c4ab..00000000 --- a/app/Action/TaskLogMoveAnotherColumn.php +++ /dev/null @@ -1,83 +0,0 @@ - t('Column')); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array('task_id', 'column_id'); - } - - /** - * Execute the action (append to the task description). - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - if (! $this->userSession->isLogged()) { - return false; - } - - $column = $this->board->getColumn($data['column_id']); - - return (bool) $this->comment->create(array( - 'comment' => t('Moved to column %s', $column['title']), - 'task_id' => $data['task_id'], - 'user_id' => $this->userSession->getId(), - )); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['column_id'] == $this->getParam('column_id'); - } -} diff --git a/app/Action/TaskMoveAnotherProject.php b/app/Action/TaskMoveAnotherProject.php index 476e2036..fdff0d8c 100644 --- a/app/Action/TaskMoveAnotherProject.php +++ b/app/Action/TaskMoveAnotherProject.php @@ -12,6 +12,17 @@ use Kanboard\Model\Task; */ class TaskMoveAnotherProject extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Move the task to another project'); + } + /** * Get the list of compatible events * diff --git a/app/Action/TaskMoveColumnAssigned.php b/app/Action/TaskMoveColumnAssigned.php index 16622ee4..1b23a591 100644 --- a/app/Action/TaskMoveColumnAssigned.php +++ b/app/Action/TaskMoveColumnAssigned.php @@ -12,6 +12,17 @@ use Kanboard\Model\Task; */ class TaskMoveColumnAssigned extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Move the task to another column when assigned to a user'); + } + /** * Get the list of compatible events * @@ -51,7 +62,6 @@ class TaskMoveColumnAssigned extends Base return array( 'task_id', 'column_id', - 'project_id', 'owner_id' ); } diff --git a/app/Action/TaskMoveColumnCategoryChange.php b/app/Action/TaskMoveColumnCategoryChange.php index 1e12be4a..0f591eda 100644 --- a/app/Action/TaskMoveColumnCategoryChange.php +++ b/app/Action/TaskMoveColumnCategoryChange.php @@ -12,6 +12,17 @@ use Kanboard\Model\Task; */ class TaskMoveColumnCategoryChange extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Move the task to another column when the category is changed'); + } + /** * Get the list of compatible events * @@ -50,7 +61,6 @@ class TaskMoveColumnCategoryChange extends Base return array( 'task_id', 'column_id', - 'project_id', 'category_id', ); } @@ -71,7 +81,8 @@ class TaskMoveColumnCategoryChange extends Base $data['task_id'], $this->getParam('dest_column_id'), $original_task['position'], - $original_task['swimlane_id'] + $original_task['swimlane_id'], + false ); } diff --git a/app/Action/TaskMoveColumnUnAssigned.php b/app/Action/TaskMoveColumnUnAssigned.php index 617c75a8..99ef9351 100644 --- a/app/Action/TaskMoveColumnUnAssigned.php +++ b/app/Action/TaskMoveColumnUnAssigned.php @@ -12,6 +12,17 @@ use Kanboard\Model\Task; */ class TaskMoveColumnUnAssigned extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Move the task to another column when assignee is cleared'); + } + /** * Get the list of compatible events * @@ -51,7 +62,6 @@ class TaskMoveColumnUnAssigned extends Base return array( 'task_id', 'column_id', - 'project_id', 'owner_id' ); } diff --git a/app/Action/TaskOpen.php b/app/Action/TaskOpen.php index 2e84c695..a1ab622c 100644 --- a/app/Action/TaskOpen.php +++ b/app/Action/TaskOpen.php @@ -14,6 +14,17 @@ use Kanboard\Integration\BitbucketWebhook; */ class TaskOpen extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Open a task'); + } + /** * Get the list of compatible events * diff --git a/app/Action/TaskUpdateStartDate.php b/app/Action/TaskUpdateStartDate.php index 4cd548af..011a5baf 100644 --- a/app/Action/TaskUpdateStartDate.php +++ b/app/Action/TaskUpdateStartDate.php @@ -12,6 +12,17 @@ use Kanboard\Model\Task; */ class TaskUpdateStartDate extends Base { + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Automatically update the start date'); + } + /** * Get the list of compatible events * diff --git a/app/Api/Action.php b/app/Api/Action.php index 0ae91f10..bdb5b26e 100644 --- a/app/Api/Action.php +++ b/app/Api/Action.php @@ -12,17 +12,17 @@ class Action extends \Kanboard\Core\Base { public function getAvailableActions() { - return $this->action->getAvailableActions(); + return $this->actionManager->getAvailableActions(); } public function getAvailableActionEvents() { - return $this->action->getAvailableEvents(); + return $this->eventManager->getAll(); } public function getCompatibleActionEvents($action_name) { - return $this->action->getCompatibleEvents($action_name); + return $this->actionManager->getCompatibleEvents($action_name); } public function removeAction($action_id) @@ -32,22 +32,10 @@ class Action extends \Kanboard\Core\Base public function getActions($project_id) { - $actions = $this->action->getAllByProject($project_id); - - foreach ($actions as $index => $action) { - $params = array(); - - foreach ($action['params'] as $param) { - $params[$param['name']] = $param['value']; - } - - $actions[$index]['params'] = $params; - } - - return $actions; + return $this->action->getAllByProject($project_id); } - public function createAction($project_id, $event_name, $action_name, $params) + public function createAction($project_id, $event_name, $action_name, array $params) { $values = array( 'project_id' => $project_id, @@ -63,16 +51,16 @@ class Action extends \Kanboard\Core\Base } // Check if the action exists - $actions = $this->action->getAvailableActions(); + $actions = $this->actionManager->getAvailableActions(); if (! isset($actions[$action_name])) { return false; } // Check the event - $action = $this->action->load($action_name, $project_id, $event_name); + $action = $this->actionManager->getAction($action_name); - if (! in_array($event_name, $action->getCompatibleEvents())) { + if (! in_array($event_name, $action->getEvents())) { return false; } diff --git a/app/Controller/Action.php b/app/Controller/Action.php index 3caea45c..9b803893 100644 --- a/app/Controller/Action.php +++ b/app/Controller/Action.php @@ -18,17 +18,18 @@ class Action extends Base public function index() { $project = $this->getProject(); + $actions = $this->action->getAllByProject($project['id']); $this->response->html($this->projectLayout('action/index', array( 'values' => array('project_id' => $project['id']), 'project' => $project, - 'actions' => $this->action->getAllByProject($project['id']), - 'available_actions' => $this->action->getAvailableActions(), - 'available_events' => $this->action->getAvailableEvents(), - 'available_params' => $this->action->getAllActionParameters(), + 'actions' => $actions, + 'available_actions' => $this->actionManager->getAvailableActions(), + 'available_events' => $this->eventManager->getAll(), + 'available_params' => $this->actionManager->getAvailableParameters($actions), 'columns_list' => $this->board->getColumnsList($project['id']), 'users_list' => $this->projectUserRole->getAssignableUsersList($project['id']), - 'projects_list' => $this->project->getList(false), + 'projects_list' => $this->projectUserRole->getProjectsByUser($this->userSession->getId()), 'colors_list' => $this->color->getList(), 'categories_list' => $this->category->getList($project['id']), 'links_list' => $this->link->getList(0, false), @@ -53,7 +54,7 @@ class Action extends Base $this->response->html($this->projectLayout('action/event', array( 'values' => $values, 'project' => $project, - 'events' => $this->action->getCompatibleEvents($values['action_name']), + 'events' => $this->actionManager->getCompatibleEvents($values['action_name']), 'title' => t('Automatic actions') ))); } @@ -72,14 +73,14 @@ class Action extends Base $this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id']))); } - $action = $this->action->load($values['action_name'], $values['project_id'], $values['event_name']); + $action = $this->actionManager->getAction($values['action_name']); $action_params = $action->getActionRequiredParameters(); if (empty($action_params)) { $this->doCreation($project, $values + array('params' => array())); } - $projects_list = $this->project->getList(false); + $projects_list = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()); unset($projects_list[$project['id']]); $this->response->html($this->projectLayout('action/params', array( @@ -139,8 +140,8 @@ class Action extends Base $this->response->html($this->projectLayout('action/remove', array( 'action' => $this->action->getById($this->request->getIntegerParam('action_id')), - 'available_events' => $this->action->getAvailableEvents(), - 'available_actions' => $this->action->getAvailableActions(), + 'available_events' => $this->eventManager->getAll(), + 'available_actions' => $this->actionManager->getAvailableActions(), 'project' => $project, 'title' => t('Remove an action') ))); diff --git a/app/Core/Action/ActionManager.php b/app/Core/Action/ActionManager.php new file mode 100644 index 00000000..921a8b98 --- /dev/null +++ b/app/Core/Action/ActionManager.php @@ -0,0 +1,141 @@ +actions[$action->getName()] = $action; + return $this; + } + + /** + * Get automatic action instance + * + * @access public + * @param string $name Absolute class name with namespace + * @return ActionBase + */ + public function getAction($name) + { + if (isset($this->actions[$name])) { + return $this->actions[$name]; + } + + throw new RuntimeException('Automatic Action Not Found: '.$name); + } + + /** + * Get available automatic actions + * + * @access public + * @return array + */ + public function getAvailableActions() + { + $actions = array(); + + foreach ($this->actions as $action) { + if (count($action->getEvents()) > 0) { + $actions[$action->getName()] = $action->getDescription(); + } + } + + asort($actions); + + return $actions; + } + + /** + * Get all available action parameters + * + * @access public + * @param array $actions + * @return array + */ + public function getAvailableParameters(array $actions) + { + $params = array(); + + foreach ($actions as $action) { + $currentAction = $this->getAction($action['action_name']); + $params[$currentAction->getName()] = $currentAction->getActionRequiredParameters(); + } + + return $params; + } + + /** + * Get list of compatible events for a given action + * + * @access public + * @param string $name + * @return array + */ + public function getCompatibleEvents($name) + { + $events = array(); + $actionEvents = $this->getAction($name)->getEvents(); + + foreach ($this->eventManager->getAll() as $event => $description) { + if (in_array($event, $actionEvents)) { + $events[$event] = $description; + } + } + + return $events; + } + + /** + * Bind automatic actions to events + * + * @access public + * @return ActionManager + */ + public function attachEvents() + { + if ($this->userSession->isLogged()) { + $actions = $this->action->getAllByUser($this->userSession->getId()); + } else { + $actions = $this->action->getAll(); + } + + foreach ($actions as $action) { + $listener = $this->getAction($action['action_name'])->setProjectId($action['project_id']); + + foreach ($action['params'] as $param_name => $param_value) { + $listener->setParam($param_name, $param_value); + } + + $this->dispatcher->addListener($action['event_name'], array($listener, 'execute')); + } + + return $this; + } +} diff --git a/app/Core/Base.php b/app/Core/Base.php index a4cf787a..11a0be68 100644 --- a/app/Core/Base.php +++ b/app/Core/Base.php @@ -10,7 +10,9 @@ use Pimple\Container; * @package core * @author Frederic Guillot * + * @property \Kanboard\Core\Action\ActionManager $actionManager * @property \Kanboard\Core\Cache\MemoryCache $memoryCache + * @property \Kanboard\Core\Event\EventManager $eventManager * @property \Kanboard\Core\Group\GroupManager $groupManager * @property \Kanboard\Core\Http\Client $httpClient * @property \Kanboard\Core\Http\OAuth2 $oauth @@ -54,6 +56,7 @@ use Pimple\Container; * @property \Kanboard\Formatter\UserFilterAutoCompleteFormatter $userFilterAutoCompleteFormatter * @property \Kanboard\Formatter\GroupAutoCompleteFormatter $groupAutoCompleteFormatter * @property \Kanboard\Model\Action $action + * @property \Kanboard\Model\ActionParameter $actionParameter * @property \Kanboard\Model\Authentication $authentication * @property \Kanboard\Model\Board $board * @property \Kanboard\Model\Category $category diff --git a/app/Core/Event/EventManager.php b/app/Core/Event/EventManager.php new file mode 100644 index 00000000..8e66cc12 --- /dev/null +++ b/app/Core/Event/EventManager.php @@ -0,0 +1,83 @@ +events[$event] = $description; + return $this; + } + + /** + * Get the list of events and description that can be used from the user interface + * + * @access public + * @return array + */ + public function getAll() + { + $events = array( + TaskLink::EVENT_CREATE_UPDATE => t('Task link creation or modification'), + Task::EVENT_MOVE_COLUMN => t('Move a task to another column'), + Task::EVENT_UPDATE => t('Task modification'), + Task::EVENT_CREATE => t('Task creation'), + Task::EVENT_OPEN => t('Reopen a task'), + Task::EVENT_CLOSE => t('Closing a task'), + Task::EVENT_CREATE_UPDATE => t('Task creation or modification'), + Task::EVENT_ASSIGNEE_CHANGE => t('Task assignee change'), + GithubWebhook::EVENT_COMMIT => t('Github commit received'), + GithubWebhook::EVENT_ISSUE_OPENED => t('Github issue opened'), + GithubWebhook::EVENT_ISSUE_CLOSED => t('Github issue closed'), + GithubWebhook::EVENT_ISSUE_REOPENED => t('Github issue reopened'), + GithubWebhook::EVENT_ISSUE_ASSIGNEE_CHANGE => t('Github issue assignee change'), + GithubWebhook::EVENT_ISSUE_LABEL_CHANGE => t('Github issue label change'), + GithubWebhook::EVENT_ISSUE_COMMENT => t('Github issue comment created'), + GitlabWebhook::EVENT_COMMIT => t('Gitlab commit received'), + GitlabWebhook::EVENT_ISSUE_OPENED => t('Gitlab issue opened'), + GitlabWebhook::EVENT_ISSUE_REOPENED => t('Gitlab issue reopened'), + GitlabWebhook::EVENT_ISSUE_CLOSED => t('Gitlab issue closed'), + GitlabWebhook::EVENT_ISSUE_COMMENT => t('Gitlab issue comment created'), + BitbucketWebhook::EVENT_COMMIT => t('Bitbucket commit received'), + BitbucketWebhook::EVENT_ISSUE_OPENED => t('Bitbucket issue opened'), + BitbucketWebhook::EVENT_ISSUE_CLOSED => t('Bitbucket issue closed'), + BitbucketWebhook::EVENT_ISSUE_REOPENED => t('Bitbucket issue reopened'), + BitbucketWebhook::EVENT_ISSUE_ASSIGNEE_CHANGE => t('Bitbucket issue assignee change'), + BitbucketWebhook::EVENT_ISSUE_COMMENT => t('Bitbucket issue comment created'), + ); + + $events = array_merge($events, $this->events); + asort($events); + + return $events; + } +} diff --git a/app/Core/Mail/Client.php b/app/Core/Mail/Client.php index 7b4268bd..e1f31696 100644 --- a/app/Core/Mail/Client.php +++ b/app/Core/Mail/Client.php @@ -45,19 +45,21 @@ class Client extends Base */ public function send($email, $name, $subject, $html) { - $this->container['logger']->debug('Sending email to '.$email.' ('.MAIL_TRANSPORT.')'); + if (! empty($email)) { + $this->logger->debug('Sending email to '.$email.' ('.MAIL_TRANSPORT.')'); - $start_time = microtime(true); - $author = 'Kanboard'; + $start_time = microtime(true); + $author = 'Kanboard'; - if ($this->userSession->isLogged()) { - $author = e('%s via Kanboard', $this->helper->user->getFullname()); - } + if ($this->userSession->isLogged()) { + $author = e('%s via Kanboard', $this->helper->user->getFullname()); + } - $this->getTransport(MAIL_TRANSPORT)->sendEmail($email, $name, $subject, $html, $author); + $this->getTransport(MAIL_TRANSPORT)->sendEmail($email, $name, $subject, $html, $author); - if (DEBUG) { - $this->logger->debug('Email sent in '.round(microtime(true) - $start_time, 6).' seconds'); + if (DEBUG) { + $this->logger->debug('Email sent in '.round(microtime(true) - $start_time, 6).' seconds'); + } } return $this; diff --git a/app/Integration/BitbucketWebhook.php b/app/Integration/BitbucketWebhook.php index 3814e35c..e6ba3f1a 100644 --- a/app/Integration/BitbucketWebhook.php +++ b/app/Integration/BitbucketWebhook.php @@ -303,7 +303,7 @@ class BitbucketWebhook extends \Kanboard\Core\Base 'task_id' => $task_id, 'commit_message' => $commit['message'], 'commit_url' => $commit['links']['html']['href'], - 'commit_comment' => $commit['message']."\n\n[".t('Commit made by @%s on Bitbucket', $actor['display_name']).']('.$commit['links']['html']['href'].')', + 'comment' => $commit['message']."\n\n[".t('Commit made by @%s on Bitbucket', $actor['display_name']).']('.$commit['links']['html']['href'].')', ) + $task) ); diff --git a/app/Integration/GithubWebhook.php b/app/Integration/GithubWebhook.php index 6dd7a8d9..cdd2fc48 100644 --- a/app/Integration/GithubWebhook.php +++ b/app/Integration/GithubWebhook.php @@ -98,7 +98,7 @@ class GithubWebhook extends \Kanboard\Core\Base 'task_id' => $task_id, 'commit_message' => $commit['message'], 'commit_url' => $commit['url'], - 'commit_comment' => $commit['message']."\n\n[".t('Commit made by @%s on Github', $commit['author']['username']).']('.$commit['url'].')' + 'comment' => $commit['message']."\n\n[".t('Commit made by @%s on Github', $commit['author']['username']).']('.$commit['url'].')' ) + $task) ); } diff --git a/app/Integration/GitlabWebhook.php b/app/Integration/GitlabWebhook.php index 7ab4cedf..5e0aa59d 100644 --- a/app/Integration/GitlabWebhook.php +++ b/app/Integration/GitlabWebhook.php @@ -144,7 +144,7 @@ class GitlabWebhook extends \Kanboard\Core\Base 'task_id' => $task_id, 'commit_message' => $commit['message'], 'commit_url' => $commit['url'], - 'commit_comment' => $commit['message']."\n\n[".t('Commit made by @%s on Gitlab', $commit['author']['name']).']('.$commit['url'].')' + 'comment' => $commit['message']."\n\n[".t('Commit made by @%s on Gitlab', $commit['author']['name']).']('.$commit['url'].')' ) + $task) ); diff --git a/app/Model/Action.php b/app/Model/Action.php index d3d18edb..c368b494 100644 --- a/app/Model/Action.php +++ b/app/Model/Action.php @@ -2,14 +2,11 @@ namespace Kanboard\Model; -use Kanboard\Integration\GitlabWebhook; -use Kanboard\Integration\GithubWebhook; -use Kanboard\Integration\BitbucketWebhook; use SimpleValidator\Validator; use SimpleValidator\Validators; /** - * Action model + * Action Model * * @package model * @author Frederic Guillot @@ -24,143 +21,33 @@ class Action extends Base const TABLE = 'actions'; /** - * SQL table name for action parameters - * - * @var string - */ - const TABLE_PARAMS = 'action_has_params'; - - /** - * Extended actions - * - * @access private - * @var array - */ - private $actions = array(); - - /** - * Extend the list of default actions - * - * @access public - * @param string $className - * @param string $description - * @return Action - */ - public function extendActions($className, $description) - { - $this->actions[$className] = $description; - return $this; - } - - /** - * Return the name and description of available actions + * Return actions and parameters for a given user * * @access public + * @param integer $user_id * @return array */ - public function getAvailableActions() + public function getAllByUser($user_id) { - $values = array( - 'TaskClose' => t('Close a task'), - 'TaskOpen' => t('Open a task'), - 'TaskAssignSpecificUser' => t('Assign the task to a specific user'), - 'TaskAssignCurrentUser' => t('Assign the task to the person who does the action'), - 'TaskDuplicateAnotherProject' => t('Duplicate the task to another project'), - 'TaskMoveAnotherProject' => t('Move the task to another project'), - 'TaskMoveColumnAssigned' => t('Move the task to another column when assigned to a user'), - 'TaskMoveColumnUnAssigned' => t('Move the task to another column when assignee is cleared'), - 'TaskAssignColorColumn' => t('Assign a color when the task is moved to a specific column'), - 'TaskAssignColorUser' => t('Assign a color to a specific user'), - 'TaskAssignColorCategory' => t('Assign automatically a color based on a category'), - 'TaskAssignCategoryColor' => t('Assign automatically a category based on a color'), - 'TaskAssignCategoryLink' => t('Assign automatically a category based on a link'), - 'CommentCreation' => t('Create a comment from an external provider'), - 'TaskCreation' => t('Create a task from an external provider'), - 'TaskLogMoveAnotherColumn' => t('Add a comment log when moving the task between columns'), - 'TaskAssignUser' => t('Change the assignee based on an external username'), - 'TaskAssignCategoryLabel' => t('Change the category based on an external label'), - 'TaskUpdateStartDate' => t('Automatically update the start date'), - 'TaskMoveColumnCategoryChange' => t('Move the task to another column when the category is changed'), - 'TaskEmail' => t('Send a task by email to someone'), - 'TaskAssignColorLink' => t('Change task color when using a specific task link'), - ); - - $values = array_merge($values, $this->actions); + $project_ids = $this->projectPermission->getActiveProjectIds($user_id); + $actions = array(); - asort($values); + if (! empty($project_ids)) { + $actions = $this->db->table(self::TABLE)->in('project_id', $project_ids)->findAll(); - return $values; - } - - /** - * Return the name and description of available actions - * - * @access public - * @return array - */ - public function getAvailableEvents() - { - $values = array( - TaskLink::EVENT_CREATE_UPDATE => t('Task link creation or modification'), - Task::EVENT_MOVE_COLUMN => t('Move a task to another column'), - Task::EVENT_UPDATE => t('Task modification'), - Task::EVENT_CREATE => t('Task creation'), - Task::EVENT_OPEN => t('Reopen a task'), - Task::EVENT_CLOSE => t('Closing a task'), - Task::EVENT_CREATE_UPDATE => t('Task creation or modification'), - Task::EVENT_ASSIGNEE_CHANGE => t('Task assignee change'), - GithubWebhook::EVENT_COMMIT => t('Github commit received'), - GithubWebhook::EVENT_ISSUE_OPENED => t('Github issue opened'), - GithubWebhook::EVENT_ISSUE_CLOSED => t('Github issue closed'), - GithubWebhook::EVENT_ISSUE_REOPENED => t('Github issue reopened'), - GithubWebhook::EVENT_ISSUE_ASSIGNEE_CHANGE => t('Github issue assignee change'), - GithubWebhook::EVENT_ISSUE_LABEL_CHANGE => t('Github issue label change'), - GithubWebhook::EVENT_ISSUE_COMMENT => t('Github issue comment created'), - GitlabWebhook::EVENT_COMMIT => t('Gitlab commit received'), - GitlabWebhook::EVENT_ISSUE_OPENED => t('Gitlab issue opened'), - GitlabWebhook::EVENT_ISSUE_REOPENED => t('Gitlab issue reopened'), - GitlabWebhook::EVENT_ISSUE_CLOSED => t('Gitlab issue closed'), - GitlabWebhook::EVENT_ISSUE_COMMENT => t('Gitlab issue comment created'), - BitbucketWebhook::EVENT_COMMIT => t('Bitbucket commit received'), - BitbucketWebhook::EVENT_ISSUE_OPENED => t('Bitbucket issue opened'), - BitbucketWebhook::EVENT_ISSUE_CLOSED => t('Bitbucket issue closed'), - BitbucketWebhook::EVENT_ISSUE_REOPENED => t('Bitbucket issue reopened'), - BitbucketWebhook::EVENT_ISSUE_ASSIGNEE_CHANGE => t('Bitbucket issue assignee change'), - BitbucketWebhook::EVENT_ISSUE_COMMENT => t('Bitbucket issue comment created'), - ); - - asort($values); - - return $values; - } - - /** - * Return the name and description of compatible actions - * - * @access public - * @param string $action_name Action name - * @return array - */ - public function getCompatibleEvents($action_name) - { - $action = $this->load($action_name, 0, ''); - $compatible_events = $action->getCompatibleEvents(); - $events = array(); - - foreach ($this->getAvailableEvents() as $event_name => $event_description) { - if (in_array($event_name, $compatible_events)) { - $events[$event_name] = $event_description; + foreach ($actions as &$action) { + $action['params'] = $this->actionParameter->getAll($action['id']); } } - return $events; + return $actions; } /** * Return actions and parameters for a given project * * @access public - * @param $project_id + * @param integer $project_id * @return array */ public function getAllByProject($project_id) @@ -168,7 +55,7 @@ class Action extends Base $actions = $this->db->table(self::TABLE)->eq('project_id', $project_id)->findAll(); foreach ($actions as &$action) { - $action['params'] = $this->db->table(self::TABLE_PARAMS)->eq('action_id', $action['id'])->findAll(); + $action['params'] = $this->actionParameter->getAll($action['id']); } return $actions; @@ -183,52 +70,27 @@ class Action extends Base public function getAll() { $actions = $this->db->table(self::TABLE)->findAll(); - $params = $this->db->table(self::TABLE_PARAMS)->findAll(); foreach ($actions as &$action) { - $action['params'] = array(); - - foreach ($params as $param) { - if ($param['action_id'] === $action['id']) { - $action['params'][] = $param; - } - } + $action['params'] = $this->actionParameter->getAll($action['id']); } return $actions; } - /** - * Get all required action parameters for all registered actions - * - * @access public - * @return array All required parameters for all actions - */ - public function getAllActionParameters() - { - $params = array(); - - foreach ($this->getAll() as $action) { - $action = $this->load($action['action_name'], $action['project_id'], $action['event_name']); - $params += $action->getActionRequiredParameters(); - } - - return $params; - } - /** * Fetch an action * * @access public - * @param integer $action_id Action id - * @return array Action data + * @param integer $action_id + * @return array */ public function getById($action_id) { $action = $this->db->table(self::TABLE)->eq('id', $action_id)->findOne(); if (! empty($action)) { - $action['params'] = $this->db->table(self::TABLE_PARAMS)->eq('action_id', $action_id)->findAll(); + $action['params'] = $this->actionParameter->getAll($action_id); } return $action; @@ -238,8 +100,8 @@ class Action extends Base * Remove an action * * @access public - * @param integer $action_id Action id - * @return bool Success or not + * @param integer $action_id + * @return bool */ public function remove($action_id) { @@ -263,24 +125,16 @@ class Action extends Base 'action_name' => $values['action_name'], ); - if (! $this->db->table(self::TABLE)->save($action)) { + if (! $this->db->table(self::TABLE)->insert($action)) { $this->db->cancelTransaction(); return false; } $action_id = $this->db->getLastId(); - foreach ($values['params'] as $param_name => $param_value) { - $action_param = array( - 'action_id' => $action_id, - 'name' => $param_name, - 'value' => $param_value, - ); - - if (! $this->db->table(self::TABLE_PARAMS)->save($action_param)) { - $this->db->cancelTransaction(); - return false; - } + if (! $this->actionParameter->create($action_id, $values)) { + $this->db->cancelTransaction(); + return false; } $this->db->closeTransaction(); @@ -288,42 +142,6 @@ class Action extends Base return $action_id; } - /** - * Load all actions and attach events - * - * @access public - */ - public function attachEvents() - { - $actions = $this->getAll(); - - foreach ($actions as $action) { - $listener = $this->load($action['action_name'], $action['project_id'], $action['event_name']); - - foreach ($action['params'] as $param) { - $listener->setParam($param['name'], $param['value']); - } - - $this->container['dispatcher']->addListener($action['event_name'], array($listener, 'execute')); - } - } - - /** - * Load an action - * - * @access public - * @param string $name Action class name - * @param integer $project_id Project id - * @param string $event Event name - * @return \Action\Base - */ - public function load($name, $project_id, $event) - { - $className = $name{0} - !== '\\' ? '\Kanboard\Action\\'.$name : $name; - return new $className($this->container, $project_id, $event); - } - /** * Copy actions from a project to another one (skip actions that cannot resolve parameters) * @@ -346,15 +164,14 @@ class Action extends Base ); if (! $this->db->table(self::TABLE)->insert($values)) { - $this->container['logger']->debug('Action::duplicate => unable to create '.$action['action_name']); $this->db->cancelTransaction(); continue; } $action_id = $this->db->getLastId(); - if (! $this->duplicateParameters($dst_project_id, $action_id, $action['params'])) { - $this->container['logger']->debug('Action::duplicate => unable to copy parameters for '.$action['action_name']); + if (! $this->actionParameter->duplicateParameters($dst_project_id, $action_id, $action['params'])) { + $this->logger->error('Action::duplicate => skip action '.$action['action_name'].' '.$action['id']); $this->db->cancelTransaction(); continue; } @@ -365,74 +182,6 @@ class Action extends Base return true; } - /** - * Duplicate action parameters - * - * @access public - * @param integer $project_id - * @param integer $action_id - * @param array $params - * @return boolean - */ - public function duplicateParameters($project_id, $action_id, array $params) - { - foreach ($params as $param) { - $value = $this->resolveParameters($param, $project_id); - - if ($value === false) { - $this->container['logger']->debug('Action::duplicateParameters => unable to resolve '.$param['name'].'='.$param['value']); - return false; - } - - $values = array( - 'action_id' => $action_id, - 'name' => $param['name'], - 'value' => $value, - ); - - if (! $this->db->table(self::TABLE_PARAMS)->insert($values)) { - return false; - } - } - - return true; - } - - /** - * Resolve action parameter values according to another project - * - * @author Antonio Rabelo - * @access public - * @param array $param Action parameter - * @param integer $project_id Project to find the corresponding values - * @return mixed - */ - public function resolveParameters(array $param, $project_id) - { - switch ($param['name']) { - case 'project_id': - return $project_id; - case 'category_id': - return $this->category->getIdByName($project_id, $this->category->getNameById($param['value'])) ?: false; - case 'src_column_id': - case 'dest_column_id': - case 'dst_column_id': - case 'column_id': - $column = $this->board->getColumn($param['value']); - - if (empty($column)) { - return false; - } - - return $this->board->getColumnIdByTitle($project_id, $column['title']) ?: false; - case 'user_id': - case 'owner_id': - return $this->projectPermission->isAssignable($project_id, $param['value']) ? $param['value'] : false; - default: - return $param['value']; - } - } - /** * Validate action creation * diff --git a/app/Model/ActionParameter.php b/app/Model/ActionParameter.php new file mode 100644 index 00000000..f170ef66 --- /dev/null +++ b/app/Model/ActionParameter.php @@ -0,0 +1,122 @@ +db->hashtable(self::TABLE)->eq('action_id', $action_id)->getAll('name', 'value'); + } + + /** + * Insert new parameters for an action + * + * @access public + * @param integer $action_id + * @param array $values + * @return boolean + */ + public function create($action_id, array $values) + { + foreach ($values['params'] as $name => $value) { + $param = array( + 'action_id' => $action_id, + 'name' => $name, + 'value' => $value, + ); + + if (! $this->db->table(self::TABLE)->save($param)) { + return false; + } + } + + return true; + } + + /** + * Duplicate action parameters + * + * @access public + * @param integer $project_id + * @param integer $action_id + * @param array $params + * @return boolean + */ + public function duplicateParameters($project_id, $action_id, array $params) + { + foreach ($params as $name => $value) { + $value = $this->resolveParameter($project_id, $name, $value); + + if ($value === false) { + $this->logger->error('ActionParameter::duplicateParameters => unable to resolve '.$name.'='.$value); + return false; + } + + $values = array( + 'action_id' => $action_id, + 'name' => $name, + 'value' => $value, + ); + + if (! $this->db->table(self::TABLE)->insert($values)) { + return false; + } + } + + return true; + } + + /** + * Resolve action parameter values according to another project + * + * @access private + * @param integer $project_id + * @param string $name + * @param string $value + * @return mixed + */ + private function resolveParameter($project_id, $name, $value) + { + switch ($name) { + case 'project_id': + return $value != $project_id ? $value : false; + case 'category_id': + return $this->category->getIdByName($project_id, $this->category->getNameById($value)) ?: false; + case 'src_column_id': + case 'dest_column_id': + case 'dst_column_id': + case 'column_id': + $column = $this->board->getColumn($value); + return empty($column) ? false : $this->board->getColumnIdByTitle($project_id, $column['title']) ?: false; + case 'user_id': + case 'owner_id': + return $this->projectPermission->isAssignable($project_id, $value) ? $value : false; + default: + return $value; + } + } +} diff --git a/app/Model/Comment.php b/app/Model/Comment.php index 71e964dc..eb83f8d6 100644 --- a/app/Model/Comment.php +++ b/app/Model/Comment.php @@ -75,6 +75,7 @@ class Comment extends Base self::TABLE.'.user_id', self::TABLE.'.date_creation', self::TABLE.'.comment', + self::TABLE.'.reference', User::TABLE.'.username', User::TABLE.'.name' ) diff --git a/app/Model/ProjectUserRole.php b/app/Model/ProjectUserRole.php index b2c38622..6b9c23b0 100644 --- a/app/Model/ProjectUserRole.php +++ b/app/Model/ProjectUserRole.php @@ -52,11 +52,11 @@ class ProjectUserRole extends Base ->getAll(Project::TABLE.'.id', Project::TABLE.'.name'); $groupProjects = $this->projectGroupRole->getProjectsByUser($user_id, $status); - $groups = $userProjects + $groupProjects; + $projects = $userProjects + $groupProjects; - asort($groups); + asort($projects); - return $groups; + return $projects; } /** diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php index 534c3f3a..f430c00b 100644 --- a/app/Schema/Sqlite.php +++ b/app/Schema/Sqlite.php @@ -6,7 +6,30 @@ use Kanboard\Core\Security\Token; use Kanboard\Core\Security\Role; use PDO; -const VERSION = 91; +const VERSION = 92; + +function version_92(PDO $pdo) +{ + $rq = $pdo->prepare('SELECT * FROM actions'); + $rq->execute(); + $rows = $rq->fetchAll(PDO::FETCH_ASSOC) ?: array(); + + $rq = $pdo->prepare('UPDATE actions SET action_name=? WHERE id=?'); + + foreach ($rows as $row) { + if ($row['action_name'] === 'TaskAssignCurrentUser' && $row['event_name'] === 'task.move.column') { + $row['action_name'] = '\Kanboard\Action\TaskAssignCurrentUserColumn'; + } elseif ($row['action_name'] === 'TaskClose' && $row['event_name'] === 'task.move.column') { + $row['action_name'] = '\Kanboard\Action\TaskCloseColumn'; + } elseif ($row['action_name'] === 'TaskLogMoveAnotherColumn') { + $row['action_name'] = '\Kanboard\Action\CommentCreationMoveTaskColumn'; + } elseif ($row['action_name']{0} !== '\\') { + $row['action_name'] = '\Kanboard\Action\\'.$row['action_name']; + } + + $rq->execute(array($row['action_name'], $row['id'])); + } +} function version_91(PDO $pdo) { diff --git a/app/ServiceProvider/ActionProvider.php b/app/ServiceProvider/ActionProvider.php new file mode 100644 index 00000000..0aba29f1 --- /dev/null +++ b/app/ServiceProvider/ActionProvider.php @@ -0,0 +1,78 @@ +register(new CommentCreation($container)); + $container['actionManager']->register(new CommentCreationMoveTaskColumn($container)); + $container['actionManager']->register(new TaskAssignCategoryColor($container)); + $container['actionManager']->register(new TaskAssignCategoryLabel($container)); + $container['actionManager']->register(new TaskAssignCategoryLink($container)); + $container['actionManager']->register(new TaskAssignColorCategory($container)); + $container['actionManager']->register(new TaskAssignColorColumn($container)); + $container['actionManager']->register(new TaskAssignColorLink($container)); + $container['actionManager']->register(new TaskAssignColorUser($container)); + $container['actionManager']->register(new TaskAssignCurrentUser($container)); + $container['actionManager']->register(new TaskAssignCurrentUserColumn($container)); + $container['actionManager']->register(new TaskAssignSpecificUser($container)); + $container['actionManager']->register(new TaskAssignUser($container)); + $container['actionManager']->register(new TaskClose($container)); + $container['actionManager']->register(new TaskCloseColumn($container)); + $container['actionManager']->register(new TaskCreation($container)); + $container['actionManager']->register(new TaskDuplicateAnotherProject($container)); + $container['actionManager']->register(new TaskEmail($container)); + $container['actionManager']->register(new TaskMoveAnotherProject($container)); + $container['actionManager']->register(new TaskMoveColumnAssigned($container)); + $container['actionManager']->register(new TaskMoveColumnCategoryChange($container)); + $container['actionManager']->register(new TaskMoveColumnUnAssigned($container)); + $container['actionManager']->register(new TaskOpen($container)); + $container['actionManager']->register(new TaskUpdateStartDate($container)); + + return $container; + } +} diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php index 559a78c1..57e63746 100644 --- a/app/ServiceProvider/ClassProvider.php +++ b/app/ServiceProvider/ClassProvider.php @@ -17,6 +17,7 @@ class ClassProvider implements ServiceProviderInterface private $classes = array( 'Model' => array( 'Action', + 'ActionParameter', 'Authentication', 'Board', 'Category', @@ -90,6 +91,9 @@ class ClassProvider implements ServiceProviderInterface 'Lexer', 'Template', ), + 'Core\Event' => array( + 'EventManager', + ), 'Core\Http' => array( 'Request', 'Response', diff --git a/app/ServiceProvider/EventDispatcherProvider.php b/app/ServiceProvider/EventDispatcherProvider.php index 17141fd4..6cb302e6 100644 --- a/app/ServiceProvider/EventDispatcherProvider.php +++ b/app/ServiceProvider/EventDispatcherProvider.php @@ -30,9 +30,6 @@ class EventDispatcherProvider implements ServiceProviderInterface $container['dispatcher']->addSubscriber(new TransitionSubscriber($container)); $container['dispatcher']->addSubscriber(new RecurringTaskSubscriber($container)); - // Automatic actions - $container['action']->attachEvents(); - return $container; } } diff --git a/app/Subscriber/BootstrapSubscriber.php b/app/Subscriber/BootstrapSubscriber.php index e399f688..d114bf86 100644 --- a/app/Subscriber/BootstrapSubscriber.php +++ b/app/Subscriber/BootstrapSubscriber.php @@ -3,21 +3,26 @@ namespace Kanboard\Subscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Kanboard\Core\Base; -class BootstrapSubscriber extends \Kanboard\Core\Base implements EventSubscriberInterface +class BootstrapSubscriber extends Base implements EventSubscriberInterface { public static function getSubscribedEvents() { return array( - 'app.bootstrap' => array('setup', 0), + 'app.bootstrap' => 'execute', ); } - public function setup() + public function execute() { $this->config->setupTranslations(); $this->config->setupTimezone(); - $this->sessionStorage->hasSubtaskInProgress = $this->subtask->hasSubtaskInProgress($this->userSession->getId()); + $this->actionManager->attachEvents(); + + if ($this->userSession->isLogged()) { + $this->sessionStorage->hasSubtaskInProgress = $this->subtask->hasSubtaskInProgress($this->userSession->getId()); + } } public function __destruct() diff --git a/app/Template/action/index.php b/app/Template/action/index.php index bf2f7475..8275f080 100644 --- a/app/Template/action/index.php +++ b/app/Template/action/index.php @@ -28,24 +28,24 @@
    - + $param_value): ?>
  • - text->in($param['name'], $available_params) ?> = + text->in($param_name, $available_params[$action['action_name']]) ?> = - text->contains($param['name'], 'column_id')): ?> - text->in($param['value'], $columns_list) ?> - text->contains($param['name'], 'user_id')): ?> - text->in($param['value'], $users_list) ?> - text->contains($param['name'], 'project_id')): ?> - text->in($param['value'], $projects_list) ?> - text->contains($param['name'], 'color_id')): ?> - text->in($param['value'], $colors_list) ?> - text->contains($param['name'], 'category_id')): ?> - text->in($param['value'], $categories_list) ?> - text->contains($param['name'], 'link_id')): ?> - text->in($param['value'], $links_list) ?> + text->contains($param_name, 'column_id')): ?> + text->in($param_value, $columns_list) ?> + text->contains($param_name, 'user_id')): ?> + text->in($param_value, $users_list) ?> + text->contains($param_name, 'project_id')): ?> + text->in($param_value, $projects_list) ?> + text->contains($param_name, 'color_id')): ?> + text->in($param_value, $colors_list) ?> + text->contains($param_name, 'category_id')): ?> + text->in($param_value, $categories_list) ?> + text->contains($param_name, 'link_id')): ?> + text->in($param_value, $links_list) ?> - e($param['value']) ?> + e($param_value) ?>
  • diff --git a/app/common.php b/app/common.php index 91e24c65..fe287811 100644 --- a/app/common.php +++ b/app/common.php @@ -33,4 +33,5 @@ $container->register(new Kanboard\ServiceProvider\ClassProvider); $container->register(new Kanboard\ServiceProvider\EventDispatcherProvider); $container->register(new Kanboard\ServiceProvider\GroupProvider); $container->register(new Kanboard\ServiceProvider\RouteProvider); +$container->register(new Kanboard\ServiceProvider\ActionProvider); $container->register(new Kanboard\ServiceProvider\PluginProvider); diff --git a/doc/api-action-procedures.markdown b/doc/api-action-procedures.markdown index 5dd88f4a..67bd85de 100644 --- a/doc/api-action-procedures.markdown +++ b/doc/api-action-procedures.markdown @@ -25,24 +25,24 @@ Response example: "jsonrpc": "2.0", "id": 1217735483, "result": { - "TaskLogMoveAnotherColumn": "Add a comment logging moving the task between columns", - "TaskAssignColorUser": "Assign a color to a specific user", - "TaskAssignColorColumn": "Assign a color when the task is moved to a specific column", - "TaskAssignCategoryColor": "Assign automatically a category based on a color", - "TaskAssignColorCategory": "Assign automatically a color based on a category", - "TaskAssignSpecificUser": "Assign the task to a specific user", - "TaskAssignCurrentUser": "Assign the task to the person who does the action", - "TaskUpdateStartDate": "Automatically update the start date", - "TaskAssignUser": "Change the assignee based on an external username", - "TaskAssignCategoryLabel": "Change the category based on an external label", - "TaskClose": "Close a task", - "CommentCreation": "Create a comment from an external provider", - "TaskCreation": "Create a task from an external provider", - "TaskDuplicateAnotherProject": "Duplicate the task to another project", - "TaskMoveColumnAssigned": "Move the task to another column when assigned to a user", - "TaskMoveColumnUnAssigned": "Move the task to another column when assignee is cleared", - "TaskMoveAnotherProject": "Move the task to another project", - "TaskOpen": "Open a task" + "\Kanboard\Action\TaskLogMoveAnotherColumn": "Add a comment logging moving the task between columns", + "\Kanboard\Action\TaskAssignColorUser": "Assign a color to a specific user", + "\Kanboard\Action\TaskAssignColorColumn": "Assign a color when the task is moved to a specific column", + "\Kanboard\Action\TaskAssignCategoryColor": "Assign automatically a category based on a color", + "\Kanboard\Action\TaskAssignColorCategory": "Assign automatically a color based on a category", + "\Kanboard\Action\TaskAssignSpecificUser": "Assign the task to a specific user", + "\Kanboard\Action\TaskAssignCurrentUser": "Assign the task to the person who does the action", + "\Kanboard\Action\TaskUpdateStartDate": "Automatically update the start date", + "\Kanboard\Action\TaskAssignUser": "Change the assignee based on an external username", + "\Kanboard\Action\TaskAssignCategoryLabel": "Change the category based on an external label", + "\Kanboard\Action\TaskClose": "Close a task", + "\Kanboard\Action\CommentCreation": "Create a comment from an external provider", + "\Kanboard\Action\TaskCreation": "Create a task from an external provider", + "\Kanboard\Action\TaskDuplicateAnotherProject": "Duplicate the task to another project", + "\Kanboard\Action\TaskMoveColumnAssigned": "Move the task to another column when assigned to a user", + "\Kanboard\Action\TaskMoveColumnUnAssigned": "Move the task to another column when assignee is cleared", + "\Kanboard\Action\TaskMoveAnotherProject": "Move the task to another project", + "\Kanboard\Action\TaskOpen": "Open a task" } } ``` @@ -109,7 +109,7 @@ Request example: "method": "getCompatibleActionEvents", "id": 899370297, "params": [ - "TaskClose" + "\Kanboard\Action\TaskClose" ] } ``` @@ -163,7 +163,7 @@ Response example: "id" : "13", "project_id" : "2", "event_name" : "task.move.column", - "action_name" : "TaskAssignSpecificUser", + "action_name" : "\Kanboard\Action\TaskAssignSpecificUser", "params" : { "column_id" : "5", "user_id" : "1" @@ -194,7 +194,7 @@ Request example: "params": { "project_id" : "2", "event_name" : "task.move.column", - "action_name" : "TaskAssignSpecificUser", + "action_name" : "\Kanboard\Action\TaskAssignSpecificUser", "params" : { "column_id" : "3", "user_id" : "2" diff --git a/doc/automatic-actions.markdown b/doc/automatic-actions.markdown index 69352d12..db56ccc0 100644 --- a/doc/automatic-actions.markdown +++ b/doc/automatic-actions.markdown @@ -26,59 +26,33 @@ Add a new action ![Define parameters](http://kanboard.net/screenshots/documentation/project-automatic-action-step3.png) -List of available events ------------------------- - -- Move a task to another column -- Move a task to another position in the same column -- Task modification -- Task creation -- Reopen a task -- Closing a task -- Task creation or modification -- Task assignee change -- Task link created or updated -- Github commit received -- Github issue opened -- Github issue closed -- Github issue reopened -- Github issue assignee change -- Github issue label change -- Github issue comment created -- Gitlab issue opened -- Gitlab issue closed -- Gitlab commit received -- Bitbucket commit received -- Bitbucket issue opened -- Bitbucket issue closed -- Bitbucket issue reopened -- Bitbucket issue assignee change -- Bitbucket issue comment created - List of available actions ------------------------- -- Close the task -- Open a task -- Assign the task to a specific user +- Create a comment from an external provider +- Add a comment log when moving the task between columns +- Assign automatically a category based on a color +- Change the category based on an external label +- Assign automatically a category based on a link +- Assign automatically a color based on a category +- Assign a color when the task is moved to a specific column +- Change task color when using a specific task link +- Assign a color to a specific user - Assign the task to the person who does the action +- Assign the task to the person who does the action when the column is changed +- Assign the task to a specific user +- Change the assignee based on an external username +- Close the task +- Close a task in a specific column +- Create a task from an external provider - Duplicate the task to another project +- Send a task by email to someone - Move the task to another project - Move the task to another column when assigned to a user +- Move the task to another column when the category is changed - Move the task to another column when assignee is cleared -- Assign color when the task is moved to a specific column -- Assign color to a specific user -- Assign automatically a color based on a category -- Assign automatically a category based on a color -- Create a comment from an external provider -- Create a task from an external provider -- Add a comment log when moving the task between columns -- Change the assignee based on an external username -- Change the category based on an external label +- Open a task - Automatically update the start date -- Move the task to another column when the category is changed -- Send a task by email to someone -- Change task color when using a specific task link Examples -------- @@ -87,7 +61,7 @@ Here are some examples used in real life: ### When I move a task to the column "Done", automatically close this task -- Choose action: **Close the task** +- Choose action: **Close a task in a specific column** - Choose the event: **Move a task to another column** - Define action parameter: **Column = Done** (this is the destination column) @@ -99,7 +73,7 @@ Here are some examples used in real life: ### When I move a task to the column "Work in progress", assign this task to the current user -- Choose action: **Assign the task to the person who does the action** +- Choose action: **Assign the task to the person who does the action when the column is changed** - Choose the event: **Move a task to another column** - Define action parameter: **Column = Work in progress** diff --git a/doc/plugin-registration.markdown b/doc/plugin-registration.markdown index 746fa200..37e71f9a 100644 --- a/doc/plugin-registration.markdown +++ b/doc/plugin-registration.markdown @@ -138,40 +138,3 @@ $this->on('app.bootstrap', function($container) { - The first argument is the event name - The second argument is a PHP callable function (closure or class method) - -Extend Automatic Actions ------------------------- - -To define a new automatic action with a plugin, you just need to call the method `extendActions()` from the class `Kanboard\Model\Action`, here an example: - -```php -action->extendActions( - '\Kanboard\Plugin\AutomaticAction\Action\DoSomething', // Use absolute namespace - t('Do something when the task color change') - ); - } -} -``` - -- The first argument of the method `extendActions()` is the action class with the complete namespace path. **The namespace path must starts with a backslash** otherwise Kanboard will not be able to load your class. -- The second argument is the description of your automatic action. - -The automatic action class must inherit from the class `Kanboard\Action\Base` and implements all abstract methods: - -- `getCompatibleEvents()` -- `getActionRequiredParameters()` -- `getEventRequiredParameters()` -- `doAction(array $data)` -- `hasRequiredCondition(array $data)` - -For more details you should take a look to existing automatic actions or this [plugin example](https://github.com/kanboard/plugin-example-automatic-action). diff --git a/tests/functionals/ApiTest.php b/tests/functionals/ApiTest.php index fbb703c9..79d87bd6 100644 --- a/tests/functionals/ApiTest.php +++ b/tests/functionals/ApiTest.php @@ -875,7 +875,7 @@ class Api extends PHPUnit_Framework_TestCase $actions = $this->client->getAvailableActions(); $this->assertNotEmpty($actions); $this->assertInternalType('array', $actions); - $this->assertArrayHasKey('TaskLogMoveAnotherColumn', $actions); + $this->assertArrayHasKey('\Kanboard\Action\TaskClose', $actions); } public function testGetAvailableActionEvents() @@ -888,7 +888,7 @@ class Api extends PHPUnit_Framework_TestCase public function testGetCompatibleActionEvents() { - $events = $this->client->getCompatibleActionEvents('TaskClose'); + $events = $this->client->getCompatibleActionEvents('\Kanboard\Action\TaskCloseColumn'); $this->assertNotEmpty($events); $this->assertInternalType('array', $events); $this->assertArrayHasKey('task.move.column', $events); @@ -896,7 +896,7 @@ class Api extends PHPUnit_Framework_TestCase public function testCreateAction() { - $action_id = $this->client->createAction(1, 'task.move.column', 'TaskClose', array('column_id' => 1)); + $action_id = $this->client->createAction(1, 'task.move.column', '\Kanboard\Action\TaskCloseColumn', array('column_id' => 1)); $this->assertNotFalse($action_id); $this->assertEquals(1, $action_id); } diff --git a/tests/units/Action/BaseActionTest.php b/tests/units/Action/BaseActionTest.php new file mode 100644 index 00000000..1d50c70e --- /dev/null +++ b/tests/units/Action/BaseActionTest.php @@ -0,0 +1,144 @@ + 'Param 1'); + } + + public function getEventRequiredParameters() + { + return array('p1', 'p2'); + } + + public function doAction(array $data) + { + return true; + } + + public function hasRequiredCondition(array $data) + { + return $data['p1'] == $this->getParam('p1'); + } +} + +class BaseActionTest extends Base +{ + public function testGetName() + { + $dummyAction = new DummyAction($this->container); + $this->assertEquals('\\DummyAction', $dummyAction->getName()); + } + + public function testGetDescription() + { + $dummyAction = new DummyAction($this->container); + $this->assertEquals('Dummy Action', $dummyAction->getDescription()); + } + + public function testGetActionRequiredParameters() + { + $dummyAction = new DummyAction($this->container); + $this->assertEquals(array('p1' => 'Param 1'), $dummyAction->getActionRequiredParameters()); + } + + public function testGetEventRequiredParameters() + { + $dummyAction = new DummyAction($this->container); + $this->assertEquals(array('p1', 'p2'), $dummyAction->getEventRequiredParameters()); + } + + public function testGetCompatibleEvents() + { + $dummyAction = new DummyAction($this->container); + $this->assertEquals(array('my.event'), $dummyAction->getCompatibleEvents()); + } + + public function testHasRequiredCondition() + { + $dummyAction = new DummyAction($this->container); + $dummyAction->setParam('p1', 123); + $this->assertTrue($dummyAction->hasRequiredCondition(array('p1' => 123))); + $this->assertFalse($dummyAction->hasRequiredCondition(array('p1' => 456))); + } + + public function testProjectId() + { + $dummyAction = new DummyAction($this->container); + $this->assertInstanceOf('DummyAction', $dummyAction->setProjectId(123)); + $this->assertEquals(123, $dummyAction->getProjectId()); + } + + public function testParam() + { + $dummyAction = new DummyAction($this->container); + $this->assertInstanceOf('DummyAction', $dummyAction->setParam('p1', 123)); + $this->assertEquals(123, $dummyAction->getParam('p1')); + } + + public function testHasCompatibleEvents() + { + $dummyAction = new DummyAction($this->container); + $this->assertTrue($dummyAction->hasCompatibleEvent('my.event')); + $this->assertFalse($dummyAction->hasCompatibleEvent('foobar')); + } + + public function testHasRequiredProject() + { + $dummyAction = new DummyAction($this->container); + $dummyAction->setProjectId(1234); + + $this->assertTrue($dummyAction->hasRequiredProject(array('project_id' => 1234))); + $this->assertFalse($dummyAction->hasRequiredProject(array('project_id' => 1))); + $this->assertFalse($dummyAction->hasRequiredProject(array())); + } + + public function testHasRequiredParameters() + { + $dummyAction = new DummyAction($this->container); + $dummyAction->setProjectId(1234); + + $this->assertTrue($dummyAction->hasRequiredParameters(array('p1' => 12, 'p2' => 34))); + $this->assertFalse($dummyAction->hasRequiredParameters(array('p1' => 12))); + $this->assertFalse($dummyAction->hasRequiredParameters(array())); + } + + public function testAddEvent() + { + $dummyAction = new DummyAction($this->container); + $dummyAction->addEvent('foobar', 'FooBar'); + $dummyAction->addEvent('my.event', 'My Event Overrided'); + + $events = $dummyAction->getEvents(); + $this->assertcount(2, $events); + $this->assertEquals(array('my.event', 'foobar'), $events); + } + + public function testExecuteOnlyOnce() + { + $dummyAction = new DummyAction($this->container); + $dummyAction->setProjectId(1234); + $dummyAction->setParam('p1', 'something'); + $dummyAction->addEvent('foobar', 'FooBar'); + + $event = new GenericEvent(array('project_id' => 1234, 'p1' => 'something', 'p2' => 'abc')); + + $this->assertTrue($dummyAction->execute($event, 'foobar')); + $this->assertFalse($dummyAction->execute($event, 'foobar')); + } +} diff --git a/tests/units/Action/CommentCreationMoveTaskColumnTest.php b/tests/units/Action/CommentCreationMoveTaskColumnTest.php new file mode 100644 index 00000000..87ee86ea --- /dev/null +++ b/tests/units/Action/CommentCreationMoveTaskColumnTest.php @@ -0,0 +1,58 @@ +container['sessionStorage']->user = array('id' => 1); + + $projectModel = new Project($this->container); + $commentModel = new Comment($this->container); + $taskCreationModel = new TaskCreation($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 2)); + + $action = new CommentCreationMoveTaskColumn($this->container); + $action->setProjectId(1); + $action->setParam('column_id', 2); + + $this->assertTrue($action->execute($event, Task::EVENT_MOVE_COLUMN)); + + $comment = $commentModel->getById(1); + $this->assertNotEmpty($comment); + $this->assertEquals(1, $comment['task_id']); + $this->assertEquals(1, $comment['user_id']); + $this->assertEquals('Moved to column Ready', $comment['comment']); + } + + public function testWithUserNotLogged() + { + $projectModel = new Project($this->container); + $commentModel = new Comment($this->container); + $taskCreationModel = new TaskCreation($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 3)); + + $action = new CommentCreationMoveTaskColumn($this->container); + $action->setProjectId(1); + $action->setParam('column_id', 2); + + $this->assertFalse($action->execute($event, Task::EVENT_MOVE_COLUMN)); + } +} diff --git a/tests/units/Action/CommentCreationTest.php b/tests/units/Action/CommentCreationTest.php index 8a689309..8460a350 100644 --- a/tests/units/Action/CommentCreationTest.php +++ b/tests/units/Action/CommentCreationTest.php @@ -7,119 +7,88 @@ use Kanboard\Model\Task; use Kanboard\Model\TaskCreation; use Kanboard\Model\Comment; use Kanboard\Model\Project; -use Kanboard\Integration\GithubWebhook; +use Kanboard\Model\ProjectUserRole; +use Kanboard\Model\User; use Kanboard\Action\CommentCreation; +use Kanboard\Core\Security\Role; class CommentCreationTest extends Base { - public function testWithoutRequiredParams() + public function testSuccess() { - $action = new CommentCreation($this->container, 1, GithubWebhook::EVENT_ISSUE_COMMENT); - - // We create a task in the first column - $tc = new TaskCreation($this->container); - $p = new Project($this->container); - $c = new Comment($this->container); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); - - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'user_id' => 1, - ); - - // Our event should be executed - $this->assertFalse($action->execute(new GenericEvent($event))); - - $comment = $c->getById(1); - $this->assertEmpty($comment); - } + $userModel = new User($this->container); + $projectModel = new Project($this->container); + $projectUserRoleModel = new ProjectUserRole($this->container); + $commentModel = new Comment($this->container); + $taskCreationModel = new TaskCreation($this->container); - public function testWithCommitMessage() - { - $action = new CommentCreation($this->container, 1, GithubWebhook::EVENT_ISSUE_COMMENT); - - // We create a task in the first column - $tc = new TaskCreation($this->container); - $p = new Project($this->container); - $c = new Comment($this->container); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); - - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'commit_comment' => 'plop', - ); - - // Our event should be executed - $this->assertTrue($action->execute(new GenericEvent($event))); - - $comment = $c->getById(1); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + $this->assertEquals(2, $userModel->create(array('username' => 'user1'))); + $this->assertTrue($projectUserRoleModel->addUser(1, 2, Role::PROJECT_MEMBER)); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'comment' => 'test123', 'reference' => 'ref123', 'user_id' => 2)); + + $action = new CommentCreation($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); + + $this->assertTrue($action->execute($event, 'test.event')); + + $comment = $commentModel->getById(1); $this->assertNotEmpty($comment); $this->assertEquals(1, $comment['task_id']); - $this->assertEquals(0, $comment['user_id']); - $this->assertEquals('plop', $comment['comment']); + $this->assertEquals('test123', $comment['comment']); + $this->assertEquals('ref123', $comment['reference']); + $this->assertEquals(2, $comment['user_id']); } - public function testWithUser() + public function testWithUserNotAssignable() { - $action = new CommentCreation($this->container, 1, GithubWebhook::EVENT_ISSUE_COMMENT); - - // We create a task in the first column - $tc = new TaskCreation($this->container); - $p = new Project($this->container); - $c = new Comment($this->container); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); - - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'user_id' => 1, - 'comment' => 'youpi', - ); - - // Our event should be executed - $this->assertTrue($action->execute(new GenericEvent($event))); - - $comment = $c->getById(1); + $userModel = new User($this->container); + $projectModel = new Project($this->container); + $projectUserRoleModel = new ProjectUserRole($this->container); + $commentModel = new Comment($this->container); + $taskCreationModel = new TaskCreation($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + $this->assertEquals(2, $userModel->create(array('username' => 'user1'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'comment' => 'test123', 'user_id' => 2)); + + $action = new CommentCreation($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); + + $this->assertTrue($action->execute($event, 'test.event')); + + $comment = $commentModel->getById(1); $this->assertNotEmpty($comment); $this->assertEquals(1, $comment['task_id']); - $this->assertEquals(1, $comment['user_id']); - $this->assertEquals('youpi', $comment['comment']); + $this->assertEquals('test123', $comment['comment']); + $this->assertEquals('', $comment['reference']); + $this->assertEquals(0, $comment['user_id']); } - public function testWithNoUser() + public function testWithNoComment() { - $action = new CommentCreation($this->container, 1, GithubWebhook::EVENT_ISSUE_COMMENT); - - // We create a task in the first column - $tc = new TaskCreation($this->container); - $p = new Project($this->container); - $c = new Comment($this->container); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); - - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'user_id' => 0, - 'comment' => 'youpi', - ); - - // Our event should be executed - $this->assertTrue($action->execute(new GenericEvent($event))); - - $comment = $c->getById(1); - $this->assertNotEmpty($comment); - $this->assertEquals(1, $comment['task_id']); - $this->assertEquals(0, $comment['user_id']); - $this->assertEquals('youpi', $comment['comment']); + $userModel = new User($this->container); + $projectModel = new Project($this->container); + $projectUserRoleModel = new ProjectUserRole($this->container); + $commentModel = new Comment($this->container); + $taskCreationModel = new TaskCreation($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + $this->assertEquals(2, $userModel->create(array('username' => 'user1'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1)); + + $action = new CommentCreation($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); + + $this->assertFalse($action->execute($event, 'test.event')); } } diff --git a/tests/units/Action/TaskAssignCategoryColorTest.php b/tests/units/Action/TaskAssignCategoryColorTest.php new file mode 100644 index 00000000..bd8181e8 --- /dev/null +++ b/tests/units/Action/TaskAssignCategoryColorTest.php @@ -0,0 +1,60 @@ +container); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + $this->assertEquals(1, $categoryModel->create(array('name' => 'c1', 'project_id' => 1))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'color_id' => 'red')); + + $action = new TaskAssignCategoryColor($this->container); + $action->setProjectId(1); + $action->setParam('color_id', 'red'); + $action->setParam('category_id', 1); + + $this->assertTrue($action->execute($event, Task::EVENT_CREATE_UPDATE)); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals(1, $task['category_id']); + } + + public function testWithWrongColor() + { + $categoryModel = new Category($this->container); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + $this->assertEquals(1, $categoryModel->create(array('name' => 'c1', 'project_id' => 1))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'color_id' => 'blue')); + + $action = new TaskAssignCategoryColor($this->container); + $action->setProjectId(1); + $action->setParam('color_id', 'red'); + $action->setParam('category_id', 1); + + $this->assertFalse($action->execute($event, Task::EVENT_CREATE_UPDATE)); + } +} diff --git a/tests/units/Action/TaskAssignCategoryLabelTest.php b/tests/units/Action/TaskAssignCategoryLabelTest.php new file mode 100644 index 00000000..bf8bdb5b --- /dev/null +++ b/tests/units/Action/TaskAssignCategoryLabelTest.php @@ -0,0 +1,85 @@ +container); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + $this->assertEquals(1, $categoryModel->create(array('name' => 'c1', 'project_id' => 1))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'label' => 'foobar')); + + $action = new TaskAssignCategoryLabel($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); + $action->setParam('label', 'foobar'); + $action->setParam('category_id', 1); + + $this->assertTrue($action->execute($event, 'test.event')); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals(1, $task['category_id']); + } + + public function testWithWrongLabel() + { + $categoryModel = new Category($this->container); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + $this->assertEquals(1, $categoryModel->create(array('name' => 'c1', 'project_id' => 1))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'label' => 'something')); + + $action = new TaskAssignCategoryLabel($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); + $action->setParam('label', 'foobar'); + $action->setParam('category_id', 1); + + $this->assertFalse($action->execute($event, 'test.event')); + } + + public function testWithExistingCategory() + { + $categoryModel = new Category($this->container); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $categoryModel->create(array('name' => 'c1', 'project_id' => 1))); + $this->assertEquals(2, $categoryModel->create(array('name' => 'c2', 'project_id' => 1))); + + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test', 'category_id' => 2))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'label' => 'foobar', 'category_id' => 2)); + + $action = new TaskAssignCategoryLabel($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); + $action->setParam('label', 'foobar'); + $action->setParam('category_id', 1); + + $this->assertFalse($action->execute($event, 'test.event')); + } +} diff --git a/tests/units/Action/TaskAssignCategoryLinkTest.php b/tests/units/Action/TaskAssignCategoryLinkTest.php index 4f2d757e..f638e017 100644 --- a/tests/units/Action/TaskAssignCategoryLinkTest.php +++ b/tests/units/Action/TaskAssignCategoryLinkTest.php @@ -20,7 +20,8 @@ class TaskAssignCategoryLinkTest extends Base $p = new Project($this->container); $c = new Category($this->container); - $action = new TaskAssignCategoryLink($this->container, 1, TaskLink::EVENT_CREATE_UPDATE); + $action = new TaskAssignCategoryLink($this->container); + $action->setProjectId(1); $action->setParam('category_id', 1); $action->setParam('link_id', 2); @@ -28,30 +29,28 @@ class TaskAssignCategoryLinkTest extends Base $this->assertEquals(1, $c->create(array('name' => 'C1', 'project_id' => 1))); $this->assertEquals(1, $tc->create(array('title' => 'T1', 'project_id' => 1))); - $task = $tf->getById(1); - $this->assertEquals(0, $task['category_id']); - - $event = array( + $event = new TaskLinkEvent(array( 'project_id' => 1, 'task_id' => 1, 'opposite_task_id' => 2, 'link_id' => 2, - ); + )); - $this->assertTrue($action->execute(new TaskLinkEvent($event))); + $this->assertTrue($action->execute($event, TaskLink::EVENT_CREATE_UPDATE)); $task = $tf->getById(1); $this->assertEquals(1, $task['category_id']); } - public function testThatLinkDontMatch() + public function testWhenLinkDontMatch() { $tc = new TaskCreation($this->container); $tf = new TaskFinder($this->container); $p = new Project($this->container); $c = new Category($this->container); - $action = new TaskAssignCategoryLink($this->container, 1, TaskLink::EVENT_CREATE_UPDATE); + $action = new TaskAssignCategoryLink($this->container); + $action->setProjectId(1); $action->setParam('category_id', 1); $action->setParam('link_id', 1); @@ -59,14 +58,14 @@ class TaskAssignCategoryLinkTest extends Base $this->assertEquals(1, $c->create(array('name' => 'C1', 'project_id' => 1))); $this->assertEquals(1, $tc->create(array('title' => 'T1', 'project_id' => 1))); - $event = array( + $event = new TaskLinkEvent(array( 'project_id' => 1, 'task_id' => 1, 'opposite_task_id' => 2, 'link_id' => 2, - ); + )); - $this->assertFalse($action->execute(new TaskLinkEvent($event))); + $this->assertFalse($action->execute($event, TaskLink::EVENT_CREATE_UPDATE)); } public function testThatExistingCategoryWillNotChange() @@ -76,7 +75,8 @@ class TaskAssignCategoryLinkTest extends Base $p = new Project($this->container); $c = new Category($this->container); - $action = new TaskAssignCategoryLink($this->container, 1, TaskLink::EVENT_CREATE_UPDATE); + $action = new TaskAssignCategoryLink($this->container); + $action->setProjectId(1); $action->setParam('category_id', 2); $action->setParam('link_id', 2); @@ -85,13 +85,13 @@ class TaskAssignCategoryLinkTest extends Base $this->assertEquals(2, $c->create(array('name' => 'C2', 'project_id' => 1))); $this->assertEquals(1, $tc->create(array('title' => 'T1', 'project_id' => 1, 'category_id' => 1))); - $event = array( + $event = new TaskLinkEvent(array( 'project_id' => 1, 'task_id' => 1, 'opposite_task_id' => 2, 'link_id' => 2, - ); + )); - $this->assertFalse($action->execute(new TaskLinkEvent($event))); + $this->assertFalse($action->execute($event, TaskLink::EVENT_CREATE_UPDATE)); } } diff --git a/tests/units/Action/TaskAssignColorCategoryTest.php b/tests/units/Action/TaskAssignColorCategoryTest.php index 1bd3493b..9f188645 100644 --- a/tests/units/Action/TaskAssignColorCategoryTest.php +++ b/tests/units/Action/TaskAssignColorCategoryTest.php @@ -2,80 +2,58 @@ require_once __DIR__.'/../Base.php'; -use Kanboard\Model\Task; +use Kanboard\Event\GenericEvent; +use Kanboard\Model\Category; use Kanboard\Model\TaskCreation; use Kanboard\Model\TaskFinder; use Kanboard\Model\Project; -use Kanboard\Model\Category; -use Kanboard\Event\GenericEvent; +use Kanboard\Model\Task; use Kanboard\Action\TaskAssignColorCategory; class TaskAssignColorCategoryTest extends Base { - public function testBadProject() + public function testChangeColor() { - $action = new TaskAssignColorCategory($this->container, 3, Task::EVENT_CREATE_UPDATE); + $categoryModel = new Category($this->container); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); - $event = array( - 'project_id' => 2, - 'task_id' => 3, - 'column_id' => 5, - ); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + $this->assertEquals(1, $categoryModel->create(array('name' => 'c1', 'project_id' => 1))); - $this->assertFalse($action->isExecutable($event)); - $this->assertFalse($action->execute(new GenericEvent($event))); - } + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'category_id' => 1)); - public function testExecute() - { - $action = new TaskAssignColorCategory($this->container, 1, Task::EVENT_CREATE_UPDATE); + $action = new TaskAssignColorCategory($this->container); + $action->setProjectId(1); + $action->setParam('color_id', 'red'); $action->setParam('category_id', 1); - $action->setParam('color_id', 'blue'); - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); - $c = new Category($this->container); + $this->assertTrue($action->execute($event, Task::EVENT_CREATE_UPDATE)); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $c->create(array('name' => 'c1', 'project_id' => 1))); - $this->assertEquals(2, $c->create(array('name' => 'c2', 'project_id' => 1))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1, 'color_id' => 'green', 'category_id' => 2))); + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals('red', $task['color_id']); + } - // We create an event but we don't do anything - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 1, - 'category_id' => 2, - 'position' => 2, - ); + public function testWithWrongCategory() + { + $categoryModel = new Category($this->container); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); - // Our event should NOT be executed - $this->assertFalse($action->execute(new GenericEvent($event))); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - // Our task should be assigned to the ategory_id=1 and have the green color - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(2, $task['category_id']); - $this->assertEquals('green', $task['color_id']); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'category_id' => 2)); - // We create an event to move the task - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 1, - 'position' => 5, - 'category_id' => 1, - ); - - // Our event should be executed - $this->assertTrue($action->execute(new GenericEvent($event))); + $action = new TaskAssignColorCategory($this->container); + $action->setProjectId(1); + $action->setParam('color_id', 'red'); + $action->setParam('category_id', 1); - // Our task should have the blue color - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals('blue', $task['color_id']); + $this->assertFalse($action->execute($event, Task::EVENT_CREATE_UPDATE)); } } diff --git a/tests/units/Action/TaskAssignColorColumnTest.php b/tests/units/Action/TaskAssignColorColumnTest.php index c09dc96e..e5858b19 100644 --- a/tests/units/Action/TaskAssignColorColumnTest.php +++ b/tests/units/Action/TaskAssignColorColumnTest.php @@ -3,40 +3,53 @@ require_once __DIR__.'/../Base.php'; use Kanboard\Event\GenericEvent; -use Kanboard\Model\Task; use Kanboard\Model\TaskCreation; use Kanboard\Model\TaskFinder; use Kanboard\Model\Project; +use Kanboard\Model\Task; use Kanboard\Action\TaskAssignColorColumn; class TaskAssignColorColumnTest extends Base { - public function testColorChange() + public function testChangeColumn() { - $action = new TaskAssignColorColumn($this->container, 1, Task::EVENT_MOVE_COLUMN); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 2)); + + $action = new TaskAssignColorColumn($this->container); + $action->setProjectId(1); + $action->setParam('color_id', 'red'); $action->setParam('column_id', 2); - $action->setParam('color_id', 'green'); - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); + $this->assertTrue($action->execute($event, Task::EVENT_MOVE_COLUMN)); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1, 'color_id' => 'yellow'))); + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals('red', $task['color_id']); + } + + public function testWithWrongCategory() + { + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 2, - 'color_id' => 'green', - ); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - // Our event should be executed - $this->assertTrue($action->execute(new GenericEvent($event))); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 3)); + + $action = new TaskAssignColorColumn($this->container); + $action->setProjectId(1); + $action->setParam('color_id', 'red'); + $action->setParam('column_id', 2); - // Our task should have color green - $task = $tf->getById(1); - $this->assertEquals('green', $task['color_id']); + $this->assertFalse($action->execute($event, Task::EVENT_MOVE_COLUMN)); } } diff --git a/tests/units/Action/TaskAssignColorLinkTest.php b/tests/units/Action/TaskAssignColorLinkTest.php index 36a831dd..d89c8b06 100644 --- a/tests/units/Action/TaskAssignColorLinkTest.php +++ b/tests/units/Action/TaskAssignColorLinkTest.php @@ -2,47 +2,54 @@ require_once __DIR__.'/../Base.php'; -use Kanboard\Event\TaskLinkEvent; -use Kanboard\Model\Task; +use Kanboard\Event\GenericEvent; use Kanboard\Model\TaskCreation; use Kanboard\Model\TaskFinder; -use Kanboard\Model\TaskLink; use Kanboard\Model\Project; +use Kanboard\Model\TaskLink; use Kanboard\Action\TaskAssignColorLink; class TaskAssignColorLinkTest extends Base { - public function testExecute() + public function testChangeColor() { - $action = new TaskAssignColorLink($this->container, 1, TaskLink::EVENT_CREATE_UPDATE); - $action->setParam('link_id', 2); - $action->setParam('color_id', 'green'); - - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $tl = new TaskLink($this->container); - $p = new Project($this->container); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1))); - - // The color should be yellow - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals('yellow', $task['color_id']); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'link_id' => 2, - ); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - // Our event should be executed - $this->assertTrue($action->execute(new TaskLinkEvent($event))); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'link_id' => 1)); - // The color should be green - $task = $tf->getById(1); + $action = new TaskAssignColorLink($this->container); + $action->setProjectId(1); + $action->setParam('color_id', 'red'); + $action->setParam('link_id', 1); + + $this->assertTrue($action->execute($event, TaskLink::EVENT_CREATE_UPDATE)); + + $task = $taskFinderModel->getById(1); $this->assertNotEmpty($task); - $this->assertEquals('green', $task['color_id']); + $this->assertEquals('red', $task['color_id']); + } + + public function testWithWrongLink() + { + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'link_id' => 2)); + + $action = new TaskAssignColorLink($this->container); + $action->setProjectId(1); + $action->setParam('color_id', 'red'); + $action->setParam('link_id', 1); + + $this->assertFalse($action->execute($event, TaskLink::EVENT_CREATE_UPDATE)); } } diff --git a/tests/units/Action/TaskAssignColorUserTest.php b/tests/units/Action/TaskAssignColorUserTest.php index ea2a8f38..e2656cc0 100644 --- a/tests/units/Action/TaskAssignColorUserTest.php +++ b/tests/units/Action/TaskAssignColorUserTest.php @@ -2,72 +2,54 @@ require_once __DIR__.'/../Base.php'; -use Kanboard\Model\Task; +use Kanboard\Event\GenericEvent; use Kanboard\Model\TaskCreation; use Kanboard\Model\TaskFinder; use Kanboard\Model\Project; -use Kanboard\Event\GenericEvent; +use Kanboard\Model\Task; use Kanboard\Action\TaskAssignColorUser; class TaskAssignColorUserTest extends Base { - public function testBadProject() + public function testChangeColor() { - $action = new TaskAssignColorUser($this->container, 3, Task::EVENT_CREATE); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); - $event = array( - 'project_id' => 2, - 'task_id' => 3, - 'column_id' => 5, - ); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - $this->assertFalse($action->isExecutable($event)); - $this->assertFalse($action->execute(new GenericEvent($event))); - } + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'owner_id' => 1)); - public function testExecute() - { - $action = new TaskAssignColorUser($this->container, 1, Task::EVENT_ASSIGNEE_CHANGE); + $action = new TaskAssignColorUser($this->container); + $action->setProjectId(1); + $action->setParam('color_id', 'red'); $action->setParam('user_id', 1); - $action->setParam('color_id', 'blue'); - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1, 'color_id' => 'green'))); + $this->assertTrue($action->execute($event, Task::EVENT_ASSIGNEE_CHANGE)); - // We change the assignee - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'owner_id' => 5, - ); + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals('red', $task['color_id']); + } - // Our event should NOT be executed - $this->assertFalse($action->execute(new GenericEvent($event))); + public function testWithWrongUser() + { + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); - // Our task should be assigned to nobody and have the green color - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(0, $task['owner_id']); - $this->assertEquals('green', $task['color_id']); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - // We change the assignee - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'owner_id' => 1, - ); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'owner_id' => 2)); - // Our event should be executed - $this->assertTrue($action->execute(new GenericEvent($event))); + $action = new TaskAssignColorUser($this->container); + $action->setProjectId(1); + $action->setParam('color_id', 'red'); + $action->setParam('user_id', 1); - // Our task should be assigned to nobody and have the blue color - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(0, $task['owner_id']); - $this->assertEquals('blue', $task['color_id']); + $this->assertFalse($action->execute($event, Task::EVENT_ASSIGNEE_CHANGE)); } } diff --git a/tests/units/Action/TaskAssignCurrentUserColumnTest.php b/tests/units/Action/TaskAssignCurrentUserColumnTest.php new file mode 100644 index 00000000..41576ee4 --- /dev/null +++ b/tests/units/Action/TaskAssignCurrentUserColumnTest.php @@ -0,0 +1,75 @@ +container['sessionStorage']->user = array('id' => 1); + + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 2)); + + $action = new TaskAssignCurrentUserColumn($this->container); + $action->setProjectId(1); + $action->setParam('column_id', 2); + + $this->assertTrue($action->execute($event, Task::EVENT_MOVE_COLUMN)); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals(1, $task['owner_id']); + } + + public function testWithWrongColumn() + { + $this->container['sessionStorage']->user = array('id' => 1); + + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 3)); + + $action = new TaskAssignCurrentUserColumn($this->container); + $action->setProjectId(1); + $action->setParam('column_id', 2); + + $this->assertFalse($action->execute($event, Task::EVENT_MOVE_COLUMN)); + } + + public function testWithNoUserSession() + { + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 2)); + + $action = new TaskAssignCurrentUserColumn($this->container); + $action->setProjectId(1); + $action->setParam('column_id', 2); + + $this->assertFalse($action->execute($event, Task::EVENT_MOVE_COLUMN)); + } +} diff --git a/tests/units/Action/TaskAssignCurrentUserTest.php b/tests/units/Action/TaskAssignCurrentUserTest.php index e2d1c11a..2fe84a5d 100644 --- a/tests/units/Action/TaskAssignCurrentUserTest.php +++ b/tests/units/Action/TaskAssignCurrentUserTest.php @@ -3,73 +3,51 @@ require_once __DIR__.'/../Base.php'; use Kanboard\Event\GenericEvent; -use Kanboard\Model\Task; use Kanboard\Model\TaskCreation; use Kanboard\Model\TaskFinder; use Kanboard\Model\Project; -use Kanboard\Core\User\UserSession; +use Kanboard\Model\Task; use Kanboard\Action\TaskAssignCurrentUser; class TaskAssignCurrentUserTest extends Base { - public function testBadProject() + public function testChangeUser() { - $action = new TaskAssignCurrentUser($this->container, 3, Task::EVENT_CREATE); - $action->setParam('column_id', 5); + $this->container['sessionStorage']->user = array('id' => 1); - $event = array( - 'project_id' => 2, - 'task_id' => 3, - 'column_id' => 5, - ); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); - $this->assertFalse($action->isExecutable($event)); - $this->assertFalse($action->execute(new GenericEvent($event))); - } + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - public function testBadColumn() - { - $action = new TaskAssignCurrentUser($this->container, 3, Task::EVENT_CREATE); - $action->setParam('column_id', 5); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1)); + + $action = new TaskAssignCurrentUser($this->container); + $action->setProjectId(1); - $event = array( - 'project_id' => 3, - 'task_id' => 3, - 'column_id' => 3, - ); + $this->assertTrue($action->execute($event, Task::EVENT_CREATE)); - $this->assertFalse($action->execute(new GenericEvent($event))); + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals(1, $task['owner_id']); } - public function testExecute() + public function testWithNoUserSession() { - $this->container['sessionStorage']->user = array('id' => 5); - - $action = new TaskAssignCurrentUser($this->container, 1, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 2); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1)); - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 2, - ); + $action = new TaskAssignCurrentUser($this->container); + $action->setProjectId(1); - // Our event should be executed - $this->assertTrue($action->execute(new GenericEvent($event))); - - // Our task should be assigned to the user 5 (from the session) - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(1, $task['id']); - $this->assertEquals(5, $task['owner_id']); + $this->assertFalse($action->execute($event, Task::EVENT_CREATE)); } } diff --git a/tests/units/Action/TaskAssignSpecificUserTest.php b/tests/units/Action/TaskAssignSpecificUserTest.php index a67335e8..67b2c397 100644 --- a/tests/units/Action/TaskAssignSpecificUserTest.php +++ b/tests/units/Action/TaskAssignSpecificUserTest.php @@ -3,69 +3,53 @@ require_once __DIR__.'/../Base.php'; use Kanboard\Event\GenericEvent; -use Kanboard\Model\Task; use Kanboard\Model\TaskCreation; use Kanboard\Model\TaskFinder; use Kanboard\Model\Project; +use Kanboard\Model\Task; use Kanboard\Action\TaskAssignSpecificUser; class TaskAssignSpecificUserTest extends Base { - public function testBadProject() + public function testChangeUser() { - $action = new TaskAssignSpecificUser($this->container, 3, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 5); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); - $event = array( - 'project_id' => 2, - 'task_id' => 3, - 'column_id' => 5, - ); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test', 'owner_id' => 0))); - $this->assertFalse($action->isExecutable($event)); - $this->assertFalse($action->execute(new GenericEvent($event))); - } + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 2)); - public function testBadColumn() - { - $action = new TaskAssignSpecificUser($this->container, 3, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 5); + $action = new TaskAssignSpecificUser($this->container); + $action->setProjectId(1); + $action->setParam('column_id', 2); + $action->setParam('user_id', 1); - $event = array( - 'project_id' => 3, - 'task_id' => 3, - 'column_id' => 3, - ); + $this->assertTrue($action->execute($event, Task::EVENT_MOVE_COLUMN)); - $this->assertFalse($action->execute(new GenericEvent($event))); + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals(1, $task['owner_id']); } - public function testExecute() + public function testWithWrongColumn() { - $action = new TaskAssignSpecificUser($this->container, 1, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 2); - $action->setParam('user_id', 1); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 2, - ); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 3)); - // Our event should be executed - $this->assertTrue($action->execute(new GenericEvent($event))); + $action = new TaskAssignSpecificUser($this->container); + $action->setProjectId(1); + $action->setParam('column_id', 2); + $action->setParam('user_id', 1); - // Our task should be assigned to the user 1 - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(1, $task['owner_id']); + $this->assertFalse($action->execute($event, Task::EVENT_MOVE_COLUMN)); } } diff --git a/tests/units/Action/TaskAssignUserTest.php b/tests/units/Action/TaskAssignUserTest.php new file mode 100644 index 00000000..d1cb72b9 --- /dev/null +++ b/tests/units/Action/TaskAssignUserTest.php @@ -0,0 +1,62 @@ +container); + $projectModel = new Project($this->container); + $projectUserRoleModel = new ProjectUserRole($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test', 'owner_id' => 0))); + $this->assertEquals(2, $userModel->create(array('username' => 'user1'))); + $this->assertTrue($projectUserRoleModel->addUser(1, 2, Role::PROJECT_MEMBER)); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'owner_id' => 2)); + + $action = new TaskAssignUser($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); + + $this->assertTrue($action->execute($event, 'test.event')); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals(2, $task['owner_id']); + } + + public function testWithNotAssignableUser() + { + $userModel = new User($this->container); + $projectModel = new Project($this->container); + $projectUserRoleModel = new ProjectUserRole($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'owner_id' => 1)); + + $action = new TaskAssignUser($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); + + $this->assertFalse($action->execute($event, 'test.event')); + } +} diff --git a/tests/units/Action/TaskCloseColumnTest.php b/tests/units/Action/TaskCloseColumnTest.php new file mode 100644 index 00000000..ce41bb41 --- /dev/null +++ b/tests/units/Action/TaskCloseColumnTest.php @@ -0,0 +1,53 @@ +container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 2)); + + $action = new TaskCloseColumn($this->container); + $action->setProjectId(1); + $action->setParam('column_id', 2); + + $this->assertTrue($action->execute($event, Task::EVENT_MOVE_COLUMN)); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals(0, $task['is_active']); + } + + public function testWithWrongColumn() + { + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 3)); + + $action = new TaskCloseColumn($this->container); + $action->setProjectId(1); + $action->setParam('column_id', 2); + + $this->assertFalse($action->execute($event, Task::EVENT_MOVE_COLUMN)); + } +} diff --git a/tests/units/Action/TaskCloseTest.php b/tests/units/Action/TaskCloseTest.php index b2d83194..536d79ca 100644 --- a/tests/units/Action/TaskCloseTest.php +++ b/tests/units/Action/TaskCloseTest.php @@ -3,107 +3,49 @@ require_once __DIR__.'/../Base.php'; use Kanboard\Event\GenericEvent; -use Kanboard\Model\Task; use Kanboard\Model\TaskCreation; use Kanboard\Model\TaskFinder; use Kanboard\Model\Project; -use Kanboard\Integration\GithubWebhook; use Kanboard\Action\TaskClose; class TaskCloseTest extends Base { - public function testExecutable() + public function testClose() { - $action = new TaskClose($this->container, 3, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 5); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); - $event = array( - 'project_id' => 3, - 'task_id' => 3, - 'column_id' => 5, - ); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - $this->assertTrue($action->isExecutable($event)); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1)); - $action = new TaskClose($this->container, 3, GithubWebhook::EVENT_COMMIT); + $action = new TaskClose($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); - $event = array( - 'project_id' => 3, - 'task_id' => 3, - ); + $this->assertTrue($action->execute($event, 'test.event')); - $this->assertTrue($action->isExecutable($event)); - } - - public function testBadEvent() - { - $action = new TaskClose($this->container, 3, Task::EVENT_UPDATE); - $action->setParam('column_id', 5); - - $event = array( - 'project_id' => 3, - 'task_id' => 3, - 'column_id' => 5, - ); - - $this->assertFalse($action->isExecutable($event)); - $this->assertFalse($action->execute(new GenericEvent($event))); - } - - public function testBadProject() - { - $action = new TaskClose($this->container, 3, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 5); - - $event = array( - 'project_id' => 2, - 'task_id' => 3, - 'column_id' => 5, - ); - - $this->assertFalse($action->isExecutable($event)); - $this->assertFalse($action->execute(new GenericEvent($event))); - } - - public function testBadColumn() - { - $action = new TaskClose($this->container, 3, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 5); - - $event = array( - 'project_id' => 3, - 'task_id' => 3, - 'column_id' => 3, - ); - - $this->assertFalse($action->execute(new GenericEvent($event))); + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals(0, $task['is_active']); } - public function testExecute() + public function testWithNoTaskId() { - $action = new TaskClose($this->container, 1, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 2); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 2, - ); + $event = new GenericEvent(array('project_id' => 1)); - // Our event should be executed - $this->assertTrue($action->execute(new GenericEvent($event))); + $action = new TaskClose($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); - // Our task should be closed - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(0, $task['is_active']); + $this->assertFalse($action->execute($event, 'test.event')); } } diff --git a/tests/units/Action/TaskCreationTest.php b/tests/units/Action/TaskCreationTest.php new file mode 100644 index 00000000..57c2995d --- /dev/null +++ b/tests/units/Action/TaskCreationTest.php @@ -0,0 +1,49 @@ +container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'title' => 'test123', 'reference' => 'ref123', 'description' => 'test')); + + $action = new TaskCreationAction($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); + + $this->assertTrue($action->execute($event, 'test.event')); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals('test123', $task['title']); + $this->assertEquals('ref123', $task['reference']); + $this->assertEquals('test', $task['description']); + } + + public function testWithNoTitle() + { + $projectModel = new Project($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'reference' => 'ref123', 'description' => 'test')); + + $action = new TaskCreationAction($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); + + $this->assertFalse($action->execute($event, 'test.event')); + } +} diff --git a/tests/units/Action/TaskDuplicateAnotherProjectTest.php b/tests/units/Action/TaskDuplicateAnotherProjectTest.php index 50cbad01..d9491dd9 100644 --- a/tests/units/Action/TaskDuplicateAnotherProjectTest.php +++ b/tests/units/Action/TaskDuplicateAnotherProjectTest.php @@ -4,92 +4,53 @@ require_once __DIR__.'/../Base.php'; use Kanboard\Event\GenericEvent; use Kanboard\Model\Task; -use Kanboard\Model\TaskCreation; use Kanboard\Model\TaskFinder; +use Kanboard\Model\TaskCreation; use Kanboard\Model\Project; use Kanboard\Action\TaskDuplicateAnotherProject; class TaskDuplicateAnotherProjectTest extends Base { - public function testBadProject() + public function testSuccess() { - $action = new TaskDuplicateAnotherProject($this->container, 3, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 5); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); - $event = array( - 'project_id' => 2, - 'task_id' => 3, - 'column_id' => 5, - ); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - $this->assertFalse($action->isExecutable($event)); - $this->assertFalse($action->execute(new GenericEvent($event))); - } + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 2)); - public function testBadColumn() - { - $action = new TaskDuplicateAnotherProject($this->container, 3, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 5); + $action = new TaskDuplicateAnotherProject($this->container); + $action->setProjectId(1); + $action->setParam('project_id', 2); + $action->setParam('column_id', 2); - $event = array( - 'project_id' => 3, - 'task_id' => 3, - 'column_id' => 3, - ); + $this->assertTrue($action->execute($event, Task::EVENT_CLOSE)); - $this->assertFalse($action->execute(new GenericEvent($event))); + $task = $taskFinderModel->getById(2); + $this->assertNotEmpty($task); + $this->assertEquals('test', $task['title']); + $this->assertEquals(2, $task['project_id']); } - public function testExecute() + public function testWithWrongColumn() { - $action = new TaskDuplicateAnotherProject($this->container, 1, Task::EVENT_MOVE_COLUMN); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); - $this->assertEquals(1, $p->create(array('name' => 'project 1'))); - $this->assertEquals(2, $p->create(array('name' => 'project 2'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 2, - ); - - // Our event should NOT be executed because we define the same project - $action->setParam('column_id', 2); - $action->setParam('project_id', 1); - $this->assertFalse($action->execute(new GenericEvent($event))); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 3)); - // Our task should be assigned to the project 1 - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(1, $task['project_id']); - - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 2, - ); - - // Our event should be executed because we define a different project - $action->setParam('column_id', 2); + $action = new TaskDuplicateAnotherProject($this->container); + $action->setProjectId(1); $action->setParam('project_id', 2); - $this->assertTrue($action->hasRequiredCondition($event)); - $this->assertTrue($action->execute(new GenericEvent($event))); - - // Our task should be assigned to the project 1 - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(1, $task['project_id']); + $action->setParam('column_id', 2); - // We should have another task assigned to the project 2 - $task = $tf->getById(2); - $this->assertNotEmpty($task); - $this->assertEquals(2, $task['project_id']); + $this->assertFalse($action->execute($event, Task::EVENT_CLOSE)); } } diff --git a/tests/units/Action/TaskEmailTest.php b/tests/units/Action/TaskEmailTest.php index 404865f4..ef32a296 100644 --- a/tests/units/Action/TaskEmailTest.php +++ b/tests/units/Action/TaskEmailTest.php @@ -5,98 +5,30 @@ require_once __DIR__.'/../Base.php'; use Kanboard\Event\GenericEvent; use Kanboard\Model\Task; use Kanboard\Model\TaskCreation; -use Kanboard\Model\TaskFinder; use Kanboard\Model\Project; use Kanboard\Model\User; use Kanboard\Action\TaskEmail; class TaskEmailTest extends Base { - public function testNoEmail() + public function testSuccess() { - $action = new TaskEmail($this->container, 1, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 2); - $action->setParam('user_id', 1); - $action->setParam('subject', 'My email subject'); - - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); - $u = new User($this->container); - - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); + $userModel = new User($this->container); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 2, - ); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + $this->assertTrue($userModel->update(array('id' => 1, 'email' => 'admin@localhost'))); - // Email should be not be sent - $this->container['emailClient']->expects($this->never())->method('send'); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 2)); - // Our event should be executed - $this->assertFalse($action->execute(new GenericEvent($event))); - } - - public function testWrongColumn() - { - $action = new TaskEmail($this->container, 1, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 2); - $action->setParam('user_id', 1); - $action->setParam('subject', 'My email subject'); - - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); - $u = new User($this->container); - - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); - - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 3, - ); - - // Email should be not be sent - $this->container['emailClient']->expects($this->never())->method('send'); - - // Our event should be executed - $this->assertFalse($action->execute(new GenericEvent($event))); - } - - public function testMoveColumn() - { - $action = new TaskEmail($this->container, 1, Task::EVENT_MOVE_COLUMN); + $action = new TaskEmail($this->container); + $action->setProjectId(1); $action->setParam('column_id', 2); $action->setParam('user_id', 1); $action->setParam('subject', 'My email subject'); - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); - $u = new User($this->container); - - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); - $this->assertTrue($u->update(array('id' => 1, 'email' => 'admin@localhost'))); - - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 2, - ); - - // Email should be sent $this->container['emailClient']->expects($this->once()) ->method('send') ->with( @@ -106,45 +38,24 @@ class TaskEmailTest extends Base $this->stringContains('test') ); - // Our event should be executed - $this->assertTrue($action->execute(new GenericEvent($event))); + $this->assertTrue($action->execute($event, Task::EVENT_CLOSE)); } - public function testTaskClose() + public function testWithWrongColumn() { - $action = new TaskEmail($this->container, 1, Task::EVENT_CLOSE); - $action->setParam('column_id', 2); - $action->setParam('user_id', 1); - $action->setParam('subject', 'My email subject'); - - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); - $u = new User($this->container); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); - $this->assertTrue($u->update(array('id' => 1, 'email' => 'admin@localhost'))); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); - // We create an event - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 2, - ); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 3)); - // Email should be sent - $this->container['emailClient']->expects($this->once()) - ->method('send') - ->with( - $this->equalTo('admin@localhost'), - $this->equalTo('admin'), - $this->equalTo('My email subject'), - $this->stringContains('test') - ); + $action = new TaskEmail($this->container); + $action->setProjectId(1); + $action->setParam('column_id', 2); + $action->setParam('user_id', 1); + $action->setParam('subject', 'My email subject'); - // Our event should be executed - $this->assertTrue($action->execute(new GenericEvent($event))); + $this->assertFalse($action->execute($event, Task::EVENT_CLOSE)); } } diff --git a/tests/units/Action/TaskMoveAnotherProjectTest.php b/tests/units/Action/TaskMoveAnotherProjectTest.php index 93ee3b94..dfabe5f8 100644 --- a/tests/units/Action/TaskMoveAnotherProjectTest.php +++ b/tests/units/Action/TaskMoveAnotherProjectTest.php @@ -4,86 +4,54 @@ require_once __DIR__.'/../Base.php'; use Kanboard\Event\GenericEvent; use Kanboard\Model\Task; -use Kanboard\Model\TaskCreation; use Kanboard\Model\TaskFinder; +use Kanboard\Model\TaskCreation; use Kanboard\Model\Project; use Kanboard\Action\TaskMoveAnotherProject; class TaskMoveAnotherProjectTest extends Base { - public function testBadProject() + public function testSuccess() { - $action = new TaskMoveAnotherProject($this->container, 3, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 5); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); - $event = array( - 'project_id' => 2, - 'task_id' => 3, - 'column_id' => 5, - ); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - $this->assertFalse($action->isExecutable($event)); - $this->assertFalse($action->execute(new GenericEvent($event))); - } + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 2)); - public function testBadColumn() - { - $action = new TaskMoveAnotherProject($this->container, 3, Task::EVENT_MOVE_COLUMN); - $action->setParam('column_id', 5); + $action = new TaskMoveAnotherProject($this->container); + $action->setProjectId(1); + $action->setParam('project_id', 2); + $action->setParam('column_id', 2); - $event = array( - 'project_id' => 3, - 'task_id' => 3, - 'column_id' => 3, - ); + $this->assertTrue($action->execute($event, Task::EVENT_CLOSE)); - $this->assertFalse($action->execute(new GenericEvent($event))); + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals('test', $task['title']); + $this->assertEquals(2, $task['project_id']); + $this->assertEquals(5, $task['column_id']); } - public function testExecute() + public function testWithWrongColumn() { - $action = new TaskMoveAnotherProject($this->container, 1, Task::EVENT_MOVE_COLUMN); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); - $this->assertEquals(1, $p->create(array('name' => 'project 1'))); - $this->assertEquals(2, $p->create(array('name' => 'project 2'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 2, - ); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 3)); - // Our event should NOT be executed because we define the same project - $action->setParam('column_id', 2); - $action->setParam('project_id', 1); - $this->assertFalse($action->execute(new GenericEvent($event))); - - // Our task should be assigned to the project 1 - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(1, $task['project_id']); - - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 2, - ); - - // Our event should be executed because we define a different project - $action->setParam('column_id', 2); + $action = new TaskMoveAnotherProject($this->container); + $action->setProjectId(1); $action->setParam('project_id', 2); - $this->assertTrue($action->execute(new GenericEvent($event))); + $action->setParam('column_id', 2); - // Our task should be assigned to the project 2 - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(2, $task['project_id']); + $this->assertFalse($action->execute($event, Task::EVENT_CLOSE)); } } diff --git a/tests/units/Action/TaskMoveColumnAssignedTest.php b/tests/units/Action/TaskMoveColumnAssignedTest.php new file mode 100644 index 00000000..f0eec894 --- /dev/null +++ b/tests/units/Action/TaskMoveColumnAssignedTest.php @@ -0,0 +1,56 @@ +container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 1, 'owner_id' => 1)); + + $action = new TaskMoveColumnAssigned($this->container); + $action->setProjectId(1); + $action->setParam('src_column_id', 1); + $action->setParam('dest_column_id', 2); + + $this->assertTrue($action->execute($event, Task::EVENT_ASSIGNEE_CHANGE)); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals('test', $task['title']); + $this->assertEquals(2, $task['column_id']); + } + + public function testWithWrongColumn() + { + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 3, 'owner_id' => 1)); + + $action = new TaskMoveColumnAssigned($this->container); + $action->setProjectId(1); + $action->setParam('src_column_id', 1); + $action->setParam('dest_column_id', 2); + + $this->assertFalse($action->execute($event, Task::EVENT_ASSIGNEE_CHANGE)); + } +} diff --git a/tests/units/Action/TaskMoveColumnCategoryChangeTest.php b/tests/units/Action/TaskMoveColumnCategoryChangeTest.php index 03423776..1f0768c1 100644 --- a/tests/units/Action/TaskMoveColumnCategoryChangeTest.php +++ b/tests/units/Action/TaskMoveColumnCategoryChangeTest.php @@ -3,60 +3,84 @@ require_once __DIR__.'/../Base.php'; use Kanboard\Event\GenericEvent; +use Kanboard\Model\Category; use Kanboard\Model\Task; -use Kanboard\Model\TaskCreation; use Kanboard\Model\TaskFinder; +use Kanboard\Model\TaskCreation; use Kanboard\Model\Project; -use Kanboard\Model\Category; -use Kanboard\Integration\GithubWebhook; use Kanboard\Action\TaskMoveColumnCategoryChange; class TaskMoveColumnCategoryChangeTest extends Base { - public function testExecute() + public function testSuccess() { - $action = new TaskMoveColumnCategoryChange($this->container, 1, Task::EVENT_UPDATE); - $action->setParam('dest_column_id', 3); - $action->setParam('category_id', 1); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + $categoryModel = new Category($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + $this->assertEquals(1, $categoryModel->create(array('name' => 'c1', 'project_id' => 1))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - $this->assertEquals(3, $action->getParam('dest_column_id')); - $this->assertEquals(1, $action->getParam('category_id')); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 1, 'category_id' => 1)); - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); - $c = new Category($this->container); + $action = new TaskMoveColumnCategoryChange($this->container); + $action->setProjectId(1); + $action->setParam('category_id', 1); + $action->setParam('dest_column_id', 2); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $c->create(array('name' => 'bug', 'project_id' => 1))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); + $this->assertTrue($action->execute($event, Task::EVENT_UPDATE)); - // No category should be assigned + column_id=1 - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEmpty($task['category_id']); - $this->assertEquals(1, $task['column_id']); - - // We create an event to move the task to the 2nd column - $event = array( - 'task_id' => 1, - 'column_id' => 1, - 'project_id' => 1, - 'category_id' => 1, - ); - - // Our event should be executed - $this->assertTrue($action->hasCompatibleEvent()); - $this->assertTrue($action->hasRequiredProject($event)); - $this->assertTrue($action->hasRequiredParameters($event)); - $this->assertTrue($action->hasRequiredCondition($event)); - $this->assertTrue($action->isExecutable($event)); - $this->assertTrue($action->execute(new GenericEvent($event))); - - // Our task should be moved to the other column - $task = $tf->getById(1); + $task = $taskFinderModel->getById(1); $this->assertNotEmpty($task); - $this->assertEquals(3, $task['column_id']); + $this->assertEquals('test', $task['title']); + $this->assertEquals(2, $task['column_id']); + } + + public function testWithWrongColumn() + { + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + $categoryModel = new Category($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + $this->assertEquals(1, $categoryModel->create(array('name' => 'c1', 'project_id' => 1))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 2, 'category_id' => 1)); + + $action = new TaskMoveColumnCategoryChange($this->container); + $action->setProjectId(1); + $action->setParam('category_id', 1); + $action->setParam('dest_column_id', 2); + + $this->assertFalse($action->execute($event, Task::EVENT_UPDATE)); + } + + public function testWithWrongCategory() + { + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + $categoryModel = new Category($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + $this->assertEquals(1, $categoryModel->create(array('name' => 'c1', 'project_id' => 1))); + $this->assertEquals(2, $categoryModel->create(array('name' => 'c2', 'project_id' => 1))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 1, 'category_id' => 2)); + + $action = new TaskMoveColumnCategoryChange($this->container); + $action->setProjectId(1); + $action->setParam('category_id', 1); + $action->setParam('dest_column_id', 2); + + $this->assertFalse($action->execute($event, Task::EVENT_UPDATE)); } } diff --git a/tests/units/Action/TaskMoveColumnUnAssignedTest.php b/tests/units/Action/TaskMoveColumnUnAssignedTest.php new file mode 100644 index 00000000..0b54b781 --- /dev/null +++ b/tests/units/Action/TaskMoveColumnUnAssignedTest.php @@ -0,0 +1,74 @@ +container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 1, 'owner_id' => 0)); + + $action = new TaskMoveColumnUnAssigned($this->container); + $action->setProjectId(1); + $action->setParam('src_column_id', 1); + $action->setParam('dest_column_id', 2); + + $this->assertTrue($action->execute($event, Task::EVENT_ASSIGNEE_CHANGE)); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals('test', $task['title']); + $this->assertEquals(2, $task['column_id']); + } + + public function testWithWrongColumn() + { + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 2, 'owner_id' => 0)); + + $action = new TaskMoveColumnUnAssigned($this->container); + $action->setProjectId(1); + $action->setParam('src_column_id', 1); + $action->setParam('dest_column_id', 2); + + $this->assertFalse($action->execute($event, Task::EVENT_ASSIGNEE_CHANGE)); + } + + public function testWithWrongUser() + { + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 1, 'owner_id' => 1)); + + $action = new TaskMoveColumnUnAssigned($this->container); + $action->setProjectId(1); + $action->setParam('src_column_id', 1); + $action->setParam('dest_column_id', 2); + + $this->assertFalse($action->execute($event, Task::EVENT_ASSIGNEE_CHANGE)); + } +} diff --git a/tests/units/Action/TaskOpenTest.php b/tests/units/Action/TaskOpenTest.php new file mode 100644 index 00000000..01290a64 --- /dev/null +++ b/tests/units/Action/TaskOpenTest.php @@ -0,0 +1,51 @@ +container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test', 'is_active' => 0))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1)); + + $action = new TaskOpen($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); + + $this->assertTrue($action->execute($event, 'test.event')); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals(1, $task['is_active']); + } + + public function testWithNoTaskId() + { + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1)); + + $action = new TaskOpen($this->container); + $action->setProjectId(1); + $action->addEvent('test.event', 'Test Event'); + + $this->assertFalse($action->execute($event, 'test.event')); + } +} diff --git a/tests/units/Action/TaskUpdateStartDateTest.php b/tests/units/Action/TaskUpdateStartDateTest.php index 7d558e28..adf5bd9d 100644 --- a/tests/units/Action/TaskUpdateStartDateTest.php +++ b/tests/units/Action/TaskUpdateStartDateTest.php @@ -3,44 +3,50 @@ require_once __DIR__.'/../Base.php'; use Kanboard\Event\GenericEvent; -use Kanboard\Model\Task; use Kanboard\Model\TaskCreation; use Kanboard\Model\TaskFinder; use Kanboard\Model\Project; +use Kanboard\Model\Task; use Kanboard\Action\TaskUpdateStartDate; class TaskUpdateStartDateTest extends Base { - public function testExecute() + public function testClose() { - $action = new TaskUpdateStartDate($this->container, 1, Task::EVENT_MOVE_COLUMN); + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 2)); + + $action = new TaskUpdateStartDate($this->container); + $action->setProjectId(1); $action->setParam('column_id', 2); - // We create a task in the first column - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); + $this->assertTrue($action->execute($event, Task::EVENT_MOVE_COLUMN)); - // The start date must be empty - $task = $tf->getById(1); + $task = $taskFinderModel->getById(1); $this->assertNotEmpty($task); - $this->assertEmpty($task['date_started']); + $this->assertEquals(time(), $task['date_started'], 'Date started delta', 2); + } - // We create an event to move the task to the 2nd column - $event = array( - 'project_id' => 1, - 'task_id' => 1, - 'column_id' => 2, - ); + public function testWithWrongColumn() + { + $projectModel = new Project($this->container); + $taskCreationModel = new TaskCreation($this->container); - // Our event should be executed - $this->assertTrue($action->execute(new GenericEvent($event))); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); - // Our task should be updated - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(time(), $task['date_started'], '', 2); + $event = new GenericEvent(array('project_id' => 1, 'task_id' => 1, 'column_id' => 3)); + + $action = new TaskUpdateStartDate($this->container); + $action->setProjectId(1); + $action->setParam('column_id', 2); + + $this->assertFalse($action->execute($event, Task::EVENT_MOVE_COLUMN)); } } diff --git a/tests/units/Core/Action/ActionManagerTest.php b/tests/units/Core/Action/ActionManagerTest.php new file mode 100644 index 00000000..3714583b --- /dev/null +++ b/tests/units/Core/Action/ActionManagerTest.php @@ -0,0 +1,157 @@ +container); + $actionTaskClose = new TaskClose($this->container); + + $actionManager->register($actionTaskClose); + $this->assertInstanceOf(get_class($actionTaskClose), $actionManager->getAction($actionTaskClose->getName())); + } + + public function testGetActionNotFound() + { + $this->setExpectedException('RuntimeException', 'Automatic Action Not Found: foobar'); + $actionManager = new ActionManager($this->container); + $actionManager->getAction('foobar'); + } + + public function testGetAvailableActions() + { + $actionManager = new ActionManager($this->container); + $actionTaskClose1 = new TaskClose($this->container); + $actionTaskClose2 = new TaskClose($this->container); + $actionTaskUpdateStartDate = new TaskUpdateStartDate($this->container); + + $actionManager + ->register($actionTaskClose1) + ->register($actionTaskClose2) + ->register($actionTaskUpdateStartDate); + + $actions = $actionManager->getAvailableActions(); + $this->assertCount(2, $actions); + $this->assertArrayHasKey($actionTaskClose1->getName(), $actions); + $this->assertArrayHasKey($actionTaskUpdateStartDate->getName(), $actions); + $this->assertNotEmpty($actions[$actionTaskClose1->getName()]); + $this->assertNotEmpty($actions[$actionTaskUpdateStartDate->getName()]); + } + + public function testGetAvailableParameters() + { + $actionManager = new ActionManager($this->container); + + $actionManager + ->register(new TaskCloseColumn($this->container)) + ->register(new TaskUpdateStartDate($this->container)); + + $params = $actionManager->getAvailableParameters(array( + array('action_name' => '\Kanboard\Action\TaskCloseColumn'), + array('action_name' => '\Kanboard\Action\TaskUpdateStartDate'), + )); + + $this->assertCount(2, $params); + $this->assertArrayHasKey('column_id', $params['\Kanboard\Action\TaskCloseColumn']); + $this->assertArrayHasKey('column_id', $params['\Kanboard\Action\TaskUpdateStartDate']); + $this->assertNotEmpty($params['\Kanboard\Action\TaskCloseColumn']['column_id']); + $this->assertNotEmpty($params['\Kanboard\Action\TaskUpdateStartDate']['column_id']); + } + + public function testGetCompatibleEvents() + { + $actionTaskAssignColorColumn = new TaskAssignColorColumn($this->container); + $actionManager = new ActionManager($this->container); + $actionManager->register($actionTaskAssignColorColumn); + + $events = $actionManager->getCompatibleEvents('\\'.get_class($actionTaskAssignColorColumn)); + $this->assertCount(2, $events); + $this->assertArrayHasKey(Task::EVENT_CREATE, $events); + $this->assertArrayHasKey(Task::EVENT_MOVE_COLUMN, $events); + $this->assertNotEmpty($events[Task::EVENT_CREATE]); + $this->assertNotEmpty($events[Task::EVENT_MOVE_COLUMN]); + } + + public function testAttachEventsWithoutUserSession() + { + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + $actionTaskAssignColorColumn = new TaskAssignColorColumn($this->container); + $actionManager = new ActionManager($this->container); + $actionManager->register($actionTaskAssignColorColumn); + + $actions = $actionManager->getAvailableActions(); + + $actionManager->attachEvents(); + $this->assertEmpty($this->container['dispatcher']->getListeners()); + + $this->assertEquals(1, $projectModel->create(array('name' =>'test'))); + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_CREATE, + 'action_name' => key($actions), + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); + + $actionManager->attachEvents(); + $listeners = $this->container['dispatcher']->getListeners(Task::EVENT_CREATE); + $this->assertCount(1, $listeners); + $this->assertInstanceOf(get_class($actionTaskAssignColorColumn), $listeners[0][0]); + + $this->assertEquals(1, $listeners[0][0]->getProjectId()); + } + + public function testAttachEventsWithLoggedUser() + { + $this->container['sessionStorage']->user = array('id' => 1); + + $projectModel = new Project($this->container); + $projectUserRoleModel = new ProjectUserRole($this->container); + $actionModel = new Action($this->container); + $actionTaskAssignColorColumn = new TaskAssignColorColumn($this->container); + $actionManager = new ActionManager($this->container); + $actionManager->register($actionTaskAssignColorColumn); + + $actions = $actionManager->getAvailableActions(); + + $this->assertEquals(1, $projectModel->create(array('name' =>'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' =>'test2'))); + + $this->assertTrue($projectUserRoleModel->addUser(2, 1, Role::PROJECT_MEMBER)); + + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_CREATE, + 'action_name' => key($actions), + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); + + $this->assertEquals(2, $actionModel->create(array( + 'project_id' => 2, + 'event_name' => Task::EVENT_MOVE_COLUMN, + 'action_name' => key($actions), + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); + + $actionManager->attachEvents(); + + $listeners = $this->container['dispatcher']->getListeners(Task::EVENT_MOVE_COLUMN); + $this->assertCount(1, $listeners); + $this->assertInstanceOf(get_class($actionTaskAssignColorColumn), $listeners[0][0]); + + $this->assertEquals(2, $listeners[0][0]->getProjectId()); + } +} diff --git a/tests/units/Core/Event/EventManagerTest.php b/tests/units/Core/Event/EventManagerTest.php new file mode 100644 index 00000000..974fde62 --- /dev/null +++ b/tests/units/Core/Event/EventManagerTest.php @@ -0,0 +1,18 @@ +register('my.event', 'My Event'); + + $events = $eventManager->getAll(); + $this->assertArrayHasKey('my.event', $events); + $this->assertEquals('My Event', $events['my.event']); + } +} diff --git a/tests/units/Integration/BitbucketWebhookTest.php b/tests/units/Integration/BitbucketWebhookTest.php index 40dbde2e..bb6755c2 100644 --- a/tests/units/Integration/BitbucketWebhookTest.php +++ b/tests/units/Integration/BitbucketWebhookTest.php @@ -319,7 +319,7 @@ class BitbucketWebhookTest extends Base $this->assertEquals(1, $data['project_id']); $this->assertEquals(2, $data['task_id']); $this->assertEquals('test2', $data['title']); - $this->assertEquals("Test another commit #2\n\n\n[Commit made by @Frederic Guillot on Bitbucket](https://bitbucket.org/minicoders/test-webhook/commits/824059cce7667d3f8d8780cc707391be821e0ea6)", $data['commit_comment']); + $this->assertEquals("Test another commit #2\n\n\n[Commit made by @Frederic Guillot on Bitbucket](https://bitbucket.org/minicoders/test-webhook/commits/824059cce7667d3f8d8780cc707391be821e0ea6)", $data['comment']); $this->assertEquals("Test another commit #2\n", $data['commit_message']); $this->assertEquals('https://bitbucket.org/minicoders/test-webhook/commits/824059cce7667d3f8d8780cc707391be821e0ea6', $data['commit_url']); } diff --git a/tests/units/Integration/GithubWebhookTest.php b/tests/units/Integration/GithubWebhookTest.php index f00e5dde..6b5e19a5 100644 --- a/tests/units/Integration/GithubWebhookTest.php +++ b/tests/units/Integration/GithubWebhookTest.php @@ -453,7 +453,7 @@ class GithubWebhookTest extends Base $this->assertEquals(1, $data['project_id']); $this->assertEquals(1, $data['task_id']); $this->assertEquals('boo', $data['title']); - $this->assertEquals("Update README to fix #1\n\n[Commit made by @fguillot on Github](https://github.com/kanboardapp/webhook/commit/98dee3e49ee7aa66ffec1f761af93da5ffd711f6)", $data['commit_comment']); + $this->assertEquals("Update README to fix #1\n\n[Commit made by @fguillot on Github](https://github.com/kanboardapp/webhook/commit/98dee3e49ee7aa66ffec1f761af93da5ffd711f6)", $data['comment']); $this->assertEquals('Update README to fix #1', $data['commit_message']); $this->assertEquals('https://github.com/kanboardapp/webhook/commit/98dee3e49ee7aa66ffec1f761af93da5ffd711f6', $data['commit_url']); } diff --git a/tests/units/Integration/GitlabWebhookTest.php b/tests/units/Integration/GitlabWebhookTest.php index 3e0e6d2c..afd9f7f1 100644 --- a/tests/units/Integration/GitlabWebhookTest.php +++ b/tests/units/Integration/GitlabWebhookTest.php @@ -221,7 +221,7 @@ class GitlabWebhookTest extends Base $this->assertEquals(1, $data['project_id']); $this->assertEquals(2, $data['task_id']); $this->assertEquals('test2', $data['title']); - $this->assertEquals("Fix bug #2\n\n[Commit made by @Fred on Gitlab](https://gitlab.com/minicoders/test-webhook/commit/48aafa75eef9ad253aa254b0c82c987a52ebea78)", $data['commit_comment']); + $this->assertEquals("Fix bug #2\n\n[Commit made by @Fred on Gitlab](https://gitlab.com/minicoders/test-webhook/commit/48aafa75eef9ad253aa254b0c82c987a52ebea78)", $data['comment']); $this->assertEquals("Fix bug #2", $data['commit_message']); $this->assertEquals('https://gitlab.com/minicoders/test-webhook/commit/48aafa75eef9ad253aa254b0c82c987a52ebea78', $data['commit_url']); } diff --git a/tests/units/Model/ActionTest.php b/tests/units/Model/ActionTest.php index 4a338707..8d574115 100644 --- a/tests/units/Model/ActionTest.php +++ b/tests/units/Model/ActionTest.php @@ -4,388 +4,506 @@ require_once __DIR__.'/../Base.php'; use Kanboard\Model\Action; use Kanboard\Model\Project; -use Kanboard\Model\Board; use Kanboard\Model\Task; -use Kanboard\Model\TaskPosition; -use Kanboard\Model\TaskCreation; -use Kanboard\Model\TaskFinder; -use Kanboard\Model\Category; use Kanboard\Model\User; +use Kanboard\Model\Board; +use Kanboard\Model\Category; use Kanboard\Model\ProjectUserRole; -use Kanboard\Integration\GithubWebhook; -use Kanboard\Integration\BitbucketWebhook; use Kanboard\Core\Security\Role; class ActionTest extends Base { - public function testGetActions() + public function testCreate() { - $a = new Action($this->container); + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test'))); - $actions = $a->getAvailableActions(); - $this->assertNotEmpty($actions); - $this->assertEquals('Add a comment log when moving the task between columns', current($actions)); - $this->assertEquals('TaskLogMoveAnotherColumn', key($actions)); + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_CREATE, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); } - public function testExtendActions() + public function testRemove() { - $a = new Action($this->container); - $a->extendActions('MyClass', 'Description'); + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test'))); + + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_CREATE, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); - $actions = $a->getAvailableActions(); - $this->assertNotEmpty($actions); - $this->assertContains('Description', $actions); - $this->assertArrayHasKey('MyClass', $actions); + $this->assertNotEmpty($actionModel->getById(1)); + $this->assertTrue($actionModel->remove(1)); + $this->assertEmpty($actionModel->getById(1)); } - public function testGetEvents() + public function testGetById() { - $a = new Action($this->container); + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test'))); - $events = $a->getAvailableEvents(); - $this->assertNotEmpty($events); - $this->assertEquals('Bitbucket commit received', current($events)); - $this->assertEquals(BitbucketWebhook::EVENT_COMMIT, key($events)); + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_CREATE, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); + + $action = $actionModel->getById(1); + $this->assertNotEmpty($action); + $this->assertEquals(1, $action['project_id']); + $this->assertEquals('\Kanboard\Action\TaskAssignColorColumn', $action['action_name']); + $this->assertEquals(Task::EVENT_CREATE, $action['event_name']); + $this->assertEquals(array('column_id' => 1, 'color_id' => 'red'), $action['params']); } - public function testGetCompatibleEvents() + public function testGetAll() { - $a = new Action($this->container); - $events = $a->getCompatibleEvents('TaskAssignSpecificUser'); + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); - $this->assertNotEmpty($events); - $this->assertCount(2, $events); - $this->assertArrayHasKey(Task::EVENT_CREATE_UPDATE, $events); - $this->assertArrayHasKey(Task::EVENT_MOVE_COLUMN, $events); + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_CREATE, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); + + $this->assertEquals(2, $actionModel->create(array( + 'project_id' => 2, + 'event_name' => Task::EVENT_MOVE_COLUMN, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('column_id' => 6, 'color_id' => 'blue'), + ))); + + $actions = $actionModel->getAll(); + $this->assertCount(2, $actions); + + $this->assertEquals(1, $actions[0]['project_id']); + $this->assertEquals('\Kanboard\Action\TaskAssignColorColumn', $actions[0]['action_name']); + $this->assertEquals(Task::EVENT_CREATE, $actions[0]['event_name']); + $this->assertEquals(array('column_id' => 1, 'color_id' => 'red'), $actions[0]['params']); + + $this->assertEquals(2, $actions[1]['project_id']); + $this->assertEquals('\Kanboard\Action\TaskAssignColorColumn', $actions[1]['action_name']); + $this->assertEquals(Task::EVENT_MOVE_COLUMN, $actions[1]['event_name']); + $this->assertEquals(array('column_id' => 6, 'color_id' => 'blue'), $actions[1]['params']); } - public function testResolveDuplicatedParameters() + public function testGetAllByProject() { - $p = new Project($this->container); - $pp = new ProjectUserRole($this->container); - $a = new Action($this->container); - $c = new Category($this->container); - $u = new User($this->container); - - $this->assertEquals(1, $p->create(array('name' => 'P1'))); - $this->assertEquals(2, $p->create(array('name' => 'P2'))); - - $this->assertEquals(1, $c->create(array('name' => 'C1', 'project_id' => 1))); - - $this->assertEquals(2, $c->create(array('name' => 'C2', 'project_id' => 2))); - $this->assertEquals(3, $c->create(array('name' => 'C1', 'project_id' => 2))); - - $this->assertEquals(2, $u->create(array('username' => 'unittest1'))); - $this->assertEquals(3, $u->create(array('username' => 'unittest2'))); - - $this->assertTrue($pp->addUser(1, 2, Role::PROJECT_MEMBER)); - $this->assertTrue($pp->addUser(1, 3, Role::PROJECT_MEMBER)); - $this->assertTrue($pp->addUser(2, 3, Role::PROJECT_MEMBER)); - - // anything - $this->assertEquals('blah', $a->resolveParameters(array('name' => 'foobar', 'value' => 'blah'), 2)); - - // project_id - $this->assertEquals(2, $a->resolveParameters(array('name' => 'project_id', 'value' => 'blah'), 2)); - - // category_id - $this->assertEquals(3, $a->resolveParameters(array('name' => 'category_id', 'value' => 1), 2)); - $this->assertFalse($a->resolveParameters(array('name' => 'category_id', 'value' => 0), 2)); - $this->assertFalse($a->resolveParameters(array('name' => 'category_id', 'value' => 5), 2)); - - // column_id - $this->assertFalse($a->resolveParameters(array('name' => 'column_id', 'value' => 10), 2)); - $this->assertFalse($a->resolveParameters(array('name' => 'column_id', 'value' => 0), 2)); - $this->assertEquals(5, $a->resolveParameters(array('name' => 'column_id', 'value' => 1), 2)); - $this->assertEquals(6, $a->resolveParameters(array('name' => 'dest_column_id', 'value' => 2), 2)); - $this->assertEquals(7, $a->resolveParameters(array('name' => 'dst_column_id', 'value' => 3), 2)); - $this->assertEquals(8, $a->resolveParameters(array('name' => 'src_column_id', 'value' => 4), 2)); - - // user_id - $this->assertFalse($a->resolveParameters(array('name' => 'user_id', 'value' => 10), 2)); - $this->assertFalse($a->resolveParameters(array('name' => 'user_id', 'value' => 0), 2)); - $this->assertFalse($a->resolveParameters(array('name' => 'user_id', 'value' => 2), 2)); - $this->assertFalse($a->resolveParameters(array('name' => 'owner_id', 'value' => 2), 2)); - $this->assertEquals(3, $a->resolveParameters(array('name' => 'user_id', 'value' => 3), 2)); - $this->assertEquals(3, $a->resolveParameters(array('name' => 'owner_id', 'value' => 3), 2)); + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_CREATE, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); + + $this->assertEquals(2, $actionModel->create(array( + 'project_id' => 2, + 'event_name' => Task::EVENT_MOVE_COLUMN, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('column_id' => 6, 'color_id' => 'blue'), + ))); + + $actions = $actionModel->getAllByProject(1); + $this->assertCount(1, $actions); + + $this->assertEquals(1, $actions[0]['project_id']); + $this->assertEquals('\Kanboard\Action\TaskAssignColorColumn', $actions[0]['action_name']); + $this->assertEquals(Task::EVENT_CREATE, $actions[0]['event_name']); + $this->assertEquals(array('column_id' => 1, 'color_id' => 'red'), $actions[0]['params']); + + + $actions = $actionModel->getAllByProject(2); + $this->assertCount(1, $actions); + + $this->assertEquals(2, $actions[0]['project_id']); + $this->assertEquals('\Kanboard\Action\TaskAssignColorColumn', $actions[0]['action_name']); + $this->assertEquals(Task::EVENT_MOVE_COLUMN, $actions[0]['event_name']); + $this->assertEquals(array('column_id' => 6, 'color_id' => 'blue'), $actions[0]['params']); } - public function testDuplicateSuccess() + public function testGetAllByUser() { - $p = new Project($this->container); - $pp = new ProjectUserRole($this->container); - $a = new Action($this->container); - $u = new User($this->container); + $projectModel = new Project($this->container); + $projectUserRoleModel = new ProjectUserRole($this->container); + $userModel = new User($this->container); + $actionModel = new Action($this->container); - $this->assertEquals(1, $p->create(array('name' => 'P1'))); - $this->assertEquals(2, $p->create(array('name' => 'P2'))); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + $this->assertEquals(3, $projectModel->create(array('name' => 'test4', 'is_active' => 0))); - $this->assertEquals(2, $u->create(array('username' => 'unittest1'))); - $this->assertEquals(3, $u->create(array('username' => 'unittest2'))); + $this->assertEquals(2, $userModel->create(array('username' => 'user1'))); + $this->assertEquals(3, $userModel->create(array('username' => 'user2'))); - $this->assertTrue($pp->addUser(1, 2, Role::PROJECT_MEMBER)); - $this->assertTrue($pp->addUser(1, 3, Role::PROJECT_MEMBER)); - $this->assertTrue($pp->addUser(2, 3, Role::PROJECT_MEMBER)); + $this->assertTrue($projectUserRoleModel->addUser(1, 2, Role::PROJECT_VIEWER)); + $this->assertTrue($projectUserRoleModel->addUser(2, 3, Role::PROJECT_MANAGER)); + $this->assertTrue($projectUserRoleModel->addUser(3, 3, Role::PROJECT_MANAGER)); - $this->assertEquals(1, $a->create(array( + $this->assertEquals(1, $actionModel->create(array( 'project_id' => 1, - 'event_name' => Task::EVENT_CREATE_UPDATE, - 'action_name' => 'TaskAssignSpecificUser', - 'params' => array( - 'column_id' => 1, - 'user_id' => 3, - ) + 'event_name' => Task::EVENT_CREATE, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('column_id' => 1, 'color_id' => 'red'), ))); - $action = $a->getById(1); - $this->assertNotEmpty($action); - $this->assertNotEmpty($action['params']); - $this->assertEquals(1, $action['project_id']); + $this->assertEquals(2, $actionModel->create(array( + 'project_id' => 2, + 'event_name' => Task::EVENT_MOVE_COLUMN, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('column_id' => 6, 'color_id' => 'blue'), + ))); - $this->assertTrue($a->duplicate(1, 2)); + $this->assertEquals(3, $actionModel->create(array( + 'project_id' => 3, + 'event_name' => Task::EVENT_MOVE_COLUMN, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('column_id' => 10, 'color_id' => 'green'), + ))); - $action = $a->getById(2); - $this->assertNotEmpty($action); - $this->assertNotEmpty($action['params']); - $this->assertEquals(2, $action['project_id']); - $this->assertEquals(Task::EVENT_CREATE_UPDATE, $action['event_name']); - $this->assertEquals('TaskAssignSpecificUser', $action['action_name']); - $this->assertEquals('column_id', $action['params'][0]['name']); - $this->assertEquals(5, $action['params'][0]['value']); - $this->assertEquals('user_id', $action['params'][1]['name']); - $this->assertEquals(3, $action['params'][1]['value']); + $actions = $actionModel->getAllByUser(1); + $this->assertCount(0, $actions); + + $actions = $actionModel->getAllByUser(2); + $this->assertCount(1, $actions); + + $this->assertEquals(1, $actions[0]['project_id']); + $this->assertEquals('\Kanboard\Action\TaskAssignColorColumn', $actions[0]['action_name']); + $this->assertEquals(Task::EVENT_CREATE, $actions[0]['event_name']); + $this->assertEquals(array('column_id' => 1, 'color_id' => 'red'), $actions[0]['params']); + + $actions = $actionModel->getAllByUser(3); + $this->assertCount(1, $actions); + + $this->assertEquals(2, $actions[0]['project_id']); + $this->assertEquals('\Kanboard\Action\TaskAssignColorColumn', $actions[0]['action_name']); + $this->assertEquals(Task::EVENT_MOVE_COLUMN, $actions[0]['event_name']); + $this->assertEquals(array('column_id' => 6, 'color_id' => 'blue'), $actions[0]['params']); } - public function testDuplicateUnableToResolveParams() + public function testDuplicateWithColumnAndColorParameter() { - $p = new Project($this->container); - $pp = new ProjectUserRole($this->container); - $a = new Action($this->container); - $u = new User($this->container); + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); - $this->assertEquals(1, $p->create(array('name' => 'P1'))); - $this->assertEquals(2, $p->create(array('name' => 'P2'))); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); - $this->assertEquals(2, $u->create(array('username' => 'unittest1'))); + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_CREATE, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); - $this->assertTrue($pp->addUser(1, 2, Role::PROJECT_MEMBER)); + $this->assertTrue($actionModel->duplicate(1, 2)); - $this->assertEquals(1, $a->create(array( + $actions = $actionModel->getAllByProject(2); + $this->assertCount(1, $actions); + + $this->assertEquals(2, $actions[0]['project_id']); + $this->assertEquals('\Kanboard\Action\TaskAssignColorColumn', $actions[0]['action_name']); + $this->assertEquals(Task::EVENT_CREATE, $actions[0]['event_name']); + $this->assertEquals(array('column_id' => 5, 'color_id' => 'red'), $actions[0]['params']); + } + + public function testDuplicateWithColumnsParameter() + { + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + + $this->assertEquals(1, $actionModel->create(array( 'project_id' => 1, - 'event_name' => Task::EVENT_CREATE_UPDATE, - 'action_name' => 'TaskAssignSpecificUser', - 'params' => array( - 'column_id' => 1, - 'user_id' => 2, - ) + 'event_name' => Task::EVENT_CREATE, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('src_column_id' => 1, 'dst_column_id' => 2, 'dest_column_id' => 3), ))); - $action = $a->getById(1); - $this->assertNotEmpty($action); - $this->assertNotEmpty($action['params']); - $this->assertEquals(1, $action['project_id']); - $this->assertEquals('user_id', $action['params'][1]['name']); - $this->assertEquals(2, $action['params'][1]['value']); + $this->assertTrue($actionModel->duplicate(1, 2)); - $this->assertTrue($a->duplicate(1, 2)); + $actions = $actionModel->getAllByProject(2); + $this->assertCount(1, $actions); - $action = $a->getById(2); - $this->assertEmpty($action); + $this->assertEquals(2, $actions[0]['project_id']); + $this->assertEquals('\Kanboard\Action\TaskAssignColorColumn', $actions[0]['action_name']); + $this->assertEquals(Task::EVENT_CREATE, $actions[0]['event_name']); + $this->assertEquals(array('src_column_id' => 5, 'dst_column_id' => 6, 'dest_column_id' => 7), $actions[0]['params']); } - public function testDuplicateMixedResults() + public function testDuplicateWithColumnParameterNotfound() { - $p = new Project($this->container); - $pp = new ProjectUserRole($this->container); - $a = new Action($this->container); - $u = new User($this->container); - $c = new Category($this->container); + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + $boardModel = new Board($this->container); - $this->assertEquals(1, $p->create(array('name' => 'P1'))); - $this->assertEquals(2, $p->create(array('name' => 'P2'))); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); - $this->assertEquals(1, $c->create(array('name' => 'C1', 'project_id' => 1))); - $this->assertEquals(2, $c->create(array('name' => 'C2', 'project_id' => 2))); - $this->assertEquals(3, $c->create(array('name' => 'C1', 'project_id' => 2))); + $this->assertTrue($boardModel->updateColumn(2, 'My unique column')); - $this->assertEquals(2, $u->create(array('username' => 'unittest1'))); - - $this->assertTrue($pp->addUser(1, 2, Role::PROJECT_MEMBER)); + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_CREATE, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); - $this->assertEquals(1, $a->create(array( + $this->assertEquals(2, $actionModel->create(array( 'project_id' => 1, - 'event_name' => Task::EVENT_CREATE_UPDATE, - 'action_name' => 'TaskAssignSpecificUser', - 'params' => array( - 'column_id' => 1, - 'user_id' => 2, - ) + 'event_name' => Task::EVENT_MOVE_COLUMN, + 'action_name' => '\Kanboard\Action\TaskAssignColorColumn', + 'params' => array('column_id' => 2, 'color_id' => 'green'), ))); - $action = $a->getById(1); - $this->assertNotEmpty($action); - $this->assertNotEmpty($action['params']); + $this->assertTrue($actionModel->duplicate(1, 2)); + + $actions = $actionModel->getAllByProject(2); + $this->assertCount(1, $actions); + + $this->assertEquals(2, $actions[0]['project_id']); + $this->assertEquals('\Kanboard\Action\TaskAssignColorColumn', $actions[0]['action_name']); + $this->assertEquals(Task::EVENT_CREATE, $actions[0]['event_name']); + $this->assertEquals(array('column_id' => 5, 'color_id' => 'red'), $actions[0]['params']); + } + + public function testDuplicateWithProjectParameter() + { + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + $this->assertEquals(3, $projectModel->create(array('name' => 'test2'))); - $this->assertEquals(2, $a->create(array( + $this->assertEquals(1, $actionModel->create(array( 'project_id' => 1, - 'event_name' => Task::EVENT_CREATE_UPDATE, - 'action_name' => 'TaskAssignCategoryColor', - 'params' => array( - 'color_id' => 'blue', - 'category_id' => 1, - ) + 'event_name' => Task::EVENT_CLOSE, + 'action_name' => '\Kanboard\Action\TaskDuplicateAnotherProject', + 'params' => array('column_id' => 1, 'project_id' => 3), ))); - $action = $a->getById(2); - $this->assertNotEmpty($action); - $this->assertNotEmpty($action['params']); - $this->assertEquals('category_id', $action['params'][1]['name']); - $this->assertEquals(1, $action['params'][1]['value']); + $this->assertTrue($actionModel->duplicate(1, 2)); - $actions = $a->getAllByProject(1); - $this->assertNotEmpty($actions); - $this->assertCount(2, $actions); + $actions = $actionModel->getAllByProject(2); + $this->assertCount(1, $actions); - $this->assertTrue($a->duplicate(1, 2)); + $this->assertEquals(2, $actions[0]['project_id']); + $this->assertEquals('\Kanboard\Action\TaskDuplicateAnotherProject', $actions[0]['action_name']); + $this->assertEquals(Task::EVENT_CLOSE, $actions[0]['event_name']); + $this->assertEquals(array('column_id' => 5, 'project_id' => 3), $actions[0]['params']); + } - $actions = $a->getAllByProject(2); - $this->assertNotEmpty($actions); - $this->assertCount(1, $actions); + public function testDuplicateWithProjectParameterIdenticalToDestination() + { + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); - $actions = $a->getAll(); - $this->assertNotEmpty($actions); - $this->assertCount(3, $actions); + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); - $action = $a->getById($actions[2]['id']); - $this->assertNotEmpty($action); - $this->assertNotEmpty($action['params']); - $this->assertEquals('color_id', $action['params'][0]['name']); - $this->assertEquals('blue', $action['params'][0]['value']); - $this->assertEquals('category_id', $action['params'][1]['name']); - $this->assertEquals(3, $action['params'][1]['value']); + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_CLOSE, + 'action_name' => '\Kanboard\Action\TaskDuplicateAnotherProject', + 'params' => array('column_id' => 1, 'project_id' => 2), + ))); + + $this->assertTrue($actionModel->duplicate(1, 2)); + + $actions = $actionModel->getAllByProject(2); + $this->assertCount(0, $actions); } - public function testSingleAction() + public function testDuplicateWithUserParameter() { - $tp = new TaskPosition($this->container); - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $board = new Board($this->container); - $project = new Project($this->container); - $action = new Action($this->container); - - // We create a project - $this->assertEquals(1, $project->create(array('name' => 'unit_test'))); - - // We create a new action - $this->assertEquals(1, $action->create(array( + $projectUserRoleModel = new ProjectUserRole($this->container); + $userModel = new User($this->container); + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + + $this->assertEquals(2, $userModel->create(array('username' => 'user1'))); + + $this->assertTrue($projectUserRoleModel->addUser(1, 2, Role::PROJECT_MEMBER)); + $this->assertTrue($projectUserRoleModel->addUser(2, 2, Role::PROJECT_MEMBER)); + + $this->assertEquals(1, $actionModel->create(array( 'project_id' => 1, 'event_name' => Task::EVENT_MOVE_COLUMN, - 'action_name' => 'TaskClose', - 'params' => array( - 'column_id' => 4, - ) + 'action_name' => '\Kanboard\Action\TaskAssignSpecificUser', + 'params' => array('column_id' => 1, 'user_id' => 2), ))); - // We create a task - $this->assertEquals(1, $tc->create(array( - 'title' => 'unit_test', + $this->assertTrue($actionModel->duplicate(1, 2)); + + $actions = $actionModel->getAllByProject(2); + $this->assertCount(1, $actions); + + $this->assertEquals(2, $actions[0]['project_id']); + $this->assertEquals('\Kanboard\Action\TaskAssignSpecificUser', $actions[0]['action_name']); + $this->assertEquals(Task::EVENT_MOVE_COLUMN, $actions[0]['event_name']); + $this->assertEquals(array('column_id' => 5, 'user_id' => 2), $actions[0]['params']); + } + + public function testDuplicateWithUserParameterButNotAssignable() + { + $projectUserRoleModel = new ProjectUserRole($this->container); + $userModel = new User($this->container); + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + + $this->assertEquals(2, $userModel->create(array('username' => 'user1'))); + + $this->assertTrue($projectUserRoleModel->addUser(1, 2, Role::PROJECT_MEMBER)); + $this->assertTrue($projectUserRoleModel->addUser(2, 2, Role::PROJECT_VIEWER)); + + $this->assertEquals(1, $actionModel->create(array( 'project_id' => 1, - 'owner_id' => 1, - 'color_id' => 'red', - 'column_id' => 1, + 'event_name' => Task::EVENT_MOVE_COLUMN, + 'action_name' => '\Kanboard\Action\TaskAssignSpecificUser', + 'params' => array('column_id' => 1, 'user_id' => 2), ))); - // We attach events - $action->attachEvents(); + $this->assertTrue($actionModel->duplicate(1, 2)); + + $actions = $actionModel->getAllByProject(2); + $this->assertCount(0, $actions); + } + + public function testDuplicateWithUserParameterButNotAvailable() + { + $projectUserRoleModel = new ProjectUserRole($this->container); + $userModel = new User($this->container); + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + + $this->assertEquals(2, $userModel->create(array('username' => 'user1'))); - // Our task should be open - $t1 = $tf->getById(1); - $this->assertEquals(1, $t1['is_active']); - $this->assertEquals(1, $t1['column_id']); + $this->assertTrue($projectUserRoleModel->addUser(1, 2, Role::PROJECT_MEMBER)); - // We move our task - $tp->movePosition(1, 1, 4, 1); + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_MOVE_COLUMN, + 'action_name' => '\Kanboard\Action\TaskAssignSpecificUser', + 'params' => array('column_id' => 1, 'owner_id' => 2), + ))); - // Our task should be closed - $t1 = $tf->getById(1); - $this->assertEquals(4, $t1['column_id']); - $this->assertEquals(0, $t1['is_active']); + $this->assertTrue($actionModel->duplicate(1, 2)); + + $actions = $actionModel->getAllByProject(2); + $this->assertCount(0, $actions); } - public function testMultipleActions() + public function testDuplicateWithCategoryParameter() { - $tp = new TaskPosition($this->container); - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $b = new Board($this->container); - $p = new Project($this->container); - $a = new Action($this->container); - $g = new GithubWebhook($this->container); - - // We create a project - $this->assertEquals(1, $p->create(array('name' => 'unit_test'))); - - // We create a new action - $this->assertEquals(1, $a->create(array( + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + $categoryModel = new Category($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + + $this->assertEquals(1, $categoryModel->create(array('name' => 'c1', 'project_id' => 1))); + $this->assertEquals(2, $categoryModel->create(array('name' => 'c1', 'project_id' => 2))); + + $this->assertEquals(1, $actionModel->create(array( 'project_id' => 1, - 'event_name' => GithubWebhook::EVENT_ISSUE_OPENED, - 'action_name' => 'TaskCreation', - 'params' => array() + 'event_name' => Task::EVENT_CREATE_UPDATE, + 'action_name' => '\Kanboard\Action\TaskAssignColorCategory', + 'params' => array('column_id' => 1, 'category_id' => 1), ))); - $this->assertEquals(2, $a->create(array( + $this->assertTrue($actionModel->duplicate(1, 2)); + + $actions = $actionModel->getAllByProject(2); + $this->assertCount(1, $actions); + + $this->assertEquals(2, $actions[0]['project_id']); + $this->assertEquals('\Kanboard\Action\TaskAssignColorCategory', $actions[0]['action_name']); + $this->assertEquals(Task::EVENT_CREATE_UPDATE, $actions[0]['event_name']); + $this->assertEquals(array('column_id' => 5, 'category_id' => 2), $actions[0]['params']); + } + + public function testDuplicateWithCategoryParameterButDifferentName() + { + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + $categoryModel = new Category($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + + $this->assertEquals(1, $categoryModel->create(array('name' => 'c1', 'project_id' => 1))); + $this->assertEquals(2, $categoryModel->create(array('name' => 'c2', 'project_id' => 2))); + + $this->assertEquals(1, $actionModel->create(array( 'project_id' => 1, - 'event_name' => GithubWebhook::EVENT_ISSUE_LABEL_CHANGE, - 'action_name' => 'TaskAssignCategoryLabel', - 'params' => array( - 'label' => 'bug', - 'category_id' => 1, - ) + 'event_name' => Task::EVENT_CREATE_UPDATE, + 'action_name' => '\Kanboard\Action\TaskAssignColorCategory', + 'params' => array('column_id' => 1, 'category_id' => 1), ))); - $this->assertEquals(3, $a->create(array( + $this->assertTrue($actionModel->duplicate(1, 2)); + + $actions = $actionModel->getAllByProject(2); + $this->assertCount(0, $actions); + } + + public function testDuplicateWithCategoryParameterButNotFound() + { + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + $categoryModel = new Category($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + + $this->assertEquals(1, $categoryModel->create(array('name' => 'c1', 'project_id' => 1))); + + $this->assertEquals(1, $actionModel->create(array( 'project_id' => 1, 'event_name' => Task::EVENT_CREATE_UPDATE, - 'action_name' => 'TaskAssignColorCategory', - 'params' => array( - 'color_id' => 'red', - 'category_id' => 1, - ) + 'action_name' => '\Kanboard\Action\TaskAssignColorCategory', + 'params' => array('column_id' => 1, 'category_id' => 1), ))); - // We attach events - $a->attachEvents(); - $g->setProjectId(1); - - // We create a Github issue - $issue = array( - 'number' => 123, - 'title' => 'Bugs everywhere', - 'body' => 'There is a bug!', - 'html_url' => 'http://localhost/', - ); - - $this->assertTrue($g->handleIssueOpened($issue)); - - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(1, $task['is_active']); - $this->assertEquals(0, $task['category_id']); - $this->assertEquals('yellow', $task['color_id']); - - // We assign a label to our issue - $label = array( - 'name' => 'bug', - ); - - $this->assertTrue($g->handleIssueLabeled($issue, $label)); - - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(1, $task['is_active']); - $this->assertEquals(1, $task['category_id']); - $this->assertEquals('red', $task['color_id']); + $this->assertTrue($actionModel->duplicate(1, 2)); + + $actions = $actionModel->getAllByProject(2); + $this->assertCount(0, $actions); } } diff --git a/tests/units/Model/ProjectDuplicationTest.php b/tests/units/Model/ProjectDuplicationTest.php index 8b74675b..db5da525 100644 --- a/tests/units/Model/ProjectDuplicationTest.php +++ b/tests/units/Model/ProjectDuplicationTest.php @@ -165,7 +165,7 @@ class ProjectDuplicationTest extends Base $this->assertNotEmpty($actions); $this->assertEquals('TaskAssignCurrentUser', $actions[0]['action_name']); $this->assertNotEmpty($actions[0]['params']); - $this->assertEquals(6, $actions[0]['params'][0]['value']); + $this->assertEquals(6, $actions[0]['params']['column_id']); } public function testCloneProjectWithActionTaskAssignColorCategory() @@ -195,8 +195,8 @@ class ProjectDuplicationTest extends Base $this->assertNotEmpty($actions); $this->assertEquals('TaskAssignColorCategory', $actions[0]['action_name']); $this->assertNotEmpty($actions[0]['params']); - $this->assertEquals('blue', $actions[0]['params'][0]['value']); - $this->assertEquals(5, $actions[0]['params'][1]['value']); + $this->assertEquals('blue', $actions[0]['params']['color_id']); + $this->assertEquals(5, $actions[0]['params']['category_id']); } public function testCloneProjectWithSwimlanesAndTasks() -- cgit v1.2.3 From 805be7d33155478ef32c4bd3643dcf4025d85a05 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Thu, 14 Jan 2016 20:18:13 -0500 Subject: Move validator methods --- app/Api/Category.php | 4 +- app/Api/Comment.php | 4 +- app/Api/Link.php | 4 +- app/Controller/Auth.php | 2 +- app/Controller/Category.php | 4 +- app/Controller/Comment.php | 4 +- app/Controller/Currency.php | 2 +- app/Controller/Customfilter.php | 4 +- app/Controller/Group.php | 4 +- app/Controller/Link.php | 4 +- app/Core/Base.php | 9 +- app/Model/Authentication.php | 130 --------------------- app/Model/Category.php | 62 ---------- app/Model/Comment.php | 61 ---------- app/Model/Currency.php | 23 ---- app/Model/CustomFilter.php | 62 ---------- app/Model/Group.php | 55 --------- app/Model/Link.php | 45 ------- app/ServiceProvider/ClassProvider.php | 8 +- app/Validator/AuthValidator.php | 130 +++++++++++++++++++++ app/Validator/CategoryValidator.php | 74 ++++++++++++ app/Validator/CommentValidator.php | 74 ++++++++++++ app/Validator/CurrencyValidator.php | 35 ++++++ app/Validator/CustomFilterValidator.php | 74 ++++++++++++ app/Validator/GroupValidator.php | 71 +++++++++++ app/Validator/LinkValidator.php | 59 ++++++++++ tests/units/Model/CommentTest.php | 49 -------- tests/units/Model/CustomFilterTest.php | 28 ----- tests/units/Model/GroupTest.php | 22 ---- tests/units/Model/LinkTest.php | 46 -------- tests/units/Validator/CommentValidatorTest.php | 57 +++++++++ .../units/Validator/CustomFilterValidatorTest.php | 40 +++++++ tests/units/Validator/GroupValidatorTest.php | 30 +++++ tests/units/Validator/LinkValidatorTest.php | 54 +++++++++ 34 files changed, 731 insertions(+), 603 deletions(-) delete mode 100644 app/Model/Authentication.php create mode 100644 app/Validator/AuthValidator.php create mode 100644 app/Validator/CategoryValidator.php create mode 100644 app/Validator/CommentValidator.php create mode 100644 app/Validator/CurrencyValidator.php create mode 100644 app/Validator/CustomFilterValidator.php create mode 100644 app/Validator/GroupValidator.php create mode 100644 app/Validator/LinkValidator.php create mode 100644 tests/units/Validator/CommentValidatorTest.php create mode 100644 tests/units/Validator/CustomFilterValidatorTest.php create mode 100644 tests/units/Validator/GroupValidatorTest.php create mode 100644 tests/units/Validator/LinkValidatorTest.php (limited to 'app/Model/Comment.php') diff --git a/app/Api/Category.php b/app/Api/Category.php index 458eaef6..fbd61c56 100644 --- a/app/Api/Category.php +++ b/app/Api/Category.php @@ -32,7 +32,7 @@ class Category extends \Kanboard\Core\Base 'name' => $name, ); - list($valid, ) = $this->category->validateCreation($values); + list($valid, ) = $this->categoryValidator->validateCreation($values); return $valid ? $this->category->create($values) : false; } @@ -43,7 +43,7 @@ class Category extends \Kanboard\Core\Base 'name' => $name, ); - list($valid, ) = $this->category->validateModification($values); + list($valid, ) = $this->categoryValidator->validateModification($values); return $valid && $this->category->update($values); } } diff --git a/app/Api/Comment.php b/app/Api/Comment.php index 4c4027c0..1fc1c708 100644 --- a/app/Api/Comment.php +++ b/app/Api/Comment.php @@ -34,7 +34,7 @@ class Comment extends \Kanboard\Core\Base 'reference' => $reference, ); - list($valid, ) = $this->comment->validateCreation($values); + list($valid, ) = $this->commentValidator->validateCreation($values); return $valid ? $this->comment->create($values) : false; } @@ -46,7 +46,7 @@ class Comment extends \Kanboard\Core\Base 'comment' => $content, ); - list($valid, ) = $this->comment->validateModification($values); + list($valid, ) = $this->commentValidator->validateModification($values); return $valid && $this->comment->update($values); } } diff --git a/app/Api/Link.php b/app/Api/Link.php index d4df18fe..23a9916d 100644 --- a/app/Api/Link.php +++ b/app/Api/Link.php @@ -72,7 +72,7 @@ class Link extends \Kanboard\Core\Base 'opposite_label' => $opposite_label, ); - list($valid, ) = $this->link->validateCreation($values); + list($valid, ) = $this->linkValidator->validateCreation($values); return $valid ? $this->link->create($label, $opposite_label) : false; } @@ -93,7 +93,7 @@ class Link extends \Kanboard\Core\Base 'label' => $label, ); - list($valid, ) = $this->link->validateModification($values); + list($valid, ) = $this->linkValidator->validateModification($values); return $valid && $this->link->update($values); } diff --git a/app/Controller/Auth.php b/app/Controller/Auth.php index 07e66070..5284e126 100644 --- a/app/Controller/Auth.php +++ b/app/Controller/Auth.php @@ -39,7 +39,7 @@ class Auth extends Base { $values = $this->request->getValues(); $this->sessionStorage->hasRememberMe = ! empty($values['remember_me']); - list($valid, $errors) = $this->authentication->validateForm($values); + list($valid, $errors) = $this->authValidator->validateForm($values); if ($valid) { $this->redirectAfterLogin(); diff --git a/app/Controller/Category.php b/app/Controller/Category.php index 9864348c..a0af4139 100644 --- a/app/Controller/Category.php +++ b/app/Controller/Category.php @@ -57,7 +57,7 @@ class Category extends Base $project = $this->getProject(); $values = $this->request->getValues(); - list($valid, $errors) = $this->category->validateCreation($values); + list($valid, $errors) = $this->categoryValidator->validateCreation($values); if ($valid) { if ($this->category->create($values)) { @@ -99,7 +99,7 @@ class Category extends Base $project = $this->getProject(); $values = $this->request->getValues(); - list($valid, $errors) = $this->category->validateModification($values); + list($valid, $errors) = $this->categoryValidator->validateModification($values); if ($valid) { if ($this->category->update($values)) { diff --git a/app/Controller/Comment.php b/app/Controller/Comment.php index 54339e48..a608dd1c 100644 --- a/app/Controller/Comment.php +++ b/app/Controller/Comment.php @@ -78,7 +78,7 @@ class Comment extends Base $values = $this->request->getValues(); $ajax = $this->request->isAjax() || $this->request->getIntegerParam('ajax'); - list($valid, $errors) = $this->comment->validateCreation($values); + list($valid, $errors) = $this->commentValidator->validateCreation($values); if ($valid) { if ($this->comment->create($values)) { @@ -127,7 +127,7 @@ class Comment extends Base $comment = $this->getComment(); $values = $this->request->getValues(); - list($valid, $errors) = $this->comment->validateModification($values); + list($valid, $errors) = $this->commentValidator->validateModification($values); if ($valid) { if ($this->comment->update($values)) { diff --git a/app/Controller/Currency.php b/app/Controller/Currency.php index 4c5b8ee8..3d0deeac 100644 --- a/app/Controller/Currency.php +++ b/app/Controller/Currency.php @@ -51,7 +51,7 @@ class Currency extends Base public function create() { $values = $this->request->getValues(); - list($valid, $errors) = $this->currency->validate($values); + list($valid, $errors) = $this->currencyValidator->validateCreation($values); if ($valid) { if ($this->currency->create($values['currency'], $values['rate'])) { diff --git a/app/Controller/Customfilter.php b/app/Controller/Customfilter.php index 12cc8e78..1b43f1d0 100644 --- a/app/Controller/Customfilter.php +++ b/app/Controller/Customfilter.php @@ -42,7 +42,7 @@ class Customfilter extends Base $values = $this->request->getValues(); $values['user_id'] = $this->userSession->getId(); - list($valid, $errors) = $this->customFilter->validateCreation($values); + list($valid, $errors) = $this->customFilterValidator->validateCreation($values); if ($valid) { if ($this->customFilter->create($values)) { @@ -121,7 +121,7 @@ class Customfilter extends Base $values += array('append' => 0); } - list($valid, $errors) = $this->customFilter->validateModification($values); + list($valid, $errors) = $this->customFilterValidator->validateModification($values); if ($valid) { if ($this->customFilter->update($values)) { diff --git a/app/Controller/Group.php b/app/Controller/Group.php index 3c9c4a07..e952c0e5 100644 --- a/app/Controller/Group.php +++ b/app/Controller/Group.php @@ -79,7 +79,7 @@ class Group extends Base public function save() { $values = $this->request->getValues(); - list($valid, $errors) = $this->group->validateCreation($values); + list($valid, $errors) = $this->groupValidator->validateCreation($values); if ($valid) { if ($this->group->create($values['name']) !== false) { @@ -120,7 +120,7 @@ class Group extends Base public function update() { $values = $this->request->getValues(); - list($valid, $errors) = $this->group->validateModification($values); + list($valid, $errors) = $this->groupValidator->validateModification($values); if ($valid) { if ($this->group->update($values) !== false) { diff --git a/app/Controller/Link.php b/app/Controller/Link.php index 2ae57b1a..d52d1f91 100644 --- a/app/Controller/Link.php +++ b/app/Controller/Link.php @@ -67,7 +67,7 @@ class Link extends Base public function save() { $values = $this->request->getValues(); - list($valid, $errors) = $this->link->validateCreation($values); + list($valid, $errors) = $this->linkValidator->validateCreation($values); if ($valid) { if ($this->link->create($values['label'], $values['opposite_label']) !== false) { @@ -108,7 +108,7 @@ class Link extends Base public function update() { $values = $this->request->getValues(); - list($valid, $errors) = $this->link->validateModification($values); + list($valid, $errors) = $this->linkValidator->validateModification($values); if ($valid) { if ($this->link->update($values)) { diff --git a/app/Core/Base.php b/app/Core/Base.php index 22f09403..a3a30e60 100644 --- a/app/Core/Base.php +++ b/app/Core/Base.php @@ -54,7 +54,6 @@ use Pimple\Container; * @property \Kanboard\Formatter\GroupAutoCompleteFormatter $groupAutoCompleteFormatter * @property \Kanboard\Model\Action $action * @property \Kanboard\Model\ActionParameter $actionParameter - * @property \Kanboard\Model\Authentication $authentication * @property \Kanboard\Model\Board $board * @property \Kanboard\Model\Category $category * @property \Kanboard\Model\Color $color @@ -114,7 +113,15 @@ use Pimple\Container; * @property \Kanboard\Model\UserMetadata $userMetadata * @property \Kanboard\Model\Webhook $webhook * @property \Kanboard\Validator\ActionValidator $actionValidator + * @property \Kanboard\Validator\AuthValidator $authValidator * @property \Kanboard\Validator\ColumnValidator $columnValidator + * @property \Kanboard\Validator\CategoryValidator $categoryValidator + * @property \Kanboard\Validator\ColumnValidator $columnValidator + * @property \Kanboard\Validator\CommentValidator $commentValidator + * @property \Kanboard\Validator\CurrencyValidator $currencyValidator + * @property \Kanboard\Validator\CustomFilterValidator $customFilterValidator + * @property \Kanboard\Validator\GroupValidator $groupValidator + * @property \Kanboard\Validator\LinkValidator $linkValidator * @property \Kanboard\Validator\PasswordResetValidator $passwordResetValidator * @property \Kanboard\Validator\ProjectValidator $projectValidator * @property \Kanboard\Validator\SubtaskValidator $subtaskValidator diff --git a/app/Model/Authentication.php b/app/Model/Authentication.php deleted file mode 100644 index d10f2bf8..00000000 --- a/app/Model/Authentication.php +++ /dev/null @@ -1,130 +0,0 @@ -$method($values); - - if (! $result) { - break; - } - } - - return array($result, $errors); - } - - /** - * Validate credentials syntax - * - * @access private - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - private function validateFields(array $values) - { - $v = new Validator($values, array( - new Validators\Required('username', t('The username is required')), - new Validators\MaxLength('username', t('The maximum length is %d characters', 50), 50), - new Validators\Required('password', t('The password is required')), - )); - - return array( - $v->execute(), - $v->getErrors(), - ); - } - - /** - * Validate user locking - * - * @access private - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - private function validateLocking(array $values) - { - $result = true; - $errors = array(); - - if ($this->userLocking->isLocked($values['username'])) { - $result = false; - $errors['login'] = t('Your account is locked for %d minutes', BRUTEFORCE_LOCKDOWN_DURATION); - $this->logger->error('Account locked: '.$values['username']); - } - - return array($result, $errors); - } - - /** - * Validate password syntax - * - * @access private - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - private function validateCredentials(array $values) - { - $result = true; - $errors = array(); - - if (! $this->authenticationManager->passwordAuthentication($values['username'], $values['password'])) { - $result = false; - $errors['login'] = t('Bad username or password'); - } - - return array($result, $errors); - } - - /** - * Validate captcha - * - * @access private - * @param array $values Form values - * @return boolean - */ - private function validateCaptcha(array $values) - { - $result = true; - $errors = array(); - - if ($this->userLocking->hasCaptcha($values['username'])) { - if (! isset($this->sessionStorage->captcha)) { - $result = false; - } else { - $builder = new CaptchaBuilder; - $builder->setPhrase($this->sessionStorage->captcha); - $result = $builder->testPhrase(isset($values['captcha']) ? $values['captcha'] : ''); - - if (! $result) { - $errors['login'] = t('Invalid captcha'); - } - } - } - - return array($result, $errors);; - } -} diff --git a/app/Model/Category.php b/app/Model/Category.php index bf40c60a..58cee738 100644 --- a/app/Model/Category.php +++ b/app/Model/Category.php @@ -2,9 +2,6 @@ namespace Kanboard\Model; -use SimpleValidator\Validator; -use SimpleValidator\Validators; - /** * Category model * @@ -212,63 +209,4 @@ class Category extends Base return true; } - - /** - * Validate category creation - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateCreation(array $values) - { - $rules = array( - new Validators\Required('project_id', t('The project id is required')), - new Validators\Required('name', t('The name is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate category modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The id is required')), - new Validators\Required('name', t('The name is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Common validation rules - * - * @access private - * @return array - */ - private function commonValidationRules() - { - return array( - new Validators\Integer('id', t('The id must be an integer')), - new Validators\Integer('project_id', t('The project id must be an integer')), - new Validators\MaxLength('name', t('The maximum length is %d characters', 50), 50) - ); - } } diff --git a/app/Model/Comment.php b/app/Model/Comment.php index eb83f8d6..6eb4a1e5 100644 --- a/app/Model/Comment.php +++ b/app/Model/Comment.php @@ -3,8 +3,6 @@ namespace Kanboard\Model; use Kanboard\Event\CommentEvent; -use SimpleValidator\Validator; -use SimpleValidator\Validators; /** * Comment model @@ -152,63 +150,4 @@ class Comment extends Base { return $this->db->table(self::TABLE)->eq('id', $comment_id)->remove(); } - - /** - * Validate comment creation - * - * @access public - * @param array $values Required parameters to save an action - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateCreation(array $values) - { - $rules = array( - new Validators\Required('task_id', t('This value is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate comment modification - * - * @access public - * @param array $values Required parameters to save an action - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('This value is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Common validation rules - * - * @access private - * @return array - */ - private function commonValidationRules() - { - return array( - new Validators\Integer('id', t('This value must be an integer')), - new Validators\Integer('task_id', t('This value must be an integer')), - new Validators\Integer('user_id', t('This value must be an integer')), - new Validators\MaxLength('reference', t('The maximum length is %d characters', 50), 50), - new Validators\Required('comment', t('Comment is required')) - ); - } } diff --git a/app/Model/Currency.php b/app/Model/Currency.php index c1156610..316a0141 100644 --- a/app/Model/Currency.php +++ b/app/Model/Currency.php @@ -2,9 +2,6 @@ namespace Kanboard\Model; -use SimpleValidator\Validator; -use SimpleValidator\Validators; - /** * Currency * @@ -83,24 +80,4 @@ class Currency extends Base { return $this->db->table(self::TABLE)->eq('currency', $currency)->update(array('rate' => $rate)); } - - /** - * Validate - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validate(array $values) - { - $v = new Validator($values, array( - new Validators\Required('currency', t('Field required')), - new Validators\Required('rate', t('Field required')), - )); - - return array( - $v->execute(), - $v->getErrors() - ); - } } diff --git a/app/Model/CustomFilter.php b/app/Model/CustomFilter.php index 6550b4a7..3a6a1a3a 100644 --- a/app/Model/CustomFilter.php +++ b/app/Model/CustomFilter.php @@ -2,9 +2,6 @@ namespace Kanboard\Model; -use SimpleValidator\Validator; -use SimpleValidator\Validators; - /** * Custom Filter model * @@ -102,63 +99,4 @@ class CustomFilter extends Base { return $this->db->table(self::TABLE)->eq('id', $filter_id)->remove(); } - - /** - * Common validation rules - * - * @access private - * @return array - */ - private function commonValidationRules() - { - return array( - new Validators\Required('project_id', t('Field required')), - new Validators\Required('user_id', t('Field required')), - new Validators\Required('name', t('Field required')), - new Validators\Required('filter', t('Field required')), - new Validators\Integer('user_id', t('This value must be an integer')), - new Validators\Integer('project_id', t('This value must be an integer')), - new Validators\MaxLength('name', t('The maximum length is %d characters', 100), 100), - new Validators\MaxLength('filter', t('The maximum length is %d characters', 100), 100) - ); - } - - /** - * Validate filter creation - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateCreation(array $values) - { - $v = new Validator($values, $this->commonValidationRules()); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate filter modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('Field required')), - new Validators\Integer('id', t('This value must be an integer')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } } diff --git a/app/Model/Group.php b/app/Model/Group.php index a086fe9d..ce8c0284 100644 --- a/app/Model/Group.php +++ b/app/Model/Group.php @@ -117,59 +117,4 @@ class Group extends Base { return $this->db->table(self::TABLE)->eq('id', $values['id'])->update($values); } - - /** - * Validate creation - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateCreation(array $values) - { - $v = new Validator($values, $this->commonValidationRules()); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The id is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Common validation rules - * - * @access private - * @return array - */ - private function commonValidationRules() - { - return array( - new Validators\Required('name', t('The name is required')), - new Validators\MaxLength('name', t('The maximum length is %d characters', 100), 100), - new Validators\Unique('name', t('The name must be unique'), $this->db->getConnection(), self::TABLE, 'id'), - new Validators\MaxLength('external_id', t('The maximum length is %d characters', 255), 255), - new Validators\Integer('id', t('This value must be an integer')), - ); - } } diff --git a/app/Model/Link.php b/app/Model/Link.php index 00b6dfc5..7b81a237 100644 --- a/app/Model/Link.php +++ b/app/Model/Link.php @@ -3,8 +3,6 @@ namespace Kanboard\Model; use PDO; -use SimpleValidator\Validator; -use SimpleValidator\Validators; /** * Link model @@ -176,47 +174,4 @@ class Link extends Base $this->db->table(self::TABLE)->eq('opposite_id', $link_id)->update(array('opposite_id' => 0)); return $this->db->table(self::TABLE)->eq('id', $link_id)->remove(); } - - /** - * Validate creation - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateCreation(array $values) - { - $v = new Validator($values, array( - new Validators\Required('label', t('Field required')), - new Validators\Unique('label', t('This label must be unique'), $this->db->getConnection(), self::TABLE), - new Validators\NotEquals('label', 'opposite_label', t('The labels must be different')), - )); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $v = new Validator($values, array( - new Validators\Required('id', t('Field required')), - new Validators\Required('opposite_id', t('Field required')), - new Validators\Required('label', t('Field required')), - new Validators\Unique('label', t('This label must be unique'), $this->db->getConnection(), self::TABLE), - )); - - return array( - $v->execute(), - $v->getErrors() - ); - } } diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php index 61c97a07..a0f8901a 100644 --- a/app/ServiceProvider/ClassProvider.php +++ b/app/ServiceProvider/ClassProvider.php @@ -17,7 +17,6 @@ class ClassProvider implements ServiceProviderInterface 'Model' => array( 'Action', 'ActionParameter', - 'Authentication', 'Board', 'Category', 'Color', @@ -86,7 +85,14 @@ class ClassProvider implements ServiceProviderInterface ), 'Validator' => array( 'ActionValidator', + 'AuthValidator', + 'CategoryValidator', 'ColumnValidator', + 'CommentValidator', + 'CurrencyValidator', + 'CustomFilterValidator', + 'GroupValidator', + 'LinkValidator', 'PasswordResetValidator', 'ProjectValidator', 'SubtaskValidator', diff --git a/app/Validator/AuthValidator.php b/app/Validator/AuthValidator.php new file mode 100644 index 00000000..e77a88c8 --- /dev/null +++ b/app/Validator/AuthValidator.php @@ -0,0 +1,130 @@ +$method($values); + + if (! $result) { + break; + } + } + + return array($result, $errors); + } + + /** + * Validate credentials syntax + * + * @access private + * @param array $values Form values + * @return array $valid, $errors [0] = Success or not, [1] = List of errors + */ + private function validateFields(array $values) + { + $v = new Validator($values, array( + new Validators\Required('username', t('The username is required')), + new Validators\MaxLength('username', t('The maximum length is %d characters', 50), 50), + new Validators\Required('password', t('The password is required')), + )); + + return array( + $v->execute(), + $v->getErrors(), + ); + } + + /** + * Validate user locking + * + * @access private + * @param array $values Form values + * @return array $valid, $errors [0] = Success or not, [1] = List of errors + */ + private function validateLocking(array $values) + { + $result = true; + $errors = array(); + + if ($this->userLocking->isLocked($values['username'])) { + $result = false; + $errors['login'] = t('Your account is locked for %d minutes', BRUTEFORCE_LOCKDOWN_DURATION); + $this->logger->error('Account locked: '.$values['username']); + } + + return array($result, $errors); + } + + /** + * Validate password syntax + * + * @access private + * @param array $values Form values + * @return array $valid, $errors [0] = Success or not, [1] = List of errors + */ + private function validateCredentials(array $values) + { + $result = true; + $errors = array(); + + if (! $this->authenticationManager->passwordAuthentication($values['username'], $values['password'])) { + $result = false; + $errors['login'] = t('Bad username or password'); + } + + return array($result, $errors); + } + + /** + * Validate captcha + * + * @access private + * @param array $values Form values + * @return boolean + */ + private function validateCaptcha(array $values) + { + $result = true; + $errors = array(); + + if ($this->userLocking->hasCaptcha($values['username'])) { + if (! isset($this->sessionStorage->captcha)) { + $result = false; + } else { + $builder = new CaptchaBuilder; + $builder->setPhrase($this->sessionStorage->captcha); + $result = $builder->testPhrase(isset($values['captcha']) ? $values['captcha'] : ''); + + if (! $result) { + $errors['login'] = t('Invalid captcha'); + } + } + } + + return array($result, $errors);; + } +} diff --git a/app/Validator/CategoryValidator.php b/app/Validator/CategoryValidator.php new file mode 100644 index 00000000..715aed66 --- /dev/null +++ b/app/Validator/CategoryValidator.php @@ -0,0 +1,74 @@ +commonValidationRules())); + + return array( + $v->execute(), + $v->getErrors() + ); + } + + /** + * Validate category modification + * + * @access public + * @param array $values Form values + * @return array $valid, $errors [0] = Success or not, [1] = List of errors + */ + public function validateModification(array $values) + { + $rules = array( + new Validators\Required('id', t('The id is required')), + new Validators\Required('name', t('The name is required')), + ); + + $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); + + return array( + $v->execute(), + $v->getErrors() + ); + } + + /** + * Common validation rules + * + * @access private + * @return array + */ + private function commonValidationRules() + { + return array( + new Validators\Integer('id', t('The id must be an integer')), + new Validators\Integer('project_id', t('The project id must be an integer')), + new Validators\MaxLength('name', t('The maximum length is %d characters', 50), 50) + ); + } +} diff --git a/app/Validator/CommentValidator.php b/app/Validator/CommentValidator.php new file mode 100644 index 00000000..4eb54206 --- /dev/null +++ b/app/Validator/CommentValidator.php @@ -0,0 +1,74 @@ +commonValidationRules())); + + return array( + $v->execute(), + $v->getErrors() + ); + } + + /** + * Validate comment modification + * + * @access public + * @param array $values Required parameters to save an action + * @return array $valid, $errors [0] = Success or not, [1] = List of errors + */ + public function validateModification(array $values) + { + $rules = array( + new Validators\Required('id', t('This value is required')), + ); + + $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); + + return array( + $v->execute(), + $v->getErrors() + ); + } + + /** + * Common validation rules + * + * @access private + * @return array + */ + private function commonValidationRules() + { + return array( + new Validators\Integer('id', t('This value must be an integer')), + new Validators\Integer('task_id', t('This value must be an integer')), + new Validators\Integer('user_id', t('This value must be an integer')), + new Validators\MaxLength('reference', t('The maximum length is %d characters', 50), 50), + new Validators\Required('comment', t('Comment is required')) + ); + } +} diff --git a/app/Validator/CurrencyValidator.php b/app/Validator/CurrencyValidator.php new file mode 100644 index 00000000..a00af738 --- /dev/null +++ b/app/Validator/CurrencyValidator.php @@ -0,0 +1,35 @@ +execute(), + $v->getErrors() + ); + } +} diff --git a/app/Validator/CustomFilterValidator.php b/app/Validator/CustomFilterValidator.php new file mode 100644 index 00000000..07f2a1eb --- /dev/null +++ b/app/Validator/CustomFilterValidator.php @@ -0,0 +1,74 @@ +commonValidationRules()); + + return array( + $v->execute(), + $v->getErrors() + ); + } + + /** + * Validate filter modification + * + * @access public + * @param array $values Form values + * @return array $valid, $errors [0] = Success or not, [1] = List of errors + */ + public function validateModification(array $values) + { + $rules = array( + new Validators\Required('id', t('Field required')), + new Validators\Integer('id', t('This value must be an integer')), + ); + + $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); + + return array( + $v->execute(), + $v->getErrors() + ); + } +} diff --git a/app/Validator/GroupValidator.php b/app/Validator/GroupValidator.php new file mode 100644 index 00000000..2226abd3 --- /dev/null +++ b/app/Validator/GroupValidator.php @@ -0,0 +1,71 @@ +commonValidationRules()); + + return array( + $v->execute(), + $v->getErrors() + ); + } + + /** + * Validate modification + * + * @access public + * @param array $values Form values + * @return array $valid, $errors [0] = Success or not, [1] = List of errors + */ + public function validateModification(array $values) + { + $rules = array( + new Validators\Required('id', t('The id is required')), + ); + + $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); + + return array( + $v->execute(), + $v->getErrors() + ); + } + + /** + * Common validation rules + * + * @access private + * @return array + */ + private function commonValidationRules() + { + return array( + new Validators\Required('name', t('The name is required')), + new Validators\MaxLength('name', t('The maximum length is %d characters', 100), 100), + new Validators\Unique('name', t('The name must be unique'), $this->db->getConnection(), Group::TABLE, 'id'), + new Validators\MaxLength('external_id', t('The maximum length is %d characters', 255), 255), + new Validators\Integer('id', t('This value must be an integer')), + ); + } +} diff --git a/app/Validator/LinkValidator.php b/app/Validator/LinkValidator.php new file mode 100644 index 00000000..10a826da --- /dev/null +++ b/app/Validator/LinkValidator.php @@ -0,0 +1,59 @@ +db->getConnection(), Link::TABLE), + new Validators\NotEquals('label', 'opposite_label', t('The labels must be different')), + )); + + return array( + $v->execute(), + $v->getErrors() + ); + } + + /** + * Validate modification + * + * @access public + * @param array $values Form values + * @return array $valid, $errors [0] = Success or not, [1] = List of errors + */ + public function validateModification(array $values) + { + $v = new Validator($values, array( + new Validators\Required('id', t('Field required')), + new Validators\Required('opposite_id', t('Field required')), + new Validators\Required('label', t('Field required')), + new Validators\Unique('label', t('This label must be unique'), $this->db->getConnection(), Link::TABLE), + )); + + return array( + $v->execute(), + $v->getErrors() + ); + } +} diff --git a/tests/units/Model/CommentTest.php b/tests/units/Model/CommentTest.php index 07c39fe3..ec4e7a56 100644 --- a/tests/units/Model/CommentTest.php +++ b/tests/units/Model/CommentTest.php @@ -90,53 +90,4 @@ class CommentTest extends Base $this->assertFalse($c->remove(1)); $this->assertFalse($c->remove(1111)); } - - public function testValidateCreation() - { - $c = new Comment($this->container); - - $result = $c->validateCreation(array('user_id' => 1, 'task_id' => 1, 'comment' => 'bla')); - $this->assertTrue($result[0]); - - $result = $c->validateCreation(array('user_id' => 1, 'task_id' => 1, 'comment' => '')); - $this->assertFalse($result[0]); - - $result = $c->validateCreation(array('user_id' => 1, 'task_id' => 'a', 'comment' => 'bla')); - $this->assertFalse($result[0]); - - $result = $c->validateCreation(array('user_id' => 'b', 'task_id' => 1, 'comment' => 'bla')); - $this->assertFalse($result[0]); - - $result = $c->validateCreation(array('user_id' => 1, 'comment' => 'bla')); - $this->assertFalse($result[0]); - - $result = $c->validateCreation(array('task_id' => 1, 'comment' => 'bla')); - $this->assertTrue($result[0]); - - $result = $c->validateCreation(array('comment' => 'bla')); - $this->assertFalse($result[0]); - - $result = $c->validateCreation(array()); - $this->assertFalse($result[0]); - } - - public function testValidateModification() - { - $c = new Comment($this->container); - - $result = $c->validateModification(array('id' => 1, 'comment' => 'bla')); - $this->assertTrue($result[0]); - - $result = $c->validateModification(array('id' => 1, 'comment' => '')); - $this->assertFalse($result[0]); - - $result = $c->validateModification(array('comment' => 'bla')); - $this->assertFalse($result[0]); - - $result = $c->validateModification(array('id' => 'b', 'comment' => 'bla')); - $this->assertFalse($result[0]); - - $result = $c->validateModification(array()); - $this->assertFalse($result[0]); - } } diff --git a/tests/units/Model/CustomFilterTest.php b/tests/units/Model/CustomFilterTest.php index 190da899..a73bc401 100644 --- a/tests/units/Model/CustomFilterTest.php +++ b/tests/units/Model/CustomFilterTest.php @@ -52,34 +52,6 @@ class CustomFilterTest extends Base $this->assertEquals(1, $filter['is_shared']); } - public function testValidation() - { - $cf = new CustomFilter($this->container); - - // Validate creation - $r = $cf->validateCreation(array('filter' => 'test', 'name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); - $this->assertTrue($r[0]); - - $r = $cf->validateCreation(array('filter' => str_repeat('a', 101), 'name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); - $this->assertFalse($r[0]); - - $r = $cf->validateCreation(array('name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); - $this->assertFalse($r[0]); - - // Validate modification - $r = $cf->validateModification(array('id' => 1, 'filter' => 'test', 'name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); - $this->assertTrue($r[0]); - - $r = $cf->validateModification(array('filter' => 'test', 'name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); - $this->assertFalse($r[0]); - - $r = $cf->validateModification(array('id' => 1, 'filter' => str_repeat('a', 101), 'name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); - $this->assertFalse($r[0]); - - $r = $cf->validateModification(array('id' => 1, 'name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); - $this->assertFalse($r[0]); - } - public function testGetAll() { $u = new User($this->container); diff --git a/tests/units/Model/GroupTest.php b/tests/units/Model/GroupTest.php index 2cbb254a..36b47dc5 100644 --- a/tests/units/Model/GroupTest.php +++ b/tests/units/Model/GroupTest.php @@ -57,26 +57,4 @@ class GroupTest extends Base $this->assertTrue($groupModel->remove(1)); $this->assertEmpty($groupModel->getById(1)); } - - public function testValidateCreation() - { - $groupModel = new Group($this->container); - - $result = $groupModel->validateCreation(array('name' => 'Test')); - $this->assertTrue($result[0]); - - $result = $groupModel->validateCreation(array('name' => '')); - $this->assertFalse($result[0]); - } - - public function testValidateModification() - { - $groupModel = new Group($this->container); - - $result = $groupModel->validateModification(array('name' => 'Test', 'id' => 1)); - $this->assertTrue($result[0]); - - $result = $groupModel->validateModification(array('name' => 'Test')); - $this->assertFalse($result[0]); - } } diff --git a/tests/units/Model/LinkTest.php b/tests/units/Model/LinkTest.php index de9d843a..b102646d 100644 --- a/tests/units/Model/LinkTest.php +++ b/tests/units/Model/LinkTest.php @@ -124,50 +124,4 @@ class LinkTest extends Base $this->assertArrayNotHasKey(0, $links); $this->assertEquals('relates to', $links[1]); } - - public function testValidateCreation() - { - $l = new Link($this->container); - - $r = $l->validateCreation(array('label' => 'a')); - $this->assertTrue($r[0]); - - $r = $l->validateCreation(array('label' => 'a', 'opposite_label' => 'b')); - $this->assertTrue($r[0]); - - $r = $l->validateCreation(array('label' => 'relates to')); - $this->assertFalse($r[0]); - - $r = $l->validateCreation(array('label' => 'a', 'opposite_label' => 'a')); - $this->assertFalse($r[0]); - - $r = $l->validateCreation(array('label' => '')); - $this->assertFalse($r[0]); - } - - public function testValidateModification() - { - $l = new Link($this->container); - - $r = $l->validateModification(array('id' => 20, 'label' => 'a', 'opposite_id' => 0)); - $this->assertTrue($r[0]); - - $r = $l->validateModification(array('id' => 20, 'label' => 'a', 'opposite_id' => '1')); - $this->assertTrue($r[0]); - - $r = $l->validateModification(array('id' => 20, 'label' => 'relates to', 'opposite_id' => '1')); - $this->assertFalse($r[0]); - - $r = $l->validateModification(array('id' => 20, 'label' => '', 'opposite_id' => '1')); - $this->assertFalse($r[0]); - - $r = $l->validateModification(array('label' => '', 'opposite_id' => '1')); - $this->assertFalse($r[0]); - - $r = $l->validateModification(array('id' => 20, 'opposite_id' => '1')); - $this->assertFalse($r[0]); - - $r = $l->validateModification(array('label' => 'test')); - $this->assertFalse($r[0]); - } } diff --git a/tests/units/Validator/CommentValidatorTest.php b/tests/units/Validator/CommentValidatorTest.php new file mode 100644 index 00000000..378fe924 --- /dev/null +++ b/tests/units/Validator/CommentValidatorTest.php @@ -0,0 +1,57 @@ +container); + + $result = $validator->validateCreation(array('user_id' => 1, 'task_id' => 1, 'comment' => 'bla')); + $this->assertTrue($result[0]); + + $result = $validator->validateCreation(array('user_id' => 1, 'task_id' => 1, 'comment' => '')); + $this->assertFalse($result[0]); + + $result = $validator->validateCreation(array('user_id' => 1, 'task_id' => 'a', 'comment' => 'bla')); + $this->assertFalse($result[0]); + + $result = $validator->validateCreation(array('user_id' => 'b', 'task_id' => 1, 'comment' => 'bla')); + $this->assertFalse($result[0]); + + $result = $validator->validateCreation(array('user_id' => 1, 'comment' => 'bla')); + $this->assertFalse($result[0]); + + $result = $validator->validateCreation(array('task_id' => 1, 'comment' => 'bla')); + $this->assertTrue($result[0]); + + $result = $validator->validateCreation(array('comment' => 'bla')); + $this->assertFalse($result[0]); + + $result = $validator->validateCreation(array()); + $this->assertFalse($result[0]); + } + + public function testValidateModification() + { + $validator = new CommentValidator($this->container); + + $result = $validator->validateModification(array('id' => 1, 'comment' => 'bla')); + $this->assertTrue($result[0]); + + $result = $validator->validateModification(array('id' => 1, 'comment' => '')); + $this->assertFalse($result[0]); + + $result = $validator->validateModification(array('comment' => 'bla')); + $this->assertFalse($result[0]); + + $result = $validator->validateModification(array('id' => 'b', 'comment' => 'bla')); + $this->assertFalse($result[0]); + + $result = $validator->validateModification(array()); + $this->assertFalse($result[0]); + } +} diff --git a/tests/units/Validator/CustomFilterValidatorTest.php b/tests/units/Validator/CustomFilterValidatorTest.php new file mode 100644 index 00000000..3b70e42c --- /dev/null +++ b/tests/units/Validator/CustomFilterValidatorTest.php @@ -0,0 +1,40 @@ +container); + + // Validate creation + $r = $validator->validateCreation(array('filter' => 'test', 'name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); + $this->assertTrue($r[0]); + + $r = $validator->validateCreation(array('filter' => str_repeat('a', 101), 'name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); + $this->assertFalse($r[0]); + + $r = $validator->validateCreation(array('name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); + $this->assertFalse($r[0]); + } + + public function testValidateModification() + { + $validator = new CustomFilterValidator($this->container); + + $r = $validator->validateModification(array('id' => 1, 'filter' => 'test', 'name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); + $this->assertTrue($r[0]); + + $r = $validator->validateModification(array('filter' => 'test', 'name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); + $this->assertFalse($r[0]); + + $r = $validator->validateModification(array('id' => 1, 'filter' => str_repeat('a', 101), 'name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); + $this->assertFalse($r[0]); + + $r = $validator->validateModification(array('id' => 1, 'name' => 'test', 'user_id' => 1, 'project_id' => 1, 'is_shared' => 0)); + $this->assertFalse($r[0]); + } +} diff --git a/tests/units/Validator/GroupValidatorTest.php b/tests/units/Validator/GroupValidatorTest.php new file mode 100644 index 00000000..879f99ce --- /dev/null +++ b/tests/units/Validator/GroupValidatorTest.php @@ -0,0 +1,30 @@ +container); + + $result = $validator->validateCreation(array('name' => 'Test')); + $this->assertTrue($result[0]); + + $result = $validator->validateCreation(array('name' => '')); + $this->assertFalse($result[0]); + } + + public function testValidateModification() + { + $validator = new GroupValidator($this->container); + + $result = $validator->validateModification(array('name' => 'Test', 'id' => 1)); + $this->assertTrue($result[0]); + + $result = $validator->validateModification(array('name' => 'Test')); + $this->assertFalse($result[0]); + } +} diff --git a/tests/units/Validator/LinkValidatorTest.php b/tests/units/Validator/LinkValidatorTest.php new file mode 100644 index 00000000..8b7b182c --- /dev/null +++ b/tests/units/Validator/LinkValidatorTest.php @@ -0,0 +1,54 @@ +container); + + $r = $validator->validateCreation(array('label' => 'a')); + $this->assertTrue($r[0]); + + $r = $validator->validateCreation(array('label' => 'a', 'opposite_label' => 'b')); + $this->assertTrue($r[0]); + + $r = $validator->validateCreation(array('label' => 'relates to')); + $this->assertFalse($r[0]); + + $r = $validator->validateCreation(array('label' => 'a', 'opposite_label' => 'a')); + $this->assertFalse($r[0]); + + $r = $validator->validateCreation(array('label' => '')); + $this->assertFalse($r[0]); + } + + public function testValidateModification() + { + $validator = new LinkValidator($this->container); + + $r = $validator->validateModification(array('id' => 20, 'label' => 'a', 'opposite_id' => 0)); + $this->assertTrue($r[0]); + + $r = $validator->validateModification(array('id' => 20, 'label' => 'a', 'opposite_id' => '1')); + $this->assertTrue($r[0]); + + $r = $validator->validateModification(array('id' => 20, 'label' => 'relates to', 'opposite_id' => '1')); + $this->assertFalse($r[0]); + + $r = $validator->validateModification(array('id' => 20, 'label' => '', 'opposite_id' => '1')); + $this->assertFalse($r[0]); + + $r = $validator->validateModification(array('label' => '', 'opposite_id' => '1')); + $this->assertFalse($r[0]); + + $r = $validator->validateModification(array('id' => 20, 'opposite_id' => '1')); + $this->assertFalse($r[0]); + + $r = $validator->validateModification(array('label' => 'test')); + $this->assertFalse($r[0]); + } +} -- cgit v1.2.3