* Refactor task-pause and add unit test.
This commit is contained in:
@@ -93,3 +93,8 @@ $config->task->form->batchCreate['estStarted'] = array('type' => 'array', 're
|
||||
$config->task->form->batchCreate['deadline'] = array('type' => 'array', 'required' => false, 'default' => array());
|
||||
$config->task->form->batchCreate['desc'] = array('type' => 'array', 'required' => false, 'default' => array());
|
||||
$config->task->form->batchCreate['pri'] = array('type' => 'array', 'required' => false, 'default' => array());
|
||||
|
||||
$config->task->form->pause = array();
|
||||
$config->task->form->pause['lastEditedBy'] = array('type' => 'string', 'required' => false, 'default' => $app->user->account);
|
||||
$config->task->form->pause['lastEditedDate'] = array('type' => 'string', 'required' => false, 'default' => helper::now());
|
||||
$config->task->form->pause['status'] = array('type' => 'string', 'required' => false, 'default' => 'pause');
|
||||
|
||||
+19
-37
@@ -802,6 +802,7 @@ class task extends control
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停任务。
|
||||
* Pause task.
|
||||
*
|
||||
* @param int $taskID
|
||||
@@ -809,7 +810,7 @@ class task extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function pause($taskID, $extra = '')
|
||||
public function pause(int $taskID, string $extra = '')
|
||||
{
|
||||
$this->taskZen->commonAction($taskID);
|
||||
|
||||
@@ -818,52 +819,33 @@ class task extends control
|
||||
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$this->loadModel('action');
|
||||
$changes = $this->task->pause($taskID, $extra);
|
||||
if(dao::isError()) return print(js::error(dao::getError()));
|
||||
/* Init task data. */
|
||||
$postData = form::data($this->config->task->form->pause);
|
||||
$task = $postData->data;
|
||||
$task->id = $taskID;
|
||||
|
||||
/* Pause task. */
|
||||
$changes = $this->task->pause($task, $output);
|
||||
if(dao::isError()) return array('result' => 'fail', 'message' => dao::getError());
|
||||
|
||||
/* Record log. */
|
||||
if($this->post->comment != '' or !empty($changes))
|
||||
{
|
||||
$actionID = $this->action->create('task', $taskID, 'Paused', $this->post->comment);
|
||||
$actionID = $this->loadModel('action')->create('task', $taskID, 'Paused', $this->post->comment);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
$this->executeHooks($taskID);
|
||||
|
||||
if(isonlybody())
|
||||
{
|
||||
$task = $this->task->getById($taskID);
|
||||
$execution = $this->execution->getByID($task->execution);
|
||||
$executionLaneType = $this->session->executionLaneType ? $this->session->executionLaneType : 'all';
|
||||
$executionGroupBy = $this->session->executionGroupBy ? $this->session->executionGroupBy : 'default';
|
||||
if(($this->app->tab == 'execution' or ($this->config->vision == 'lite' and $this->app->tab == 'project')) and $execution->type == 'kanban')
|
||||
{
|
||||
$rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
|
||||
$regionID = !empty($output['regionID']) ? $output['regionID'] : 0;
|
||||
$kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $executionLaneType, 'id_desc', $regionID, $executionGroupBy, $rdSearchValue);
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban($kanbanData, $regionID)"));
|
||||
}
|
||||
if($output['from'] == 'taskkanban')
|
||||
{
|
||||
$taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
|
||||
$kanbanData = $this->loadModel('kanban')->getExecutionKanban($task->execution, $executionLaneType, $executionGroupBy, $taskSearchValue);
|
||||
$kanbanType = $executionLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
$kanbanData = $kanbanData[$kanbanType];
|
||||
$kanbanData = json_encode($kanbanData);
|
||||
|
||||
return print(js::closeModal('parent.parent', '', "parent.parent.updateKanban(\"task\", $kanbanData)"));
|
||||
}
|
||||
return print(js::closeModal('parent.parent', 'this'));
|
||||
}
|
||||
|
||||
return print(js::locate($this->createLink('task', 'view', "taskID=$taskID"), 'parent'));
|
||||
/* Get response after the suspended task. */
|
||||
$from = zget($output, 'from');
|
||||
$task = $this->task->getById($taskID);
|
||||
$response = $this->taskZen->responseAfterChangeStatus($task, $from);
|
||||
return $this->send($response);
|
||||
}
|
||||
|
||||
$this->view->title = $this->view->execution->name . $this->lang->colon .$this->lang->task->pause;
|
||||
$this->view->position[] = $this->lang->task->pause;
|
||||
|
||||
/* Show the variables associated. */
|
||||
$this->view->title = $this->view->execution->name . $this->lang->colon .$this->lang->task->pause;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->display();
|
||||
}
|
||||
|
||||
+31
-24
@@ -1514,36 +1514,27 @@ class taskModel extends model
|
||||
/**
|
||||
* Pause task
|
||||
*
|
||||
* @param int $taskID
|
||||
* @param string $extra
|
||||
* @param object $task
|
||||
* @param array $output
|
||||
* @access public
|
||||
* @return array
|
||||
* @return array|bool
|
||||
*/
|
||||
public function pause($taskID, $extra = '')
|
||||
public function pause(object $task, array $output = array()): bool|array
|
||||
{
|
||||
$extra = str_replace(array(',', ' '), array('&', ''), $extra);
|
||||
parse_str($extra, $output);
|
||||
/* Get old task. */
|
||||
$oldTask = $this->getById($task->id);
|
||||
|
||||
$oldTask = $this->getById($taskID);
|
||||
/* Update kanban status. */
|
||||
$this->dao->update(TABLE_TASK)->data($task)->autoCheck()->checkFlow()->where('id')->eq($task->id)->exec();
|
||||
|
||||
$task = fixer::input('post')
|
||||
->add('id', $taskID)
|
||||
->setDefault('status', 'pause')
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', helper::now())
|
||||
->stripTags($this->config->task->editor->pause['id'], $this->config->allowedTags)
|
||||
->remove('comment')
|
||||
->get();
|
||||
/* If task has parent task, update status of the parent task. */
|
||||
if($oldTask->parent > 0) $this->updateParentStatus($task->id);
|
||||
|
||||
$task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->pause['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_TASK)->data($task)->autoCheck()->checkFlow()->where('id')->eq((int)$taskID)->exec();
|
||||
/* If output is not empty, update kanban cell. */
|
||||
$this->updateKanbanCell($task->id, $output, $oldTask->execution);
|
||||
|
||||
if($oldTask->parent > 0) $this->updateParentStatus($taskID);
|
||||
|
||||
$this->loadModel('kanban');
|
||||
if(!isset($output['toColID'])) $this->kanban->updateLane($oldTask->execution, 'task', $taskID);
|
||||
if(isset($output['toColID'])) $this->kanban->moveCard($taskID, $output['fromColID'], $output['toColID'], $output['fromLaneID'], $output['toLaneID']);
|
||||
if(!dao::isError()) return common::createChanges($oldTask, $task);
|
||||
if(dao::isError()) return false;
|
||||
return common::createChanges($oldTask, $task);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3455,7 +3446,7 @@ class taskModel extends model
|
||||
$menu .= $this->buildMenu('task', 'finish', $params, $task, 'browse', '', '', 'iframe', true);
|
||||
$menu .= $this->buildMenu('task', 'close', $params, $task, 'browse', '', '', 'iframe', true);
|
||||
|
||||
if(in_array(true, array($canStart, $canRestart, $canFinish, $canClose)) and in_array(true, array($canRecordEstimate, $canEdit, $canBatchCreate)))
|
||||
if(in_array(true, array($canStart, $canRestart, $canFinish, $canClose)) and in_array(true, $canRecordEstimate, $canEdit, $canBatchCreate))
|
||||
{
|
||||
$menu .= "<div class='dividing-line'></div>";
|
||||
}
|
||||
@@ -3922,4 +3913,20 @@ class taskModel extends model
|
||||
$this->action->create('task', $childTaskID, 'Opened');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新看板单元格。
|
||||
* Update kanban cell.
|
||||
*
|
||||
* @param int $taskID
|
||||
* @param array $output
|
||||
* @param int $executionID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function updateKanbanCell(int $taskID, array $output, int $executionID): void
|
||||
{
|
||||
if(!isset($output['toColID'])) $this->loadModel('kanban')->updateLane($executionID, 'task', $taskID);
|
||||
if(isset($output['toColID'])) $this->loadModel('kanban')->moveCard($taskID, $output['fromColID'], $output['toColID'], $output['fromLaneID'], $output['toLaneID']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,27 +2,24 @@
|
||||
<?php
|
||||
include dirname(__FILE__, 5) . '/test/lib/init.php';
|
||||
include dirname(__FILE__, 2) . '/task.class.php';
|
||||
su('admin');
|
||||
|
||||
zdTable('task')->config('task_pause')->gen(7);
|
||||
zdTable('project')->config('project_pause')->gen(1);
|
||||
|
||||
/**
|
||||
|
||||
title=taskModel->pause();
|
||||
timeout=0
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
wait状态任务暂停 >> status,wait,pause
|
||||
doing状态任务暂停 >> status,doing,pause
|
||||
done状态任务暂停 >> status,done,pause
|
||||
cancel状态任务暂停 >> status,cancel,pause
|
||||
closed状态任务暂停 >> status,closed,pause
|
||||
|
||||
*/
|
||||
|
||||
$taskIDList = array('19','20','21','23','24');
|
||||
$taskIDList = array('1', '2', '3', '4', '5', '7');
|
||||
|
||||
$task = new taskTest();
|
||||
r($task->pauseTest($taskIDList[0])) && p('0:field,old,new') && e('status,wait,pause'); //wait状态任务暂停
|
||||
r($task->pauseTest($taskIDList[1])) && p('0:field,old,new') && e('status,doing,pause'); //doing状态任务暂停
|
||||
r($task->pauseTest($taskIDList[2])) && p('0:field,old,new') && e('status,done,pause'); //done状态任务暂停
|
||||
r($task->pauseTest($taskIDList[3])) && p('0:field,old,new') && e('status,cancel,pause'); //cancel状态任务暂停
|
||||
r($task->pauseTest($taskIDList[4])) && p('0:field,old,new') && e('status,closed,pause'); //closed状态任务暂停
|
||||
r($task->pauseTest($taskIDList[0])) && p('0:field,old,new') && e('status,wait,pause'); // wait状态任务暂停
|
||||
r($task->pauseTest($taskIDList[1])) && p('0:field,old,new') && e('status,doing,pause'); // doing状态任务暂停
|
||||
r($task->pauseTest($taskIDList[2])) && p('0:field,old,new') && e('status,done,pause'); // done状态任务暂停
|
||||
r($task->pauseTest($taskIDList[3])) && p('0:field,old,new') && e('status,cancel,pause'); // cancel状态任务暂停
|
||||
r($task->pauseTest($taskIDList[4])) && p('0:field,old,new') && e('status,closed,pause'); // closed状态任务暂停
|
||||
r($task->pauseTest($taskIDList[5])) && p('0:field,old,new') && e('status,doing,pause'); // doing状态子任务暂停
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(__FILE__, 5) . '/test/lib/init.php';
|
||||
include dirname(__FILE__, 2) . '/task.class.php';
|
||||
|
||||
zdTable('task')->config('task_updatekanbancell')->gen(7);
|
||||
zdTable('project')->config('project_updatekanbancell')->gen(1);
|
||||
|
||||
zdTable('kanbanregion')->config('kanbanregion_updatekanbancell')->gen(1);
|
||||
zdTable('kanbanlane')->config('kanbanlane_updatekanbancell')->gen(1);
|
||||
zdTable('kanbancolumn')->config('kanbancolumn_updatekanbancell')->gen(7);
|
||||
zdTable('kanbancell')->config('kanbancell_updatekanbancell')->gen(7);
|
||||
|
||||
/**
|
||||
|
||||
title=taskModel->updateKanbanCell();
|
||||
timeout=0
|
||||
cid=1
|
||||
|
||||
*/
|
||||
|
||||
$taskIDList = array(1, 2, 3, 4, 5, 7);
|
||||
$executionID = 11;
|
||||
|
||||
$output = array();
|
||||
$output[] = array('fromColID' => 1, 'toColID' => 2, 'fromLaneID' => 1, 'toLaneID' => 1);
|
||||
$output[] = array('fromColID' => 2, 'toColID' => 6, 'fromLaneID' => 1, 'toLaneID' => 1);
|
||||
|
||||
|
||||
$task = new taskTest();
|
||||
r($task->updateKanbanCellTest($taskIDList[0], $executionID, array())) && p() && e('1:,1,|2:|3:,2,7,|4:,3,|5:|6:,4,|7:,5,'); // 测试获取wait状态任务更新看板单元格不传output后的看板单元格数据
|
||||
r($task->updateKanbanCellTest($taskIDList[1], $executionID, array())) && p() && e('1:,1,|2:|3:,2,7,|4:,3,|5:|6:,4,|7:,5,'); // 测试获取doing状态任务更新看板单元格不传output后的看板单元格数据
|
||||
r($task->updateKanbanCellTest($taskIDList[2], $executionID, array())) && p() && e('1:,1,|2:|3:,2,7,|4:,3,|5:|6:,4,|7:,5,'); // 测试获取done状态任务更新看板单元格不传output后的看板单元格数据
|
||||
r($task->updateKanbanCellTest($taskIDList[3], $executionID, array())) && p() && e('1:,1,|2:|3:,2,7,|4:,3,|5:|6:,4,|7:,5,'); // 测试获取cancel状态任务更新看板单元格不传output后的看板单元格数据
|
||||
r($task->updateKanbanCellTest($taskIDList[4], $executionID, array())) && p() && e('1:,1,|2:|3:,2,7,|4:,3,|5:|6:,4,|7:,5,'); // 测试获取closed状态任务更新看板单元格不传output后的看板单元格数据
|
||||
r($task->updateKanbanCellTest($taskIDList[0], $executionID, $output[0])) && p() && e('1:|2:,1,|3:,2,7,|4:,3,|5:|6:,4,|7:,5,'); // 测试获取wait状态从第一列挪到第二列后的看板单元格数据
|
||||
r($task->updateKanbanCellTest($taskIDList[0], $executionID, $output[1])) && p() && e('1:|2:|3:,2,7,|4:,3,|5:|6:,4,1,|7:,5,'); // 测试获取wait状态从第二列挪到第六列后的看板单元格数据
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: zt_project
|
||||
author: Mengyi Liu
|
||||
version: "1.0"
|
||||
fields:
|
||||
- field: type
|
||||
range: scrum
|
||||
...
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: zt_task
|
||||
author: Mengyi Liu
|
||||
version: "1.0"
|
||||
fields:
|
||||
- field: execution
|
||||
range: 11
|
||||
- field: story
|
||||
range: 0
|
||||
- field: parent
|
||||
range: "0{5},`-1`,6"
|
||||
- field: status
|
||||
range: "wait,doing,done,cancel,closed,doing{2}"
|
||||
...
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: zt_kanbancell
|
||||
author: Mengyi Liu
|
||||
version: "1.0"
|
||||
fields:
|
||||
- field: id
|
||||
range: 1-100
|
||||
- field: kanban
|
||||
range: 11
|
||||
- field: lane
|
||||
range: 1
|
||||
- field: column
|
||||
range: 1-7
|
||||
- field: type
|
||||
range: "task"
|
||||
- field: cards
|
||||
range: "[]"
|
||||
...
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: zt_kanbancolumn
|
||||
author: Mengyi Liu
|
||||
version: "1.0"
|
||||
fields:
|
||||
- field: id
|
||||
range: 1-7
|
||||
- field: region
|
||||
range: 1
|
||||
- field: type
|
||||
range: wait,develop,developing,developed,pause,canceled,closed,
|
||||
- field: parent
|
||||
range: "0,`-1`,2{2},0{3}"
|
||||
- field: name
|
||||
range: 未开始,开发,研发中,研发完毕,已暂停,已取消,已关闭
|
||||
- field: limit
|
||||
range: "`-1`"
|
||||
...
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: zt_kanbanlane
|
||||
author: Mengyi Liu
|
||||
version: "1.0"
|
||||
fields:
|
||||
- field: id
|
||||
range: 1-10
|
||||
- field: execution
|
||||
range: 11
|
||||
- field: type
|
||||
range: "task"
|
||||
- field: region
|
||||
range: 1
|
||||
- field: lastEditedTime
|
||||
range: "20220101 000000"
|
||||
type: timestamp
|
||||
format: "YY/MM/DD hh:mm:ss"
|
||||
...
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: zt_kanbanregion
|
||||
author: Mengyi Liu
|
||||
version: "1.0"
|
||||
fields:
|
||||
- field: id
|
||||
range: 1-10
|
||||
- field: space
|
||||
range: 0
|
||||
- field: kanban
|
||||
range: 11
|
||||
- field: lastEditedDate
|
||||
range: "20220101 000000"
|
||||
type: timestamp
|
||||
format: "YY/MM/DD hh:mm:ss"
|
||||
...
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: zt_project
|
||||
author: Mengyi Liu
|
||||
version: "1.0"
|
||||
fields:
|
||||
- field: type
|
||||
range: scrum
|
||||
...
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: zt_task
|
||||
author: Mengyi Liu
|
||||
version: "1.0"
|
||||
fields:
|
||||
- field: execution
|
||||
range: 11
|
||||
- field: story
|
||||
range: 0
|
||||
- field: parent
|
||||
range: "0{5},`-1`,6"
|
||||
- field: status
|
||||
range: "wait,doing,done,cancel,closed,doing{2}"
|
||||
...
|
||||
|
||||
@@ -584,29 +584,28 @@ class taskTest
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试暂停任务。
|
||||
* Test pause a task.
|
||||
*
|
||||
* @param int $taskID
|
||||
* @param array $param
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function pauseTest($taskID, $param = array())
|
||||
public function pauseTest(int $taskID): array
|
||||
{
|
||||
$createFields = array('status' => 'pause', 'comment' => '单元测试');
|
||||
foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
|
||||
foreach($param as $key => $value) $_POST[$key] = $value;
|
||||
$object = $this->objectModel->pause($taskID);
|
||||
unset($_POST);
|
||||
if(dao::isError())
|
||||
{
|
||||
$error = dao::getError();
|
||||
return $error[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return $object;
|
||||
}
|
||||
$task = new stdclass();
|
||||
$task->id = $taskID;
|
||||
$task->status = 'pause';
|
||||
$task->lastEditedBy = 'admin';
|
||||
$task->lastEditedDate = helper::now();
|
||||
|
||||
$_SERVER['HTTP_HOST'] = '';
|
||||
|
||||
$changes = $this->objectModel->pause($task, array());
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return $changes;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2052,4 +2051,28 @@ class taskTest
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试更新看板单元格。
|
||||
* Test update kanban cell.
|
||||
*
|
||||
* @param int $taskID
|
||||
* @param array $output
|
||||
* @param int $executionID
|
||||
* @access public
|
||||
* @return array|string
|
||||
*/
|
||||
public function updateKanbanCellTest(int $taskID, int $executionID, array $output): array|string
|
||||
{
|
||||
$_SERVER['HTTP_HOST'] = '';
|
||||
|
||||
$this->objectModel->updateKanbanCell($taskID, $output, $executionID);
|
||||
|
||||
global $tester;
|
||||
$cells = $tester->dao->select("CONCAT(id, ':', cards) as cards")->from(TABLE_KANBANCELL)->where('kanban')->eq($executionID)->fetchPairs();
|
||||
|
||||
if(dao::isError()) return dao::getError();
|
||||
|
||||
return implode('|', $cells);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* The pause view file of task module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
|
||||
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author Mengyi Liu<liumengyi@easycorp.ltd>
|
||||
* @package task
|
||||
* @link https://www.zentao.net
|
||||
*/
|
||||
|
||||
namespace zin;
|
||||
|
||||
/* ====== Define the page structure with zin widgets ====== */
|
||||
|
||||
formPanel
|
||||
(
|
||||
set::id('taskPauseForm'),
|
||||
set::title($lang->task->pause),
|
||||
formGroup
|
||||
(
|
||||
set::label($lang->comment),
|
||||
set::name('comment'),
|
||||
set::control('editor'),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
/* ====== Render page ====== */
|
||||
|
||||
render();
|
||||
@@ -1331,4 +1331,20 @@ class taskZen extends task
|
||||
$kanbanType = $executionLaneType == 'all' ? 'task' : key($kanbanData);
|
||||
return json_encode($kanbanData[$kanbanType]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理开始任务后的返回信息。
|
||||
* The information return after process the start task.
|
||||
*
|
||||
* @param object $task
|
||||
* @param string $from ''|taskkanban
|
||||
* @access protected
|
||||
* @return array
|
||||
*/
|
||||
protected function responseAfterChangeStatus(object $task, string $from): array
|
||||
{
|
||||
if($this->viewType == 'json' || (defined('RUN_MODE') && RUN_MODE == 'api')) return array('result' => 'success');
|
||||
if(isonlybody()) return $this->taskZen->responseKanban($task, $from);
|
||||
return array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => $this->createLink('task', 'view', "taskID={$task->id}"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user