From 6cfce7720a88f383f85f9f7ea88a5dcdae87daa7 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Fri, 15 Jul 2016 21:05:15 -0400 Subject: Fixed Markdown editor auto-grow on the task form --- app/Helper/TaskHelper.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'app/Helper') diff --git a/app/Helper/TaskHelper.php b/app/Helper/TaskHelper.php index e1d65cca..481a5efb 100644 --- a/app/Helper/TaskHelper.php +++ b/app/Helper/TaskHelper.php @@ -50,6 +50,7 @@ class TaskHelper extends Base public function selectDescription(array $values, array $errors) { $html = $this->helper->form->label(t('Description'), 'description'); + $html .= '
'; $html .= $this->helper->form->textarea( 'description', $values, @@ -62,6 +63,7 @@ class TaskHelper extends Base 'markdown-editor' ); + $html .= '
'; return $html; } -- cgit v1.2.3 From b6119e7dee84869a619dedccd9c80df4422a4f5b Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sat, 23 Jul 2016 14:05:15 -0400 Subject: Added internal task links to activity stream --- ChangeLog | 1 + app/Action/TaskAssignCategoryLink.php | 13 +- app/Action/TaskAssignColorLink.php | 10 +- app/Core/Base.php | 1 + app/EventBuilder/TaskLinkEventBuilder.php | 89 +++++++++++ app/Helper/HookHelper.php | 2 +- app/Job/TaskLinkEventJob.php | 45 ++++++ app/Model/NotificationModel.php | 39 ++--- app/Model/TaskLinkModel.php | 173 ++++++++++++--------- app/ServiceProvider/JobProvider.php | 5 + app/Subscriber/NotificationSubscriber.php | 3 + .../event/task_internal_link_create_update.php | 16 ++ app/Template/event/task_internal_link_delete.php | 16 ++ app/Template/notification/task_file_create.php | 2 +- .../task_internal_link_create_update.php | 11 ++ .../notification/task_internal_link_delete.php | 11 ++ tests/units/Action/TaskAssignCategoryLinkTest.php | 51 +++--- tests/units/Action/TaskAssignColorLinkTest.php | 45 ++++-- .../EventBuilder/TaskLinkEventBuilderTest.php | 70 +++++++++ tests/units/Job/TaskLinkEventJobTest.php | 65 ++++++++ tests/units/Model/NotificationModelTest.php | 39 ++--- tests/units/Model/TaskLinkModelTest.php | 28 ++++ tests/units/Notification/MailNotificationTest.php | 117 ++++++++++++++ tests/units/Notification/MailTest.php | 117 -------------- .../units/Notification/WebhookNotificationTest.php | 29 ++++ tests/units/Notification/WebhookTest.php | 29 ---- 26 files changed, 705 insertions(+), 322 deletions(-) create mode 100644 app/EventBuilder/TaskLinkEventBuilder.php create mode 100644 app/Job/TaskLinkEventJob.php create mode 100644 app/Template/event/task_internal_link_create_update.php create mode 100644 app/Template/event/task_internal_link_delete.php create mode 100644 app/Template/notification/task_internal_link_create_update.php create mode 100644 app/Template/notification/task_internal_link_delete.php create mode 100644 tests/units/EventBuilder/TaskLinkEventBuilderTest.php create mode 100644 tests/units/Job/TaskLinkEventJobTest.php create mode 100644 tests/units/Notification/MailNotificationTest.php delete mode 100644 tests/units/Notification/MailTest.php create mode 100644 tests/units/Notification/WebhookNotificationTest.php delete mode 100644 tests/units/Notification/WebhookTest.php (limited to 'app/Helper') diff --git a/ChangeLog b/ChangeLog index a1e39436..ee57c86c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ Version 1.0.32 (unreleased) New features: * New automated action to close tasks without activity in a specific column +* Added internal task links to activity stream * Added new event for removed comments * Added search filter for task priority * Added the possibility to hide tasks in dashboard for a specific column diff --git a/app/Action/TaskAssignCategoryLink.php b/app/Action/TaskAssignCategoryLink.php index 6937edd1..d4a4c0ec 100644 --- a/app/Action/TaskAssignCategoryLink.php +++ b/app/Action/TaskAssignCategoryLink.php @@ -60,8 +60,10 @@ class TaskAssignCategoryLink extends Base public function getEventRequiredParameters() { return array( - 'task_id', - 'link_id', + 'task_link' => array( + 'task_id', + 'link_id', + ) ); } @@ -75,7 +77,7 @@ class TaskAssignCategoryLink extends Base public function doAction(array $data) { $values = array( - 'id' => $data['task_id'], + 'id' => $data['task_link']['task_id'], 'category_id' => $this->getParam('category_id'), ); @@ -91,9 +93,8 @@ class TaskAssignCategoryLink extends Base */ public function hasRequiredCondition(array $data) { - if ($data['link_id'] == $this->getParam('link_id')) { - $task = $this->taskFinderModel->getById($data['task_id']); - return empty($task['category_id']); + if ($data['task_link']['link_id'] == $this->getParam('link_id')) { + return empty($data['task']['category_id']); } return false; diff --git a/app/Action/TaskAssignColorLink.php b/app/Action/TaskAssignColorLink.php index 9ab5458b..9759f622 100644 --- a/app/Action/TaskAssignColorLink.php +++ b/app/Action/TaskAssignColorLink.php @@ -59,8 +59,10 @@ class TaskAssignColorLink extends Base public function getEventRequiredParameters() { return array( - 'task_id', - 'link_id', + 'task_link' => array( + 'task_id', + 'link_id', + ) ); } @@ -74,7 +76,7 @@ class TaskAssignColorLink extends Base public function doAction(array $data) { $values = array( - 'id' => $data['task_id'], + 'id' => $data['task_link']['task_id'], 'color_id' => $this->getParam('color_id'), ); @@ -90,6 +92,6 @@ class TaskAssignColorLink extends Base */ public function hasRequiredCondition(array $data) { - return $data['link_id'] == $this->getParam('link_id'); + return $data['task_link']['link_id'] == $this->getParam('link_id'); } } diff --git a/app/Core/Base.php b/app/Core/Base.php index 098bd880..20a2d391 100644 --- a/app/Core/Base.php +++ b/app/Core/Base.php @@ -154,6 +154,7 @@ use Pimple\Container; * @property \Kanboard\Job\SubtaskEventJob $subtaskEventJob * @property \Kanboard\Job\TaskEventJob $taskEventJob * @property \Kanboard\Job\TaskFileEventJob $taskFileEventJob + * @property \Kanboard\Job\TaskLinkEventJob $taskLinkEventJob * @property \Kanboard\Job\ProjectFileEventJob $projectFileEventJob * @property \Kanboard\Job\NotificationJob $notificationJob * @property \Psr\Log\LoggerInterface $logger diff --git a/app/EventBuilder/TaskLinkEventBuilder.php b/app/EventBuilder/TaskLinkEventBuilder.php new file mode 100644 index 00000000..8be5299f --- /dev/null +++ b/app/EventBuilder/TaskLinkEventBuilder.php @@ -0,0 +1,89 @@ +taskLinkId = $taskLinkId; + return $this; + } + + /** + * Build event data + * + * @access public + * @return TaskLinkEvent|null + */ + public function build() + { + $taskLink = $this->taskLinkModel->getById($this->taskLinkId); + + if (empty($taskLink)) { + $this->logger->debug(__METHOD__.': TaskLink not found'); + return null; + } + + return new TaskLinkEvent(array( + 'task_link' => $taskLink, + 'task' => $this->taskFinderModel->getDetails($taskLink['task_id']), + )); + } + + /** + * Get event title with author + * + * @access public + * @param string $author + * @param string $eventName + * @param array $eventData + * @return string + */ + public function buildTitleWithAuthor($author, $eventName, array $eventData) + { + if ($eventName === TaskLinkModel::EVENT_CREATE_UPDATE) { + return e('%s set a new internal link for the task #%d', $author, $eventData['task']['id']); + } elseif ($eventName === TaskLinkModel::EVENT_DELETE) { + return e('%s removed an internal link for the task #%d', $author, $eventData['task']['id']); + } + + return ''; + } + + /** + * Get event title without author + * + * @access public + * @param string $eventName + * @param array $eventData + * @return string + */ + public function buildTitleWithoutAuthor($eventName, array $eventData) + { + if ($eventName === TaskLinkModel::EVENT_CREATE_UPDATE) { + return e('A new internal link for the task #%d have been defined', $eventData['task']['id']); + } elseif ($eventName === TaskLinkModel::EVENT_DELETE) { + return e('Internal link removed for the task #%d', $eventData['task']['id']); + } + + return ''; + } +} diff --git a/app/Helper/HookHelper.php b/app/Helper/HookHelper.php index 2d13ebcc..cb4dc1ef 100644 --- a/app/Helper/HookHelper.php +++ b/app/Helper/HookHelper.php @@ -56,7 +56,7 @@ class HookHelper extends Base * @access public * @param string $hook * @param string $template - * @return \Kanboard\Helper\Hook + * @return $this */ public function attach($hook, $template) { diff --git a/app/Job/TaskLinkEventJob.php b/app/Job/TaskLinkEventJob.php new file mode 100644 index 00000000..669608ad --- /dev/null +++ b/app/Job/TaskLinkEventJob.php @@ -0,0 +1,45 @@ +jobParams = array($taskLinkId, $eventName); + return $this; + } + + /** + * Execute job + * + * @param int $taskLinkId + * @param string $eventName + * @return $this + */ + public function execute($taskLinkId, $eventName) + { + $event = TaskLinkEventBuilder::getInstance($this->container) + ->withTaskLinkId($taskLinkId) + ->build(); + + if ($event !== null) { + $this->dispatcher->dispatch($eventName, $event); + } + } +} diff --git a/app/Model/NotificationModel.php b/app/Model/NotificationModel.php index 925d646e..39c1f581 100644 --- a/app/Model/NotificationModel.php +++ b/app/Model/NotificationModel.php @@ -3,6 +3,7 @@ namespace Kanboard\Model; use Kanboard\Core\Base; +use Kanboard\EventBuilder\TaskLinkEventBuilder; /** * Notification @@ -85,7 +86,9 @@ class NotificationModel extends Base case CommentModel::EVENT_USER_MENTION: return e('%s mentioned you in a comment on the task #%d', $event_author, $event_data['task']['id']); default: - return e('Notification'); + return TaskLinkEventBuilder::getInstance($this->container) + ->buildTitleWithAuthor($event_author, $event_name, $event_data) ?: + e('Notification'); } } @@ -138,7 +141,9 @@ class NotificationModel extends Base case CommentModel::EVENT_USER_MENTION: return e('You were mentioned in a comment on the task #%d', $event_data['task']['id']); default: - return e('Notification'); + return TaskLinkEventBuilder::getInstance($this->container) + ->buildTitleWithoutAuthor($event_name, $event_data) ?: + e('Notification'); } } @@ -152,32 +157,10 @@ class NotificationModel extends Base */ public function getTaskIdFromEvent($event_name, array $event_data) { - switch ($event_name) { - case TaskFileModel::EVENT_CREATE: - return $event_data['file']['task_id']; - case CommentModel::EVENT_CREATE: - case CommentModel::EVENT_UPDATE: - case CommentModel::EVENT_DELETE: - return $event_data['comment']['task_id']; - case SubtaskModel::EVENT_CREATE: - case SubtaskModel::EVENT_UPDATE: - case SubtaskModel::EVENT_DELETE: - return $event_data['subtask']['task_id']; - case TaskModel::EVENT_CREATE: - case TaskModel::EVENT_UPDATE: - case TaskModel::EVENT_CLOSE: - case TaskModel::EVENT_OPEN: - case TaskModel::EVENT_MOVE_COLUMN: - case TaskModel::EVENT_MOVE_POSITION: - case TaskModel::EVENT_MOVE_SWIMLANE: - case TaskModel::EVENT_ASSIGNEE_CHANGE: - case CommentModel::EVENT_USER_MENTION: - case TaskModel::EVENT_USER_MENTION: - return $event_data['task']['id']; - case TaskModel::EVENT_OVERDUE: - return $event_data['tasks'][0]['id']; - default: - return 0; + if ($event_name === TaskModel::EVENT_OVERDUE) { + return $event_data['tasks'][0]['id']; } + + return isset($event_data['task']['id']) ? $event_data['task']['id'] : 0; } } diff --git a/app/Model/TaskLinkModel.php b/app/Model/TaskLinkModel.php index 09978eae..e8d3c5df 100644 --- a/app/Model/TaskLinkModel.php +++ b/app/Model/TaskLinkModel.php @@ -3,7 +3,6 @@ namespace Kanboard\Model; use Kanboard\Core\Base; -use Kanboard\Event\TaskLinkEvent; /** * TaskLink model @@ -26,7 +25,8 @@ class TaskLinkModel extends Base * * @var string */ - const EVENT_CREATE_UPDATE = 'tasklink.create_update'; + const EVENT_CREATE_UPDATE = 'task_internal_link.create_update'; + const EVENT_DELETE = 'task_internal_link.delete'; /** * Get projectId from $task_link_id @@ -53,7 +53,19 @@ class TaskLinkModel extends Base */ public function getById($task_link_id) { - return $this->db->table(self::TABLE)->eq('id', $task_link_id)->findOne(); + return $this->db + ->table(self::TABLE) + ->columns( + self::TABLE.'.id', + self::TABLE.'.opposite_task_id', + self::TABLE.'.task_id', + self::TABLE.'.link_id', + LinkModel::TABLE.'.label', + LinkModel::TABLE.'.opposite_id AS opposite_link_id' + ) + ->eq(self::TABLE.'.id', $task_link_id) + ->join(LinkModel::TABLE, 'id', 'link_id') + ->findOne(); } /** @@ -139,20 +151,6 @@ class TaskLinkModel extends Base return $result; } - /** - * Publish events - * - * @access private - * @param array $events - */ - private function fireEvents(array $events) - { - foreach ($events as $event) { - $event['project_id'] = $this->taskFinderModel->getProjectId($event['task_id']); - $this->container['dispatcher']->dispatch(self::EVENT_CREATE_UPDATE, new TaskLinkEvent($event)); - } - } - /** * Create a new link * @@ -160,42 +158,25 @@ class TaskLinkModel extends Base * @param integer $task_id Task id * @param integer $opposite_task_id Opposite task id * @param integer $link_id Link id - * @return integer Task link id + * @return integer|boolean */ public function create($task_id, $opposite_task_id, $link_id) { - $events = array(); $this->db->startTransaction(); - // Get opposite link $opposite_link_id = $this->linkModel->getOppositeLinkId($link_id); + $task_link_id1 = $this->createTaskLink($task_id, $opposite_task_id, $link_id); + $task_link_id2 = $this->createTaskLink($opposite_task_id, $task_id, $opposite_link_id); - $values = array( - 'task_id' => $task_id, - 'opposite_task_id' => $opposite_task_id, - 'link_id' => $link_id, - ); - - // Create the original task link - $this->db->table(self::TABLE)->insert($values); - $task_link_id = $this->db->getLastId(); - $events[] = $values; - - // Create the opposite task link - $values = array( - 'task_id' => $opposite_task_id, - 'opposite_task_id' => $task_id, - 'link_id' => $opposite_link_id, - ); - - $this->db->table(self::TABLE)->insert($values); - $events[] = $values; + if ($task_link_id1 === false || $task_link_id2 === false) { + $this->db->cancelTransaction(); + return false; + } $this->db->closeTransaction(); + $this->fireEvents(array($task_link_id1, $task_link_id2), self::EVENT_CREATE_UPDATE); - $this->fireEvents($events); - - return (int) $task_link_id; + return $task_link_id1; } /** @@ -210,46 +191,24 @@ class TaskLinkModel extends Base */ public function update($task_link_id, $task_id, $opposite_task_id, $link_id) { - $events = array(); $this->db->startTransaction(); - // Get original task link $task_link = $this->getById($task_link_id); - - // Find opposite task link $opposite_task_link = $this->getOppositeTaskLink($task_link); - - // Get opposite link $opposite_link_id = $this->linkModel->getOppositeLinkId($link_id); - // Update the original task link - $values = array( - 'task_id' => $task_id, - 'opposite_task_id' => $opposite_task_id, - 'link_id' => $link_id, - ); - - $rs1 = $this->db->table(self::TABLE)->eq('id', $task_link_id)->update($values); - $events[] = $values; + $result1 = $this->updateTaskLink($task_link_id, $task_id, $opposite_task_id, $link_id); + $result2 = $this->updateTaskLink($opposite_task_link['id'], $opposite_task_id, $task_id, $opposite_link_id); - // Update the opposite link - $values = array( - 'task_id' => $opposite_task_id, - 'opposite_task_id' => $task_id, - 'link_id' => $opposite_link_id, - ); - - $rs2 = $this->db->table(self::TABLE)->eq('id', $opposite_task_link['id'])->update($values); - $events[] = $values; + if ($result1 === false || $result2 === false) { + $this->db->cancelTransaction(); + return false; + } $this->db->closeTransaction(); + $this->fireEvents(array($task_link_id, $opposite_task_link['id']), self::EVENT_CREATE_UPDATE); - if ($rs1 && $rs2) { - $this->fireEvents($events); - return true; - } - - return false; + return true; } /** @@ -261,21 +220,83 @@ class TaskLinkModel extends Base */ public function remove($task_link_id) { + $this->taskLinkEventJob->execute($task_link_id, self::EVENT_DELETE); + $this->db->startTransaction(); $link = $this->getById($task_link_id); $link_id = $this->linkModel->getOppositeLinkId($link['link_id']); - $this->db->table(self::TABLE)->eq('id', $task_link_id)->remove(); + $result1 = $this->db + ->table(self::TABLE) + ->eq('id', $task_link_id) + ->remove(); - $this->db + $result2 = $this->db ->table(self::TABLE) ->eq('opposite_task_id', $link['task_id']) ->eq('task_id', $link['opposite_task_id']) - ->eq('link_id', $link_id)->remove(); + ->eq('link_id', $link_id) + ->remove(); + + if ($result1 === false || $result2 === false) { + $this->db->cancelTransaction(); + return false; + } $this->db->closeTransaction(); return true; } + + /** + * Publish events + * + * @access protected + * @param integer[] $task_link_ids + * @param string $eventName + */ + protected function fireEvents(array $task_link_ids, $eventName) + { + foreach ($task_link_ids as $task_link_id) { + $this->queueManager->push($this->taskLinkEventJob->withParams($task_link_id, $eventName)); + } + } + + /** + * Create task link + * + * @access protected + * @param integer $task_id + * @param integer $opposite_task_id + * @param integer $link_id + * @return integer|boolean + */ + protected function createTaskLink($task_id, $opposite_task_id, $link_id) + { + return $this->db->table(self::TABLE)->persist(array( + 'task_id' => $task_id, + 'opposite_task_id' => $opposite_task_id, + 'link_id' => $link_id, + )); + } + + /** + * Update task link + * + * @access protected + * @param integer $task_link_id + * @param integer $task_id + * @param integer $opposite_task_id + * @param integer $link_id + * @return boolean + */ + protected function updateTaskLink($task_link_id, $task_id, $opposite_task_id, $link_id) + { + return $this->db->table(self::TABLE)->eq('id', $task_link_id)->update(array( + 'task_id' => $task_id, + 'opposite_task_id' => $opposite_task_id, + 'link_id' => $link_id, + )); + } } diff --git a/app/ServiceProvider/JobProvider.php b/app/ServiceProvider/JobProvider.php index c7f323f1..5b42794b 100644 --- a/app/ServiceProvider/JobProvider.php +++ b/app/ServiceProvider/JobProvider.php @@ -8,6 +8,7 @@ use Kanboard\Job\ProjectFileEventJob; use Kanboard\Job\SubtaskEventJob; use Kanboard\Job\TaskEventJob; use Kanboard\Job\TaskFileEventJob; +use Kanboard\Job\TaskLinkEventJob; use Pimple\Container; use Pimple\ServiceProviderInterface; @@ -44,6 +45,10 @@ class JobProvider implements ServiceProviderInterface return new TaskFileEventJob($c); }); + $container['taskLinkEventJob'] = $container->factory(function ($c) { + return new TaskLinkEventJob($c); + }); + $container['projectFileEventJob'] = $container->factory(function ($c) { return new ProjectFileEventJob($c); }); diff --git a/app/Subscriber/NotificationSubscriber.php b/app/Subscriber/NotificationSubscriber.php index 7de24e49..7cc68b26 100644 --- a/app/Subscriber/NotificationSubscriber.php +++ b/app/Subscriber/NotificationSubscriber.php @@ -3,6 +3,7 @@ namespace Kanboard\Subscriber; use Kanboard\Event\GenericEvent; +use Kanboard\Model\TaskLinkModel; use Kanboard\Model\TaskModel; use Kanboard\Model\CommentModel; use Kanboard\Model\SubtaskModel; @@ -31,6 +32,8 @@ class NotificationSubscriber extends BaseSubscriber implements EventSubscriberIn CommentModel::EVENT_DELETE => 'handleEvent', CommentModel::EVENT_USER_MENTION => 'handleEvent', TaskFileModel::EVENT_CREATE => 'handleEvent', + TaskLinkModel::EVENT_CREATE_UPDATE => 'handleEvent', + TaskLinkModel::EVENT_DELETE => 'handleEvent', ); } diff --git a/app/Template/event/task_internal_link_create_update.php b/app/Template/event/task_internal_link_create_update.php new file mode 100644 index 00000000..de257977 --- /dev/null +++ b/app/Template/event/task_internal_link_create_update.php @@ -0,0 +1,16 @@ +

+ text->e($author), + $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) + ) ?> + dt->datetime($date_creation) ?> +

