This commit is contained in:
王怡栋
2022-03-22 10:32:40 +08:00
18 changed files with 398 additions and 9 deletions

View File

@@ -0,0 +1,43 @@
<?php
/**
* The modules entry point of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package entries
* @version 1
* @link http://www.zentao.net
*/
class modulesEntry extends Entry
{
/**
* Get method.
*
* @access public
* @return void
*/
public function get()
{
$objectType = $this->param('type', '');
$objectID = $this->param('id', '');
if(!$objectType or !$objectID) return $this->sendError(400, 'Need id and type.');
if(!in_array($objectType, array('story', 'task', 'bug', 'case'))) return $this->sendError(400, 'Type is not allowed');
if($objectType == 'task')
{
$control = $this->loadController('tree', 'browsetask');
$control->browseTask($objectID);
}
else
{
$control = $this->loadController('tree', 'browse');
$control->browse($objectID, $objectType);
}
$data = $this->getData();
if(isset($data->status) and $data->status == 'success') return $this->send(200, array('modules' => $data->data->tree));
return $this->send400(isset($data->message) ? $data->message: 'error');
}
}

View File

@@ -140,6 +140,8 @@ $routes['/docs/:id'] = 'doc';
$routes['/repos'] = 'repos';
$routes['/repos/rules'] = 'reporules';
$routes['/modules'] = 'modules';
$routes['/reports'] = 'reports';
$routes['/z/folders'] = 'zfolders';

View File

@@ -124,9 +124,7 @@ if($this->app->tab == 'project') js::set('objectID', $projectID);
<div class='input-group' id='buildBox'>
<span class="input-group-addon"><?php echo $lang->bug->openedBuild?></span>
<?php echo html::select('openedBuild[]', $builds, empty($buildID) ? '' : $buildID, "multiple=multiple class='chosen form-control'");?>
<?php if(count($builds) < 2):?>
<span class='input-group-addon fix-border' id='buildBoxActions'></span>
<?php endif;?>
<div class='input-group-btn'><?php echo html::commonButton($lang->bug->allBuilds, "class='btn' id='all' data-toggle='tooltip' onclick='loadAllBuilds()'")?></div>
</div>
</td>

View File

@@ -1317,7 +1317,7 @@ class execution extends control
$this->view->title = $this->lang->execution->tips;
$this->view->tips = $this->fetch('execution', 'tips', "executionID=$executionID");
$this->view->defaultURL = isset($this->session->closeTipsList) ? $this->session->closeTipsList : $this->createLink('execution', 'task', 'executionID=' . $executionID);
$this->view->defaultURL = $this->session->closeTipsList ? $this->session->closeTipsList : $this->createLink('execution', 'task', 'executionID=' . $executionID);
$this->view->executionID = $executionID;
$this->view->projectID = $projectID;
$this->view->project = $project;

View File

@@ -1 +1 @@
#mainContent {padding-left: 0px;}
#mainContent {padding-left: 0px; height: 500px;}

View File

@@ -1 +1 @@
#mainContent {padding-left: 0px;}
#mainContent {padding-left: 0px; height: 500px;}

View File

@@ -1587,3 +1587,8 @@ function resetRegionHeight(fold)
$('.region').css('height', regionHeaderHeight);
}
}
$('.dropdown-menu').click(function()
{
$.zui.ContextMenu.hide();
})

View File

@@ -1647,14 +1647,14 @@ class kanbanModel extends model
public function getSpacePairs($browseType = 'private')
{
$account = $this->app->user->account;
$spaceIdList = $this->getCanViewObjects('kanbanspace');
$spaceIdList = $this->getCanViewObjects('kanbanspace', $browseType);
return $this->dao->select('id,name')->from(TABLE_KANBANSPACE)
->where('deleted')->eq(0)
->andWhere('id')->in($spaceIdList)
->beginIF(in_array($browseType, array('private', 'cooperation', 'public')))->andWhere('type')->eq($browseType)->fi()
->beginIF($browseType == 'involved')->andWhere('owner')->ne($account)->fi()
->beginIF($this->cookie->showClosed == 0 and $browseType != 'showClosed')->andWhere('status')->ne('closed')->fi()
->beginIF(!$this->app->user->admin)->andWhere('id')->in($spaceIdList)->fi()
->orderBy('id_desc')
->fetchPairs('id');
}
@@ -1694,7 +1694,7 @@ class kanbanModel extends model
$spaceList = $objectType == 'kanban' ? $this->dao->select('id,owner,type')->from(TABLE_KANBANSPACE)->fetchAll('id') : array();
if($this->app->user->admin and strpos('private,involved', $param) === false) return array_keys($objects);
if($param and $this->app->user->admin and strpos('private,involved', $param) === false) return array_keys($objects);
$account = $this->app->user->account;
foreach($objects as $objectID => $object)

