diff options
82 files changed, 2947 insertions, 1601 deletions
@@ -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 @@ -14,6 +13,14 @@ use Pimple\Container; abstract class Base extends \Kanboard\Core\Base { /** + * Extended events + * + * @access private + * @var array + */ + private $compatibleEvents = array(); + + /** * Flag for called listener * * @access private @@ -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 @@ -15,6 +15,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 * * @access public @@ -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/TaskLogMoveAnotherColumn.php b/app/Action/CommentCreationMoveTaskColumn.php index a699c4ab..4473cf91 100644 --- a/app/Action/TaskLogMoveAnotherColumn.php +++ b/app/Action/CommentCreationMoveTaskColumn.php @@ -5,14 +5,25 @@ namespace Kanboard\Action; use Kanboard\Model\Task; /** - * Add a log of the triggering event to the task description. + * Add a comment of the triggering event to the task description. * * @package action * @author Oren Ben-Kiki */ -class TaskLogMoveAnotherColumn extends Base +class CommentCreationMoveTaskColumn extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Add a comment log when moving the task between columns'); + } + + /** * Get the list of compatible events * * @access public 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 @@ -13,6 +13,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 * * @access public 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 @@ -13,6 +13,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 * * @access public @@ -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 @@ -14,6 +14,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 * * @access public @@ -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 @@ -13,6 +13,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 * * @access public 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 @@ -13,6 +13,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 * * @access public 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 @@ -13,6 +13,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 * * @access public 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 @@ -13,6 +13,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 * * @access public 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 @@ -13,6 +13,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 * * @access public @@ -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 @@ +<?php + +namespace Kanboard\Action; + +use Kanboard\Model\Task; + +/** + * Assign a task to the logged user on column change + * + * @package action + * @author Frederic Guillot + */ +class TaskAssignCurrentUserColumn 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 when the column is changed'); + } + + /** + * Get the list of compatible events + * + * @access public + * @return array + */ + public function getCompatibleEvents() + { + return array( + Task::EVENT_MOVE_COLUMN, + ); + } + + /** + * Get the required parameter for the action (defined by the user) + * + * @access public + * @return array + */ + public function getActionRequiredParameters() + { + return array( + 'column_id' => 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 @@ -13,6 +13,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 * * @access public 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 @@ -14,6 +14,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 * * @access public @@ -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 @@ -16,6 +16,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 * * @access public @@ -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 @@ +<?php + +namespace Kanboard\Action; + +use Kanboard\Model\Task; + +/** + * Close automatically a task in a specific column + * + * @package action + * @author Frederic Guillot + */ +class TaskCloseColumn extends Base +{ + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Close a task in a specific column'); + } + + /** + * Get the list of compatible events + * + * @access public + * @return array + */ + public function getCompatibleEvents() + { + return array( + Task::EVENT_MOVE_COLUMN, + ); + } + + /** + * Get the required parameter for the action (defined by the user) + * + * @access public + * @return array + */ + public function getActionRequiredParameters() + { + return array('column_id' => 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 @@ -15,6 +15,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 * * @access public 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 @@ -13,6 +13,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 * * @access public @@ -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 @@ -13,6 +13,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 * * @access public 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 @@ -13,6 +13,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 * * @access public 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 @@ -13,6 +13,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 * * @access public @@ -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 @@ -13,6 +13,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 * * @access public @@ -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 @@ -13,6 +13,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 * * @access public @@ -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 @@ -15,6 +15,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 * * @access public 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 @@ -13,6 +13,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 * * @access public 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 @@ +<?php + +namespace Kanboard\Core\Action; + +use RuntimeException; +use Kanboard\Core\Base; +use Kanboard\Action\Base as ActionBase; + +/** + * Action Manager + * + * @package action + * @author Frederic Guillot + */ +class ActionManager extends Base +{ + /** + * List of automatic actions + * + * @access private + * @var array + */ + private $actions = array(); + + /** + * Register a new automatic action + * + * @access public + * @param ActionBase $action + * @return ActionManager + */ + public function register(ActionBase $action) + { + $this->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 @@ +<?php + +namespace Kanboard\Core\Event; + +use Kanboard\Integration\GitlabWebhook; +use Kanboard\Integration\GithubWebhook; +use Kanboard\Integration\BitbucketWebhook; +use Kanboard\Model\Task; +use Kanboard\Model\TaskLink; + +/** + * Event Manager + * + * @package event + * @author Frederic Guillot + */ +class EventManager +{ + /** + * Extended events + * + * @access private + * @var array + */ + private $events = array(); + + /** + * Add new event + * + * @access public + * @param string $event + * @param string $description + * @return EventManager + */ + public function register($event, $description) + { + $this->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(); @@ -289,42 +143,6 @@ class Action extends Base } /** - * 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) * * @author Antonio Rabelo @@ -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; } @@ -366,74 +183,6 @@ class Action extends Base } /** - * 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 * * @access public 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 @@ +<?php + +namespace Kanboard\Model; + +use SimpleValidator\Validator; +use SimpleValidator\Validators; + +/** + * Action Parameter Model + * + * @package model + * @author Frederic Guillot + */ +class ActionParameter extends Base +{ + /** + * SQL table name + * + * @var string + */ + const TABLE = 'action_has_params'; + + /** + * Get all action params + * + * @access public + * @param integer $action_id + * @return array + */ + public function getAll($action_id) + { + return $this->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 @@ +<?php + +namespace Kanboard\ServiceProvider; + +use Pimple\Container; +use Pimple\ServiceProviderInterface; +use Kanboard\Core\Action\ActionManager; +use Kanboard\Action\CommentCreation; +use Kanboard\Action\CommentCreationMoveTaskColumn; +use Kanboard\Action\TaskAssignCategoryColor; +use Kanboard\Action\TaskAssignCategoryLabel; +use Kanboard\Action\TaskAssignCategoryLink; +use Kanboard\Action\TaskAssignColorCategory; +use Kanboard\Action\TaskAssignColorColumn; +use Kanboard\Action\TaskAssignColorLink; +use Kanboard\Action\TaskAssignColorUser; +use Kanboard\Action\TaskAssignCurrentUser; +use Kanboard\Action\TaskAssignCurrentUserColumn; +use Kanboard\Action\TaskAssignSpecificUser; +use Kanboard\Action\TaskAssignUser; +use Kanboard\Action\TaskClose; +use Kanboard\Action\TaskCloseColumn; +use Kanboard\Action\TaskCreation; +use Kanboard\Action\TaskDuplicateAnotherProject; +use Kanboard\Action\TaskEmail; +use Kanboard\Action\TaskMoveAnotherProject; +use Kanboard\Action\TaskMoveColumnAssigned; +use Kanboard\Action\TaskMoveColumnCategoryChange; +use Kanboard\Action\TaskMoveColumnUnAssigned; +use Kanboard\Action\TaskOpen; +use Kanboard\Action\TaskUpdateStartDate; + +/** + * Action Provider + * + * @package serviceProvider + * @author Frederic Guillot + */ +class ActionProvider implements ServiceProviderInterface +{ + /** + * Register providers + * + * @access public + * @param \Pimple\Container $container + * @return \Pimple\Container + */ + public function register(Container $container) + { + $container['actionManager'] = new ActionManager($container); + $container['actionManager']->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 @@ </td> <td> <ul> - <?php foreach ($action['params'] as $param): ?> + <?php foreach ($action['params'] as $param_name => $param_value): ?> <li> - <?= $this->text->in($param['name'], $available_params) ?> = + <?= $this->text->in($param_name, $available_params[$action['action_name']]) ?> = <strong> - <?php if ($this->text->contains($param['name'], 'column_id')): ?> - <?= $this->text->in($param['value'], $columns_list) ?> - <?php elseif ($this->text->contains($param['name'], 'user_id')): ?> - <?= $this->text->in($param['value'], $users_list) ?> - <?php elseif ($this->text->contains($param['name'], 'project_id')): ?> - <?= $this->text->in($param['value'], $projects_list) ?> - <?php elseif ($this->text->contains($param['name'], 'color_id')): ?> - <?= $this->text->in($param['value'], $colors_list) ?> - <?php elseif ($this->text->contains($param['name'], 'category_id')): ?> - <?= $this->text->in($param['value'], $categories_list) ?> - <?php elseif ($this->text->contains($param['name'], 'link_id')): ?> - <?= $this->text->in($param['value'], $links_list) ?> + <?php if ($this->text->contains($param_name, 'column_id')): ?> + <?= $this->text->in($param_value, $columns_list) ?> + <?php elseif ($this->text->contains($param_name, 'user_id')): ?> + <?= $this->text->in($param_value, $users_list) ?> + <?php elseif ($this->text->contains($param_name, 'project_id')): ?> + <?= $this->text->in($param_value, $projects_list) ?> + <?php elseif ($this->text->contains($param_name, 'color_id')): ?> + <?= $this->text->in($param_value, $colors_list) ?> + <?php elseif ($this->text->contains($param_name, 'category_id')): ?> + <?= $this->text->in($param_value, $categories_list) ?> + <?php elseif ($this->text->contains($param_name, 'link_id')): ?> + <?= $this->text->in($param_value, $links_list) ?> <?php else: ?> - <?= $this->e($param['value']) ?> + <?= $this->e($param_value) ?> <?php endif ?> </strong> </li> 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 -<?php - -namespace Kanboard\Plugin\AutomaticAction; - -use Kanboard\Core\Plugin\Base; - -class Plugin extends Base -{ - public function initialize() - { - $this->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 @@ +<?php + +require_once __DIR__.'/../Base.php'; + +use Kanboard\Event\GenericEvent; + +class DummyAction extends Kanboard\Action\Base +{ + public function getDescription() + { + return 'Dummy Action'; + } + + public function getCompatibleEvents() + { + return array('my.event'); + } + + public function getActionRequiredParameters() + { + return array('p1' => '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 @@ +<?php + +require_once __DIR__.'/../Base.php'; + +use Kanboard\Event\GenericEvent; +use Kanboard\Model\Task; +use Kanboard\Model\TaskCreation; +use Kanboard\Model\Comment; +use Kanboard\Model\Project; +use Kanboard\Model\ProjectUserRole; +use Kanboard\Action\CommentCreationMoveTaskColumn; + +class CommentCreationMoveTaskColumnTest extends Base +{ + public function testSuccess() + { + $this->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 @@ +<?php + +require_once __DIR__.'/../Base.php'; + +use Kanboard\Event\GenericEvent; +use Kanboard\Model\Category; +use Kanboard\Model\TaskCreation; +use Kanboard\Model\TaskFinder; +use Kanboard\Model\Project; +use Kanboard\Model\Task; +use Kanboard\Action\TaskAssignCategoryColor; + +class TaskAssignCategoryColorTest extends Base +{ + public function testChangeCategory() + { + $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' => '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 @@ +<?php + +require_once __DIR__.'/../Base.php'; + +use Kanboard\Event\GenericEvent; +use Kanboard\Model\Category; +use Kanboard\Model\TaskCreation; +use Kanboard\Model\TaskFinder; +use Kanboard\Model\Project; +use Kanboard\Action\TaskAssignCategoryLabel; + +class TaskAssignCategoryLabelTest extends Base +{ + public function testChangeCategory() + { + $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' => '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 @@ +<?php + +require_once __DIR__.'/../Base.php'; + +use Kanboard\Event\GenericEvent; +use Kanboard\Model\TaskCreation; +use Kanboard\Model\TaskFinder; +use Kanboard\Model\Project; +use Kanboard\Model\Task; +use Kanboard\Action\TaskAssignCurrentUserColumn; + +class TaskAssignCurrentUserColumnTest extends Base +{ + public function testChangeUser() + { + $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' => 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 @@ +<?php + +require_once __DIR__.'/../Base.php'; + +use Kanboard\Event\GenericEvent; +use Kanboard\Model\TaskCreation; +use Kanboard\Model\TaskFinder; +use Kanboard\Model\Project; +use Kanboard\Model\ProjectUserRole; +use Kanboard\Model\User; +use Kanboard\Model\Task; +use Kanboard\Action\TaskAssignUser; +use Kanboard\Core\Security\Role; + +class TaskAssignUserTest extends Base +{ + public function testChangeUser() + { + $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', '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 @@ +<?php + +require_once __DIR__.'/../Base.php'; + +use Kanboard\Event\GenericEvent; +use Kanboard\Model\TaskCreation; +use Kanboard\Model\TaskFinder; +use Kanboard\Model\Project; +use Kanboard\Model\Task; +use Kanboard\Action\TaskCloseColumn; + +class TaskCloseColumnTest extends Base +{ + public function testClose() + { + $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 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 @@ +<?php + +require_once __DIR__.'/../Base.php'; + +use Kanboard\Event\GenericEvent; +use Kanboard\Model\TaskFinder; +use Kanboard\Model\Project; +use Kanboard\Action\TaskCreation as TaskCreationAction; + +class TaskCreationActionTest extends Base +{ + public function testSuccess() + { + $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, '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 @@ +<?php + +require_once __DIR__.'/../Base.php'; + +use Kanboard\Event\GenericEvent; +use Kanboard\Model\Task; +use Kanboard\Model\TaskFinder; +use Kanboard\Model\TaskCreation; +use Kanboard\Model\Project; +use Kanboard\Action\TaskMoveColumnAssigned; + +class TaskMoveColumnAssignedTest extends Base +{ + public function testSuccess() + { + $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(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 @@ +<?php + +require_once __DIR__.'/../Base.php'; + +use Kanboard\Event\GenericEvent; +use Kanboard\Model\Task; +use Kanboard\Model\TaskFinder; +use Kanboard\Model\TaskCreation; +use Kanboard\Model\Project; +use Kanboard\Action\TaskMoveColumnUnAssigned; + +class TaskMoveColumnUnAssignedTest extends Base +{ + public function testSuccess() + { + $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(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 @@ +<?php + +require_once __DIR__.'/../Base.php'; + +use Kanboard\Event\GenericEvent; +use Kanboard\Model\TaskCreation; +use Kanboard\Model\TaskFinder; +use Kanboard\Model\Project; +use Kanboard\Action\TaskOpen; + +class TaskOpenTest extends Base +{ + public function testClose() + { + $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', '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 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Action\ActionManager; +use Kanboard\Action\TaskAssignColorColumn; +use Kanboard\Action\TaskClose; +use Kanboard\Action\TaskCloseColumn; +use Kanboard\Action\TaskUpdateStartDate; +use Kanboard\Model\Action; +use Kanboard\Model\Task; +use Kanboard\Model\Project; +use Kanboard\Model\ProjectUserRole; +use Kanboard\Core\Security\Role; + +class ActionManagerTest extends Base +{ + public function testRegister() + { + $actionManager = new ActionManager($this->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 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Event\EventManager; + +class EventManagerTest extends Base +{ + public function testAddEvent() + { + $eventManager = new EventManager; + $eventManager->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() |