+
+

+ url->link(t('#%d', $task_link['opposite_task_id']), 'TaskViewController', 'show', array('task_id' => $task_link['opposite_task_id'])), + $this->text->e($task_link['label']) + ) ?> +

+
diff --git a/app/Template/event/task_internal_link_delete.php b/app/Template/event/task_internal_link_delete.php new file mode 100644 index 00000000..e537bf81 --- /dev/null +++ b/app/Template/event/task_internal_link_delete.php @@ -0,0 +1,16 @@ +

+ text->e($author), + $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) + ) ?> + dt->datetime($date_creation) ?> +

+
+

+ text->e($task_link['label']), + $this->url->link(t('#%d', $task_link['opposite_task_id']), 'TaskViewController', 'show', array('task_id' => $task_link['opposite_task_id'])) + ) ?> +

+
diff --git a/app/Template/notification/task_file_create.php b/app/Template/notification/task_file_create.php index feab8dd2..c19f7279 100644 --- a/app/Template/notification/task_file_create.php +++ b/app/Template/notification/task_file_create.php @@ -2,4 +2,4 @@

-render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file +render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> diff --git a/app/Template/notification/task_internal_link_create_update.php b/app/Template/notification/task_internal_link_create_update.php new file mode 100644 index 00000000..73cad84d --- /dev/null +++ b/app/Template/notification/task_internal_link_create_update.php @@ -0,0 +1,11 @@ +