View File

@@ -71,6 +71,7 @@
</div>
</td>
</tr>
<?php if($card->progress):?>
<tr>
<th><?php echo $lang->kanbancard->progress;?></th>
<td>
@@ -80,6 +81,7 @@
</div>
</td>
</tr>
<?php endif;?>
</table>
</div>
</div>

View File

@@ -114,10 +114,12 @@
<th><?php echo $lang->kanbancard->estimate;?></th>
<td><?php echo round($card->estimate, 2) . ' ' . $lang->kanbancard->lblHour;?></td>
</tr>
<?php if($card->progress):?>
<tr>
<th><?php echo $lang->kanbancard->progress;?></th>
<td><?php echo round($card->progress, 2) . ' %';?></td>
</tr>
<?php endif;?>
</tbody>
</table>
</div>

View File

@@ -50,7 +50,12 @@ class tree extends control
if(strpos('story|bug|case', $viewType) !== false)
{
$product = $this->loadModel('product')->getById($rootID);
if(empty($product)) $this->locate($this->createLink('product', 'create'));
if(empty($product))
{
if($this->viewType == 'json' or (defined('RUN_MODE') && RUN_MODE == 'api')) return $this->send(array('result' => 'fail', 'message' => 'No product.'));
$this->locate($this->createLink('product', 'create'));
}
if(!empty($product->type) && $product->type != 'normal')
{
$branches = $this->loadModel('branch')->getPairs($product->id);

View File

@@ -1841,4 +1841,118 @@ class bugTest
return $array;
}
}
/**
* Test form customed bugs.
*
* @param array $bugIDList
* @access public
* @return array
*/
public function formCustomedBugsTest($bugIDList)
{
$bugs = $this->objectModel->getByList($bugIDList);
$array = $this->objectModel->formCustomedBugs($bugs);
if(dao::isError())
{
return dao::getError();
}
else
{
return $array;
}
}
/**
* Test adjust the action is clickable.
*
* @param object $bug
* @param string $action
* @access public
* @return int
*/
public function isClickableTest($bug, $action)
{
$object = $this->objectModel->isClickable($bug, $action);
if(dao::isError())
{
return dao::getError();
}
else
{
return $object ? 1 : 2;
}
}
/**
* Test link bug to build and release.
*
* @param array $bugIDList
* @param int $resolvedBuild
* @access public
* @return object
*/
public function linkBugToBuildTest($bugIDList, $resolvedBuild)
{
$this->objectModel->linkBugToBuild($bugIDList, $resolvedBuild);
global $tester;
$release = $tester->dao->select('id,bugs')->from(TABLE_RELEASE)->where('build')->eq($resolvedBuild)->andWhere('deleted')->eq('0')->fetch();
if(dao::isError())
{
return dao::getError();
}
else
{
return $release;
}
}
/**
* Test get project list.
*
* @param int $productID
* @access public
* @return string
*/
public function getProjectsTest($productID)
{
$array = $this->objectModel->getProjects($productID);
$title = '';
foreach($array as $id => $project) $title .= ',' . $project;
$title = trim($title, ',');
if(dao::isError())
{
return dao::getError();
}
else
{
return $title;
}
}
/**
* Test get id list of all projects.
*
* @access public
* @return array
*/
public function getAllProjectIdsTest()
{
$array = $this->objectModel->getAllProjectIds();
if(dao::isError())
{
return dao::getError();
}
else
{
return $array;
}
}
}

View File

