* Refactor task-pause and add unit test.

This commit is contained in:
liumengyi
2023-05-12 16:19:22 +08:00
parent 773e033434
commit 7625a4fdab
16 changed files with 312 additions and 91 deletions
+5
View File
@@ -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
View File
@@ -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
View File
@@ -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']);
}
}
+11 -14
View File
@@ -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状态从第二列挪到第六列后的看板单元格数据
+9
View File
@@ -0,0 +1,9 @@
---
title: zt_project
author: Mengyi Liu
version: "1.0"
fields:
- field: type
range: scrum
...
+15
View File
@@ -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}"
...
+39 -16
View File
@@ -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);
}
}
+32
View File
@@ -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();
+16
View File
@@ -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}"));
}
}