text->e($task['title']) ?> (#)

+ +

+ url->link(t('#%d', $task_link['opposite_task_id']), 'TaskViewController', 'show', array('task_id' => $task_link['opposite_task_id'])), + $this->text->e($task_link['label']) + ) ?> +

+ +render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> diff --git a/app/Template/notification/task_internal_link_delete.php b/app/Template/notification/task_internal_link_delete.php new file mode 100644 index 00000000..bb54e0a7 --- /dev/null +++ b/app/Template/notification/task_internal_link_delete.php @@ -0,0 +1,11 @@ +

text->e($task['title']) ?> (#)

+ +

+ text->e($task_link['label']), + $this->url->link(t('#%d', $task_link['opposite_task_id']), 'TaskViewController', 'show', array('task_id' => $task_link['opposite_task_id'])) + ) ?> +

+ +render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> diff --git a/tests/units/Action/TaskAssignCategoryLinkTest.php b/tests/units/Action/TaskAssignCategoryLinkTest.php index d7e68f72..b9d7e9d9 100644 --- a/tests/units/Action/TaskAssignCategoryLinkTest.php +++ b/tests/units/Action/TaskAssignCategoryLinkTest.php @@ -2,12 +2,12 @@ require_once __DIR__.'/../Base.php'; +use Kanboard\EventBuilder\TaskLinkEventBuilder; use Kanboard\Model\TaskCreationModel; use Kanboard\Model\TaskFinderModel; use Kanboard\Model\ProjectModel; use Kanboard\Model\TaskLinkModel; use Kanboard\Model\CategoryModel; -use Kanboard\Event\TaskLinkEvent; use Kanboard\Action\TaskAssignCategoryLink; class TaskAssignCategoryLinkTest extends Base @@ -18,6 +18,7 @@ class TaskAssignCategoryLinkTest extends Base $taskFinderModel = new TaskFinderModel($this->container); $projectModel = new ProjectModel($this->container); $categoryModel = new CategoryModel($this->container); + $taskLinkModel = new TaskLinkModel($this->container); $action = new TaskAssignCategoryLink($this->container); $action->setProjectId(1); @@ -27,13 +28,12 @@ class TaskAssignCategoryLinkTest extends Base $this->assertEquals(1, $projectModel->create(array('name' => 'P1'))); $this->assertEquals(1, $categoryModel->create(array('name' => 'C1', 'project_id' => 1))); $this->assertEquals(1, $taskCreationModel->create(array('title' => 'T1', 'project_id' => 1))); + $this->assertEquals(2, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1))); + $this->assertEquals(1, $taskLinkModel->create(1, 2, 2)); - $event = new TaskLinkEvent(array( - 'project_id' => 1, - 'task_id' => 1, - 'opposite_task_id' => 2, - 'link_id' => 2, - )); + $event = TaskLinkEventBuilder::getInstance($this->container) + ->withTaskLinkId(1) + ->build(); $this->assertTrue($action->execute($event, TaskLinkModel::EVENT_CREATE_UPDATE)); @@ -44,51 +44,58 @@ class TaskAssignCategoryLinkTest extends Base public function testWhenLinkDontMatch() { $taskCreationModel = new TaskCreationModel($this->container); + $taskFinderModel = new TaskFinderModel($this->container); $projectModel = new ProjectModel($this->container); $categoryModel = new CategoryModel($this->container); + $taskLinkModel = new TaskLinkModel($this->container); $action = new TaskAssignCategoryLink($this->container); $action->setProjectId(1); $action->setParam('category_id', 1); - $action->setParam('link_id', 1); + $action->setParam('link_id', 2); $this->assertEquals(1, $projectModel->create(array('name' => 'P1'))); $this->assertEquals(1, $categoryModel->create(array('name' => 'C1', 'project_id' => 1))); $this->assertEquals(1, $taskCreationModel->create(array('title' => 'T1', 'project_id' => 1))); + $this->assertEquals(2, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1))); + $this->assertEquals(1, $taskLinkModel->create(1, 2, 1)); - $event = new TaskLinkEvent(array( - 'project_id' => 1, - 'task_id' => 1, - 'opposite_task_id' => 2, - 'link_id' => 2, - )); + $event = TaskLinkEventBuilder::getInstance($this->container) + ->withTaskLinkId(1) + ->build(); $this->assertFalse($action->execute($event, TaskLinkModel::EVENT_CREATE_UPDATE)); + + $task = $taskFinderModel->getById(1); + $this->assertEquals(0, $task['category_id']); } public function testThatExistingCategoryWillNotChange() { $taskCreationModel = new TaskCreationModel($this->container); + $taskFinderModel = new TaskFinderModel($this->container); $projectModel = new ProjectModel($this->container); $categoryModel = new CategoryModel($this->container); + $taskLinkModel = new TaskLinkModel($this->container); $action = new TaskAssignCategoryLink($this->container); $action->setProjectId(1); - $action->setParam('category_id', 2); + $action->setParam('category_id', 1); $action->setParam('link_id', 2); $this->assertEquals(1, $projectModel->create(array('name' => 'P1'))); $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('title' => 'T1', 'project_id' => 1, 'category_id' => 1))); + $this->assertEquals(2, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1))); + $this->assertEquals(1, $taskLinkModel->create(1, 2, 2)); - $event = new TaskLinkEvent(array( - 'project_id' => 1, - 'task_id' => 1, - 'opposite_task_id' => 2, - 'link_id' => 2, - )); + $event = TaskLinkEventBuilder::getInstance($this->container) + ->withTaskLinkId(1) + ->build(); $this->assertFalse($action->execute($event, TaskLinkModel::EVENT_CREATE_UPDATE)); + + $task = $taskFinderModel->getById(1); + $this->assertEquals(1, $task['category_id']); } } diff --git a/tests/units/Action/TaskAssignColorLinkTest.php b/tests/units/Action/TaskAssignColorLinkTest.php index 07d0969b..27364bc9 100644 --- a/tests/units/Action/TaskAssignColorLinkTest.php +++ b/tests/units/Action/TaskAssignColorLinkTest.php @@ -2,7 +2,7 @@ require_once __DIR__.'/../Base.php'; -use Kanboard\Event\GenericEvent; +use Kanboard\EventBuilder\TaskLinkEventBuilder; use Kanboard\Model\TaskCreationModel; use Kanboard\Model\TaskFinderModel; use Kanboard\Model\ProjectModel; @@ -13,42 +13,55 @@ class TaskAssignColorLinkTest extends Base { public function testChangeColor() { - $projectModel = new ProjectModel($this->container); $taskCreationModel = new TaskCreationModel($this->container); $taskFinderModel = new TaskFinderModel($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' => 1)); + $projectModel = new ProjectModel($this->container); + $taskLinkModel = new TaskLinkModel($this->container); $action = new TaskAssignColorLink($this->container); $action->setProjectId(1); + $action->setParam('link_id', 2); $action->setParam('color_id', 'red'); - $action->setParam('link_id', 1); + + $this->assertEquals(1, $projectModel->create(array('name' => 'P1'))); + $this->assertEquals(1, $taskCreationModel->create(array('title' => 'T1', 'project_id' => 1))); + $this->assertEquals(2, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1))); + $this->assertEquals(1, $taskLinkModel->create(1, 2, 2)); + + $event = TaskLinkEventBuilder::getInstance($this->container) + ->withTaskLinkId(1) + ->build(); $this->assertTrue($action->execute($event, TaskLinkModel::EVENT_CREATE_UPDATE)); $task = $taskFinderModel->getById(1); - $this->assertNotEmpty($task); $this->assertEquals('red', $task['color_id']); } public function testWithWrongLink() { - $projectModel = new ProjectModel($this->container); $taskCreationModel = new TaskCreationModel($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)); + $taskFinderModel = new TaskFinderModel($this->container); + $projectModel = new ProjectModel($this->container); + $taskLinkModel = new TaskLinkModel($this->container); $action = new TaskAssignColorLink($this->container); $action->setProjectId(1); + $action->setParam('link_id', 2); $action->setParam('color_id', 'red'); - $action->setParam('link_id', 1); + + $this->assertEquals(1, $projectModel->create(array('name' => 'P1'))); + $this->assertEquals(1, $taskCreationModel->create(array('title' => 'T1', 'project_id' => 1))); + $this->assertEquals(2, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1))); + $this->assertEquals(1, $taskLinkModel->create(1, 2, 1)); + + $event = TaskLinkEventBuilder::getInstance($this->container) + ->withTaskLinkId(1) + ->build(); $this->assertFalse($action->execute($event, TaskLinkModel::EVENT_CREATE_UPDATE)); + + $task = $taskFinderModel->getById(1); + $this->assertEquals('yellow', $task['color_id']); } } diff --git a/tests/units/EventBuilder/TaskLinkEventBuilderTest.php b/tests/units/EventBuilder/TaskLinkEventBuilderTest.php new file mode 100644 index 00000000..7364d651 --- /dev/null +++ b/tests/units/EventBuilder/TaskLinkEventBuilderTest.php @@ -0,0 +1,70 @@ +container); + $taskLinkEventBuilder->withTaskLinkId(42); + $this->assertNull($taskLinkEventBuilder->build()); + } + + public function testBuild() + { + $taskLinkModel = new TaskLinkModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + $projectModel = new ProjectModel($this->container); + $taskLinkEventBuilder = new TaskLinkEventBuilder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('title' => 'task 1', 'project_id' => 1))); + $this->assertEquals(2, $taskCreationModel->create(array('title' => 'task 2', 'project_id' => 1))); + $this->assertEquals(1, $taskLinkModel->create(1, 2, 1)); + + $event = $taskLinkEventBuilder->withTaskLinkId(1)->build(); + + $this->assertInstanceOf('Kanboard\Event\TaskLinkEvent', $event); + $this->assertNotEmpty($event['task_link']); + $this->assertNotEmpty($event['task']); + } + + public function testBuildTitle() + { + $taskLinkModel = new TaskLinkModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + $projectModel = new ProjectModel($this->container); + $taskLinkEventBuilder = new TaskLinkEventBuilder($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('title' => 'task 1', 'project_id' => 1))); + $this->assertEquals(2, $taskCreationModel->create(array('title' => 'task 2', 'project_id' => 1))); + $this->assertEquals(1, $taskLinkModel->create(1, 2, 1)); + + $eventData = $taskLinkEventBuilder->withTaskLinkId(1)->build(); + + $title = $taskLinkEventBuilder->buildTitleWithAuthor('Foobar', TaskLinkModel::EVENT_CREATE_UPDATE, $eventData->getAll()); + $this->assertEquals('Foobar set a new internal link for the task #1', $title); + + $title = $taskLinkEventBuilder->buildTitleWithAuthor('Foobar', TaskLinkModel::EVENT_DELETE, $eventData->getAll()); + $this->assertEquals('Foobar removed an internal link for the task #1', $title); + + $title = $taskLinkEventBuilder->buildTitleWithAuthor('Foobar', 'not found', $eventData->getAll()); + $this->assertSame('', $title); + + $title = $taskLinkEventBuilder->buildTitleWithoutAuthor(TaskLinkModel::EVENT_CREATE_UPDATE, $eventData->getAll()); + $this->assertEquals('A new internal link for the task #1 have been defined', $title); + + $title = $taskLinkEventBuilder->buildTitleWithoutAuthor(TaskLinkModel::EVENT_DELETE, $eventData->getAll()); + $this->assertEquals('Internal link removed for the task #1', $title); + + $title = $taskLinkEventBuilder->buildTitleWithoutAuthor('not found', $eventData->getAll()); + $this->assertSame('', $title); + } +} diff --git a/tests/units/Job/TaskLinkEventJobTest.php b/tests/units/Job/TaskLinkEventJobTest.php new file mode 100644 index 00000000..1949316a --- /dev/null +++ b/tests/units/Job/TaskLinkEventJobTest.php @@ -0,0 +1,65 @@ +container); + $taskLinkEventJob->withParams(123, 'foobar'); + + $this->assertSame(array(123, 'foobar'), $taskLinkEventJob->getJobParams()); + } + + public function testWithMissingLink() + { + $this->container['dispatcher']->addListener(TaskLinkModel::EVENT_CREATE_UPDATE, function() {}); + + $taskLinkEventJob = new TaskLinkEventJob($this->container); + $taskLinkEventJob->execute(42, TaskLinkModel::EVENT_CREATE_UPDATE); + + $called = $this->container['dispatcher']->getCalledListeners(); + $this->assertEmpty($called); + } + + public function testTriggerCreationEvents() + { + $this->container['dispatcher']->addListener(TaskLinkModel::EVENT_CREATE_UPDATE, function() {}); + + $taskCreationModel = new TaskCreationModel($this->container); + $projectModel = new ProjectModel($this->container); + $taskLinkModel = new TaskLinkModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('title' => 'task 1', 'project_id' => 1))); + $this->assertEquals(2, $taskCreationModel->create(array('title' => 'task 2', 'project_id' => 1))); + $this->assertEquals(1, $taskLinkModel->create(1, 2, 1)); + + $called = $this->container['dispatcher']->getCalledListeners(); + $this->assertArrayHasKey(TaskLinkModel::EVENT_CREATE_UPDATE.'.closure', $called); + } + + public function testTriggerDeleteEvents() + { + $this->container['dispatcher']->addListener(TaskLinkModel::EVENT_DELETE, function() {}); + + $taskCreationModel = new TaskCreationModel($this->container); + $projectModel = new ProjectModel($this->container); + $taskLinkModel = new TaskLinkModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('title' => 'task 1', 'project_id' => 1))); + $this->assertEquals(2, $taskCreationModel->create(array('title' => 'task 2', 'project_id' => 1))); + $this->assertEquals(1, $taskLinkModel->create(1, 2, 1)); + $this->assertTrue($taskLinkModel->remove(1)); + + $called = $this->container['dispatcher']->getCalledListeners(); + $this->assertArrayHasKey(TaskLinkModel::EVENT_DELETE.'.closure', $called); + } +} diff --git a/tests/units/Model/NotificationModelTest.php b/tests/units/Model/NotificationModelTest.php index 889f3349..0bd9db6e 100644 --- a/tests/units/Model/NotificationModelTest.php +++ b/tests/units/Model/NotificationModelTest.php @@ -7,6 +7,7 @@ use Kanboard\Model\TaskCreationModel; use Kanboard\Model\SubtaskModel; use Kanboard\Model\CommentModel; use Kanboard\Model\TaskFileModel; +use Kanboard\Model\TaskLinkModel; use Kanboard\Model\TaskModel; use Kanboard\Model\ProjectModel; use Kanboard\Model\NotificationModel; @@ -23,47 +24,38 @@ class NotificationModelTest extends Base $subtaskModel = new SubtaskModel($this->container); $commentModel = new CommentModel($this->container); $taskFileModel = new TaskFileModel($this->container); + $taskLinkModel = new TaskLinkModel($this->container); $this->assertEquals(1, $projectModel->create(array('name' => 'test'))); $this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1))); + $this->assertEquals(2, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1))); $this->assertEquals(1, $subtaskModel->create(array('title' => 'test', 'task_id' => 1))); $this->assertEquals(1, $commentModel->create(array('comment' => 'test', 'task_id' => 1, 'user_id' => 1))); $this->assertEquals(1, $taskFileModel->create(1, 'test', 'blah', 123)); + $this->assertEquals(1, $taskLinkModel->create(1, 2, 1)); $task = $taskFinderModel->getDetails(1); $subtask = $subtaskModel->getById(1, true); $comment = $commentModel->getById(1); $file = $commentModel->getById(1); + $tasklink = $taskLinkModel->getById(1); - $this->assertNotEmpty($task); - $this->assertNotEmpty($subtask); - $this->assertNotEmpty($comment); - $this->assertNotEmpty($file); - - foreach (NotificationSubscriber::getSubscribedEvents() as $event_name => $values) { - $title = $notificationModel->getTitleWithoutAuthor($event_name, array( - 'task' => $task, - 'comment' => $comment, - 'subtask' => $subtask, - 'file' => $file, - 'changes' => array() - )); - - $this->assertNotEmpty($title); - - $title = $notificationModel->getTitleWithAuthor('foobar', $event_name, array( + foreach (NotificationSubscriber::getSubscribedEvents() as $eventName => $values) { + $eventData = array( 'task' => $task, 'comment' => $comment, 'subtask' => $subtask, 'file' => $file, + 'task_link' => $tasklink, 'changes' => array() - )); + ); - $this->assertNotEmpty($title); + $this->assertNotEmpty($notificationModel->getTitleWithoutAuthor($eventName, $eventData)); + $this->assertNotEmpty($notificationModel->getTitleWithAuthor('Foobar', $eventName, $eventData)); } $this->assertNotEmpty($notificationModel->getTitleWithoutAuthor(TaskModel::EVENT_OVERDUE, array('tasks' => array(array('id' => 1))))); - $this->assertNotEmpty($notificationModel->getTitleWithoutAuthor('unkown', array())); + $this->assertNotEmpty($notificationModel->getTitleWithoutAuthor('unknown', array())); } public function testGetTaskIdFromEvent() @@ -75,6 +67,7 @@ class NotificationModelTest extends Base $subtaskModel = new SubtaskModel($this->container); $commentModel = new CommentModel($this->container); $taskFileModel = new TaskFileModel($this->container); + $taskLinkModel = new TaskLinkModel($this->container); $this->assertEquals(1, $projectModel->create(array('name' => 'test'))); $this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1))); @@ -86,18 +79,20 @@ class NotificationModelTest extends Base $subtask = $subtaskModel->getById(1, true); $comment = $commentModel->getById(1); $file = $commentModel->getById(1); + $tasklink = $taskLinkModel->getById(1); $this->assertNotEmpty($task); $this->assertNotEmpty($subtask); $this->assertNotEmpty($comment); $this->assertNotEmpty($file); - foreach (NotificationSubscriber::getSubscribedEvents() as $event_name => $values) { - $task_id = $notificationModel->getTaskIdFromEvent($event_name, array( + foreach (NotificationSubscriber::getSubscribedEvents() as $eventName => $values) { + $task_id = $notificationModel->getTaskIdFromEvent($eventName, array( 'task' => $task, 'comment' => $comment, 'subtask' => $subtask, 'file' => $file, + 'task_link' => $tasklink, 'changes' => array() )); diff --git a/tests/units/Model/TaskLinkModelTest.php b/tests/units/Model/TaskLinkModelTest.php index 78590891..01a7888b 100644 --- a/tests/units/Model/TaskLinkModelTest.php +++ b/tests/units/Model/TaskLinkModelTest.php @@ -9,6 +9,34 @@ use Kanboard\Model\ProjectModel; class TaskLinkModelTest extends Base { + public function testGeyById() + { + $taskLinkModel = new TaskLinkModel($this->container); + $projectModel = new ProjectModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'A'))); + $this->assertEquals(2, $taskCreationModel->create(array('project_id' => 1, 'title' => 'B'))); + $this->assertEquals(1, $taskLinkModel->create(1, 2, 6)); + + $taskLink = $taskLinkModel->getById(1); + $this->assertEquals(1, $taskLink['id']); + $this->assertEquals(1, $taskLink['task_id']); + $this->assertEquals(2, $taskLink['opposite_task_id']); + $this->assertEquals(6, $taskLink['link_id']); + $this->assertEquals(7, $taskLink['opposite_link_id']); + $this->assertEquals('is a child of', $taskLink['label']); + + $taskLink = $taskLinkModel->getById(2); + $this->assertEquals(2, $taskLink['id']); + $this->assertEquals(2, $taskLink['task_id']); + $this->assertEquals(1, $taskLink['opposite_task_id']); + $this->assertEquals(7, $taskLink['link_id']); + $this->assertEquals(6, $taskLink['opposite_link_id']); + $this->assertEquals('is a parent of', $taskLink['label']); + } + // Check postgres issue: "Cardinality violation: 7 ERROR: more than one row returned by a subquery used as an expression" public function testGetTaskWithMultipleMilestoneLink() { diff --git a/tests/units/Notification/MailNotificationTest.php b/tests/units/Notification/MailNotificationTest.php new file mode 100644 index 00000000..6579d9bc --- /dev/null +++ b/tests/units/Notification/MailNotificationTest.php @@ -0,0 +1,117 @@ +container); + $projectModel = new ProjectModel($this->container); + $taskFinderModel = new TaskFinderModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + $subtaskModel = new SubtaskModel($this->container); + $commentModel = new CommentModel($this->container); + $fileModel = new TaskFileModel($this->container); + $taskLinkModel = new TaskLinkModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test'))); + $this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1))); + $this->assertEquals(2, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1))); + $this->assertEquals(1, $subtaskModel->create(array('title' => 'test', 'task_id' => 1))); + $this->assertEquals(1, $commentModel->create(array('comment' => 'test', 'task_id' => 1, 'user_id' => 1))); + $this->assertEquals(1, $fileModel->create(1, 'test', 'blah', 123)); + $this->assertEquals(1, $taskLinkModel->create(1, 2, 1)); + + $task = $taskFinderModel->getDetails(1); + $subtask = $subtaskModel->getById(1, true); + $comment = $commentModel->getById(1); + $file = $commentModel->getById(1); + $tasklink = $taskLinkModel->getById(1); + + $this->assertNotEmpty($task); + $this->assertNotEmpty($subtask); + $this->assertNotEmpty($comment); + $this->assertNotEmpty($file); + + foreach (NotificationSubscriber::getSubscribedEvents() as $eventName => $values) { + $eventData = array( + 'task' => $task, + 'comment' => $comment, + 'subtask' => $subtask, + 'file' => $file, + 'task_link' => $tasklink, + 'changes' => array() + ); + $this->assertNotEmpty($mailNotification->getMailContent($eventName, $eventData)); + $this->assertNotEmpty($mailNotification->getMailSubject($eventName, $eventData)); + } + } + + public function testSendWithEmailAddress() + { + $mailNotification = new MailNotification($this->container); + $projectModel = new ProjectModel($this->container); + $taskFinderModel = new TaskFinderModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + $userModel = new UserModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test'))); + $this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1))); + $this->assertTrue($userModel->update(array('id' => 1, 'email' => 'test@localhost'))); + + $this->container['emailClient'] = $this + ->getMockBuilder('\Kanboard\Core\Mail\Client') + ->setConstructorArgs(array($this->container)) + ->setMethods(array('send')) + ->getMock(); + + $this->container['emailClient'] + ->expects($this->once()) + ->method('send') + ->with( + $this->equalTo('test@localhost'), + $this->equalTo('admin'), + $this->equalTo('[test][New task] test (#1)'), + $this->stringContains('test') + ); + + $mailNotification->notifyUser($userModel->getById(1), TaskModel::EVENT_CREATE, array('task' => $taskFinderModel->getDetails(1))); + } + + public function testSendWithoutEmailAddress() + { + $mailNotification = new MailNotification($this->container); + $projectModel = new ProjectModel($this->container); + $taskFinderModel = new TaskFinderModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + $userModel = new UserModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test'))); + $this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1))); + + $this->container['emailClient'] = $this + ->getMockBuilder('\Kanboard\Core\Mail\Client') + ->setConstructorArgs(array($this->container)) + ->setMethods(array('send')) + ->getMock(); + + $this->container['emailClient'] + ->expects($this->never()) + ->method('send'); + + $mailNotification->notifyUser($userModel->getById(1), TaskModel::EVENT_CREATE, array('task' => $taskFinderModel->getDetails(1))); + } +} diff --git a/tests/units/Notification/MailTest.php b/tests/units/Notification/MailTest.php deleted file mode 100644 index 9f077ac8..00000000 --- a/tests/units/Notification/MailTest.php +++ /dev/null @@ -1,117 +0,0 @@ -container); - $p = new ProjectModel($this->container); - $tf = new TaskFinderModel($this->container); - $tc = new TaskCreationModel($this->container); - $s = new SubtaskModel($this->container); - $c = new CommentModel($this->container); - $f = new TaskFileModel($this->container); - - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1))); - $this->assertEquals(1, $s->create(array('title' => 'test', 'task_id' => 1))); - $this->assertEquals(1, $c->create(array('comment' => 'test', 'task_id' => 1, 'user_id' => 1))); - $this->assertEquals(1, $f->create(1, 'test', 'blah', 123)); - - $task = $tf->getDetails(1); - $subtask = $s->getById(1, true); - $comment = $c->getById(1); - $file = $c->getById(1); - - $this->assertNotEmpty($task); - $this->assertNotEmpty($subtask); - $this->assertNotEmpty($comment); - $this->assertNotEmpty($file); - - foreach (NotificationSubscriber::getSubscribedEvents() as $event => $values) { - $this->assertNotEmpty($en->getMailContent($event, array( - 'task' => $task, - 'comment' => $comment, - 'subtask' => $subtask, - 'file' => $file, - 'changes' => array()) - )); - - $this->assertNotEmpty($en->getMailSubject($event, array( - 'task' => $task, - 'comment' => $comment, - 'subtask' => $subtask, - 'file' => $file, - 'changes' => array()) - )); - } - } - - public function testSendWithEmailAddress() - { - $en = new MailNotification($this->container); - $p = new ProjectModel($this->container); - $tf = new TaskFinderModel($this->container); - $tc = new TaskCreationModel($this->container); - $u = new UserModel($this->container); - - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1))); - $this->assertTrue($u->update(array('id' => 1, 'email' => 'test@localhost'))); - - $this->container['emailClient'] = $this - ->getMockBuilder('\Kanboard\Core\Mail\Client') - ->setConstructorArgs(array($this->container)) - ->setMethods(array('send')) - ->getMock(); - - $this->container['emailClient'] - ->expects($this->once()) - ->method('send') - ->with( - $this->equalTo('test@localhost'), - $this->equalTo('admin'), - $this->equalTo('[test][New task] test (#1)'), - $this->stringContains('test') - ); - - $en->notifyUser($u->getById(1), TaskModel::EVENT_CREATE, array('task' => $tf->getDetails(1))); - } - - public function testSendWithoutEmailAddress() - { - $en = new MailNotification($this->container); - $p = new ProjectModel($this->container); - $tf = new TaskFinderModel($this->container); - $tc = new TaskCreationModel($this->container); - $u = new UserModel($this->container); - - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1))); - - $this->container['emailClient'] = $this - ->getMockBuilder('\Kanboard\Core\Mail\Client') - ->setConstructorArgs(array($this->container)) - ->setMethods(array('send')) - ->getMock(); - - $this->container['emailClient'] - ->expects($this->never()) - ->method('send'); - - $en->notifyUser($u->getById(1), TaskModel::EVENT_CREATE, array('task' => $tf->getDetails(1))); - } -} diff --git a/tests/units/Notification/WebhookNotificationTest.php b/tests/units/Notification/WebhookNotificationTest.php new file mode 100644 index 00000000..6fbc349c --- /dev/null +++ b/tests/units/Notification/WebhookNotificationTest.php @@ -0,0 +1,29 @@ +container); + $projectModel = new ProjectModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + $this->container['dispatcher']->addSubscriber(new NotificationSubscriber($this->container)); + + $configModel->save(array('webhook_url' => 'http://localhost/?task-creation')); + + $this->container['httpClient'] + ->expects($this->once()) + ->method('postJson') + ->with($this->stringContains('http://localhost/?task-creation&token='), $this->anything()); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + } +} diff --git a/tests/units/Notification/WebhookTest.php b/tests/units/Notification/WebhookTest.php deleted file mode 100644 index 5a9eb1c7..00000000 --- a/tests/units/Notification/WebhookTest.php +++ /dev/null @@ -1,29 +0,0 @@ -container); - $p = new ProjectModel($this->container); - $tc = new TaskCreationModel($this->container); - $this->container['dispatcher']->addSubscriber(new NotificationSubscriber($this->container)); - - $c->save(array('webhook_url' => 'http://localhost/?task-creation')); - - $this->container['httpClient'] - ->expects($this->once()) - ->method('postJson') - ->with($this->stringContains('http://localhost/?task-creation&token='), $this->anything()); - - $this->assertEquals(1, $p->create(array('name' => 'test'))); - $this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'test'))); - } -} -- cgit v1.2.3 From be22f0619e25b15c8c3d002cf1f190aa9976bc71 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sun, 24 Jul 2016 13:29:24 -0400 Subject: Remove method UserModel::getFullname() --- app/Helper/UserHelper.php | 3 +- app/Model/UserModel.php | 13 +- tests/units/Helper/UserHelperTest.php | 15 ++ tests/units/Model/UserModelTest.php | 384 ++++++++++++++++++++++++++++++++ tests/units/Model/UserTest.php | 400 ---------------------------------- 5 files changed, 402 insertions(+), 413 deletions(-) create mode 100644 tests/units/Model/UserModelTest.php delete mode 100644 tests/units/Model/UserTest.php (limited to 'app/Helper') diff --git a/app/Helper/UserHelper.php b/app/Helper/UserHelper.php index ab259a62..e42bafe4 100644 --- a/app/Helper/UserHelper.php +++ b/app/Helper/UserHelper.php @@ -50,7 +50,8 @@ class UserHelper extends Base */ public function getFullname(array $user = array()) { - return $this->userModel->getFullname(empty($user) ? $this->userSession->getAll() : $user); + $user = empty($user) ? $this->userSession->getAll() : $user; + return $user['name'] ?: $user['username']; } /** diff --git a/app/Model/UserModel.php b/app/Model/UserModel.php index f7a051c5..56b1a960 100644 --- a/app/Model/UserModel.php +++ b/app/Model/UserModel.php @@ -64,17 +64,6 @@ class UserModel extends Base return $this->db->table(self::TABLE); } - /** - * Return the full name - * - * @param array $user User properties - * @return string - */ - public function getFullname(array $user) - { - return $user['name'] ?: $user['username']; - } - /** * Return true is the given user id is administrator * @@ -230,7 +219,7 @@ class UserModel extends Base $result = array(); foreach ($users as $user) { - $result[$user['id']] = $this->getFullname($user); + $result[$user['id']] = $this->helper->user->getFullname($user); } asort($result); diff --git a/tests/units/Helper/UserHelperTest.php b/tests/units/Helper/UserHelperTest.php index d5bd1789..4d1947d8 100644 --- a/tests/units/Helper/UserHelperTest.php +++ b/tests/units/Helper/UserHelperTest.php @@ -13,6 +13,21 @@ use Kanboard\Model\UserModel; class UserHelperTest extends Base { + public function testGetFullname() + { + $userModel = new UserModel($this->container); + $userHelper = new UserHelper($this->container); + + $this->assertEquals(2, $userModel->create(array('username' => 'user1'))); + $this->assertEquals(3, $userModel->create(array('username' => 'user2', 'name' => 'User #2'))); + + $user1 = $userModel->getById(2); + $user2 = $userModel->getById(3); + + $this->assertEquals('user1', $userHelper->getFullname($user1)); + $this->assertEquals('User #2', $userHelper->getFullname($user2)); + } + public function testInitials() { $helper = new UserHelper($this->container); diff --git a/tests/units/Model/UserModelTest.php b/tests/units/Model/UserModelTest.php new file mode 100644 index 00000000..a0c9c575 --- /dev/null +++ b/tests/units/Model/UserModelTest.php @@ -0,0 +1,384 @@ +container); + $this->assertNotFalse($userModel->create(array('username' => 'user1', 'password' => '123456', 'email' => 'user1@localhost'))); + $this->assertNotFalse($userModel->create(array('username' => 'user2', 'password' => '123456', 'email' => ''))); + + $this->assertNotEmpty($userModel->getByEmail('user1@localhost')); + $this->assertEmpty($userModel->getByEmail('')); + } + + public function testGetByExternalId() + { + $userModel = new UserModel($this->container); + $this->assertNotFalse($userModel->create(array('username' => 'user1', 'password' => '123456', 'gitlab_id' => '1234'))); + + $this->assertNotEmpty($userModel->getByExternalId('gitlab_id', '1234')); + $this->assertEmpty($userModel->getByExternalId('gitlab_id', '')); + + $userModel = new UserModel($this->container); + $this->assertNotFalse($userModel->create(array('username' => 'user2', 'password' => '123456', 'github_id' => 'plop'))); + $this->assertNotFalse($userModel->create(array('username' => 'user3', 'password' => '123456', 'github_id' => ''))); + + $this->assertNotEmpty($userModel->getByExternalId('github_id', 'plop')); + $this->assertEmpty($userModel->getByExternalId('github_id', '')); + + $userModel = new UserModel($this->container); + $this->assertNotFalse($userModel->create(array('username' => 'user4', 'password' => '123456', 'google_id' => '1234'))); + $this->assertNotFalse($userModel->create(array('username' => 'user5', 'password' => '123456', 'google_id' => ''))); + + $this->assertNotEmpty($userModel->getByExternalId('google_id', '1234')); + $this->assertEmpty($userModel->getByExternalId('google_id', '')); + } + + public function testGetByToken() + { + $userModel = new UserModel($this->container); + $this->assertNotFalse($userModel->create(array('username' => 'user1', 'token' => 'random'))); + $this->assertNotFalse($userModel->create(array('username' => 'user2', 'token' => ''))); + + $this->assertNotEmpty($userModel->getByToken('random')); + $this->assertEmpty($userModel->getByToken('')); + } + + public function testGetByUsername() + { + $userModel = new UserModel($this->container); + $this->assertNotFalse($userModel->create(array('username' => 'user1'))); + + $this->assertNotEmpty($userModel->getByUsername('user1')); + $this->assertEmpty($userModel->getByUsername('user2')); + $this->assertEmpty($userModel->getByUsername('')); + } + + public function testExists() + { + $userModel = new UserModel($this->container); + $this->assertNotFalse($userModel->create(array('username' => 'user1'))); + + $this->assertTrue($userModel->exists(1)); + $this->assertTrue($userModel->exists(2)); + $this->assertFalse($userModel->exists(3)); + } + + public function testCount() + { + $userModel = new UserModel($this->container); + $this->assertNotFalse($userModel->create(array('username' => 'user1'))); + $this->assertEquals(2, $userModel->count()); + } + + public function testGetAll() + { + $userModel = new UserModel($this->container); + $this->assertEquals(2, $userModel->create(array('username' => 'you'))); + $this->assertEquals(3, $userModel->create(array('username' => 'me', 'name' => 'Me'))); + + $users = $userModel->getAll(); + $this->assertCount(3, $users); + $this->assertEquals('admin', $users[0]['username']); + $this->assertEquals('me', $users[1]['username']); + $this->assertEquals('you', $users[2]['username']); + } + + public function testGetActiveUsersList() + { + $userModel = new UserModel($this->container); + $this->assertEquals(2, $userModel->create(array('username' => 'you'))); + $this->assertEquals(3, $userModel->create(array('username' => 'me', 'name' => 'Me too'))); + $this->assertEquals(4, $userModel->create(array('username' => 'foobar', 'is_active' => 0))); + + $users = $userModel->getActiveUsersList(); + + $expected = array( + 1 => 'admin', + 3 => 'Me too', + 2 => 'you', + ); + + $this->assertEquals($expected, $users); + + $users = $userModel->getActiveUsersList(true); + + $expected = array( + UserModel::EVERYBODY_ID => 'Everybody', + 1 => 'admin', + 3 => 'Me too', + 2 => 'you', + ); + + $this->assertEquals($expected, $users); + } + + public function testIsAdmin() + { + $userModel = new UserModel($this->container); + $this->assertEquals(2, $userModel->create(array('username' => 'user1'))); + + $this->assertTrue($userModel->isAdmin(1)); + $this->assertFalse($userModel->isAdmin(2)); + } + + public function testPassword() + { + $password = 'test123'; + $hash = password_hash($password, PASSWORD_BCRYPT); + + $this->assertNotEmpty($hash); + $this->assertTrue(password_verify($password, $hash)); + } + + public function testPrepare() + { + $userModel = new UserModel($this->container); + + $input = array( + 'username' => 'user1', + 'password' => '1234', + 'confirmation' => '1234', + 'name' => 'me', + 'role' => Role::APP_ADMIN, + ); + + $userModel->prepare($input); + $this->assertArrayNotHasKey('confirmation', $input); + + $this->assertArrayHasKey('password', $input); + $this->assertNotEquals('1234', $input['password']); + $this->assertNotEmpty($input['password']); + + $input = array( + 'username' => 'user1', + 'password' => '1234', + 'current_password' => 'bla', + 'confirmation' => '1234', + 'name' => 'me', + 'is_ldap_user' => '1', + ); + + $userModel->prepare($input); + $this->assertArrayNotHasKey('confirmation', $input); + $this->assertArrayNotHasKey('current_password', $input); + + $this->assertArrayHasKey('password', $input); + $this->assertNotEquals('1234', $input['password']); + $this->assertNotEmpty($input['password']); + + $this->assertArrayHasKey('is_ldap_user', $input); + $this->assertEquals(1, $input['is_ldap_user']); + + $input = array( + 'id' => 2, + 'name' => 'me', + ); + + $userModel->prepare($input); + $this->assertEquals(array('id' => 2, 'name' => 'me'), $input); + + $input = array( + 'gitlab_id' => '1234', + ); + + $userModel->prepare($input); + $this->assertEquals(array('gitlab_id' => 1234), $input); + + $input = array( + 'gitlab_id' => '', + ); + + $userModel->prepare($input); + $this->assertEquals(array('gitlab_id' => null), $input); + + $input = array( + 'gitlab_id' => 'something', + ); + + $userModel->prepare($input); + $this->assertEquals(array('gitlab_id' => 0), $input); + + $input = array( + 'username' => 'something', + 'password' => '' + ); + + $userModel->prepare($input); + $this->assertEquals(array('username' => 'something'), $input); + } + + public function testCreate() + { + $userModel = new UserModel($this->container); + $this->assertEquals(2, $userModel->create(array('username' => 'user #1', 'password' => '123456', 'name' => 'User'))); + $this->assertEquals(3, $userModel->create(array('username' => 'user #2', 'is_ldap_user' => 1))); + $this->assertEquals(4, $userModel->create(array('username' => 'user #3', 'role' => Role::APP_MANAGER))); + $this->assertEquals(5, $userModel->create(array('username' => 'user #4', 'gitlab_id' => '', 'role' => Role::APP_ADMIN))); + $this->assertEquals(6, $userModel->create(array('username' => 'user #5', 'gitlab_id' => '1234'))); + $this->assertFalse($userModel->create(array('username' => 'user #1'))); + + $user = $userModel->getById(1); + $this->assertEquals('admin', $user['username']); + $this->assertEquals('', $user['name']); + $this->assertEquals(Role::APP_ADMIN, $user['role']); + $this->assertEquals(0, $user['is_ldap_user']); + + $user = $userModel->getById(2); + $this->assertEquals('user #1', $user['username']); + $this->assertEquals('User', $user['name']); + $this->assertEquals(Role::APP_USER, $user['role']); + $this->assertEquals(0, $user['is_ldap_user']); + + $user = $userModel->getById(3); + $this->assertEquals('user #2', $user['username']); + $this->assertEquals('', $user['name']); + $this->assertEquals(Role::APP_USER, $user['role']); + $this->assertEquals(1, $user['is_ldap_user']); + + $user = $userModel->getById(4); + $this->assertEquals('user #3', $user['username']); + $this->assertEquals(Role::APP_MANAGER, $user['role']); + + $user = $userModel->getById(5); + $this->assertEquals('user #4', $user['username']); + $this->assertEquals('', $user['gitlab_id']); + $this->assertEquals(Role::APP_ADMIN, $user['role']); + + $user = $userModel->getById(6); + $this->assertEquals('user #5', $user['username']); + $this->assertEquals('1234', $user['gitlab_id']); + $this->assertEquals(Role::APP_USER, $user['role']); + } + + public function testUpdate() + { + $userModel = new UserModel($this->container); + $this->assertEquals(2, $userModel->create(array('username' => 'toto', 'password' => '123456', 'name' => 'Toto'))); + $this->assertEquals(3, $userModel->create(array('username' => 'plop', 'gitlab_id' => '123'))); + + $this->assertTrue($userModel->update(array('id' => 2, 'username' => 'biloute'))); + $this->assertTrue($userModel->update(array('id' => 3, 'gitlab_id' => ''))); + + $user = $userModel->getById(2); + $this->assertEquals('biloute', $user['username']); + $this->assertEquals('Toto', $user['name']); + $this->assertEquals(Role::APP_USER, $user['role']); + $this->assertEquals(0, $user['is_ldap_user']); + + $user = $userModel->getById(3); + $this->assertNotEmpty($user); + $this->assertEquals(null, $user['gitlab_id']); + } + + public function testRemove() + { + $userModel = new UserModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + $taskFinderModel = new TaskFinderModel($this->container); + $projectModel = new ProjectModel($this->container); + $subtaskModel = new SubtaskModel($this->container); + $commentModel = new CommentModel($this->container); + + $this->assertNotFalse($userModel->create(array('username' => 'toto', 'password' => '123456', 'name' => 'Toto'))); + $this->assertEquals(1, $projectModel->create(array('name' => 'Project #1'))); + $this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task #1', 'project_id' => 1, 'owner_id' => 2))); + $this->assertEquals(1, $subtaskModel->create(array('title' => 'Subtask #1', 'user_id' => 2, 'task_id' => 1))); + $this->assertEquals(1, $commentModel->create(array('comment' => 'foobar', 'user_id' => 2, 'task_id' => 1))); + + $task = $taskFinderModel->getById(1); + $this->assertEquals(1, $task['id']); + $this->assertEquals(2, $task['owner_id']); + + $this->assertTrue($userModel->remove(1)); + $this->assertTrue($userModel->remove(2)); + $this->assertFalse($userModel->remove(2)); + $this->assertFalse($userModel->remove(55)); + + // Make sure that assigned tasks are unassigned after removing the user + $task = $taskFinderModel->getById(1); + $this->assertEquals(1, $task['id']); + $this->assertEquals(0, $task['owner_id']); + + // Make sure that assigned subtasks are unassigned after removing the user + $subtask = $subtaskModel->getById(1); + $this->assertEquals(1, $subtask['id']); + $this->assertEquals(0, $subtask['user_id']); + + // Make sure that comments are not related to the user anymore + $comment = $commentModel->getById(1); + $this->assertEquals(1, $comment['id']); + $this->assertEquals(0, $comment['user_id']); + + // Make sure that private projects are also removed + $user_id1 = $userModel->create(array('username' => 'toto1', 'password' => '123456', 'name' => 'Toto')); + $user_id2 = $userModel->create(array('username' => 'toto2', 'password' => '123456', 'name' => 'Toto')); + $this->assertNotFalse($user_id1); + $this->assertNotFalse($user_id2); + $this->assertEquals(2, $projectModel->create(array('name' => 'Private project #1', 'is_private' => 1), $user_id1, true)); + $this->assertEquals(3, $projectModel->create(array('name' => 'Private project #2', 'is_private' => 1), $user_id2, true)); + + $this->assertTrue($userModel->remove($user_id1)); + + $this->assertNotEmpty($projectModel->getById(1)); + $this->assertNotEmpty($projectModel->getById(3)); + + $this->assertEmpty($projectModel->getById(2)); + } + + public function testEnableDisablePublicAccess() + { + $userModel = new UserModel($this->container); + $this->assertNotFalse($userModel->create(array('username' => 'toto', 'password' => '123456'))); + + $user = $userModel->getById(2); + $this->assertNotEmpty($user); + $this->assertEquals('toto', $user['username']); + $this->assertEmpty($user['token']); + + $this->assertTrue($userModel->enablePublicAccess(2)); + + $user = $userModel->getById(2); + $this->assertNotEmpty($user); + $this->assertEquals('toto', $user['username']); + $this->assertNotEmpty($user['token']); + + $this->assertTrue($userModel->disablePublicAccess(2)); + + $user = $userModel->getById(2); + $this->assertNotEmpty($user); + $this->assertEquals('toto', $user['username']); + $this->assertEmpty($user['token']); + } + + public function testEnableDisable() + { + $userModel = new UserModel($this->container); + $this->assertEquals(2, $userModel->create(array('username' => 'toto'))); + + $this->assertTrue($userModel->isActive(2)); + $user = $userModel->getById(2); + $this->assertEquals(1, $user['is_active']); + + $this->assertTrue($userModel->disable(2)); + $user = $userModel->getById(2); + $this->assertEquals(0, $user['is_active']); + $this->assertFalse($userModel->isActive(2)); + + $this->assertTrue($userModel->enable(2)); + $user = $userModel->getById(2); + $this->assertEquals(1, $user['is_active']); + $this->assertTrue($userModel->isActive(2)); + } +} diff --git a/tests/units/Model/UserTest.php b/tests/units/Model/UserTest.php deleted file mode 100644 index 0be6172e..00000000 --- a/tests/units/Model/UserTest.php +++ /dev/null @@ -1,400 +0,0 @@ -container); - $this->assertNotFalse($u->create(array('username' => 'user1', 'password' => '123456', 'email' => 'user1@localhost'))); - $this->assertNotFalse($u->create(array('username' => 'user2', 'password' => '123456', 'email' => ''))); - - $this->assertNotEmpty($u->getByEmail('user1@localhost')); - $this->assertEmpty($u->getByEmail('')); - } - - public function testGetByExternalId() - { - $u = new UserModel($this->container); - $this->assertNotFalse($u->create(array('username' => 'user1', 'password' => '123456', 'gitlab_id' => '1234'))); - - $this->assertNotEmpty($u->getByExternalId('gitlab_id', '1234')); - $this->assertEmpty($u->getByExternalId('gitlab_id', '')); - - $u = new UserModel($this->container); - $this->assertNotFalse($u->create(array('username' => 'user2', 'password' => '123456', 'github_id' => 'plop'))); - $this->assertNotFalse($u->create(array('username' => 'user3', 'password' => '123456', 'github_id' => ''))); - - $this->assertNotEmpty($u->getByExternalId('github_id', 'plop')); - $this->assertEmpty($u->getByExternalId('github_id', '')); - - $u = new UserModel($this->container); - $this->assertNotFalse($u->create(array('username' => 'user4', 'password' => '123456', 'google_id' => '1234'))); - $this->assertNotFalse($u->create(array('username' => 'user5', 'password' => '123456', 'google_id' => ''))); - - $this->assertNotEmpty($u->getByExternalId('google_id', '1234')); - $this->assertEmpty($u->getByExternalId('google_id', '')); - } - - public function testGetByToken() - { - $u = new UserModel($this->container); - $this->assertNotFalse($u->create(array('username' => 'user1', 'token' => 'random'))); - $this->assertNotFalse($u->create(array('username' => 'user2', 'token' => ''))); - - $this->assertNotEmpty($u->getByToken('random')); - $this->assertEmpty($u->getByToken('')); - } - - public function testGetByUsername() - { - $u = new UserModel($this->container); - $this->assertNotFalse($u->create(array('username' => 'user1'))); - - $this->assertNotEmpty($u->getByUsername('user1')); - $this->assertEmpty($u->getByUsername('user2')); - $this->assertEmpty($u->getByUsername('')); - } - - public function testExists() - { - $u = new UserModel($this->container); - $this->assertNotFalse($u->create(array('username' => 'user1'))); - - $this->assertTrue($u->exists(1)); - $this->assertTrue($u->exists(2)); - $this->assertFalse($u->exists(3)); - } - - public function testCount() - { - $u = new UserModel($this->container); - $this->assertNotFalse($u->create(array('username' => 'user1'))); - $this->assertEquals(2, $u->count()); - } - - public function testGetAll() - { - $u = new UserModel($this->container); - $this->assertEquals(2, $u->create(array('username' => 'you'))); - $this->assertEquals(3, $u->create(array('username' => 'me', 'name' => 'Me'))); - - $users = $u->getAll(); - $this->assertCount(3, $users); - $this->assertEquals('admin', $users[0]['username']); - $this->assertEquals('me', $users[1]['username']); - $this->assertEquals('you', $users[2]['username']); - } - - public function testGetActiveUsersList() - { - $u = new UserModel($this->container); - $this->assertEquals(2, $u->create(array('username' => 'you'))); - $this->assertEquals(3, $u->create(array('username' => 'me', 'name' => 'Me too'))); - $this->assertEquals(4, $u->create(array('username' => 'foobar', 'is_active' => 0))); - - $users = $u->getActiveUsersList(); - - $expected = array( - 1 => 'admin', - 3 => 'Me too', - 2 => 'you', - ); - - $this->assertEquals($expected, $users); - - $users = $u->getActiveUsersList(true); - - $expected = array( - UserModel::EVERYBODY_ID => 'Everybody', - 1 => 'admin', - 3 => 'Me too', - 2 => 'you', - ); - - $this->assertEquals($expected, $users); - } - - public function testGetFullname() - { - $u = new UserModel($this->container); - $this->assertEquals(2, $u->create(array('username' => 'user1'))); - $this->assertEquals(3, $u->create(array('username' => 'user2', 'name' => 'User #2'))); - - $user1 = $u->getById(2); - $user2 = $u->getById(3); - - $this->assertNotEmpty($user1); - $this->assertNotEmpty($user2); - - $this->assertEquals('user1', $u->getFullname($user1)); - $this->assertEquals('User #2', $u->getFullname($user2)); - } - - public function testIsAdmin() - { - $u = new UserModel($this->container); - $this->assertEquals(2, $u->create(array('username' => 'user1'))); - - $this->assertTrue($u->isAdmin(1)); - $this->assertFalse($u->isAdmin(2)); - } - - public function testPassword() - { - $password = 'test123'; - $hash = password_hash($password, PASSWORD_BCRYPT); - - $this->assertNotEmpty($hash); - $this->assertTrue(password_verify($password, $hash)); - } - - public function testPrepare() - { - $u = new UserModel($this->container); - - $input = array( - 'username' => 'user1', - 'password' => '1234', - 'confirmation' => '1234', - 'name' => 'me', - 'role' => Role::APP_ADMIN, - ); - - $u->prepare($input); - $this->assertArrayNotHasKey('confirmation', $input); - - $this->assertArrayHasKey('password', $input); - $this->assertNotEquals('1234', $input['password']); - $this->assertNotEmpty($input['password']); - - $input = array( - 'username' => 'user1', - 'password' => '1234', - 'current_password' => 'bla', - 'confirmation' => '1234', - 'name' => 'me', - 'is_ldap_user' => '1', - ); - - $u->prepare($input); - $this->assertArrayNotHasKey('confirmation', $input); - $this->assertArrayNotHasKey('current_password', $input); - - $this->assertArrayHasKey('password', $input); - $this->assertNotEquals('1234', $input['password']); - $this->assertNotEmpty($input['password']); - - $this->assertArrayHasKey('is_ldap_user', $input); - $this->assertEquals(1, $input['is_ldap_user']); - - $input = array( - 'id' => 2, - 'name' => 'me', - ); - - $u->prepare($input); - $this->assertEquals(array('id' => 2, 'name' => 'me'), $input); - - $input = array( - 'gitlab_id' => '1234', - ); - - $u->prepare($input); - $this->assertEquals(array('gitlab_id' => 1234), $input); - - $input = array( - 'gitlab_id' => '', - ); - - $u->prepare($input); - $this->assertEquals(array('gitlab_id' => null), $input); - - $input = array( - 'gitlab_id' => 'something', - ); - - $u->prepare($input); - $this->assertEquals(array('gitlab_id' => 0), $input); - - $input = array( - 'username' => 'something', - 'password' => '' - ); - - $u->prepare($input); - $this->assertEquals(array('username' => 'something'), $input); - } - - public function testCreate() - { - $u = new UserModel($this->container); - $this->assertEquals(2, $u->create(array('username' => 'user #1', 'password' => '123456', 'name' => 'User'))); - $this->assertEquals(3, $u->create(array('username' => 'user #2', 'is_ldap_user' => 1))); - $this->assertEquals(4, $u->create(array('username' => 'user #3', 'role' => Role::APP_MANAGER))); - $this->assertEquals(5, $u->create(array('username' => 'user #4', 'gitlab_id' => '', 'role' => Role::APP_ADMIN))); - $this->assertEquals(6, $u->create(array('username' => 'user #5', 'gitlab_id' => '1234'))); - $this->assertFalse($u->create(array('username' => 'user #1'))); - - $user = $u->getById(1); - $this->assertEquals('admin', $user['username']); - $this->assertEquals('', $user['name']); - $this->assertEquals(Role::APP_ADMIN, $user['role']); - $this->assertEquals(0, $user['is_ldap_user']); - - $user = $u->getById(2); - $this->assertEquals('user #1', $user['username']); - $this->assertEquals('User', $user['name']); - $this->assertEquals(Role::APP_USER, $user['role']); - $this->assertEquals(0, $user['is_ldap_user']); - - $user = $u->getById(3); - $this->assertEquals('user #2', $user['username']); - $this->assertEquals('', $user['name']); - $this->assertEquals(Role::APP_USER, $user['role']); - $this->assertEquals(1, $user['is_ldap_user']); - - $user = $u->getById(4); - $this->assertEquals('user #3', $user['username']); - $this->assertEquals(Role::APP_MANAGER, $user['role']); - - $user = $u->getById(5); - $this->assertEquals('user #4', $user['username']); - $this->assertEquals('', $user['gitlab_id']); - $this->assertEquals(Role::APP_ADMIN, $user['role']); - - $user = $u->getById(6); - $this->assertEquals('user #5', $user['username']); - $this->assertEquals('1234', $user['gitlab_id']); - $this->assertEquals(Role::APP_USER, $user['role']); - } - - public function testUpdate() - { - $u = new UserModel($this->container); - $this->assertEquals(2, $u->create(array('username' => 'toto', 'password' => '123456', 'name' => 'Toto'))); - $this->assertEquals(3, $u->create(array('username' => 'plop', 'gitlab_id' => '123'))); - - $this->assertTrue($u->update(array('id' => 2, 'username' => 'biloute'))); - $this->assertTrue($u->update(array('id' => 3, 'gitlab_id' => ''))); - - $user = $u->getById(2); - $this->assertEquals('biloute', $user['username']); - $this->assertEquals('Toto', $user['name']); - $this->assertEquals(Role::APP_USER, $user['role']); - $this->assertEquals(0, $user['is_ldap_user']); - - $user = $u->getById(3); - $this->assertNotEmpty($user); - $this->assertEquals(null, $user['gitlab_id']); - } - - public function testRemove() - { - $u = new UserModel($this->container); - $tc = new TaskCreationModel($this->container); - $tf = new TaskFinderModel($this->container); - $p = new ProjectModel($this->container); - $s = new SubtaskModel($this->container); - $c = new CommentModel($this->container); - - $this->assertNotFalse($u->create(array('username' => 'toto', 'password' => '123456', 'name' => 'Toto'))); - $this->assertEquals(1, $p->create(array('name' => 'Project #1'))); - $this->assertEquals(1, $tc->create(array('title' => 'Task #1', 'project_id' => 1, 'owner_id' => 2))); - $this->assertEquals(1, $s->create(array('title' => 'Subtask #1', 'user_id' => 2, 'task_id' => 1))); - $this->assertEquals(1, $c->create(array('comment' => 'foobar', 'user_id' => 2, 'task_id' => 1))); - - $task = $tf->getById(1); - $this->assertEquals(1, $task['id']); - $this->assertEquals(2, $task['owner_id']); - - $this->assertTrue($u->remove(1)); - $this->assertTrue($u->remove(2)); - $this->assertFalse($u->remove(2)); - $this->assertFalse($u->remove(55)); - - // Make sure that assigned tasks are unassigned after removing the user - $task = $tf->getById(1); - $this->assertEquals(1, $task['id']); - $this->assertEquals(0, $task['owner_id']); - - // Make sure that assigned subtasks are unassigned after removing the user - $subtask = $s->getById(1); - $this->assertEquals(1, $subtask['id']); - $this->assertEquals(0, $subtask['user_id']); - - // Make sure that comments are not related to the user anymore - $comment = $c->getById(1); - $this->assertEquals(1, $comment['id']); - $this->assertEquals(0, $comment['user_id']); - - // Make sure that private projects are also removed - $user_id1 = $u->create(array('username' => 'toto1', 'password' => '123456', 'name' => 'Toto')); - $user_id2 = $u->create(array('username' => 'toto2', 'password' => '123456', 'name' => 'Toto')); - $this->assertNotFalse($user_id1); - $this->assertNotFalse($user_id2); - $this->assertEquals(2, $p->create(array('name' => 'Private project #1', 'is_private' => 1), $user_id1, true)); - $this->assertEquals(3, $p->create(array('name' => 'Private project #2', 'is_private' => 1), $user_id2, true)); - - $this->assertTrue($u->remove($user_id1)); - - $this->assertNotEmpty($p->getById(1)); - $this->assertNotEmpty($p->getById(3)); - - $this->assertEmpty($p->getById(2)); - } - - public function testEnableDisablePublicAccess() - { - $u = new UserModel($this->container); - $this->assertNotFalse($u->create(array('username' => 'toto', 'password' => '123456'))); - - $user = $u->getById(2); - $this->assertNotEmpty($user); - $this->assertEquals('toto', $user['username']); - $this->assertEmpty($user['token']); - - $this->assertTrue($u->enablePublicAccess(2)); - - $user = $u->getById(2); - $this->assertNotEmpty($user); - $this->assertEquals('toto', $user['username']); - $this->assertNotEmpty($user['token']); - - $this->assertTrue($u->disablePublicAccess(2)); - - $user = $u->getById(2); - $this->assertNotEmpty($user); - $this->assertEquals('toto', $user['username']); - $this->assertEmpty($user['token']); - } - - public function testEnableDisable() - { - $userModel = new UserModel($this->container); - $this->assertEquals(2, $userModel->create(array('username' => 'toto'))); - - $this->assertTrue($userModel->isActive(2)); - $user = $userModel->getById(2); - $this->assertEquals(1, $user['is_active']); - - $this->assertTrue($userModel->disable(2)); - $user = $userModel->getById(2); - $this->assertEquals(0, $user['is_active']); - $this->assertFalse($userModel->isActive(2)); - - $this->assertTrue($userModel->enable(2)); - $user = $userModel->getById(2); - $this->assertEquals(1, $user['is_active']); - $this->assertTrue($userModel->isActive(2)); - } -} -- cgit v1.2.3 From 9d6715ddc01586e524ef433732d649e17f1d88b5 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sun, 24 Jul 2016 13:55:35 -0400 Subject: Improve project page titles --- ChangeLog | 2 ++ app/Controller/AnalyticController.php | 16 ++++++++-------- app/Helper/LayoutHelper.php | 4 ++++ app/Template/analytic/compare_hours.php | 2 +- app/Template/export/subtasks.php | 4 ++-- app/Template/export/summary.php | 4 ++-- app/Template/export/tasks.php | 4 ++-- app/Template/header.php | 2 +- app/Template/task/sidebar.php | 8 ++++++-- app/Template/user_view/sidebar.php | 8 ++++++++ 10 files changed, 36 insertions(+), 18 deletions(-) (limited to 'app/Helper') diff --git a/ChangeLog b/ChangeLog index 6da73200..de486987 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,8 @@ New features: Improvements: +* Improve project page title +* Remove sidebar titles when not necessary * Internal events management refactoring * Handle header X-Real-IP to get IP address * Display project name for task auto-complete fields diff --git a/app/Controller/AnalyticController.php b/app/Controller/AnalyticController.php index cf3ba034..ab0646a2 100644 --- a/app/Controller/AnalyticController.php +++ b/app/Controller/AnalyticController.php @@ -33,7 +33,7 @@ class AnalyticController extends BaseController 'metrics' => $this->projectDailyStatsModel->getRawMetrics($project['id'], $from, $to), 'date_format' => $this->configModel->get('application_date_format'), 'date_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getDateFormats()), - 'title' => t('Lead and Cycle time for "%s"', $project['name']), + 'title' => t('Lead and cycle time'), ))); } @@ -60,7 +60,7 @@ class AnalyticController extends BaseController 'project' => $project, 'paginator' => $paginator, 'metrics' => $this->estimatedTimeComparisonAnalytic->build($project['id']), - 'title' => t('Compare hours for "%s"', $project['name']), + 'title' => t('Estimated vs actual time'), ))); } @@ -76,7 +76,7 @@ class AnalyticController extends BaseController $this->response->html($this->helper->layout->analytic('analytic/avg_time_columns', array( 'project' => $project, 'metrics' => $this->averageTimeSpentColumnAnalytic->build($project['id']), - 'title' => t('Average time spent into each column for "%s"', $project['name']), + 'title' => t('Average time into each column'), ))); } @@ -92,7 +92,7 @@ class AnalyticController extends BaseController $this->response->html($this->helper->layout->analytic('analytic/tasks', array( 'project' => $project, 'metrics' => $this->taskDistributionAnalytic->build($project['id']), - 'title' => t('Task repartition for "%s"', $project['name']), + 'title' => t('Task distribution'), ))); } @@ -108,7 +108,7 @@ class AnalyticController extends BaseController $this->response->html($this->helper->layout->analytic('analytic/users', array( 'project' => $project, 'metrics' => $this->userDistributionAnalytic->build($project['id']), - 'title' => t('User repartition for "%s"', $project['name']), + 'title' => t('User repartition'), ))); } @@ -119,7 +119,7 @@ class AnalyticController extends BaseController */ public function cfd() { - $this->commonAggregateMetrics('analytic/cfd', 'total', 'Cumulative flow diagram for "%s"'); + $this->commonAggregateMetrics('analytic/cfd', 'total', t('Cumulative flow diagram')); } /** @@ -129,7 +129,7 @@ class AnalyticController extends BaseController */ public function burndown() { - $this->commonAggregateMetrics('analytic/burndown', 'score', 'Burndown chart for "%s"'); + $this->commonAggregateMetrics('analytic/burndown', 'score', t('Burndown chart')); } /** @@ -157,7 +157,7 @@ class AnalyticController extends BaseController 'project' => $project, 'date_format' => $this->configModel->get('application_date_format'), 'date_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getDateFormats()), - 'title' => t($title, $project['name']), + 'title' => $title, ))); } diff --git a/app/Helper/LayoutHelper.php b/app/Helper/LayoutHelper.php index 8ebb05d4..8d2e7e00 100644 --- a/app/Helper/LayoutHelper.php +++ b/app/Helper/LayoutHelper.php @@ -156,6 +156,10 @@ class LayoutHelper extends Base */ public function analytic($template, array $params) { + if (isset($params['project']['name'])) { + $params['title'] = $params['project']['name'].' > '.$params['title']; + } + return $this->subLayout('analytic/layout', 'analytic/sidebar', $template, $params); } diff --git a/app/Template/analytic/compare_hours.php b/app/Template/analytic/compare_hours.php index 70d8d02b..e4a0b60e 100644 --- a/app/Template/analytic/compare_hours.php +++ b/app/Template/analytic/compare_hours.php @@ -1,5 +1,5 @@
diff --git a/app/Template/export/subtasks.php b/app/Template/export/subtasks.php index a82cb3d1..878a7132 100644 --- a/app/Template/export/subtasks.php +++ b/app/Template/export/subtasks.php @@ -1,5 +1,5 @@

@@ -21,4 +21,4 @@
- \ No newline at end of file + diff --git a/app/Template/export/summary.php b/app/Template/export/summary.php index 60aa306f..d9362a9b 100644 --- a/app/Template/export/summary.php +++ b/app/Template/export/summary.php @@ -1,5 +1,5 @@

@@ -21,4 +21,4 @@
- \ No newline at end of file + diff --git a/app/Template/export/tasks.php b/app/Template/export/tasks.php index bed8ab90..ae411326 100644 --- a/app/Template/export/tasks.php +++ b/app/Template/export/tasks.php @@ -1,5 +1,5 @@

@@ -21,4 +21,4 @@
- \ No newline at end of file + diff --git a/app/Template/header.php b/app/Template/header.php index f99f1031..a2b3fcb3 100644 --- a/app/Template/header.php +++ b/app/Template/header.php @@ -5,7 +5,7 @@ url->link('KB', 'DashboardController', 'show', array(), false, '', t('Dashboard')) ?> - + url->link($this->text->e($project['name']), 'BoardViewController', 'show', array('project_id' => $project['id'])) ?> text->e($title) ?> diff --git a/app/Template/task/sidebar.php b/app/Template/task/sidebar.php index b44e6f0b..728741ba 100644 --- a/app/Template/task/sidebar.php +++ b/app/Template/task/sidebar.php @@ -1,5 +1,7 @@