@@ -0,0 +1,32 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/bug.class.php';
su('admin');
/**
title=测试bugModel->formCustomedBugs();
cid=1
pid=1
获取bug 1 2的module story task case execution名称 >> 产品模块1,软件需求2,0,0,迭代1;产品模块2,软件需求6,0,0,迭代1
获取bug 3 4的module story task case execution名称 >> 产品模块3,软件需求10,0,0,迭代1;产品模块5,软件需求14,0,0,迭代2
获取bug 5 6的module story task case execution名称 >> 产品模块6,软件需求18,0,0,迭代2;产品模块7,软件需求22,0,0,迭代2
获取bug 7 8的module story task case execution名称 >> 产品模块11,软件需求26,0,0,迭代3;产品模块12,软件需求30,0,0,迭代3
获取bug 9 10的module story task case execution名称 >> 产品模块13,软件需求34,0,0,迭代3;0,软件需求38,0,0,迭代4
*/
$bugIDList1 = array('1', '2');
$bugIDList2 = array('3', '4');
$bugIDList3 = array('5', '6');
$bugIDList4 = array('7', '8');
$bugIDList5 = array('9', '10');
$bug = new bugTest();
r($bug->formCustomedBugsTest($bugIDList1)) && p('1:module,story,task,case,execution;2:module,story,task,case,execution') && e('产品模块1,软件需求2,0,0,迭代1;产品模块2,软件需求6,0,0,迭代1'); // 获取bug 1 2的module story task case execution名称
r($bug->formCustomedBugsTest($bugIDList2)) && p('3:module,story,task,case,execution;4:module,story,task,case,execution') && e('产品模块3,软件需求10,0,0,迭代1;产品模块5,软件需求14,0,0,迭代2'); // 获取bug 3 4的module story task case execution名称
r($bug->formCustomedBugsTest($bugIDList3)) && p('5:module,story,task,case,execution;6:module,story,task,case,execution') && e('产品模块6,软件需求18,0,0,迭代2;产品模块7,软件需求22,0,0,迭代2'); // 获取bug 5 6的module story task case execution名称
r($bug->formCustomedBugsTest($bugIDList4)) && p('7:module,story,task,case,execution;8:module,story,task,case,execution') && e('产品模块11,软件需求26,0,0,迭代3;产品模块12,软件需求30,0,0,迭代3'); // 获取bug 7 8的module story task case execution名称
r($bug->formCustomedBugsTest($bugIDList5)) && p('9:module,story,task,case,execution;10:module,story,task,case,execution') && e('产品模块13,软件需求34,0,0,迭代3;0,软件需求38,0,0,迭代'); // 获取bug 9 10的module story task case execution名称

View File

@@ -0,0 +1,29 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php'; su('admin');
include dirname(dirname(dirname(__FILE__))) . '/class/bug.class.php';
/**
title=bugModel->getAllProjectIds();
cid=1
pid=1
测试projectId为11的项目 >> 11
测试projectId为12的项目 >> 12
测试projectId为13的项目 >> 13
测试projectId为41的项目 >> 41
测试projectId为51的项目 >> 51
测试projectId为91的项目 >> 91
*/
$projectIDList = array('11', '12', '13', '41', '51', '91');
$bug=new bugTest();
r($bug->getAllProjectIdsTest()) && p("$projectIDList[0]") && e('11'); // 测试projectId为11的项目
r($bug->getAllProjectIdsTest()) && p("$projectIDList[1]") && e('12'); // 测试projectId为12的项目
r($bug->getAllProjectIdsTest()) && p("$projectIDList[2]") && e('13'); // 测试projectId为13的项目
r($bug->getAllProjectIdsTest()) && p("$projectIDList[3]") && e('41'); // 测试projectId为41的项目
r($bug->getAllProjectIdsTest()) && p("$projectIDList[4]") && e('51'); // 测试projectId为51的项目
r($bug->getAllProjectIdsTest()) && p("$projectIDList[5]") && e('91'); // 测试projectId为91的项目

32
test/model/bug/getprojects.php Executable file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php'; su('admin');
include dirname(dirname(dirname(__FILE__))) . '/class/bug.class.php';
/**
title=bugModel->getProjects();
cid=1
pid=1
测试获取productID为1的项目 >> 项目1,项目11
测试获取productID为2的项目 >> 项目2,项目12
测试获取productID为3的项目 >> 项目3,项目13
测试获取productID为4的项目 >> 项目4,项目14
测试获取productID为5的项目 >> 项目5,项目15
测试获取productID为6的项目 >> 项目6,项目16
测试获取不存在的product的项目 >> 0
*/
$productIDList = array('1', '2', '3', '4','5', '6', '1000001');
$bug=new bugTest();
r($bug->getProjectsTest($productIDList[0])) && p() && e('项目1,项目11'); // 测试获取productID为1的项目
r($bug->getProjectsTest($productIDList[1])) && p() && e('项目2,项目12'); // 测试获取productID为2的项目
r($bug->getProjectsTest($productIDList[2])) && p() && e('项目3,项目13'); // 测试获取productID为3的项目
r($bug->getProjectsTest($productIDList[3])) && p() && e('项目4,项目14'); // 测试获取productID为4的项目
r($bug->getProjectsTest($productIDList[4])) && p() && e('项目5,项目15'); // 测试获取productID为5的项目
r($bug->getProjectsTest($productIDList[5])) && p() && e('项目6,项目16'); // 测试获取productID为6的项目
r($bug->getProjectsTest($productIDList[6])) && p() && e('0'); // 测试获取不存在的product的项目

82
test/model/bug/isclickable.php Executable file
View File

@@ -0,0 +1,82 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/bug.class.php';
su('admin');
/**
title=bugModel->isClickable();
cid=1
pid=1
状态为active confirmed为0的bug能否执行confirmbug动作 >> 1
状态为active confirmed为0的bug能否执行resolve动作 >> 1
状态为active confirmed为0的bug能否执行close动作 >> 2
状态为active confirmed为0的bug能否执行activate动作 >> 2
状态为active confirmed为0的bug能否执行tostory动作 >> 1
状态为active confirmed为0的bug能否执行test动作 >> 1
状态为active confirmed为1的bug能否执行confirmbug动作 >> 2
状态为active confirmed为1的bug能否执行resolve动作 >> 1
状态为active confirmed为1的bug能否执行close动作 >> 2
状态为active confirmed为1的bug能否执行activate动作 >> 2
状态为active confirmed为1的bug能否执行tostory动作 >> 1
状态为active confirmed为1的bug能否执行test动作 >> 1
状态为resolved的bug能否执行confirmbug动作 >> 2
状态为resolved的bug能否执行resolve动作 >> 2
状态为resolved的bug能否执行close动作 >> 1
状态为resolved的bug能否执行activate动作 >> 1
状态为resolved的bug能否执行tostory动作 >> 2
状态为resolved的bug能否执行test动作 >> 1
状态为closed的bug能否执行confirmbug动作 >> 2
状态为closed的bug能否执行resolve动作 >> 2
状态为closed的bug能否执行close动作 >> 2
状态为closed的bug能否执行activate动作 >> 1
状态为closed的bug能否执行tostory动作 >> 2
状态为closed的bug能否执行test动作 >> 1
*/
$object1 = new stdclass();
$object1->status = 'active';
$object1->confirmed = 0;
$object2 = new stdclass();
$object2->status = 'active';
$object2->confirmed = 1;
$object3 = new stdclass();
$object3->status = 'resolved';
$object4 = new stdclass();
$object4->status = 'closed';
$actionList = array('confirmbug', 'resolve', 'close', 'activate', 'tostory', 'test');
$bug=new bugTest();
r($bug->isClickableTest($object1, $actionList[0])) && p() && e('1'); // 状态为active confirmed为0的bug能否执行confirmbug动作
r($bug->isClickableTest($object1, $actionList[1])) && p() && e('1'); // 状态为active confirmed为0的bug能否执行resolve动作
r($bug->isClickableTest($object1, $actionList[2])) && p() && e('2'); // 状态为active confirmed为0的bug能否执行close动作
r($bug->isClickableTest($object1, $actionList[3])) && p() && e('2'); // 状态为active confirmed为0的bug能否执行activate动作
r($bug->isClickableTest($object1, $actionList[4])) && p() && e('1'); // 状态为active confirmed为0的bug能否执行tostory动作
r($bug->isClickableTest($object1, $actionList[5])) && p() && e('1'); // 状态为active confirmed为0的bug能否执行test动作
r($bug->isClickableTest($object2, $actionList[0])) && p() && e('2'); // 状态为active confirmed为1的bug能否执行confirmbug动作
r($bug->isClickableTest($object2, $actionList[1])) && p() && e('1'); // 状态为active confirmed为1的bug能否执行resolve动作
r($bug->isClickableTest($object2, $actionList[2])) && p() && e('2'); // 状态为active confirmed为1的bug能否执行close动作
r($bug->isClickableTest($object2, $actionList[3])) && p() && e('2'); // 状态为active confirmed为1的bug能否执行activate动作
r($bug->isClickableTest($object2, $actionList[4])) && p() && e('1'); // 状态为active confirmed为1的bug能否执行tostory动作
r($bug->isClickableTest($object2, $actionList[5])) && p() && e('1'); // 状态为active confirmed为1的bug能否执行test动作
r($bug->isClickableTest($object3, $actionList[0])) && p() && e('2'); // 状态为resolved的bug能否执行confirmbug动作
r($bug->isClickableTest($object3, $actionList[1])) && p() && e('2'); // 状态为resolved的bug能否执行resolve动作
r($bug->isClickableTest($object3, $actionList[2])) && p() && e('1'); // 状态为resolved的bug能否执行close动作
r($bug->isClickableTest($object3, $actionList[3])) && p() && e('1'); // 状态为resolved的bug能否执行activate动作
r($bug->isClickableTest($object3, $actionList[4])) && p() && e('2'); // 状态为resolved的bug能否执行tostory动作
r($bug->isClickableTest($object3, $actionList[5])) && p() && e('1'); // 状态为resolved的bug能否执行test动作
r($bug->isClickableTest($object4, $actionList[0])) && p() && e('2'); // 状态为closed的bug能否执行confirmbug动作
r($bug->isClickableTest($object4, $actionList[1])) && p() && e('2'); // 状态为closed的bug能否执行resolve动作
r($bug->isClickableTest($object4, $actionList[2])) && p() && e('2'); // 状态为closed的bug能否执行close动作
r($bug->isClickableTest($object4, $actionList[3])) && p() && e('1'); // 状态为closed的bug能否执行activate动作
r($bug->isClickableTest($object4, $actionList[4])) && p() && e('2'); // 状态为closed的bug能否执行tostory动作
r($bug->isClickableTest($object4, $actionList[5])) && p() && e('1'); // 状态为closed的bug能否执行test动作

View File

@@ -0,0 +1,36 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/bug.class.php';
su('admin');
/**
title=测试bugModel->linkBugToBuild();
cid=1
pid=1
把bug 1 2关联到build 1 >> 1,2
把bug 3 4关联到build 3 >> 3,4
把bug 5 6关联到build 4 >> 5,6
把bug 7 8关联到build 1 >> 1,2,7,8
把bug 9 10关联到build 1 >> 1,2,7,8,9,10
*/
$bugIDList1 = array('1', '2');
$bugIDList2 = array('3', '4');
$bugIDList3 = array('5', '6');
$bugIDList4 = array('7', '8');
$bugIDList5 = array('9', '10');
$buildList = array('1', '3', '5');
$bug = new bugTest();
r($bug->linkBugToBuildTest($bugIDList1, $buildList[0])) && p('bugs') && e('1,2'); // 把bug 1 2关联到build 1
r($bug->linkBugToBuildTest($bugIDList2, $buildList[1])) && p('bugs') && e('3,4'); // 把bug 3 4关联到build 3
r($bug->linkBugToBuildTest($bugIDList3, $buildList[2])) && p('bugs') && e('5,6'); // 把bug 5 6关联到build 5
r($bug->linkBugToBuildTest($bugIDList4, $buildList[0])) && p('bugs') && e('1,2,7,8'); // 把bug 5 6关联到build 1
r($bug->linkBugToBuildTest($bugIDList5, $buildList[0])) && p('bugs') && e('1,2,7,8,9,10'); // 把bug 5 6关联到build 1
system("./ztest init");

View File

@@ -900,5 +900,12 @@ $(document).ready(function()
$('#globalCreate').hover(function()
{
$(this).prev().removeClass('open');
$(this).addClass('dropdown-hover');
});
/* Hide create button when global create menu is clicked. */
$('#globalCreate').click(function()
{
$(this).removeClass('dropdown-hover');
});
});