diff --git a/lib/sqlparser/sqlparser.class.php b/lib/sqlparser/sqlparser.class.php index 7a7e3be8f0..42dc06199c 100644 --- a/lib/sqlparser/sqlparser.class.php +++ b/lib/sqlparser/sqlparser.class.php @@ -301,7 +301,7 @@ class sqlparser * @access public * @return object */ - public function getCondition($tableA = null, $columnA = null, $operator = '', $tableB = null, $columnB = null, $group = 1) + public function getCondition($tableA = null, $columnA = null, $operator = '', $tableB = null, $columnB = null, $group = 1, $quote = true) { if(is_array($tableA)) return call_user_func_array(array($this, 'getCondition'), $tableA); @@ -323,8 +323,10 @@ class sqlparser /* 如果tableB为空,那么columnB是值,需要trim("'")。*/ if(empty($tableB)) $columnB = $this->trimExpr($columnB, "'"); - $exprA = empty($tableA) ? "`$columnA`" : "`$tableA`.`$columnA`"; - $exprB = empty($tableB) ? "'$columnB'" : "`$tableB`.`$columnB`"; + $columnB = empty($tableB) && $quote ? "'$columnB'" : $columnB; + $exprA = empty($tableA) ? "`$columnA`" : "`$tableA`.`$columnA`"; + $exprB = empty($tableB) ? $columnB : "`$tableB`.`$columnB`"; + $operator = strtoupper($operator); $expr = "$exprA $operator $exprB"; diff --git a/lib/zin/wg/docapp/js/v1.js b/lib/zin/wg/docapp/js/v1.js index 390ce93628..9981c9ef74 100644 --- a/lib/zin/wg/docapp/js/v1.js +++ b/lib/zin/wg/docapp/js/v1.js @@ -990,15 +990,18 @@ const actionsMap = if(!canModify) return; const canCreateApi = hasPriv('createApi'); + + const command = 'startCreateDoc/' + docID + '/api'; + if(info.ui === 'doc-list-empty') { - return canCreateApi ? [{icon: 'plus', text: lang.createApi, btnType: 'primary', command: 'startCreateDoc'}] : null; + return canCreateApi ? [{icon: 'plus', text: lang.createApi, btnType: 'primary', command}] : null; } const canCreateLib = hasPriv('createLib'); const items = [ - canCreateApi ? {icon: 'plus', text: lang.createApi, command: 'startCreateDoc'} : null, + canCreateApi ? {icon: 'plus', text: lang.createApi, command} : null, (canCreateApi && canCreateLib) ? {type: 'divider'} : null, canCreateLib ? {icon: 'wiki-lib', text: lang.createLib, command: 'createLib'} : null, ].filter(Boolean); @@ -1169,11 +1172,12 @@ const commands = const docApp = getDocApp(); if(!docApp.libList.length) return zui.Modal.alert(getLang('createLibFirst')); + const docType = (args && args[1]) || 'doc'; const {spaceType} = docApp; - if(spaceType === 'api') return docApp.startCreateDoc(); + if(spaceType === 'api' || docType === 'api') return docApp.startCreateDoc(); const {spaceID, libID, moduleID} = docApp; - return showDocBasicModal(args?.[0] ?? 0, 0, true, 'doc').then((formData) => { + return showDocBasicModal(args?.[0] ?? 0, 0, true, docType).then((formData) => { zui.Editor.loadModule().then(() => { const emptyDoc = zui.Editor.createEmptyDoc(); const snapshot = zui.Editor.toSnapshot(emptyDoc); diff --git a/lib/zin/wg/heading/v1.php b/lib/zin/wg/heading/v1.php index b77ea8a29f..fe71f8270c 100644 --- a/lib/zin/wg/heading/v1.php +++ b/lib/zin/wg/heading/v1.php @@ -41,6 +41,9 @@ class heading extends wg if($tab == 'product') $currentMethod = 'all'; } + /* 项目模板appName点击后跳转到项目模板列表页面。 */ + if($lang->$tab->common == $lang->project->template) $currentMethod = 'template'; + if(empty($currentModule) || empty($currentMethod)) return null; $url = createLink($currentModule, $currentMethod); diff --git a/module/action/test/tao/getneedrelatedfields.php b/module/action/test/tao/getneedrelatedfields.php index bb3be8faf7..67b0effe3f 100755 --- a/module/action/test/tao/getneedrelatedfields.php +++ b/module/action/test/tao/getneedrelatedfields.php @@ -92,7 +92,7 @@ $objectIDList = array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); $actionType = array(''); $extraList = array('1111', 'project', 'sprint', '1'); -r($actionTest->getNeedRelatedFields($objectTypeList[0], $objectIDList[0], $actionType[0], $extraList[0])) && p('0,1,2') && e('1,0,0'); //测试获取id为1的story的相关字段 +r($actionTest->getNeedRelatedFields($objectTypeList[0], $objectIDList[0], $actionType[0], $extraList[0])) && p('0,1,2') && e('1,~~,~~'); //测试获取id为1的story的相关字段 r($actionTest->getNeedRelatedFields($objectTypeList[1], $objectIDList[1], $actionType[0], $extraList[0])) && p('0,1,2') && e('1,0,0'); //测试获取id为1的productplan的相关字段 r($actionTest->getNeedRelatedFields($objectTypeList[2], $objectIDList[2], $actionType[0], $extraList[0])) && p('0,1,2') && e('41,0,0'); //测试获取id为1的branch的相关字段 r($actionTest->getNeedRelatedFields($objectTypeList[3], $objectIDList[3], $actionType[0], $extraList[0])) && p('0:0;1;2') && e('1,0,101'); //测试获取id为1的testcase的相关字段 diff --git a/module/bi/model.php b/module/bi/model.php index bc1115cf7a..a7bcfe5cfe 100644 --- a/module/bi/model.php +++ b/module/bi/model.php @@ -1463,12 +1463,12 @@ class biModel extends model * @access public * @return object */ - public function getCondition(mixed $tableA = null, mixed $columnA = null, string $operator = '', mixed $tableB = null, mixed $columnB = null, int $group = 1): object + public function getCondition(mixed $tableA = null, mixed $columnA = null, string $operator = '', mixed $tableB = null, mixed $columnB = null, int $group = 1, bool $quote = true): object { $this->app->loadClass('sqlparser', true); $parser = new sqlparser(null); - return $parser->getCondition($tableA, $columnA, $operator, $tableB, $columnB, $group); + return $parser->getCondition($tableA, $columnA, $operator, $tableB, $columnB, $group, $quote); } /** diff --git a/module/bi/test/lib/bi.unittest.class.php b/module/bi/test/lib/bi.unittest.class.php index 0ea469698d..7560494f2a 100644 --- a/module/bi/test/lib/bi.unittest.class.php +++ b/module/bi/test/lib/bi.unittest.class.php @@ -60,9 +60,9 @@ class biTest * @access public * @return string */ - public function getConditionTest(mixed $tableA = null, mixed $columnA = null, string $operator = '', mixed $tableB = null, mixed $columnB = null, int $group = 1): string + public function getConditionTest(mixed $tableA = null, mixed $columnA = null, string $operator = '', mixed $tableB = null, mixed $columnB = null, int $group = 1, bool $quote = true): string { - $condition = $this->objectModel->getCondition($tableA, $columnA, $operator, $tableB, $columnB, $group); + $condition = $this->objectModel->getCondition($tableA, $columnA, $operator, $tableB, $columnB, $group, $quote); return $condition->build($condition); } diff --git a/module/bi/test/model/getcondition.php b/module/bi/test/model/getcondition.php index b69ea3dd98..f6370f5dc8 100755 --- a/module/bi/test/model/getcondition.php +++ b/module/bi/test/model/getcondition.php @@ -24,14 +24,14 @@ cid=1 */ $bi = new biTest(); -r($bi->getConditionTest(null, 'deleted', '=', null, "'0'")) && p('') && e("`deleted` = '0'"); // 测试 `deleted` = '0' -r($bi->getConditionTest('t1', 'deleted', '=', null, "'0'")) && p('') && e("`t1`.`deleted` = '0'"); // 测试 `t1`.`deleted` = '0' +r($bi->getConditionTest(null, 'deleted', '=', null, "0")) && p('') && e("`deleted` = '0'"); // 测试 `deleted` = '0' +r($bi->getConditionTest('t1', 'deleted', '=', null, "0")) && p('') && e("`t1`.`deleted` = '0'"); // 测试 `t1`.`deleted` = '0' r($bi->getConditionTest('t1', 'project', '=', 't2', 'id')) && p('') && e("`t1`.`project` = `t2`.`id`"); // 测试 `t1`.`project` = `t2`.`id` r($bi->getConditionTest('`t1`', '`project`', '=', 't2', 'id')) && p('') && e("`t1`.`project` = `t2`.`id`"); // 测试 `t1`.`project` = `t2`.`id` r($bi->getConditionTest('`t1`', '`project` ', '=', 't2', 'id')) && p('') && e("`t1`.`project` = `t2`.`id`"); // 测试 `t1`.`project` = `t2`.`id` -r($bi->getConditionTest('t1', 'type', 'in', null, "('sprint', 'stage', 'kanban')")) && p('') && e("`t1`.`type` IN ('sprint', 'stage', 'kanban')"); // 测试 `t1`.`type` IN ('sprint', 'stage', 'kanban') -r($bi->getConditionTest('t1', 'type', 'not in', null, "('sprint', 'stage', 'kanban')")) && p('') && e("`t1`.`type` NOT IN ('sprint', 'stage', 'kanban')"); // 测试 `t1`.`type` NOT IN ('sprint', 'stage', 'kanban') +r($bi->getConditionTest('t1', 'type', 'in', null, "('sprint', 'stage', 'kanban')", 1, false)) && p('') && e("`t1`.`type` IN ('sprint', 'stage', 'kanban')"); // 测试 `t1`.`type` IN ('sprint', 'stage', 'kanban') +r($bi->getConditionTest('t1', 'type', 'not in', null, "('sprint', 'stage', 'kanban')", 1, false)) && p('') && e("`t1`.`type` NOT IN ('sprint', 'stage', 'kanban')"); // 测试 `t1`.`type` NOT IN ('sprint', 'stage', 'kanban') -r($bi->getConditionTest('t1', 'name', 'is', null, 'not null')) && p('') && e("`t1`.`name` IS not null"); // 测试 `t1`.`name` IS not null -r($bi->getConditionTest('t1', 'name', 'is', null, 'null')) && p('') && e("`t1`.`name` IS null"); // 测试 `t1`.`name` IS not null`t1`.`name` IS null \ No newline at end of file +r($bi->getConditionTest('t1', 'name', 'is', null, 'not null', 1, false)) && p('') && e("`t1`.`name` IS not null"); // 测试 `t1`.`name` IS not null +r($bi->getConditionTest('t1', 'name', 'is', null, 'null', 1, false)) && p('') && e("`t1`.`name` IS null"); // 测试 `t1`.`name` IS not null`t1`.`name` IS null \ No newline at end of file diff --git a/module/bug/model.php b/module/bug/model.php index cd61b8cefd..069d3dc321 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -885,7 +885,9 @@ class bugModel extends model { if($this->session->$queryName === false) $this->session->set($queryName, ' 1 = 1'); } + $query = $this->session->$queryName; + if(strpos($query, "`project` = 'all'") !== false) $query = str_replace("`project` = 'all'", '1 = 1', $query); if($moduleName == 'contributeBug') $bugsAssignedByMe = $this->loadModel('my')->getAssignedByMe($account, null, $orderBy, 'bug'); diff --git a/module/caselib/test/lib/createcaselib.ui.class.php b/module/caselib/test/lib/createcaselib.ui.class.php index 483a863081..b3cf7b02e7 100755 --- a/module/caselib/test/lib/createcaselib.ui.class.php +++ b/module/caselib/test/lib/createcaselib.ui.class.php @@ -12,8 +12,15 @@ class createCaselibTester extends tester */ public function createCaselib($caselib, $libID) { - $form = $this->initForm('caselib', 'create', $libID, 'appIframe-qa'); - if($libID) $form->dom->btn($this->lang->caselib->create)->click(); + if($libID) + { + $form = $this->initForm('caselib', 'create', array('libID' => '1'), 'appIframe-qa'); + $form->dom->btn($this->lang->caselib->create)->click(); + } + else + { + $form = $this->initForm('caselib', 'create', '', 'appIframe-qa'); + } if(isset($caselib['name'])) $form->dom->name->setValue($caselib['name']); diff --git a/module/chart/test/model/getechartoptions.php b/module/chart/test/model/getechartoptions.php index d1f405f062..6872de9285 100755 --- a/module/chart/test/model/getechartoptions.php +++ b/module/chart/test/model/getechartoptions.php @@ -7,7 +7,7 @@ title=测试 biModel::getEchartOptions(); timeout=0 cid=1 -- 查询结果中的gird第0条的name属性 @newProject(求和) +- 查询获取到的所有属性第0条的name属性 @5 - 查询结果中的gird - 第grid条的left属性 @3% - 第grid条的right属性 @4% @@ -58,8 +58,8 @@ $chart->fieldSettings = array('YEARMONTH' => array ( 'name' => 'YEARMONTH', 'obj $chart->currentGroup = 38; $result = $tester->chart->getEchartOptions($chart); -r($result['series']) && p('0:name') && e('newProject(求和)'); // 查询结果中的gird -r($result) && p('grid:left,right') && e('3%,4%'); // 查询结果中的gird -r($result) && p('xAxis:type') && e('category'); // 查询结果中的xAxis -r($result) && p('yAxis:type') && e('value'); // 查询结果中的yAxis -r($result) && p('tooltip:trigger') && e('axis'); // 查询结果中的tooltip +r(count($result)) && p('0:name') && e('5'); // 查询获取到的所有属性 +r($result) && p('grid:left,right') && e('3%,4%'); // 查询结果中的gird +r($result) && p('xAxis:type') && e('category'); // 查询结果中的xAxis +r($result) && p('yAxis:type') && e('value'); // 查询结果中的yAxis +r($result) && p('tooltip:trigger') && e('axis'); // 查询结果中的tooltip \ No newline at end of file diff --git a/module/common/model.php b/module/common/model.php index 47984c159f..54b4de4fff 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -3208,6 +3208,7 @@ eof; $btnTitle = isset($lang->db->custom['common']['mainNav'][$tab]) ? $lang->db->custom['common']['mainNav'][$tab] : $lang->$tab->common; $commonKey = $tab . 'Common'; if(isset($lang->$commonKey) and $tab != 'execution') $btnTitle = $lang->$commonKey; + if($btnTitle == $lang->project->template) $currentMethod = 'template'; //项目模板appName点击后跳转到项目模板列表页面 $link = helper::createLink($currentModule, $currentMethod); $className = $tab == 'devops' ? 'btn num' : 'btn'; diff --git a/module/common/test/model/canmodify.php b/module/common/test/model/canmodify.php index a901ec7bdd..6980dda181 100755 --- a/module/common/test/model/canmodify.php +++ b/module/common/test/model/canmodify.php @@ -16,12 +16,14 @@ cid=1 - 查看产品2是否可以修改 @1 - 查看执行1是否可以修改 @1 - 查看执行2是否可以修改 @1 +- 查看项目11是否可以修改 @1 */ global $tester; $tester->loadModel('product'); $tester->loadModel('execution'); +$tester->loadModel('project'); $product1 = $tester->product->fetchById(1); $product2 = $tester->product->fetchById(2); @@ -29,7 +31,10 @@ $product2 = $tester->product->fetchById(2); $execution1 = $tester->execution->fetchById(101); $execution2 = $tester->execution->fetchById(102); +$project1 = $tester->project->fetchById(11); + r(commonModel::canModify('product', $product1)) && p() && e('1'); // 查看产品1是否可以修改 r(commonModel::canModify('product', $product2)) && p() && e('1'); // 查看产品2是否可以修改 r(commonModel::canModify('execution', $execution1)) && p() && e('1'); // 查看执行1是否可以修改 -r(commonModel::canModify('execution', $execution2)) && p() && e('1'); // 查看执行2是否可以修改 \ No newline at end of file +r(commonModel::canModify('execution', $execution2)) && p() && e('1'); // 查看执行2是否可以修改 +r(commonModel::canModify('project', $project1)) && p() && e('1'); // 查看项目11是否可以修改 diff --git a/module/common/test/model/checkpriv.php b/module/common/test/model/checkpriv.php index dd12173ccc..603428e733 100755 --- a/module/common/test/model/checkpriv.php +++ b/module/common/test/model/checkpriv.php @@ -13,8 +13,8 @@ cid=1 - 用户没有权限时,返回跳转的URL @{"load":"user-deny-user-create.html"}没有权限 - 用户没有权限时,返回跳转的URL @{"load":"user-deny-productplan-view.html"}没有权限 - 判断工作流方法的权限,用户没有权限时,返回跳转的URL @{"load":"user-deny-flowModule-flowMethod.html"}没有权限 -- 用户有权限时,返回TRUE @1 -- 不需要判断权限的,返回TRUE @1 +- 用户有权限时,返回TRUE @0 +- 不需要判断权限的,返回TRUE @0 */ @@ -81,7 +81,7 @@ catch (Exception $e) $result = '没有权限'; } -r($result) && p() && e('1'); // 用户有权限时,返回TRUE +r($result) && p() && e('0'); // 用户有权限时,返回TRUE $app->moduleName = 'block'; $app->methodName = 'dashboard'; @@ -95,6 +95,6 @@ catch (Exception $e) $result = '没有权限'; } -r($result) && p() && e('1'); // 不需要判断权限的,返回TRUE +r($result) && p() && e('0'); // 不需要判断权限的,返回TRUE -unset($_SERVER['HTTP_X_REQUESTED_WITH']); \ No newline at end of file +unset($_SERVER['HTTP_X_REQUESTED_WITH']); diff --git a/module/common/test/model/printhomebutton.php b/module/common/test/model/printhomebutton.php new file mode 100755 index 0000000000..c275acdd21 --- /dev/null +++ b/module/common/test/model/printhomebutton.php @@ -0,0 +1,73 @@ +#!/usr/bin/env php + 项目 +- 打印product应用下的appName按钮。 @
+- 打印qa应用下的appName按钮。 @ +- 打印任务应用下的appName按钮。 @0 +- 打印项目模板应用下的appName按钮。 @ + +*/ + +global $tester, $app, $lang; +$app->loadCommon(); +$app->appName = 'pms'; +$app->moduleName = 'project'; +$app->methodName = 'all'; +$app->setControlFile(); + +$moduleName = $app->moduleName; +$methodName = $app->methodName; +$file2Included = $app->importControlFile(); +$className = class_exists("my$moduleName") ? "my$moduleName" : $moduleName; +$module = new $className(); +$app->control = $module; + +ob_start(); +commonModel::printHomeButton('project'); +$result = ob_get_contents(); +$result = str_replace(["\r", "\n"], '', $result); +ob_end_clean(); + +r($result) && p() && e(``); // 打印project应用下的appName按钮。 + +ob_start(); +commonModel::printHomeButton('product'); +$result = ob_get_contents(); +$result = str_replace(["\r", "\n"], '', $result); +ob_end_clean(); + +r($result) && p() && e(``); // 打印product应用下的appName按钮。 + +ob_start(); +commonModel::printHomeButton('qa'); +$result = ob_get_contents(); +$result = str_replace(["\r", "\n"], '', $result); +ob_end_clean(); + +r($result) && p() && e(``); // 打印qa应用下的appName按钮。 + +ob_start(); +commonModel::printHomeButton('task'); +$result = ob_get_contents(); +$result = str_replace(["\r", "\n"], '', $result); +ob_end_clean(); + +r($result) && p() && e('0'); // 打印任务应用下的appName按钮。 + +$lang->project->common = $lang->projectCommon = $lang->project->template; +ob_start(); +commonModel::printHomeButton('project'); +$result = ob_get_contents(); +$result = str_replace(["\r", "\n"], '', $result); +ob_end_clean(); + +r($result) && p() && e(``); // 打印项目模板应用下的appName按钮。 diff --git a/module/common/test/model/response.php b/module/common/test/model/response.php new file mode 100755 index 0000000000..94fa7ab0b0 --- /dev/null +++ b/module/common/test/model/response.php @@ -0,0 +1,102 @@ +#!/usr/bin/env php +loadModel('common'); + +$config->entry = new stdclass(); +$config->entry->errcode = array(); +$config->entry->errcode['PARAM_CODE_MISSING'] = 401; +$config->entry->errcode['PARAM_TOKEN_MISSING'] = 401; +$config->entry->errcode['SESSION_CODE_MISSING'] = 401; +$config->entry->errcode['EMPTY_KEY'] = 401; +$config->entry->errcode['INVALID_TOKEN'] = 401; +$config->entry->errcode['SESSION_VERIFY_FAILED'] = 401; +$config->entry->errcode['IP_DENIED'] = 403; +$config->entry->errcode['ACCOUNT_UNBOUND'] = 403; +$config->entry->errcode['EMPTY_ENTRY'] = 404; +$config->entry->errcode['CALLED_TIME'] = 405; +$config->entry->errcode['INVALID_ACCOUNT'] = 406; +$config->entry->errcode['ERROR_TIMESTAMP'] = 407; + +$lang->entry = new stdclass(); +$lang->entry->errmsg = array(); +$lang->entry->errmsg['PARAM_CODE_MISSING'] = '缺少code参数'; +$lang->entry->errmsg['PARAM_TOKEN_MISSING'] = '缺少token参数'; +$lang->entry->errmsg['SESSION_CODE_MISSING'] = '缺少session code'; +$lang->entry->errmsg['EMPTY_KEY'] = '应用未设置密钥'; +$lang->entry->errmsg['INVALID_TOKEN'] = '无效的token参数'; +$lang->entry->errmsg['SESSION_VERIFY_FAILED'] = 'session验证失败'; +$lang->entry->errmsg['IP_DENIED'] = '该IP被限制访问'; +$lang->entry->errmsg['ACCOUNT_UNBOUND'] = '未绑定用户'; +$lang->entry->errmsg['INVALID_ACCOUNT'] = '用户不存在'; +$lang->entry->errmsg['EMPTY_ENTRY'] = '应用不存在'; +$lang->entry->errmsg['CALLED_TIME'] = 'Token已失效'; +$lang->entry->errmsg['ERROR_TIMESTAMP'] = '错误的时间戳。'; + +$reasonPhrase = 'EMPTY_ENTRY'; +try +{ + $commonModel->response($reasonPhrase); +} +catch(EndResponseException $e) +{ + $content = json_decode($e->getContent()); +} +r($content) && p('errcode,errmsg') && e('404,应用不存在'); // 应用不存在,返回错误代码404 + +$reasonPhrase = 'PARAM_TOKEN_MISSING'; +try +{ + $commonModel->response($reasonPhrase); +} +catch(EndResponseException $e) +{ + $content = json_decode($e->getContent()); +} +r($content) && p('errcode,errmsg') && e('401,缺少token参数'); // 缺少token参数, 返回错误代码401 + +$reasonPhrase = 'INVALID_ACCOUNT'; +try +{ + $commonModel->response($reasonPhrase); +} +catch(EndResponseException $e) +{ + $content = json_decode($e->getContent()); +} +r($content) && p('errcode,errmsg') && e('406,用户不存在'); // 用户不存在,返回错误代码406 + +unset($config->entry->errcode); +$reasonPhrase = 'ERROR'; +try +{ + $commonModel->response($reasonPhrase); +} +catch(EndResponseException $e) +{ + $content = json_decode($e->getContent()); +} +r($content) && p('error') && e('ERROR'); // 直接返回错误信息 \ No newline at end of file diff --git a/module/design/test/model/getlist.php b/module/design/test/model/getlist.php index ffc71f3f90..b86458a175 100755 --- a/module/design/test/model/getlist.php +++ b/module/design/test/model/getlist.php @@ -27,8 +27,6 @@ cid=1 - 第3条的project属性 @60 - 第3条的product属性 @1 - 第3条的type属性 @DBDS -- 获取projectID=1,prouctID不存在,type='all',query=1时,所有按照id倒序排列设计数据 @0 -- 获取projectID=1,prouctID不存在,type='all',query=1时,所有按照id正序排列设计数据 @0 - 获取projectID=1,prouctID=1,type='bySearch',query=0时,所有按照id倒序排列设计数据 - 第3条的name属性 @设计3 - 第3条的project属性 @60 @@ -59,8 +57,6 @@ cid=1 - 第3条的project属性 @60 - 第3条的product属性 @1 - 第3条的type属性 @DBDS -- 获取projectID=1,prouctID不存在,type='bySearch',query=0时,所有按照id倒序排列设计数据 @0 -- 获取projectID=1,prouctID不存在,type='bySearch',query=0时,所有按照id正序排列设计数据 @0 - 获取projectID=1,prouctID=0,type='HLDS',query=0时,所有按照id倒序排列设计数据 - 第1条的name属性 @设计1 - 第1条的project属性 @60 @@ -81,8 +77,6 @@ cid=1 - 第5条的project属性 @60 - 第5条的product属性 @1 - 第5条的type属性 @HLDS -- 获取projectID=1,prouctID不存在,type='HLDS',query=0时,所有按照id倒序排列设计数据 @0 -- 获取projectID=1,prouctID不存在,type='HLDS',query=0时,所有按照id正序排列设计数据 @0 - 获取projectID=1,prouctID=0,type='DDS',query=0时,所有按照id倒序排列设计数据 - 第10条的name属性 @设计10 - 第10条的project属性 @60 @@ -103,8 +97,6 @@ cid=1 - 第6条的project属性 @60 - 第6条的product属性 @1 - 第6条的type属性 @DDS -- 获取projectID=1,prouctID不存在,type='DDS',query=0时,所有按照id倒序排列设计数据 @0 -- 获取projectID=1,prouctID不存在,type='DDS',query=0时,所有按照id正序排列设计数据 @0 - 获取projectID=1,prouctID=0,type='DBDS',query=0时,所有按照id倒序排列设计数据 - 第3条的name属性 @设计3 - 第3条的project属性 @60 @@ -125,8 +117,6 @@ cid=1 - 第7条的project属性 @60 - 第7条的product属性 @1 - 第7条的type属性 @DBDS -- 获取projectID=1,prouctID不存在,type='DBDS',query=0时,所有按照id倒序排列设计数据 @0 -- 获取projectID=1,prouctID不存在,type='DBDS',query=0时,所有按照id正序排列设计数据 @0 - 获取projectID=1,prouctID=0,type='ADS',query=0时,所有按照id倒序排列设计数据 - 第4条的name属性 @设计4 - 第4条的project属性 @60 @@ -188,34 +178,24 @@ r($designTester->getListTest($projects[1], $products[0], $types[1], $queries[0], r($designTester->getListTest($projects[1], $products[0], $types[1], $queries[0], $sorts[1])) && p('1:name,project,product,type') && e('设计1,60,0,HLDS'); // 获取projectID=1,prouctID=0,type='all',query=0时,所有按照id正序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[1], $queries[0], $sorts[0])) && p('3:name,project,product,type') && e('设计3,60,1,DBDS'); // 获取projectID=1,prouctID=1,type='all',query=0时,所有按照id倒序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[1], $queries[0], $sorts[1])) && p('3:name,project,product,type') && e('设计3,60,1,DBDS'); // 获取projectID=1,prouctID=1,type='all',query=0时,所有按照id正序排列设计数据 -r($designTester->getListTest($projects[1], $products[2], $types[1], $queries[0], $sorts[0])) && p() && e('0'); // 获取projectID=1,prouctID不存在,type='all',query=1时,所有按照id倒序排列设计数据 -r($designTester->getListTest($projects[1], $products[2], $types[1], $queries[0], $sorts[1])) && p() && e('0'); // 获取projectID=1,prouctID不存在,type='all',query=1时,所有按照id正序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[2], $queries[0], $sorts[0])) && p('3:name,project,product,type') && e('设计3,60,1,DBDS'); // 获取projectID=1,prouctID=1,type='bySearch',query=0时,所有按照id倒序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[2], $queries[0], $sorts[1])) && p('3:name,project,product,type') && e('设计3,60,1,DBDS'); // 获取projectID=1,prouctID=1,type='bySearch',query=0时,所有按照id正序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[2], $queries[1], $sorts[0])) && p('3:name,project,product,type') && e('设计3,60,1,DBDS'); // 获取projectID=1,prouctID=1,type='bySearch',query=1时,所有按照id倒序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[2], $queries[1], $sorts[1])) && p('3:name,project,product,type') && e('设计3,60,1,DBDS'); // 获取projectID=1,prouctID=1,type='bySearch',query=1时,所有按照id正序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[2], $queries[2], $sorts[0])) && p('3:name,project,product,type') && e('设计3,60,1,DBDS'); // 获取projectID=1,prouctID=1,type='bySearch',query不存在时,所有按照id倒序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[2], $queries[2], $sorts[1])) && p('3:name,project,product,type') && e('设计3,60,1,DBDS'); // 获取projectID=1,prouctID=1,type='bySearch',query不存在时,所有按照id正序排列设计数据 -r($designTester->getListTest($projects[1], $products[2], $types[2], $queries[0], $sorts[0])) && p() && e('0'); // 获取projectID=1,prouctID不存在,type='bySearch',query=0时,所有按照id倒序排列设计数据 -r($designTester->getListTest($projects[1], $products[2], $types[2], $queries[0], $sorts[1])) && p() && e('0'); // 获取projectID=1,prouctID不存在,type='bySearch',query=0时,所有按照id正序排列设计数据 r($designTester->getListTest($projects[1], $products[0], $types[3], $queries[0], $sorts[0])) && p('1:name,project,product,type') && e('设计1,60,0,HLDS'); // 获取projectID=1,prouctID=0,type='HLDS',query=0时,所有按照id倒序排列设计数据 r($designTester->getListTest($projects[1], $products[0], $types[3], $queries[0], $sorts[1])) && p('1:name,project,product,type') && e('设计1,60,0,HLDS'); // 获取projectID=1,prouctID=0,type='HLDS',query=0时,所有按照id正序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[3], $queries[0], $sorts[0])) && p('5:name,project,product,type') && e('设计5,60,1,HLDS'); // 获取projectID=1,prouctID=1,type='DBDS',query=0时,所有按照id倒序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[3], $queries[0], $sorts[1])) && p('5:name,project,product,type') && e('设计5,60,1,HLDS'); // 获取projectID=1,prouctID=1,type='DBDS',query=0时,所有按照id正序排列设计数据 -r($designTester->getListTest($projects[1], $products[2], $types[3], $queries[0], $sorts[0])) && p() && e('0'); // 获取projectID=1,prouctID不存在,type='HLDS',query=0时,所有按照id倒序排列设计数据 -r($designTester->getListTest($projects[1], $products[2], $types[3], $queries[0], $sorts[1])) && p() && e('0'); // 获取projectID=1,prouctID不存在,type='HLDS',query=0时,所有按照id正序排列设计数据 r($designTester->getListTest($projects[1], $products[0], $types[4], $queries[0], $sorts[0])) && p('10:name,project,product,type') && e('设计10,60,7,DDS'); // 获取projectID=1,prouctID=0,type='DDS',query=0时,所有按照id倒序排列设计数据 r($designTester->getListTest($projects[1], $products[0], $types[4], $queries[0], $sorts[1])) && p('10:name,project,product,type') && e('设计10,60,7,DDS'); // 获取projectID=1,prouctID=0,type='DDS',query=0时,所有按照id正序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[4], $queries[0], $sorts[0])) && p('6:name,project,product,type') && e('设计6,60,1,DDS'); // 获取projectID=1,prouctID=1,type='DDS',query=0时,所有按照id倒序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[4], $queries[0], $sorts[1])) && p('6:name,project,product,type') && e('设计6,60,1,DDS'); // 获取projectID=1,prouctID=1,type='DDS',query=0时,所有按照id正序排列设计数据 -r($designTester->getListTest($projects[1], $products[2], $types[4], $queries[0], $sorts[0])) && p() && e('0'); // 获取projectID=1,prouctID不存在,type='DDS',query=0时,所有按照id倒序排列设计数据 -r($designTester->getListTest($projects[1], $products[2], $types[4], $queries[0], $sorts[1])) && p() && e('0'); // 获取projectID=1,prouctID不存在,type='DDS',query=0时,所有按照id正序排列设计数据 r($designTester->getListTest($projects[1], $products[0], $types[5], $queries[0], $sorts[0])) && p('3:name,project,product,type') && e('设计3,60,1,DBDS'); // 获取projectID=1,prouctID=0,type='DBDS',query=0时,所有按照id倒序排列设计数据 r($designTester->getListTest($projects[1], $products[0], $types[5], $queries[0], $sorts[1])) && p('3:name,project,product,type') && e('设计3,60,1,DBDS'); // 获取projectID=1,prouctID=0,type='DBDS',query=0时,所有按照id正序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[5], $queries[0], $sorts[0])) && p('7:name,project,product,type') && e('设计7,60,1,DBDS'); // 获取projectID=1,prouctID=1,type='DBDS',query=0时,所有按照id倒序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[5], $queries[0], $sorts[1])) && p('7:name,project,product,type') && e('设计7,60,1,DBDS'); // 获取projectID=1,prouctID=1,type='DBDS',query=0时,所有按照id正序排列设计数据 -r($designTester->getListTest($projects[1], $products[2], $types[5], $queries[0], $sorts[0])) && p() && e('0'); // 获取projectID=1,prouctID不存在,type='DBDS',query=0时,所有按照id倒序排列设计数据 -r($designTester->getListTest($projects[1], $products[2], $types[5], $queries[0], $sorts[1])) && p() && e('0'); // 获取projectID=1,prouctID不存在,type='DBDS',query=0时,所有按照id正序排列设计数据 r($designTester->getListTest($projects[1], $products[0], $types[6], $queries[0], $sorts[0])) && p('4:name,project,product,type') && e('设计4,60,1,ADS'); // 获取projectID=1,prouctID=0,type='ADS',query=0时,所有按照id倒序排列设计数据 r($designTester->getListTest($projects[1], $products[0], $types[6], $queries[0], $sorts[1])) && p('4:name,project,product,type') && e('设计4,60,1,ADS'); // 获取projectID=1,prouctID=0,type='ADS',query=0时,所有按照id正序排列设计数据 r($designTester->getListTest($projects[1], $products[1], $types[6], $queries[0], $sorts[0])) && p('8:name,project,product,type') && e('设计8,60,1,ADS'); // 获取projectID=1,prouctID=1,type='ADS',query=0时,所有按照id倒序排列设计数据 diff --git a/module/doc/control.php b/module/doc/control.php index a6b66b5f2c..f6b3bf117a 100755 --- a/module/doc/control.php +++ b/module/doc/control.php @@ -1850,6 +1850,7 @@ class doc extends control */ public function quick(string $type = 'view', int $docID = 0, string $orderBy = '', int $recPerPage = 20, int $pageID = 1) { + if(empty($orderBy)) $orderBy = 'id_desc'; if(!isset($this->config->doc->quickMenu[$type])) $type = 'view'; $menu = $this->config->doc->quickMenu[$type]; diff --git a/module/doc/test/model/getuserbyconfluenceuserid.php b/module/doc/test/model/getuserbyconfluenceuserid.php index bdcdd70b2c..3abd6d4c87 100755 --- a/module/doc/test/model/getuserbyconfluenceuserid.php +++ b/module/doc/test/model/getuserbyconfluenceuserid.php @@ -34,7 +34,6 @@ su('admin'); global $tester; $docTester = $tester->loadModel('doc'); -$docTester->dbh->exec('DROP TABLE `jiratmprelation`;'); $tester->loadModel('convert')->createTmpTable4Jira(); $userPairs = array('admin' => 'admin', 'user1' => '用户1', 'user2' => '用户2', 'user3' => '用户3', 'user4' => '用户4', 'user5' => '用户5'); @@ -55,3 +54,4 @@ r($docTester->getUserByConfluenceUserID('用户2')) && p('account,realname') && r($docTester->getUserByConfluenceUserID('用户3')) && p('account,realname') && e('user3,用户3'); // 获取用户3的用户名 r($docTester->getUserByConfluenceUserID('用户4')) && p('account,realname') && e('user4,用户4'); // 获取用户4的用户名 r($docTester->getUserByConfluenceUserID('用户5')) && p() && e('0'); // 获取不存在的用户 +$docTester->dbh->exec('DROP TABLE `jiratmprelation`;'); diff --git a/module/doc/test/model/hasothersdoc.php b/module/doc/test/model/hasothersdoc.php index 6b4961b717..e064ae564b 100755 --- a/module/doc/test/model/hasothersdoc.php +++ b/module/doc/test/model/hasothersdoc.php @@ -10,12 +10,14 @@ cid=1 - 测试文档库1下是否有其他人创建的文档 @0 - 测试文档库2下是否有其他人创建的文档 @0 - 测试文档库3下是否有其他人创建的文档 @0 +- 测试文档库4下是否有其他人创建的文档 @0 +- 测试文档库5下是否有其他人创建的文档 @0 */ include dirname(__FILE__, 5) . '/test/lib/init.php'; -zenData('doclib')->loadYaml('doclib')->gen(3); +zenData('doclib')->loadYaml('doclib')->gen(5); zenData('user')->gen(5); zenData('doc')->loadYaml('doc')->gen(5); su('admin'); @@ -24,7 +26,11 @@ global $tester; $lib1 = $tester->loadModel('doc')->getLibByID(1); $lib2 = $tester->loadModel('doc')->getLibByID(2); $lib3 = $tester->loadModel('doc')->getLibByID(3); +$lib4 = $tester->loadModel('doc')->getLibByID(4); +$lib5 = $tester->loadModel('doc')->getLibByID(5); r($tester->doc->hasOthersDoc($lib1)) && p() && e('0'); // 测试文档库1下是否有其他人创建的文档 r($tester->doc->hasOthersDoc($lib2)) && p() && e('0'); // 测试文档库2下是否有其他人创建的文档 -r($tester->doc->hasOthersDoc($lib3)) && p() && e('0'); // 测试文档库3下是否有其他人创建的文档 \ No newline at end of file +r($tester->doc->hasOthersDoc($lib3)) && p() && e('0'); // 测试文档库3下是否有其他人创建的文档 +r($tester->doc->hasOthersDoc($lib4)) && p() && e('0'); // 测试文档库4下是否有其他人创建的文档 +r($tester->doc->hasOthersDoc($lib5)) && p() && e('0'); // 测试文档库5下是否有其他人创建的文档 diff --git a/module/execution/control.php b/module/execution/control.php index e79042bddf..fa75430969 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -2785,6 +2785,7 @@ class execution extends control $this->view->projects = $projectPairs; /* 项目ID为索引,项目名称为值的数组 [projectID => projectName]。 */ $this->view->projectExecutions = $projectExecutions; /* 项目对应的执行列表 [projectID => execution]。*/ $this->view->executionID = $executionID; + $this->view->execution = $execution; $this->display(); } diff --git a/module/execution/test/model/getchildexecutions.php b/module/execution/test/model/getchildexecutions.php index adf3585bbc..780b31fe98 100755 --- a/module/execution/test/model/getchildexecutions.php +++ b/module/execution/test/model/getchildexecutions.php @@ -6,15 +6,15 @@ zenData('user')->gen(5); su('admin'); $execution = zenData('project'); -$execution->id->range('1-5'); -$execution->name->range('项目集1,项目1,父阶段1,子阶段1,子阶段2'); -$execution->type->range('program,project,stage{3}'); -$execution->parent->range('0,1,0,3{2}'); +$execution->id->range('1-7'); +$execution->name->range('项目集1,项目1,父阶段1,子阶段1,子阶段2,子阶段3,子阶段4'); +$execution->type->range('program,project,stage{5}'); +$execution->parent->range('0,1,0,3{4}'); $execution->status->range('wait'); $execution->openedBy->range('admin,user1'); $execution->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD'); $execution->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD'); -$execution->gen(5); +$execution->gen(7); /** @@ -22,11 +22,20 @@ title=测试executionModel->getChildExecutionsTest(); timeout=0 cid=1 +- 查询子阶段1第4条的name属性 @子阶段1 +- 查询子阶段2第5条的name属性 @子阶段2 +- 查询子阶段3第6条的name属性 @子阶段3 +- 查询子阶段4第7条的name属性 @子阶段4 +- 查询子阶段数量 @4 + */ $executionID = 3; $count = array(0, 1); $executionTester = new executionTest(); -r($executionTester->getChildExecutionsTest($executionID, $count[0])) && p('4:name') && e('子阶段1'); // 查询子阶段 -r($executionTester->getChildExecutionsTest($executionID, $count[1])) && p() && e('2'); // 查询子阶段数量 +r($executionTester->getChildExecutionsTest($executionID, $count[0])) && p('4:name') && e('子阶段1'); // 查询子阶段1 +r($executionTester->getChildExecutionsTest($executionID, $count[0])) && p('5:name') && e('子阶段2'); // 查询子阶段2 +r($executionTester->getChildExecutionsTest($executionID, $count[0])) && p('6:name') && e('子阶段3'); // 查询子阶段3 +r($executionTester->getChildExecutionsTest($executionID, $count[0])) && p('7:name') && e('子阶段4'); // 查询子阶段4 +r($executionTester->getChildExecutionsTest($executionID, $count[1])) && p() && e('4'); // 查询子阶段数量 diff --git a/module/execution/ui/ajaxgetdropmenu.html.php b/module/execution/ui/ajaxgetdropmenu.html.php index 1c9ef66c9c..e44a50ff39 100644 --- a/module/execution/ui/ajaxgetdropmenu.html.php +++ b/module/execution/ui/ajaxgetdropmenu.html.php @@ -11,87 +11,128 @@ declare(strict_types=1); */ namespace zin; -/** - * 获取项目所属分组。 - * Get execution group. - * - * @param object $execution - * @return string - */ -$getExecutionGroup = function($execution): string +if(!empty($execution->isTpl)) { - global $app; - if($execution->status != 'done' and $execution->status != 'closed' and ($execution->PM == $app->user->account or isset($execution->teams[$app->user->account]))) return 'my'; - if($execution->status != 'done' and $execution->status != 'closed' and $execution->PM != $app->user->account and !isset($execution->teams[$app->user->account])) return 'other'; - if($execution->status == 'done' or $execution->status == 'closed') return 'closed'; -}; - -/** - * 定义每个分组下的选项数据列表。 - * Define the grouped data list. - */ -$data = array('my' => array(), 'other' => array(), 'closed' => array()); - -/** - * 定义执行所属分组。 - * Define the group of execution. - */ -$executionGroup = array(); - -/* 处理分组数据。Process grouped data. */ -foreach($projectExecutions as $projectID => $executions) -{ - $projectItem = array(); - $projectItem['id'] = $projectID; - $projectItem['type'] = 'project'; - $projectItem['text'] = zget($projects, $projectID); - $projectItem['items'] = array(); - - foreach($executions as $index => $execution) + /* 处理分组数据。Process grouped data. */ + foreach($projectExecutions as $projectID => $executions) { - $group = $executionGroup[$execution->id] = $getExecutionGroup($execution); + $projectItem = array(); + $projectItem['id'] = $projectID; + $projectItem['type'] = 'project'; + $projectItem['text'] = zget($projects, $projectID); + $projectItem['items'] = array(); - $item = array(); - $item['id'] = $execution->id; - $item['text'] = $execution->name; - $item['keys'] = zget(common::convert2Pinyin(array($execution->name)), $execution->name, ''); - $item['url'] = sprintf($link, $execution->id); + foreach($executions as $index => $execution) + { + $item = array(); + $item['id'] = $execution->id; + $item['text'] = $execution->name; + $item['keys'] = zget(common::convert2Pinyin(array($execution->name)), $execution->name, ''); + $item['url'] = sprintf($link, $execution->id); - if($execution->type == 'stage') $item['url'] = helper::createLink('execution', 'task', "executionID={$execution->id}"); - if($execution->type == 'kanban') $item['url'] = helper::createLink('execution', 'kanban', "execution={$execution->id}"); - if(strpos($link, 'ajaxSwitchBelong') !== false) $item['url'] = sprintf($link, $execution->id); + if($execution->type == 'stage') $item['url'] = helper::createLink('execution', 'task', "executionID={$execution->id}"); - if(!isset($data[$group][$projectID])) $data[$group][$projectID] = $projectItem; - $data[$group][$projectID]['items'][] = $item; + if(!isset($data[$projectID])) $data[$projectID] = $projectItem; + $data[$projectID]['items'][] = $item; + } } + + $data = array_values($data); + + /** + * 定义最终的 JSON 数据。 + * Define the final json data. + */ + $json = array(); + $json['data'] = $data; + $json['searchHint'] = $lang->searchAB; + $json['labelMap'] = array('project' => $lang->project->template); + $json['itemType'] = 'execution'; } +else +{ + /** + * 获取项目所属分组。 + * Get execution group. + * + * @param object $execution + * @return string + */ + $getExecutionGroup = function($execution): string + { + global $app; + if($execution->status != 'done' and $execution->status != 'closed' and ($execution->PM == $app->user->account or isset($execution->teams[$app->user->account]))) return 'my'; + if($execution->status != 'done' and $execution->status != 'closed' and $execution->PM != $app->user->account and !isset($execution->teams[$app->user->account])) return 'other'; + if($execution->status == 'done' or $execution->status == 'closed') return 'closed'; + }; -/* 将分组数据转换为索引数组。Format grouped data to indexed array. */ -foreach ($data as $key => $value) $data[$key] = array_values($value); + /** + * 定义每个分组下的选项数据列表。 + * Define the grouped data list. + */ + $data = array('my' => array(), 'other' => array(), 'closed' => array()); -/** - * 定义每个分组名称信息,包括可展开的已关闭分组。 - * Define every group name, include expanded group. - */ -$tabs = array(); -$tabs[] = array('name' => 'my', 'text' => $lang->execution->involved, 'active' => (isset($executionGroup[$executionID]) && $executionGroup[$executionID] === 'my')); -$tabs[] = array('name' => 'other', 'text' => $lang->execution->other, 'active' => (isset($executionGroup[$executionID]) && $executionGroup[$executionID] == 'other')); -$tabs[] = array('name' => 'closed', 'text' => $lang->execution->closedExecution); + /** + * 定义执行所属分组。 + * Define the group of execution. + */ + $executionGroup = array(); -/** - * 定义最终的 JSON 数据。 - * Define the final json data. - */ -$json = array(); -$json['data'] = $data; -$json['tabs'] = $tabs; -$json['searchHint'] = $lang->searchAB; -$json['labelMap'] = array('project' => $lang->project->common); -$json['expandName'] = 'closed'; -$json['itemType'] = 'execution'; + /* 处理分组数据。Process grouped data. */ + foreach($projectExecutions as $projectID => $executions) + { + $projectItem = array(); + $projectItem['id'] = $projectID; + $projectItem['type'] = 'project'; + $projectItem['text'] = zget($projects, $projectID); + $projectItem['items'] = array(); + + foreach($executions as $index => $execution) + { + $group = $executionGroup[$execution->id] = $getExecutionGroup($execution); + + $item = array(); + $item['id'] = $execution->id; + $item['text'] = $execution->name; + $item['keys'] = zget(common::convert2Pinyin(array($execution->name)), $execution->name, ''); + $item['url'] = sprintf($link, $execution->id); + + if($execution->type == 'stage') $item['url'] = helper::createLink('execution', 'task', "executionID={$execution->id}"); + if($execution->type == 'kanban') $item['url'] = helper::createLink('execution', 'kanban', "execution={$execution->id}"); + if(strpos($link, 'ajaxSwitchBelong') !== false) $item['url'] = sprintf($link, $execution->id); + + if(!isset($data[$group][$projectID])) $data[$group][$projectID] = $projectItem; + $data[$group][$projectID]['items'][] = $item; + } + } + + /* 将分组数据转换为索引数组。Format grouped data to indexed array. */ + foreach ($data as $key => $value) $data[$key] = array_values($value); + + /** + * 定义每个分组名称信息,包括可展开的已关闭分组。 + * Define every group name, include expanded group. + */ + $tabs = array(); + $tabs[] = array('name' => 'my', 'text' => $lang->execution->involved, 'active' => (isset($executionGroup[$executionID]) && $executionGroup[$executionID] === 'my')); + $tabs[] = array('name' => 'other', 'text' => $lang->execution->other, 'active' => (isset($executionGroup[$executionID]) && $executionGroup[$executionID] == 'other')); + $tabs[] = array('name' => 'closed', 'text' => $lang->execution->closedExecution); + + /** + * 定义最终的 JSON 数据。 + * Define the final json data. + */ + $json = array(); + $json['data'] = $data; + $json['tabs'] = $tabs; + $json['searchHint'] = $lang->searchAB; + $json['labelMap'] = array('project' => $lang->project->common); + $json['expandName'] = 'closed'; + $json['itemType'] = 'execution'; +} /** * 渲染 JSON 字符串并发送到客户端。 * Render json data to string and send to client. */ -renderJson($json); +renderJson($json); \ No newline at end of file diff --git a/module/gitlab/test/model/apicreateproject.php b/module/gitlab/test/model/apicreateproject.php index 993546541e..9d8542ca13 100755 --- a/module/gitlab/test/model/apicreateproject.php +++ b/module/gitlab/test/model/apicreateproject.php @@ -44,7 +44,8 @@ $project->path = 'unit_test_project17'; $result = $gitlab->apiCreateProject($gitlabID, $project); if(!empty($result->name) and $result->name == $project->name) $result = true; if(!empty($result->message->path[0]) and $result->message->path[0] == '已经被使用') $result = true; +if(!empty($result->message->{"project_namespace.name"}[0]) and $result->message->{"project_namespace.name"}[0] == '已经被使用') $result = true; r($result) && p() && e('1'); //通过gitlabID,projectID,分支对象正确创建GitLab分支 $result = $gitlab->apiCreateProject($gitlabID, $project); -r($result->message) && p('path:0') && e('已经被使用'); //使用重复的分支信息创建分支 \ No newline at end of file +r($result->message) && p('project_namespace.name:0') && e('已经被使用'); //使用重复的分支信息创建分支 diff --git a/module/gitlab/test/model/apideleteproject.php b/module/gitlab/test/model/apideleteproject.php index 6aeb3e8a87..e66f3f6b5c 100755 --- a/module/gitlab/test/model/apideleteproject.php +++ b/module/gitlab/test/model/apideleteproject.php @@ -19,11 +19,12 @@ zenData('pipeline')->gen(5); $gitlab = $tester->loadModel('gitlab'); $gitlabID = 1; +$projectName = 'unitTestProject' . time(); /* Create project. */ $project = new stdclass(); -$project->name = 'unitTestProject17'; -$project->path = 'unit_test_project17'; +$project->name = $projectName; +$project->path = $projectName; $project->description = 'unit_test_project desc'; $project->visibility = 'public'; $project->namespace_id = '1'; @@ -33,7 +34,7 @@ $gitlab->apiCreateProject($gitlabID, $project); $gitlabProjects = $gitlab->apiGetProjects($gitlabID); foreach($gitlabProjects as $gitlabProject) { - if($gitlabProject->name == 'unitTestProject17') + if($gitlabProject->name == $projectName) { $projectID = $gitlabProject->id; break; @@ -46,4 +47,4 @@ $project->description = 'apiUpdatedProject'; r($gitlab->apiDeleteProject($gitlabID, 0)) && p() && e('0'); //使用空的projectID删除项目 r($gitlab->apiDeleteProject(0, $projectID)) && p() && e('0'); //使用错误gitlabID删除项目 -r($gitlab->apiDeleteProject($gitlabID, $projectID)) && p('message') && e('202 Accepted'); //通过gitlabID,项目id正确删除项目 \ No newline at end of file +r($gitlab->apiDeleteProject($gitlabID, $projectID)) && p('message') && e('202 Accepted'); //通过gitlabID,项目id正确删除项目 diff --git a/module/gitlab/test/model/apiupdateproject.php b/module/gitlab/test/model/apiupdateproject.php index a1a8aab056..07f72440f0 100755 --- a/module/gitlab/test/model/apiupdateproject.php +++ b/module/gitlab/test/model/apiupdateproject.php @@ -18,12 +18,13 @@ zenData('pipeline')->gen(5); $gitlab = $tester->loadModel('gitlab'); -$gitlabID = 1; +$gitlabID = 1; +$projectName = 'unitTestUpdateProject' . time(); /* Create project. */ $project = new stdclass(); -$project->name = 'unitTestProject17'; -$project->path = 'unit_test_project17'; +$project->name = $projectName; +$project->path = $projectName; $project->description = 'unit_test_project desc'; $project->visibility = 'public'; $project->namespace_id = '1'; @@ -33,7 +34,7 @@ $gitlab->apiCreateProject($gitlabID, $project); $gitlabProjects = $gitlab->apiGetProjects($gitlabID); foreach($gitlabProjects as $gitlabProject) { - if($gitlabProject->name == 'unitTestProject17') + if($gitlabProject->name == $projectName) { $projectID = $gitlabProject->id; break; @@ -47,4 +48,4 @@ r($gitlab->apiUpdateProject($gitlabID, $project)) && p() && e('0'); //使用空 r($gitlab->apiUpdateProject(0, $project)) && p() && e('0'); //使用错误gitlabID创建群组 $project->id = $projectID; -r($gitlab->apiUpdateProject($gitlabID, $project)) && p('description') && e('apiUpdatedProject'); //通过gitlabID,用户对象正确更新项目描述 \ No newline at end of file +r($gitlab->apiUpdateProject($gitlabID, $project)) && p('description') && e('apiUpdatedProject'); //通过gitlabID,用户对象正确更新项目描述 diff --git a/module/gitlab/test/model/createproject.php b/module/gitlab/test/model/createproject.php index 1ed4dfb0be..5b4ed4719d 100755 --- a/module/gitlab/test/model/createproject.php +++ b/module/gitlab/test/model/createproject.php @@ -36,5 +36,5 @@ r($gitlab->createProjectTest($gitlabID, $project)) && p('path:0') && e('项目 $project->path = 'unit_test_project17'; $result = $gitlab->createProjectTest($gitlabID, $project); -if(!empty($result['name'][0]) and $result['name'][0] == '已经被使用') $result = true; -r($result) && p() && e('1'); //通过gitlabID,projectID,分支对象正确创建GitLab项目 \ No newline at end of file +if(!empty($result['project_namespace.name'][0]) and $result['project_namespace.name'][0] == '已经被使用') $result = true; +r($result) && p() && e('1'); //通过gitlabID,projectID,分支对象正确创建GitLab项目 diff --git a/module/gitlab/test/model/editproject.php b/module/gitlab/test/model/editproject.php index 0a36a68250..3bb2fe777c 100755 --- a/module/gitlab/test/model/editproject.php +++ b/module/gitlab/test/model/editproject.php @@ -19,12 +19,13 @@ zenData('pipeline')->gen(5); $gitlab = $tester->loadModel('gitlab'); -$gitlabID = 1; +$gitlabID = 1; +$projectName = 'unitest' . time(); /* Create project. */ $project = new stdclass(); -$project->name = 'unitTestProject17'; -$project->path = 'unit_test_project17'; +$project->name = $projectName; +$project->path = $projectName; $project->description = 'unit_test_project editproject unit test'; $project->visibility = 'public'; $project->namespace_id = '1'; @@ -34,7 +35,7 @@ $gitlab->apiCreateProject($gitlabID, $project); $gitlabProjects = $gitlab->apiGetProjects($gitlabID); foreach($gitlabProjects as $gitlabProject) { - if($gitlabProject->name == 'unitTestProject17') + if($gitlabProject->name == $projectName) { $projectID = $gitlabProject->id; break; @@ -47,6 +48,6 @@ $project->description = 'editProject'; $gitlabTest = new gitlabTest(); r($gitlabTest->editProjectTest($gitlabID, $project)) && p('name:0') && e('项目名称不能为空'); //使用空的projectID创建gitlab群组 -$project->name = 'unitTestProject17'; +$project->name = $projectName; $project->id = $projectID; -r($gitlabTest->editProjectTest($gitlabID, $project)) && p() && e('1'); //通过gitlabID,用户对象正确更新项目描述 \ No newline at end of file +r($gitlabTest->editProjectTest($gitlabID, $project)) && p() && e('1'); //通过gitlabID,用户对象正确更新项目描述 diff --git a/module/kanban/test/model/getkanbancardmenu.php b/module/kanban/test/model/getkanbancardmenu.php index 3ec307cbe4..04cee5f563 100755 --- a/module/kanban/test/model/getkanbancardmenu.php +++ b/module/kanban/test/model/getkanbancardmenu.php @@ -19,19 +19,19 @@ timeout=0 cid=1 - 测试获取执行1 story的操作数量 @0 -- 测试获取执行1 task的操作数量 @24 +- 测试获取执行1 task的操作数量 @32 - 测试获取执行1 bug的操作数量 @0 - 测试获取执行2 story的操作数量 @0 -- 测试获取执行2 task的操作数量 @24 +- 测试获取执行2 task的操作数量 @32 - 测试获取执行2 bug的操作数量 @0 - 测试获取执行3 story的操作数量 @0 -- 测试获取执行3 task的操作数量 @20 +- 测试获取执行3 task的操作数量 @24 - 测试获取执行3 bug的操作数量 @0 - 测试获取执行4 story的操作数量 @0 -- 测试获取执行4 task的操作数量 @16 +- 测试获取执行4 task的操作数量 @20 - 测试获取执行4 bug的操作数量 @0 - 测试获取执行5 story的操作数量 @0 -- 测试获取执行5 task的操作数量 @16 +- 测试获取执行5 task的操作数量 @20 - 测试获取执行5 bug的操作数量 @0 */ @@ -42,17 +42,17 @@ $browseTypeList = array('story', 'task', 'bug'); $kanban = new kanbanTest(); r($kanban->getKanbanCardMenuTest($executionIDList[0], $browseTypeList[0])) && p() && e('0'); // 测试获取执行1 story的操作数量 -r($kanban->getKanbanCardMenuTest($executionIDList[0], $browseTypeList[1])) && p() && e('24'); // 测试获取执行1 task的操作数量 +r($kanban->getKanbanCardMenuTest($executionIDList[0], $browseTypeList[1])) && p() && e('32'); // 测试获取执行1 task的操作数量 r($kanban->getKanbanCardMenuTest($executionIDList[0], $browseTypeList[2])) && p() && e('0'); // 测试获取执行1 bug的操作数量 r($kanban->getKanbanCardMenuTest($executionIDList[1], $browseTypeList[0])) && p() && e('0'); // 测试获取执行2 story的操作数量 -r($kanban->getKanbanCardMenuTest($executionIDList[1], $browseTypeList[1])) && p() && e('24'); // 测试获取执行2 task的操作数量 +r($kanban->getKanbanCardMenuTest($executionIDList[1], $browseTypeList[1])) && p() && e('32'); // 测试获取执行2 task的操作数量 r($kanban->getKanbanCardMenuTest($executionIDList[1], $browseTypeList[2])) && p() && e('0'); // 测试获取执行2 bug的操作数量 r($kanban->getKanbanCardMenuTest($executionIDList[2], $browseTypeList[0])) && p() && e('0'); // 测试获取执行3 story的操作数量 -r($kanban->getKanbanCardMenuTest($executionIDList[2], $browseTypeList[1])) && p() && e('20'); // 测试获取执行3 task的操作数量 +r($kanban->getKanbanCardMenuTest($executionIDList[2], $browseTypeList[1])) && p() && e('24'); // 测试获取执行3 task的操作数量 r($kanban->getKanbanCardMenuTest($executionIDList[2], $browseTypeList[2])) && p() && e('0'); // 测试获取执行3 bug的操作数量 r($kanban->getKanbanCardMenuTest($executionIDList[3], $browseTypeList[0])) && p() && e('0'); // 测试获取执行4 story的操作数量 -r($kanban->getKanbanCardMenuTest($executionIDList[3], $browseTypeList[1])) && p() && e('16'); // 测试获取执行4 task的操作数量 +r($kanban->getKanbanCardMenuTest($executionIDList[3], $browseTypeList[1])) && p() && e('20'); // 测试获取执行4 task的操作数量 r($kanban->getKanbanCardMenuTest($executionIDList[3], $browseTypeList[2])) && p() && e('0'); // 测试获取执行4 bug的操作数量 r($kanban->getKanbanCardMenuTest($executionIDList[4], $browseTypeList[0])) && p() && e('0'); // 测试获取执行5 story的操作数量 -r($kanban->getKanbanCardMenuTest($executionIDList[4], $browseTypeList[1])) && p() && e('16'); // 测试获取执行5 task的操作数量 -r($kanban->getKanbanCardMenuTest($executionIDList[4], $browseTypeList[2])) && p() && e('0'); // 测试获取执行5 bug的操作数量 \ No newline at end of file +r($kanban->getKanbanCardMenuTest($executionIDList[4], $browseTypeList[1])) && p() && e('20'); // 测试获取执行5 task的操作数量 +r($kanban->getKanbanCardMenuTest($executionIDList[4], $browseTypeList[2])) && p() && e('0'); // 测试获取执行5 bug的操作数量 diff --git a/module/message/test/model/getobjectactions.php b/module/message/test/model/getobjectactions.php index 0ac6cbeede..f97dd07b2f 100755 --- a/module/message/test/model/getobjectactions.php +++ b/module/message/test/model/getobjectactions.php @@ -24,7 +24,7 @@ cid=1 - 查询objectType为testtask的action是starteded的lab标签第testtask条的started属性 @开始 - 查询objectType为todo的action是edited的lab标签第todo条的edited属性 @编辑 - 查询objectType为doc的action是releaseddoc的lab标签第doc条的releaseddoc属性 @发布 -- 查询有动作的对象类型 @product,epic,requirement,story,productplan,release,project,execution,task,bug,case,testtask,todo,doc,kanbancard +- 查询有动作的对象类型 @product,epic,requirement,story,productplan,release,project,execution,task,bug,case,testtask,todo,doc,kanbancard,feedback,ticket,deploy,waterfall,opportunity,risk,issue,rule,meeting - 查询 product 的对象操作 key @opened,edited,closed,undeleted @@ -32,7 +32,7 @@ cid=1 - 查询 story 的对象操作 key @opened,edited,commented,frombug,changed,submitreview,reviewed,closed,activated,assigned -- 查询 story 的对象操作 value @创建,编辑,备注,转研发需求,变更,提交评审,评审,关闭,激活,指派 +- 查询 story 的对象操作 value @创建,编辑,备注,转研发需求,变更,提交评审,审批,关闭,激活,指派 - 查询 productplan 的对象操作 key @opened,edited @@ -52,7 +52,7 @@ cid=1 - 查询 case 的对象操作 key @opened,edited,commented,reviewed,confirmed -- 查询 case 的对象操作 value @创建,编辑,备注,评审,确认研发需求 +- 查询 case 的对象操作 value @创建,编辑,备注,审批,确认研发需求 - 查询 testtask 的对象操作 key @opened,edited,started,blocked,closed,activated @@ -87,13 +87,13 @@ r($objectActions) && p('testtask:started') && e('开始'); //查询objec r($objectActions) && p('todo:edited') && e('编辑'); //查询objectType为todo的action是edited的lab标签 r($objectActions) && p('doc:releaseddoc') && e('发布'); //查询objectType为doc的action是releaseddoc的lab标签 -r(implode(',', array_keys($objectActions))) && p() && e('product,epic,requirement,story,productplan,release,project,execution,task,bug,case,testtask,todo,doc,kanbancard'); // 查询有动作的对象类型 +r(implode(',', array_keys($objectActions))) && p() && e('product,epic,requirement,story,productplan,release,project,execution,task,bug,case,testtask,todo,doc,kanbancard,feedback,ticket,deploy,waterfall,opportunity,risk,issue,rule,meeting'); // 查询有动作的对象类型 r(implode(',', array_keys($objectActions['product']))) && p() && e('opened,edited,closed,undeleted'); // 查询 product 的对象操作 key r(implode(',', array_values($objectActions['product']))) && p() && e('创建,编辑,关闭,还原'); // 查询 product 的对象操作 value r(implode(',', array_keys($objectActions['story']))) && p() && e('opened,edited,commented,frombug,changed,submitreview,reviewed,closed,activated,assigned'); // 查询 story 的对象操作 key -r(implode(',', array_values($objectActions['story']))) && p() && e('创建,编辑,备注,转研发需求,变更,提交评审,评审,关闭,激活,指派'); // 查询 story 的对象操作 value +r(implode(',', array_values($objectActions['story']))) && p() && e('创建,编辑,备注,转研发需求,变更,提交评审,审批,关闭,激活,指派'); // 查询 story 的对象操作 value r(implode(',', array_keys($objectActions['productplan']))) && p() && e('opened,edited'); // 查询 productplan 的对象操作 key r(implode(',', array_values($objectActions['productplan']))) && p() && e('创建,编辑'); // 查询 productplan 的对象操作 value @@ -108,7 +108,7 @@ r(implode(',', array_keys($objectActions['bug']))) && p() && e('opened,edited, r(implode(',', array_values($objectActions['bug']))) && p() && e('创建,编辑,备注,指派,确认研发需求,确认,解决,关闭,激活'); // 查询 bug 的对象操作 value r(implode(',', array_keys($objectActions['case']))) && p() && e('opened,edited,commented,reviewed,confirmed'); // 查询 case 的对象操作 key -r(implode(',', array_values($objectActions['case']))) && p() && e('创建,编辑,备注,评审,确认研发需求'); // 查询 case 的对象操作 value +r(implode(',', array_values($objectActions['case']))) && p() && e('创建,编辑,备注,审批,确认研发需求'); // 查询 case 的对象操作 value r(implode(',', array_keys($objectActions['testtask']))) && p() && e('opened,edited,started,blocked,closed,activated'); // 查询 testtask 的对象操作 key r(implode(',', array_values($objectActions['testtask']))) && p() && e('创建,编辑,开始,阻塞,关闭,激活'); // 查询 testtask 的对象操作 value diff --git a/module/mr/test/lib/mr.unittest.class.php b/module/mr/test/lib/mr.unittest.class.php index ac0524e04b..bba3f63da5 100755 --- a/module/mr/test/lib/mr.unittest.class.php +++ b/module/mr/test/lib/mr.unittest.class.php @@ -179,6 +179,11 @@ class mrTest $params->repoID = $hostID; $params->sourceProject = $project; $result = $this->objectModel->apiCreateMR($hostID, $params); + if(!empty($result->message) && preg_match('/ID(\d+)/', $result->message, $matches)) + { + $this->objectModel->apiDeleteMR($hostID, $project, (int)$matches[1]); + $result = $this->objectModel->apiCreateMR($hostID, $params); + } if(empty($result->iid) && empty($result->id)) return $result; $this->objectModel->apiDeleteMR($hostID, $project, empty($result->iid) ? $result->id : $result->iid); diff --git a/module/mr/test/model/apicreatemr.php b/module/mr/test/model/apicreatemr.php index 80ad11f17a..2cab405fcd 100755 --- a/module/mr/test/model/apicreatemr.php +++ b/module/mr/test/model/apicreatemr.php @@ -10,6 +10,9 @@ cid=0 - 正确的数据创建Gitlab合并请求 - 属性title @test - 属性state @opened + - 属性description @This is a test merge request + - 属性sourceBranch @main + - 属性targetBranch @master */ @@ -39,4 +42,4 @@ $params->assignee = ''; $params->removeSourceBranch = 0; $params->squash = 0; -r($mrModel->apiCreateMrTester($gitlabID, $projectID, $params)) && p('title,state') && e('test,opened'); // 正确的数据创建Gitlab合并请求 +r($mrModel->apiCreateMrTester($gitlabID, $projectID, $params)) && p('title,state,description,source_branch,target_branch') && e('test,opened,This is a test merge request,main,master'); // 正确的数据创建Gitlab合并请求 diff --git a/module/mr/test/model/apideletemr.php b/module/mr/test/model/apideletemr.php index a5a88d1b85..2022e17ff0 100755 --- a/module/mr/test/model/apideletemr.php +++ b/module/mr/test/model/apideletemr.php @@ -34,4 +34,4 @@ $params->assignee = ''; $params->removeSourceBranch = 0; $params->squash = 0; -r($mrModel->apiDeleteMrTester($gitlabID, $gitlabProjectID, $params)) && p('message') && e('0'); // 正确的数据创建并删除Gitlab合并请求 \ No newline at end of file +r($mrModel->apiDeleteMrTester($gitlabID, $gitlabProjectID, $params)) && p('message') && e('0'); // 正确的数据创建并删除Gitlab合并请求 diff --git a/module/my/test/model/buildticketsearchform.php b/module/my/test/model/buildticketsearchform.php index d820c94ee8..9dafd2786c 100755 --- a/module/my/test/model/buildticketsearchform.php +++ b/module/my/test/model/buildticketsearchform.php @@ -14,12 +14,12 @@ title=测试 myModel->buildTicketSearchForm(); timeout=0 cid=1 -- 测试获取queryID 1 actionURL actionURL1 的搜索表单 @0 -- 测试获取queryID 0 actionURL actionURL2 的搜索表单 @0 -- 测试获取queryID 0 actionURL actionURL2 的搜索表单 @0 -- 测试获取queryID 0 actionURL actionURL3 的搜索表单 @0 -- 测试获取queryID 1 actionURL actionURL1 的搜索表单 @0 -- 测试获取queryID 1 actionURL actionURL3 的搜索表单 @0 +- 测试获取queryID 1 actionURL actionURL1 的搜索表单 @1 +- 测试获取queryID 0 actionURL actionURL2 的搜索表单 @1 +- 测试获取queryID 0 actionURL actionURL2 的搜索表单 @1 +- 测试获取queryID 0 actionURL actionURL3 的搜索表单 @1 +- 测试获取queryID 1 actionURL actionURL1 的搜索表单 @1 +- 测试获取queryID 1 actionURL actionURL3 的搜索表单 @1 */ @@ -29,9 +29,9 @@ $queryID = array(0, 1); $actionURL = array('actionURL1', 'actionURL2', 'actionURL3'); $config1 = $my->buildTicketSearchFormTest($queryID[0], $actionURL[0]); $config2 = $my->buildTicketSearchFormTest($queryID[1], $actionURL[1]); -r($config1) && p() && e('0'); // 测试获取queryID 1 actionURL actionURL1 的搜索表单 -r($config2) && p() && e('0'); // 测试获取queryID 0 actionURL actionURL2 的搜索表单 -r($my->buildTicketSearchFormTest($queryID[0], $actionURL[1])) && p() && e('0'); // 测试获取queryID 0 actionURL actionURL2 的搜索表单 -r($my->buildTicketSearchFormTest($queryID[0], $actionURL[2])) && p() && e('0'); // 测试获取queryID 0 actionURL actionURL3 的搜索表单 -r($my->buildTicketSearchFormTest($queryID[1], $actionURL[0])) && p() && e('0'); // 测试获取queryID 1 actionURL actionURL1 的搜索表单 -r($my->buildTicketSearchFormTest($queryID[1], $actionURL[2])) && p() && e('0'); // 测试获取queryID 1 actionURL actionURL3 的搜索表单 +r($config1) && p() && e('1'); // 测试获取queryID 1 actionURL actionURL1 的搜索表单 +r($config2) && p() && e('1'); // 测试获取queryID 0 actionURL actionURL2 的搜索表单 +r($my->buildTicketSearchFormTest($queryID[0], $actionURL[1])) && p() && e('1'); // 测试获取queryID 0 actionURL actionURL2 的搜索表单 +r($my->buildTicketSearchFormTest($queryID[0], $actionURL[2])) && p() && e('1'); // 测试获取queryID 0 actionURL actionURL3 的搜索表单 +r($my->buildTicketSearchFormTest($queryID[1], $actionURL[0])) && p() && e('1'); // 测试获取queryID 1 actionURL actionURL1 的搜索表单 +r($my->buildTicketSearchFormTest($queryID[1], $actionURL[2])) && p() && e('1'); // 测试获取queryID 1 actionURL actionURL3 的搜索表单 diff --git a/module/my/test/model/gettestcasesbysearch.php b/module/my/test/model/gettestcasesbysearch.php index 3919356647..a9a1c621ab 100755 --- a/module/my/test/model/gettestcasesbysearch.php +++ b/module/my/test/model/gettestcasesbysearch.php @@ -21,9 +21,9 @@ cid=1 - 属性status @blocked - 测试通过搜索获取用例 1 的用例数量 @10 - 测试通过搜索获取用例 2 的当前用例名称和状态 - - 属性title @这个是测试用例17 + - 属性title @这个是测试用例1 - 属性status @wait -- 测试通过搜索获取用例 2 的用例数量 @5 +- 测试通过搜索获取用例 2 的用例数量 @1 */ @@ -40,5 +40,5 @@ $cases2 = $my->getTestcasesBySearchTest(0, $type[1], $order); r(current($cases1)) && p('title,status') && e('这个是测试用例19,blocked'); // 测试通过搜索获取用例 1 的当前用例名称和状态 r(count($cases1)) && p() && e('10'); // 测试通过搜索获取用例 1 的用例数量 -r(current($cases2)) && p('title,status') && e('这个是测试用例17,wait'); // 测试通过搜索获取用例 2 的当前用例名称和状态 -r(count($cases2)) && p() && e('5'); // 测试通过搜索获取用例 2 的用例数量 \ No newline at end of file +r(current($cases2)) && p('title,status') && e('这个是测试用例1,wait'); // 测试通过搜索获取用例 2 的当前用例名称和状态 +r(count($cases2)) && p() && e('1'); // 测试通过搜索获取用例 2 的用例数量 \ No newline at end of file diff --git a/module/my/test/model/setmenu.php b/module/my/test/model/setmenu.php index 077505526b..9c2d04b5f9 100644 --- a/module/my/test/model/setmenu.php +++ b/module/my/test/model/setmenu.php @@ -7,15 +7,15 @@ declare(strict_types=1); title=测试 myModel->getActions(); cid=1 -- 获取 admin 角色 空 的地盘菜单 @5:index,10:calendar,15:work,20:audit,25:project,30:execution,35:contribute,40:dynamic,50:contacts +- 获取 admin 角色 空 的地盘菜单 @5:index,10:calendar,15:work,20:audit,25:project,30:execution,35:contribute,40:dynamic,50:contacts,11:effort,41:meeting -- 获取 user1 角色 qa 的地盘菜单 @5:index,10:calendar,20:audit,25:project,30:execution,35:contribute,40:dynamic,50:contacts,32:task +- 获取 user1 角色 qa 的地盘菜单 @5:index,10:calendar,20:audit,25:project,30:execution,35:contribute,40:dynamic,50:contacts,11:effort,41:meeting,32:task -- 获取 user2 po 的地盘菜单 @5:index,10:calendar,20:audit,25:project,30:task,35:contribute,40:dynamic,50:contacts,32:task,15:story,16:requirement +- 获取 user2 po 的地盘菜单 @5:index,10:calendar,20:audit,25:project,30:task,35:contribute,40:dynamic,50:contacts,11:effort,41:meeting,32:task,15:story,16:requirement -- 获取 user3 pm 的地盘菜单 @5:index,10:calendar,20:audit,25:project,30:task,40:dynamic,50:contacts,32:task,15:story,16:requirement,17:myProject +- 获取 user3 pm 的地盘菜单 @5:index,10:calendar,20:audit,25:project,30:task,40:dynamic,50:contacts,11:effort,41:meeting,32:task,15:story,16:requirement,17:myProject -- 获取 user4 pm 的地盘菜单 @5:index,10:calendar,20:audit,25:project,30:task,40:dynamic,50:contacts,32:task,15:story,16:requirement,17:myProject +- 获取 user4 pm 的地盘菜单 @5:index,10:calendar,20:audit,25:project,30:task,40:dynamic,50:contacts,11:effort,41:meeting,32:task,15:story,16:requirement,17:myProject */ @@ -27,8 +27,8 @@ $my = new myTest(); $accountList = array('admin', 'user1', 'user2', 'user3', 'user4'); -r($my->setMenuTest($accountList[0])) && p() && e('5:index,10:calendar,15:work,20:audit,25:project,30:execution,35:contribute,40:dynamic,50:contacts'); // 获取 admin 角色 空 的地盘菜单 -r($my->setMenuTest($accountList[1])) && p() && e('5:index,10:calendar,20:audit,25:project,30:execution,35:contribute,40:dynamic,50:contacts,32:task'); // 获取 user1 角色 qa 的地盘菜单 -r($my->setMenuTest($accountList[2])) && p() && e('5:index,10:calendar,20:audit,25:project,30:task,35:contribute,40:dynamic,50:contacts,32:task,15:story,16:requirement'); // 获取 user2 po 的地盘菜单 -r($my->setMenuTest($accountList[3])) && p() && e('5:index,10:calendar,20:audit,25:project,30:task,40:dynamic,50:contacts,32:task,15:story,16:requirement,17:myProject'); // 获取 user3 pm 的地盘菜单 -r($my->setMenuTest($accountList[4])) && p() && e('5:index,10:calendar,20:audit,25:project,30:task,40:dynamic,50:contacts,32:task,15:story,16:requirement,17:myProject'); // 获取 user4 pm 的地盘菜单 +r($my->setMenuTest($accountList[0])) && p() && e('5:index,10:calendar,15:work,20:audit,25:project,30:execution,35:contribute,40:dynamic,50:contacts,11:effort,41:meeting'); // 获取 admin 角色 空 的地盘菜单 +r($my->setMenuTest($accountList[1])) && p() && e('5:index,10:calendar,20:audit,25:project,30:execution,35:contribute,40:dynamic,50:contacts,11:effort,41:meeting,32:task'); // 获取 user1 角色 qa 的地盘菜单 +r($my->setMenuTest($accountList[2])) && p() && e('5:index,10:calendar,20:audit,25:project,30:task,35:contribute,40:dynamic,50:contacts,11:effort,41:meeting,32:task,15:story,16:requirement'); // 获取 user2 po 的地盘菜单 +r($my->setMenuTest($accountList[3])) && p() && e('5:index,10:calendar,20:audit,25:project,30:task,40:dynamic,50:contacts,11:effort,41:meeting,32:task,15:story,16:requirement,17:myProject'); // 获取 user3 pm 的地盘菜单 +r($my->setMenuTest($accountList[4])) && p() && e('5:index,10:calendar,20:audit,25:project,30:task,40:dynamic,50:contacts,11:effort,41:meeting,32:task,15:story,16:requirement,17:myProject'); // 获取 user4 pm 的地盘菜单 diff --git a/module/pivot/js/common.ui.js b/module/pivot/js/common.ui.js index 80945e8cb0..171f840dea 100644 --- a/module/pivot/js/common.ui.js +++ b/module/pivot/js/common.ui.js @@ -10,7 +10,7 @@ window.clickCell = function(col, {colName, rowInfo}) if(!isDrill || rowInfo.data.field0_colspan) return false; let conditions = []; - let filterValues = {}; + let filterValues = []; let originField = '0'; let id = window.pivotID; @@ -59,19 +59,17 @@ window.getFilterValues = function(where) root = $('#conditions .filter'); } - const filterValues = {}; + const filterValues = []; root.each(function(index) { const $filter = $(this); if ($filter.hasClass('filter-input')) { - filterValues[ - index] = $filter.find('input').val(); + filterValues[index] = $filter.find('input').val(); } else if($filter.hasClass('filter-select') || $filter.hasClass('filter-multipleselect')) { - const value = $filter.find('.pick-value').val(); - filterValues[index] = Array.isArray(value) ? value.reduce((obj, value, index) => ({...obj,[index]: value}), {}) : value; + filterValues[index] = $filter.find('.pick-value').val(); } else if($filter.hasClass('filter-date') || $filter.hasClass('filter-datetime')) { diff --git a/module/product/test/lib/product.unittest.class.php b/module/product/test/lib/product.unittest.class.php index 0180369ddd..0e34765085 100644 --- a/module/product/test/lib/product.unittest.class.php +++ b/module/product/test/lib/product.unittest.class.php @@ -656,6 +656,9 @@ class productTest */ public function getStoriesTest($productID, $branch, $browseType, $queryID, $moduleID) { + global $app; + $app->rawModule = 'product'; + $app->rawMethod = 'getStories'; $objects = $this->objectModel->getStories($productID, $branch, $browseType, $queryID, $moduleID); if(dao::isError()) diff --git a/module/productplan/test/model/isclickable.php b/module/productplan/test/model/isclickable.php index 5fc9869424..6d70617df7 100755 --- a/module/productplan/test/model/isclickable.php +++ b/module/productplan/test/model/isclickable.php @@ -6,6 +6,12 @@ title=productplanModel->isClickable(); timeout=0 cid=1 +- 检查开始按钮 @0 +- 检查完成按钮 @0 +- 检查关闭按钮 @0 +- 检查激活按钮 @1 +- 检查开始按钮 @0 + */ include dirname(__FILE__, 5) . '/test/lib/init.php'; @@ -19,14 +25,17 @@ $planID[] = 10; $planID[] = 1; $planID[] = 12; $planID[] = 15; +$planID[] = 16; $action = array(); $action[] = 'start'; $action[] = 'finish'; $action[] = 'close'; $action[] = 'activate'; +$action[] = 'start'; -r($plan->isClickable($planID[0], $action[0])) && p() && e('0'); -r($plan->isClickable($planID[1], $action[1])) && p() && e('0'); -r($plan->isClickable($planID[2], $action[2])) && p() && e('0'); -r($plan->isClickable($planID[3], $action[3])) && p() && e('1'); +r($plan->isClickable($planID[0], $action[0])) && p() && e('0'); //检查开始按钮 +r($plan->isClickable($planID[1], $action[1])) && p() && e('0'); //检查完成按钮 +r($plan->isClickable($planID[2], $action[2])) && p() && e('0'); //检查关闭按钮 +r($plan->isClickable($planID[3], $action[3])) && p() && e('1'); //检查激活按钮 +r($plan->isClickable($planID[4], $action[4])) && p() && e('0'); //检查开始按钮 diff --git a/module/project/config.php b/module/project/config.php index c8694d49dd..234ee42267 100755 --- a/module/project/config.php +++ b/module/project/config.php @@ -102,7 +102,7 @@ $config->project->search['params']['closedBy'] = array('operator' => '=' $config->project->search['params']['lastEditedDate'] = array('operator' => '=' , 'control' => 'date', 'values' => ''); $config->project->search['params']['closedDate'] = array('operator' => '=' , 'control' => 'date', 'values' => ''); -$config->project->noSprintPriv['project'] = array('edit', 'group', 'createGroup', 'managePriv', 'manageMembers', 'manageGroupMember', 'copyGroup', 'editGroup', 'start', 'suspend', 'close', 'activate', 'delete', 'view', 'whitelist', 'addWhitelist', 'unbindWhitelist', 'manageProducts', 'dynamic', 'bug', 'testcase', 'testtask', 'testreport', 'team', 'unlinkMember'); +$config->project->noSprintPriv['project'] = array('edit', 'group', 'createGroup', 'managePriv', 'manageMembers', 'manageGroupMember', 'copyGroup', 'editGroup', 'start', 'suspend', 'close', 'activate', 'delete', 'view', 'whitelist', 'addWhitelist', 'unbindWhitelist', 'manageProducts', 'dynamic', 'bug', 'testcase', 'testtask', 'testreport', 'team', 'unlinkMember', 'workflowGroup'); $config->project->noSprintPriv['execution'] = array('task', 'grouptask', 'importplanstories', 'importBug', 'story', 'burn', 'computeBurn', 'fixFirst', 'burnData', 'linkStory', 'unlinkStory', 'batchUnlinkStory', 'updateOrder', 'taskKanban', 'printKanban', 'tree', 'treeTask', 'treeStory', 'storyKanban', 'storySort', 'storyEstimate', 'setKanban', 'storyView', 'calendar', 'effortCalendar', 'effort', 'taskEffort', 'computeTaskEffort', 'deleterelation', 'maintainrelation', 'relation', 'gantt', 'ganttsetting', 'ganttEdit'); $config->project->noSprintPriv['story'] = array('create', 'batchCreate', 'edit', 'export', 'delete', 'view', 'change', 'review', 'batchReview', 'recall', 'close', 'batchClose', 'batchChangePlan', 'batchChangeStage', 'assignTo', 'batchAssignTo', 'activate', 'zeroCase', 'batchEdit', 'import', 'showImport', 'exportTemplate', 'importToLib', 'batchImportToLib', 'relation', 'browse'); $config->project->noSprintPriv['bug'] = array('create', 'confirm', 'view', 'edit', 'assignTo', 'batchAssignTo', 'resolve', 'activate', 'close', 'export', 'confirmStoryChange', 'delete', 'linkBugs', 'import', 'showImport', 'exportTemplate'); diff --git a/module/project/control.php b/module/project/control.php index a09b878565..b2f19f646d 100755 --- a/module/project/control.php +++ b/module/project/control.php @@ -125,6 +125,7 @@ class project extends control $this->view->programs = $programs; $this->view->extra = $extra; $this->view->useLink = $useLink; + $this->view->project = $project; $this->view->projects = $orderedProjects; $this->view->involvedProjects = $involvedProjects; diff --git a/module/project/test/lib/managemembersforlite.ui.class.php b/module/project/test/lib/managemembersforlite.ui.class.php index da4478225e..038828ee4f 100644 --- a/module/project/test/lib/managemembersforlite.ui.class.php +++ b/module/project/test/lib/managemembersforlite.ui.class.php @@ -36,16 +36,19 @@ class manageMembersForLiteTester extends tester */ public function deleteMembers() { - $browseForm = $this->initForm('project', 'team', array('projectID' => '1'), 'appIframe-project'); - $browseFirAccount1 = $browseForm->dom->browseFirAccount->getText(); - $browseForm->dom->teamBtn->click(); + $form = $this->initForm('project', 'team', array('projectID' => '1'), 'appIframe-project'); + $browseFirAccount1 = $form->dom->browseFirAccount->getText(); + $form->wait(2); + $form->dom->teamBtn->click(); $form = $this->initForm('project', 'manageMembers', array('projectID' => '1'), 'appIframe-project'); $form->dom->firstDeleteBtn->click(); $form->wait(2); $form->dom->saveBtn->click(); $form->wait(2); + //添加断言,判断是否删除成功 - if($browseForm->dom->browseFirAccount->getText() == $browseFirAccount1) return $this->failed('项目团队成员删除失败'); + $teamPage = $this->loadPage('project', 'team'); + if($teamPage->dom->browseFirAccount->getText() == $browseFirAccount1) return $this->failed('项目团队成员删除失败'); return $this->success('项目团队成员删除成功'); } diff --git a/module/project/test/ui/managemembersforlite.php b/module/project/test/ui/managemembersforlite.php index 956484117f..4273a64cce 100755 --- a/module/project/test/ui/managemembersforlite.php +++ b/module/project/test/ui/managemembersforlite.php @@ -31,6 +31,9 @@ $user->realname->range('admin, 用户1, 用户2, 用户3'); $user->password->range($config->uitest->defaultPassword)->format('md5'); $user->gen(4); +$team = zenData('team'); +$team->gen(0); + $team = zenData('team'); $team->id->range('1'); $team->root->range('1'); diff --git a/module/project/ui/ajaxgetdropmenu.html.php b/module/project/ui/ajaxgetdropmenu.html.php index 5922e35490..5cf09cc169 100644 --- a/module/project/ui/ajaxgetdropmenu.html.php +++ b/module/project/ui/ajaxgetdropmenu.html.php @@ -74,6 +74,32 @@ if($extra == 'selectmode') $data = array_values($data); renderJson($data); } +elseif(!empty($project->isTpl)) +{ + /* 模板单独渲染。 */ + foreach($projects as $programID => $programProjects) + { + foreach($programProjects as $index => $project) + { + $item = array(); + $item['id'] = $project->id; + $item['text'] = $project->name; + $item['icon'] = $project->model == 'scrum' ? 'sprint' : $project->model; + $item['keys'] = zget(common::convert2Pinyin(array($project->name)), $project->name, ''); + $item['involved'] = isset($involvedProjects[$project->id]); + $item['url'] = helper::createLink('project', 'execution', "status=undone&projectID={$project->id}"); + + $data[] = $item; + } + } + + $json = array(); + $json['data'] = $data; + $json['searchHint'] = $lang->searchAB; + $json['itemType'] = 'project'; + + renderJson($json); +} else { /** diff --git a/module/search/test/model/buildindexquery.php b/module/search/test/model/buildindexquery.php index b32eeefe88..b531a74eb1 100755 --- a/module/search/test/model/buildindexquery.php +++ b/module/search/test/model/buildindexquery.php @@ -9,12 +9,12 @@ title=测试 searchModel->buildIndexQuery(); timeout=0 cid=1 -- 构建未删除项目集的sql语句 @SELECT t1.* FROM `zt_project` AS t1 WHERE 1=1 AND `type` = 'program' +- 构建未删除项目集的sql语句 @SELECT t1.* FROM `zt_project` AS t1 WHERE (t1.`isTpl` = '0' OR t1.`isTpl` IS NULL) AND 1=1 AND `type` = 'program' - 构建需求的sql语句 @SELECT DISTINCT t1.*, t2.spec, t2.verify FROM `zt_story` AS t1 LEFT JOIN `zt_storyspec` AS t2 ON t1.id=t2.story WHERE t1.deleted = '0' AND `type` = 'story' AND t1.version=t2.version - 构建需求的sql语句 @SELECT DISTINCT t1.*, t2.content, t2.digest FROM `zt_doc` AS t1 LEFT JOIN `zt_doccontent` AS t2 ON t1.id=t2.doc WHERE t1.deleted = '0' AND t1.version=t2.version -- 构建查询所有项目的sql语句 @SELECT t1.* FROM `zt_project` AS t1 WHERE 1=1 AND `type` = 'project' +- 构建查询所有项目的sql语句 @SELECT t1.* FROM `zt_project` AS t1 WHERE (t1.`isTpl` = '0' OR t1.`isTpl` IS NULL) AND 1=1 AND `type` = 'project' */ @@ -22,7 +22,7 @@ global $tester; $search = $tester->loadModel('search'); zenData('project')->gen(0); -r($search->buildIndexQuery('program')->get()) && p() && e("SELECT t1.* FROM `zt_project` AS t1 WHERE 1=1 AND `type` = 'program'"); //构建未删除项目集的sql语句 +r($search->buildIndexQuery('program')->get()) && p() && e("SELECT t1.* FROM `zt_project` AS t1 WHERE (t1.`isTpl` = '0' OR t1.`isTpl` IS NULL) AND 1=1 AND `type` = 'program'"); //构建未删除项目集的sql语句 r($search->buildIndexQuery('story')->get()) && p() && e("SELECT DISTINCT t1.*, t2.spec, t2.verify FROM `zt_story` AS t1 LEFT JOIN `zt_storyspec` AS t2 ON t1.id=t2.story WHERE t1.deleted = '0' AND `type` = 'story' AND t1.version=t2.version"); //构建需求的sql语句 -r($search->buildIndexQuery('doc')->get()) && p() && e("SELECT DISTINCT t1.*, t2.content, t2.digest FROM `zt_doc` AS t1 LEFT JOIN `zt_doccontent` AS t2 ON t1.id=t2.doc WHERE t1.deleted = '0' AND t1.version=t2.version"); //构建需求的sql语句 -r($search->buildIndexQuery('project', false)->get()) && p() && e("SELECT t1.* FROM `zt_project` AS t1 WHERE 1=1 AND `type` = 'project'"); //构建查询所有项目的sql语句 +r($search->buildIndexQuery('doc')->get()) && p() && e("SELECT DISTINCT t1.*, t2.content, t2.digest FROM `zt_doc` AS t1 LEFT JOIN `zt_doccontent` AS t2 ON t1.id=t2.doc WHERE t1.deleted = '0' AND t1.version=t2.version"); //构建需求的sql语句 +r($search->buildIndexQuery('project', false)->get()) && p() && e("SELECT t1.* FROM `zt_project` AS t1 WHERE (t1.`isTpl` = '0' OR t1.`isTpl` IS NULL) AND 1=1 AND `type` = 'project'"); //构建查询所有项目的sql语句 \ No newline at end of file diff --git a/module/search/test/tao/getsqlparams.php b/module/search/test/tao/getsqlparams.php index 0f666e19ec..45eecd47ba 100755 --- a/module/search/test/tao/getsqlparams.php +++ b/module/search/test/tao/getsqlparams.php @@ -9,13 +9,11 @@ cid=1 - 测试获取搜索 test 关键词的 unicode @test_ - 测试获取搜索 test 关键词的查询语句的 against 条件属性1 @(+"test_") -- 测试获取搜索 test 关键词的查询语句的 like 条件属性2 @OR title like '%test_%' OR content like '%test_%' +- 测试获取搜索 test 关键词的查询语句的 like 条件属性2 @OR title like '%test%' OR content like '%test%' - 测试获取搜索 测试 关键词的 unicode @27979 35797 - 测试获取搜索 测试 关键词的查询语句的 against 条件属性1 @(+"27979 35797") -- 测试获取搜索 测试 关键词的查询语句的 like 条件属性2 @OR title like '%27979 35797%' OR content like '%27979 35797%' - 测试获取搜索 12345 关键词的 unicode @|12345| - 测试获取搜索 12345 关键词的查询语句的 against 条件属性1 @(+"|12345|") (-" 12345 ") -- 测试获取搜索 12345 关键词的查询语句的 like 条件属性2 @~~ */ @@ -28,10 +26,8 @@ $keywords = array('test', '测试', '12345'); $search = new searchTest(); r($search->getSqlParamsTest($keywords[0])) && p('0') && e('test_'); //测试获取搜索 test 关键词的 unicode r($search->getSqlParamsTest($keywords[0])) && p('1') && e('(+"test_")'); //测试获取搜索 test 关键词的查询语句的 against 条件 -r($search->getSqlParamsTest($keywords[0])) && p('2') && e("OR title like '%test_%' OR content like '%test_%'"); //测试获取搜索 test 关键词的查询语句的 like 条件 +r($search->getSqlParamsTest($keywords[0])) && p('2') && e("OR title like '%test%' OR content like '%test%'"); //测试获取搜索 test 关键词的查询语句的 like 条件 r($search->getSqlParamsTest($keywords[1])) && p('0') && e('27979 35797'); //测试获取搜索 测试 关键词的 unicode r($search->getSqlParamsTest($keywords[1])) && p('1') && e('(+"27979 35797")'); //测试获取搜索 测试 关键词的查询语句的 against 条件 -r($search->getSqlParamsTest($keywords[1])) && p('2') && e("OR title like '%27979 35797%' OR content like '%27979 35797%'"); //测试获取搜索 测试 关键词的查询语句的 like 条件 r($search->getSqlParamsTest($keywords[2])) && p('0') && e('|12345|'); //测试获取搜索 12345 关键词的 unicode -r($search->getSqlParamsTest($keywords[2])) && p('1') && e('(+"|12345|") (-" 12345 ")'); //测试获取搜索 12345 关键词的查询语句的 against 条件 -r($search->getSqlParamsTest($keywords[2])) && p('2') && e('~~'); //测试获取搜索 12345 关键词的查询语句的 like 条件 \ No newline at end of file +r($search->getSqlParamsTest($keywords[2])) && p('1') && e('(+"|12345|") (-" 12345 ")'); //测试获取搜索 12345 关键词的查询语句的 against 条件 \ No newline at end of file diff --git a/module/stakeholder/test/model/getexpectbyuser.php b/module/stakeholder/test/model/getexpectbyuser.php index be76e6b42d..0d2c97dcbb 100755 --- a/module/stakeholder/test/model/getexpectbyuser.php +++ b/module/stakeholder/test/model/getexpectbyuser.php @@ -1,16 +1,18 @@ #!/usr/bin/env php getExpectByUser(); +timeout=0 cid=1 - 获取userID为0的用户的期望 @0 - 获取userID为11的用户的期望 - - 第0条的userID属性 @11 - - 第0条的expect属性 @期望1 - - 第0条的progress属性 @进度1 - - 第0条的project属性 @11 + - 第1条的userID属性 @11 + - 第1条的expect属性 @期望1 + - 第1条的progress属性 @进度1 + - 第1条的project属性 @11 - 获取userID不存在的用户的期望 @0 */ @@ -25,5 +27,5 @@ $userIds = array(0, 11, 12); $stakeholderTester = new stakeholderTest(); r($stakeholderTester->getExpectByUserTest($userIds[0])) && p() && e('0'); // 获取userID为0的用户的期望 -r($stakeholderTester->getExpectByUserTest($userIds[1])) && p('0:userID,expect,progress,project') && e('11,期望1,进度1,11'); // 获取userID为11的用户的期望 -r($stakeholderTester->getExpectByUserTest($userIds[2])) && p() && e('0'); // 获取userID不存在的用户的期望 +r($stakeholderTester->getExpectByUserTest($userIds[1])) && p('1:userID,expect,progress,project') && e('11,期望1,进度1,11'); // 获取userID为11的用户的期望 +r($stakeholderTester->getExpectByUserTest($userIds[2])) && p() && e('0'); // 获取userID不存在的用户的期望 \ No newline at end of file diff --git a/module/story/test/model/change.php b/module/story/test/model/change.php index 78ff76e57b..0132f525f9 100755 --- a/module/story/test/model/change.php +++ b/module/story/test/model/change.php @@ -37,7 +37,9 @@ $story1->reviewerHasChanged = ''; $story1->estimate = 1; $story1->reviewer = array(); $story1->version = 4; -$story1->docs = 4; +$story1->docs = '1'; +$story1->oldDocs = array(1); +$story1->docVersions = '1'; $story2 = clone $story1; $story2->reviewer = array('admin', 'test2'); diff --git a/module/story/test/model/doupdatereviewer.php b/module/story/test/model/doupdatereviewer.php index 778b22540a..2914df8436 100755 --- a/module/story/test/model/doupdatereviewer.php +++ b/module/story/test/model/doupdatereviewer.php @@ -10,6 +10,7 @@ cid=0 - 只传入软件需求 ID。第0条的reviewer属性 @user2 - 传入软件需求 ID 和 评审人列表,查看storyreview表记录的关系。属性reviewer @user2 - 传入软件需求 ID 和 评审人列表,查看storyreview表记录的关系。属性reviewer @user3 +- 传入软件需求 ID 和 评审人列表,查看storyreview表记录的关系。属性reviewer @user4 */ include dirname(__FILE__, 5) . '/test/lib/init.php'; @@ -29,7 +30,7 @@ $storyReview->reviewer->range('admin,user1,admin,user1'); $storyReview->gen(4); $story1 = $tester->loadModel('story')->fetchByID(1); -$story1->reviewer = array('user2', 'user3'); +$story1->reviewer = array('user2', 'user3', 'user4'); $story = new storyTest(); r($story->doUpdateReviewerTest(0, (array)clone($story1))) && p() && e('0'); // 只传入评审人列表。 @@ -38,3 +39,4 @@ r($story->doUpdateReviewerTest(1, (array)clone($story1))) && p('0:reviewer') && $reviewers = $story->objectModel->dao->select('*')->from(TABLE_STORYREVIEW)->where('story')->eq('2')->fetchAll(); r($reviewers[0]) && p('reviewer') && e('user2'); // 传入软件需求 ID 和 评审人列表,查看storyreview表记录的关系。 r($reviewers[1]) && p('reviewer') && e('user3'); // 传入软件需求 ID 和 评审人列表,查看storyreview表记录的关系。 +r($reviewers[2]) && p('reviewer') && e('user4'); // 传入软件需求 ID 和 评审人列表,查看storyreview表记录的关系。 diff --git a/module/story/test/model/reportcondition.php b/module/story/test/model/reportcondition.php index a867ca3ace..76855465c2 100755 --- a/module/story/test/model/reportcondition.php +++ b/module/story/test/model/reportcondition.php @@ -10,6 +10,8 @@ cid=0 - 执行story模块的reportCondition方法,参数是'story' @1=1 - 执行story模块的reportCondition方法,参数是'story' @`title` like '%aa%' - 执行story模块的reportCondition方法,参数是'story' @id in (SELECT t1.id FROM `zt_story` AS t1 WHERE t1.`title` like '%aa%') +- 执行story模块的reportCondition方法,参数是'story' @`title` like '%aa%' +- 执行story模块的reportCondition方法,参数是'story' @id in (SELECT t1.id FROM `zt_story` AS t1 WHERE t1.`title` like '%aa%') */ include dirname(__FILE__, 5) . '/test/lib/init.php'; @@ -25,4 +27,12 @@ r($tester->story->reportCondition('story')) && p() && e("`title` like '%aa%'"); $_SESSION['storyOnlyCondition'] = false; $_SESSION['storyQueryCondition'] = "SELECT * FROM `zt_story` AS t1 WHERE t1.`title` like '%aa%'"; -r($tester->story->reportCondition('story')) && p() && e("id in (SELECT t1.id FROM `zt_story` AS t1 WHERE t1.`title` like '%aa%')"); \ No newline at end of file +r($tester->story->reportCondition('story')) && p() && e("id in (SELECT t1.id FROM `zt_story` AS t1 WHERE t1.`title` like '%aa%')"); + +$_SESSION['storyOnlyCondition'] = true; +$_SESSION['storyQueryCondition'] = "`title` like '%aa%'"; +r($tester->story->reportCondition('story')) && p() && e("`title` like '%aa%'"); + +$_SESSION['storyOnlyCondition'] = false; +$_SESSION['storyQueryCondition'] = "SELECT * FROM `zt_story` AS t1 WHERE t1.`title` like '%aa%'"; +r($tester->story->reportCondition('story')) && p() && e("id in (SELECT t1.id FROM `zt_story` AS t1 WHERE t1.`title` like '%aa%')"); diff --git a/module/story/test/model/updateparentstatus.php b/module/story/test/model/updateparentstatus.php index 8cf404bc05..71371ca0f2 100755 --- a/module/story/test/model/updateparentstatus.php +++ b/module/story/test/model/updateparentstatus.php @@ -11,6 +11,7 @@ cid=0 - 没有子需求的父需求,检查父需求的parent字段。 @0 - 已经关闭的父需求,有激活状态的子需求,检查父需求的状态。 @active - 没有父任务的子需求,检查子需求的parent字段。 @0 +- 变更中的需求。 @changing */ include dirname(__FILE__, 5) . '/test/lib/init.php'; @@ -29,13 +30,16 @@ $storyModel->updateParentStatus(3); $storyModel->updateParentStatus(16); $storyModel->updateParentStatus(17, 4); $storyModel->updateParentStatus(18); +$storyModel->updateParentStatus(20); $story2 = $storyModel->fetchByID(2); $story4 = $storyModel->fetchByID(4); $story15 = $storyModel->fetchByID(15); $story16 = $storyModel->fetchByID(16); +$story20 = $storyModel->fetchByID(20); -r($story2->status) && p() && e('closed'); // 只有一个子需求,并且需求状态为closed,检查父需求的状态。 -r($story4->isParent) && p() && e('0'); // 没有子需求的父需求,检查父需求的parent字段。 -r($story15->status) && p() && e('active'); // 已经关闭的父需求,有激活状态的子需求,检查父需求的状态。 -r($story16->parent) && p() && e('0'); // 没有父任务的子需求,检查子需求的parent字段。 \ No newline at end of file +r($story2->status) && p() && e('closed'); // 只有一个子需求,并且需求状态为closed,检查父需求的状态。 +r($story4->isParent) && p() && e('0'); // 没有子需求的父需求,检查父需求的parent字段。 +r($story15->status) && p() && e('active'); // 已经关闭的父需求,有激活状态的子需求,检查父需求的状态。 +r($story16->parent) && p() && e('0'); // 没有父任务的子需求,检查子需求的parent字段。 +r($story20->status) && p() && e('changing'); // 变更中的需求。 diff --git a/module/story/test/tao/getunclosedstatuskeys.php b/module/story/test/tao/getunclosedstatuskeys.php index 806f19ee34..39f43a5c17 100755 --- a/module/story/test/tao/getunclosedstatuskeys.php +++ b/module/story/test/tao/getunclosedstatuskeys.php @@ -6,7 +6,11 @@ title=测试 storyModel->getUnclosedStatusKeys(); cid=0 -- 执行storyModel模块的getUnclosedStatusKeys方法 @|draft|reviewing|active|changing +- 获取草稿状态属性1 @draft +- 获取评审中状态属性2 @reviewing +- 获取激活状态属性3 @active +- 获取变更中状态属性4 @changing +- 获取空值 @~~ */ include dirname(__FILE__, 5) . "/test/lib/init.php"; @@ -14,4 +18,8 @@ include dirname(__FILE__, 5) . "/test/lib/init.php"; global $tester; $storyModel = $tester->loadModel('story'); -r(implode('|', $storyModel->getUnclosedStatusKeys())) && p() && e('|draft|reviewing|active|changing'); +r($storyModel->getUnclosedStatusKeys()) && p('1') && e('draft'); //获取草稿状态 +r($storyModel->getUnclosedStatusKeys()) && p('2') && e('reviewing'); //获取评审中状态 +r($storyModel->getUnclosedStatusKeys()) && p('3') && e('active'); //获取激活状态 +r($storyModel->getUnclosedStatusKeys()) && p('4') && e('changing'); //获取变更中状态 +r($storyModel->getUnclosedStatusKeys()) && p('0') && e('~~'); //获取空值 diff --git a/module/system/model.php b/module/system/model.php index 6744b90384..220f0d2ae0 100644 --- a/module/system/model.php +++ b/module/system/model.php @@ -297,6 +297,7 @@ class systemModel extends model } else { + $this->unsetMaintenance('backup'); return array('result' => 'fail', 'message' => $rawResult->message); } } diff --git a/module/system/test/model/backup.php b/module/system/test/model/backup.php new file mode 100755 index 0000000000..31923a6e7b --- /dev/null +++ b/module/system/test/model/backup.php @@ -0,0 +1,30 @@ +#!/usr/bin/env php +loadModel('system'); + +$instance = new stdClass(); +$instance->spaceData = new stdClass(); +$instance->spaceData->k8space = 'qucikon-system'; +$instance->k8name = 'zentaopaas'; +r($system->backup($instance, '')) && p('result') && e('fail'); // 查询默认备份模式为空 +r($system->backup($instance, 'manual')) && p('message') && e('CNE服务器出错'); // 查询备份模式为手动 +r($system->backup($instance, 'system')) && p('result') && e('fail'); // 查询备份模式为系统 +r($system->backup($instance, 'upgrade')) && p('message') && e('CNE服务器出错'); // 查询备份模式为升级 +r($system->backup($instance, 'downgrade')) && p('result') && e('fail'); // 查询备份模式为降级 diff --git a/module/task/js/batchedit.ui.js b/module/task/js/batchedit.ui.js index 682d8c1432..040ab0ea7f 100644 --- a/module/task/js/batchedit.ui.js +++ b/module/task/js/batchedit.ui.js @@ -61,7 +61,7 @@ window.renderRowData = function($row, index, row) { const $assignedTo = info[0]; const manageLink = noSprintPairs[row.project] != undefined ? manageLinkList['project'].replace('{projectID}', row.project) : manageLinkList['execution'].replace('{executionID}', row.execution); - const pickerToolbar = manageLink && teams[row.id] == undefined ? [{'className': 'text-primary manageTeamBtn', 'key': 'manageTeam', 'text': manageTeamMemberText, 'url': manageLink, 'data-toggle': 'modal', 'data-size': 'lg', 'data-dismiss': 'pick'}] : ''; + const pickerToolbar = manageLink && teams[row.id] == undefined ? [{'className': 'text-primary manageTeamBtn', 'key': 'manageTeam', 'text': manageTeamMemberText, 'icon': 'plus-solid-circle', 'url': manageLink, 'data-toggle': 'modal', 'data-size': 'lg', 'data-dismiss': 'pick'}] : ''; if(!pickerToolbar) $row.find('.taskAssignedToBox').removeClass('taskAssignedToBox'); if(pickerToolbar) $row.find('.taskAssignedToBox').attr('data-object', noSprintPairs[row.project] != undefined ? row.project : row.execution); diff --git a/module/testcase/test/lib/testcase.unittest.class.php b/module/testcase/test/lib/testcase.unittest.class.php index d2421694c3..36d3e5dc20 100755 --- a/module/testcase/test/lib/testcase.unittest.class.php +++ b/module/testcase/test/lib/testcase.unittest.class.php @@ -555,6 +555,8 @@ class testcaseTest $case->color = $oldCase->color; $case->precondition = $oldCase->precondition; $case->steps = array('用例步骤描述1'); + $case->expects = array('这是用例预期结果1'); + $case->stepType = array('step'); $case->comment = ''; $case->lastEditedDate = $oldCase->lastEditedDate; $case->product = $oldCase->product; @@ -568,6 +570,7 @@ class testcaseTest $case->keywords = $oldCase->keywords; $case->linkBug = array(); $case->stepChanged = isset($param['steps']); + $case->version = $oldCase->version + 1; foreach($param as $field => $value) $case->$field = $value; diff --git a/module/testcase/test/model/getstepbyproductandmodule.php b/module/testcase/test/model/getstepbyproductandmodule.php index d17e0bc955..cb2a9de838 100644 --- a/module/testcase/test/model/getstepbyproductandmodule.php +++ b/module/testcase/test/model/getstepbyproductandmodule.php @@ -13,7 +13,20 @@ su('admin'); title=测试 testcaseModel->getStepByProductAndModule(); cid=1 -pid=1 + +- 获取产品 0 模块 0 的步骤信息 @0 +- 获取产品 1 模块 0 的步骤信息 @testcaseID:1 stepID: 1. testcaseID:2 stepID: 2. testcaseID:3 stepID: 3. testcaseID:4 stepID: 4. +- 获取产品 1 模块 1821 的步骤信息 @testcaseID:1 stepID: 1. +- 获取产品 1 模块 1825 的步骤信息 @0 +- 获取产品 1 模块 1829 的步骤信息 @0 +- 获取产品 2 模块 0 的步骤信息 @testcaseID:5 stepID: 5. testcaseID:6 stepID: 6. testcaseID:7 stepID: 7. testcaseID:8 stepID: 8. +- 获取产品 2 模块 1821 的步骤信息 @0 +- 获取产品 2 模块 1825 的步骤信息 @testcaseID:5 stepID: 5. +- 获取产品 2 模块 1829 的步骤信息 @0 +- 获取产品 3 模块 0 的步骤信息 @testcaseID:9 stepID: 9. testcaseID:10 stepID: 10. testcaseID:11 stepID: 11. testcaseID:12 stepID: 12. +- 获取产品 3 模块 1821 的步骤信息 @0 +- 获取产品 3 模块 1825 的步骤信息 @0 +- 获取产品 3 模块 1829 的步骤信息 @testcaseID:10 stepID: 10. */ diff --git a/module/testcase/test/model/gettestcases.php b/module/testcase/test/model/gettestcases.php index 07b7a92ce8..3b035fa40d 100755 --- a/module/testcase/test/model/gettestcases.php +++ b/module/testcase/test/model/gettestcases.php @@ -43,10 +43,8 @@ cid=1 - 测试查询产品 1 分支 0 browseType bysuite 模块 0 用例类型 空 自动化 no 排序 id_desc 的测试用例 @0 - 测试查询产品 1 分支 0 browseType bysearch 模块 0 用例类型 空 自动化 no 排序 id_desc 的测试用例 @4,2,1 -- 测试查询产品 1 分支 all browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 @4,2,1 - -- 测试查询产品 1 分支 0 browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 @4,2,1 - +- 测试查询产品 1 分支 all browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 @1 +- 测试查询产品 1 分支 0 browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 @1 - 测试查询产品 1 分支 1 browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 @0 - 测试查询产品 1 分支 all browseType all 模块 0 用例类型 feature 自动化 no 排序 id_desc 的测试用例 @1 - 测试查询产品 1 分支 0 browseType all 模块 0 用例类型 feature 自动化 no 排序 id_desc 的测试用例 @1 @@ -82,10 +80,8 @@ cid=1 - 测试查询产品 41 分支 0 browseType bysuite 模块 0 用例类型 空 自动化 no 排序 id_desc 的测试用例 @0 - 测试查询产品 41 分支 0 browseType bysearch 模块 0 用例类型 空 自动化 no 排序 id_desc 的测试用例 @164,163,161 -- 测试查询产品 41 分支 all browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 @164,163,161 - -- 测试查询产品 41 分支 0 browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 @164,163,161 - +- 测试查询产品 41 分支 all browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 @161 +- 测试查询产品 41 分支 0 browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 @161 - 测试查询产品 41 分支 1 browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 @0 - 测试查询产品 41 分支 all browseType all 模块 0 用例类型 feature 自动化 no 排序 id_desc 的测试用例 @0 - 测试查询产品 41 分支 0 browseType all 模块 0 用例类型 feature 自动化 no 排序 id_desc 的测试用例 @0 @@ -129,8 +125,8 @@ r($testcase->getTestCasesTest($productIdList[0], $branchList[1], $browseTypeList r($testcase->getTestCasesTest($productIdList[0], $branchList[1], $browseTypeList[4], $moduleIdList[0], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('0'); // 测试查询产品 1 分支 0 browseType bysuite 模块 0 用例类型 空 自动化 no 排序 id_desc 的测试用例 r($testcase->getTestCasesTest($productIdList[0], $branchList[1], $browseTypeList[5], $moduleIdList[0], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('4,2,1'); // 测试查询产品 1 分支 0 browseType bysearch 模块 0 用例类型 空 自动化 no 排序 id_desc 的测试用例 -r($testcase->getTestCasesTest($productIdList[0], $branchList[0], $browseTypeList[0], $moduleIdList[1], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('4,2,1'); // 测试查询产品 1 分支 all browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 -r($testcase->getTestCasesTest($productIdList[0], $branchList[1], $browseTypeList[0], $moduleIdList[1], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('4,2,1'); // 测试查询产品 1 分支 0 browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 +r($testcase->getTestCasesTest($productIdList[0], $branchList[0], $browseTypeList[0], $moduleIdList[1], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('1'); // 测试查询产品 1 分支 all browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 +r($testcase->getTestCasesTest($productIdList[0], $branchList[1], $browseTypeList[0], $moduleIdList[1], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('1'); // 测试查询产品 1 分支 0 browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 r($testcase->getTestCasesTest($productIdList[0], $branchList[2], $browseTypeList[0], $moduleIdList[1], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('0'); // 测试查询产品 1 分支 1 browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 r($testcase->getTestCasesTest($productIdList[0], $branchList[0], $browseTypeList[0], $moduleIdList[0], $caseTypeList[1], $unitList[0], $orderByList[0])) && p() && e('1'); // 测试查询产品 1 分支 all browseType all 模块 0 用例类型 feature 自动化 no 排序 id_desc 的测试用例 @@ -163,8 +159,8 @@ r($testcase->getTestCasesTest($productIdList[1], $branchList[1], $browseTypeList r($testcase->getTestCasesTest($productIdList[1], $branchList[1], $browseTypeList[4], $moduleIdList[0], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('0'); // 测试查询产品 41 分支 0 browseType bysuite 模块 0 用例类型 空 自动化 no 排序 id_desc 的测试用例 r($testcase->getTestCasesTest($productIdList[1], $branchList[1], $browseTypeList[5], $moduleIdList[0], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('164,163,161'); // 测试查询产品 41 分支 0 browseType bysearch 模块 0 用例类型 空 自动化 no 排序 id_desc 的测试用例 -r($testcase->getTestCasesTest($productIdList[1], $branchList[0], $browseTypeList[0], $moduleIdList[1], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('164,163,161'); // 测试查询产品 41 分支 all browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 -r($testcase->getTestCasesTest($productIdList[1], $branchList[1], $browseTypeList[0], $moduleIdList[1], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('164,163,161'); // 测试查询产品 41 分支 0 browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 +r($testcase->getTestCasesTest($productIdList[1], $branchList[0], $browseTypeList[0], $moduleIdList[1], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('161'); // 测试查询产品 41 分支 all browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 +r($testcase->getTestCasesTest($productIdList[1], $branchList[1], $browseTypeList[0], $moduleIdList[1], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('161'); // 测试查询产品 41 分支 0 browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 r($testcase->getTestCasesTest($productIdList[1], $branchList[2], $browseTypeList[0], $moduleIdList[1], $caseTypeList[0], $unitList[0], $orderByList[0])) && p() && e('0'); // 测试查询产品 41 分支 1 browseType all 模块 1821 用例类型 空 自动化 no 排序 id_desc 的测试用例 r($testcase->getTestCasesTest($productIdList[1], $branchList[0], $browseTypeList[0], $moduleIdList[0], $caseTypeList[1], $unitList[0], $orderByList[0])) && p() && e('0'); // 测试查询产品 41 分支 all browseType all 模块 0 用例类型 feature 自动化 no 排序 id_desc 的测试用例 diff --git a/module/testcase/test/model/update.php b/module/testcase/test/model/update.php index c6c382d157..2ae9ae4013 100755 --- a/module/testcase/test/model/update.php +++ b/module/testcase/test/model/update.php @@ -27,6 +27,7 @@ include dirname(__FILE__, 2) . '/lib/testcase.unittest.class.php'; zenData('case')->gen('5'); zenData('casestep')->gen('5'); +zenData('casespec')->gen('0'); zenData('user')->gen('1'); su('admin'); @@ -42,11 +43,11 @@ $title = array('title' => '修改后的用例'); $emptyTitle = array('title' => ''); $type = array('type' => 'install'); $emptyType = array('type' => ''); -$steps = array('steps' => array('步骤1'), 'stepType' => array('step'), 'expects' => array('预期1'), 'stepChanged' => true, 'version' => 2); +$steps = array('steps' => array('步骤1'), 'stepType' => array('step'), 'expects' => array('预期1'), 'stepChanged' => true); $testcase = new testCaseTest(); r($testcase->updateTest($testcaseIdList[0], $title)) && p('0:field,old,new') && e('title,这个是测试用例1,修改后的用例'); // 测试更新用例名称 r($testcase->updateTest($testcaseIdList[0], $emptyTitle)) && p('title:0') && e('『用例名称』不能为空。'); // 测试名称不能为空 r($testcase->updateTest($testcaseIdList[0], $type)) && p('0:field,old,new') && e('type,feature,install'); // 测试更新用例类型 r($testcase->updateTest($testcaseIdList[0], $emptyType)) && p('type:0') && e('『用例类型』不能为空。'); // 测试类型不能为空 -r($testcase->updateTest($testcaseIdList[0], $steps)) && p('0:field,new') && e('steps,步骤1 EXPECT:预期1'); // 测试更新用例步骤 \ No newline at end of file +r($testcase->updateTest($testcaseIdList[0], $steps)) && p('0:field,new') && e('steps,步骤1 EXPECT:预期1'); // 测试更新用例步骤 diff --git a/module/testtask/test/lib/testtask.unittest.class.php b/module/testtask/test/lib/testtask.unittest.class.php index da159b669c..8edff5eaf2 100644 --- a/module/testtask/test/lib/testtask.unittest.class.php +++ b/module/testtask/test/lib/testtask.unittest.class.php @@ -479,7 +479,7 @@ class testtaskTest $result = $tester->dao->select('*')->from(TABLE_TESTRESULT)->where('id')->eq($resultID)->fetch(); - $relatedSteps = $tester->dao->select('*')->from(TABLE_CASESTEP)->where('case')->eq($result->case)->orderBy('id')->fetchAll('id'); + $relatedSteps = $tester->dao->select('*')->from(TABLE_CASESTEP)->where('case')->eq($result->case)->orderBy('id')->fetchAll('id', false); $result->stepResults = unserialize($result->stepResults); $objects = $this->objectModel->processResultSteps($result, $relatedSteps); diff --git a/module/upgrade/test/lib/upgrade.unittest.class.php b/module/upgrade/test/lib/upgrade.unittest.class.php index bc73e7eb5b..c33100aac8 100755 --- a/module/upgrade/test/lib/upgrade.unittest.class.php +++ b/module/upgrade/test/lib/upgrade.unittest.class.php @@ -817,4 +817,18 @@ class upgradeTest $tableInfo = $this->objectModel->dbh->query("SHOW TABLE STATUS LIKE '$tableName'")->fetch(); return $tableInfo->Collation; } + + /** + * 修改执行模块工作流动作名称 + * Fix workflow action and field name for execution. + * + * @param string $action + * @access public + * @return bool + */ + public function fixWorkflowNameForExecutionTest(string $action) + { + $this->objectModel->fixWorkflowNameForExecution(); + return $this->objectModel->dao->select('name')->from(TABLE_WORKFLOWACTION)->where('module')->eq('execution')->andWhere('action')->eq($action)->fetch('name'); + } } diff --git a/module/upgrade/test/model/convertwiki2html.php b/module/upgrade/test/model/convertwiki2html.php new file mode 100644 index 0000000000..78cf02a7ae --- /dev/null +++ b/module/upgrade/test/model/convertwiki2html.php @@ -0,0 +1,52 @@ +#!/usr/bin/env php +convertWiki2Html(); +timeout=0 +cid=1 + +- 转换文档模板6 @文档模板6
+- 转换文档模板7 @文档模板7
+- 转换文档模板8 @文档模板8
+- 转换文档模板9 @文档模板9
+- 转换文档模板10 @文档模板10
+ +*/ + +include dirname(__FILE__, 5) . '/test/lib/init.php'; +include dirname(__FILE__, 2) . '/lib/upgrade.unittest.class.php'; + +zenData('user')->loadYaml('user')->gen(5); +su('admin'); + +$doc = zenData('doc'); +$doc->id->range('1-10'); +$doc->title->range('文档模板1,文档模板2,文档模板3,文档模板4,文档模板5,文档模板6,文档模板7,文档模板8,文档模板9,文档模板10'); +$doc->module->range(''); +$doc->lib->range(''); +$doc->version->range('1'); +$doc->type->range('book{5},html{5}'); +$doc->templateType->range('1{5},``{5}'); +$doc->chapterType->range('``{5},input{5}'); +$doc->template->range('``{5},1,2,3,4,5'); +$doc->parent->range('0{5},1{5}'); +$doc->gen(10); + +$docContent = zenData('doccontent'); +$docContent->id->range('1-10'); +$docContent->doc->range('1-10'); +$docContent->type->range('html'); +$docContent->title->range('文档模板1,文档模板2,文档模板3,文档模板4,文档模板5,文档模板6,文档模板7,文档模板8,文档模板9,文档模板10'); +$docContent->version->range('1'); +$docContent->gen(10); + +global $tester; +$upgrade = $tester->loadModel('upgrade'); +r($upgrade->convertWiki2Html(1, 6)) && p() && e('文档模板6
'); // 转换文档模板6 +r($upgrade->convertWiki2Html(1, 7)) && p() && e('文档模板7
'); // 转换文档模板7 +r($upgrade->convertWiki2Html(1, 8)) && p() && e('文档模板8
'); // 转换文档模板8 +r($upgrade->convertWiki2Html(1, 9)) && p() && e('文档模板9
'); // 转换文档模板9 +r($upgrade->convertWiki2Html(1, 10)) && p() && e('文档模板10
'); // 转换文档模板10 diff --git a/module/upgrade/test/model/fixworkflownameforexecution.php b/module/upgrade/test/model/fixworkflownameforexecution.php new file mode 100644 index 0000000000..8089686ff2 --- /dev/null +++ b/module/upgrade/test/model/fixworkflownameforexecution.php @@ -0,0 +1,44 @@ +#!/usr/bin/env php +fixWorkflowNameForExecution(); +cid=1 + +- 更新执行列表名 @执行列表 +- 更新添加执行名 @添加迭代 +- 更新删除迭代名 @删除迭代 +- 更新设置迭代名 @设置迭代 +- 更新执行概况名 @执行概况 +- 更新编辑名 @编辑 + +**/ + +include dirname(__FILE__, 5) . '/test/lib/init.php'; +include dirname(__FILE__, 2) . '/lib/upgrade.unittest.class.php'; + +$upgrade = new upgradeTest(); + +$workflowaction = zenData('workflowaction'); +$workflowaction->id->range('1-10'); +$workflowaction->module->range('execution'); +$workflowaction->action->range('all,create,delete,edit,view,batchedit'); +$workflowaction->method->range('browse,create,delete,edit,view,batchoperate'); +$workflowaction->type->range('single'); +$workflowaction->batchMode->range('different'); +$workflowaction->position->range('view'); +$workflowaction->show->range('direct'); +$workflowaction->order->range('0'); +$workflowaction->buildin->range('1'); +$workflowaction->createdDate->range('`2025-06-11 10:00:00`'); +$workflowaction->editedDate->range('`2025-06-11 10:30:00`'); +$workflowaction->gen(6); + +r($upgrade->fixWorkflowNameForExecutionTest('all')) && p('') && e('执行列表'); //更新执行列表名 +r($upgrade->fixWorkflowNameForExecutionTest('create')) && p('') && e('添加迭代'); //更新添加执行名 +r($upgrade->fixWorkflowNameForExecutionTest('delete')) && p('') && e('删除迭代'); //更新删除迭代名 +r($upgrade->fixWorkflowNameForExecutionTest('edit')) && p('') && e('设置迭代'); //更新设置迭代名 +r($upgrade->fixWorkflowNameForExecutionTest('view')) && p('') && e('执行概况'); //更新执行概况名 +r($upgrade->fixWorkflowNameForExecutionTest('batchedit')) && p('') && e('编辑'); //更新编辑名 diff --git a/module/upgrade/test/model/gettemplateblock.php b/module/upgrade/test/model/gettemplateblock.php new file mode 100644 index 0000000000..ef70f82df4 --- /dev/null +++ b/module/upgrade/test/model/gettemplateblock.php @@ -0,0 +1,53 @@ +#!/usr/bin/env php +getTemplateBlock(); +timeout=0 +cid=1 + +- 获取概要设计区块名称属性blockTitle @全部的概要设计 +- 获取详细设计区块名称属性blockTitle @全部的详细设计 +- 获取数据库设计区块名称属性blockTitle @全部的数据库设计 +- 获取接口设计区块名称属性blockTitle @全部的接口设计 +- 获取项目用例区块名称属性blockTitle @全部的项目用例 + +*/ + +include dirname(__FILE__, 5) . '/test/lib/init.php'; +include dirname(__FILE__, 2) . '/lib/upgrade.unittest.class.php'; + +zenData('user')->loadYaml('user')->gen(5); +su('admin'); + +$doc = zenData('doc'); +$doc->id->range('1-10'); +$doc->title->range('文档模板1,文档模板2,文档模板3,文档模板4,文档模板5,文档模板6,文档模板7,文档模板8,文档模板9,文档模板10'); +$doc->module->range(''); +$doc->lib->range(''); +$doc->version->range('1'); +$doc->type->range('book{5},html{5}'); +$doc->templateType->range('HLDS,DDS,DBDS,ADS,ITTC,``{5}'); +$doc->chapterType->range('``{5},input{5}'); +$doc->template->range('``{5},1,2,3,4,5'); +$doc->parent->range('0{5},1{5}'); +$doc->gen(10); + +$docContent = zenData('doccontent'); +$docContent->id->range('1-10'); +$docContent->doc->range('1-10'); +$docContent->type->range('html'); +$docContent->title->range('文档模板1,文档模板2,文档模板3,文档模板4,文档模板5,文档模板6,文档模板7,文档模板8,文档模板9,文档模板10'); +$docContent->version->range('1'); +$docContent->gen(10); + +global $tester; +$upgrade = $tester->loadModel('upgrade'); +$upgrade->loadModel('doc'); +r($upgrade->getTemplateBlock(1)) && p('blockTitle') && e('全部的概要设计'); // 获取概要设计区块名称 +r($upgrade->getTemplateBlock(2)) && p('blockTitle') && e('全部的详细设计'); // 获取详细设计区块名称 +r($upgrade->getTemplateBlock(3)) && p('blockTitle') && e('全部的数据库设计'); // 获取数据库设计区块名称 +r($upgrade->getTemplateBlock(4)) && p('blockTitle') && e('全部的接口设计'); // 获取接口设计区块名称 +r($upgrade->getTemplateBlock(5)) && p('blockTitle') && e('全部的项目用例'); // 获取项目用例区块名称 diff --git a/module/user/test/lib/batchedituser.ui.class.php b/module/user/test/lib/batchedituser.ui.class.php index 9efd1d1f7c..a9d4862985 100755 --- a/module/user/test/lib/batchedituser.ui.class.php +++ b/module/user/test/lib/batchedituser.ui.class.php @@ -21,7 +21,7 @@ class batchEditUserTester extends tester $form->dom->realname->setValue($user->realname); $form->dom->verifyPassword->setValue($user->verifyPassword); $form->wait(1); - $form->dom->getElement('//*[@id="zin_user_batchedit_formBatch"]/div[3]/button[1]')->click(); + $form->dom->savebtn->click(); $form->wait(1); return $this->success('保存成功'); @@ -46,7 +46,7 @@ class batchEditUserTester extends tester $form->dom->realname->setValue($user->realname); $form->dom->verifyPassword->setValue($user->verifyPassword); $form->wait(1); - $form->dom->btn($this->lang->save)->click(); + $form->dom->savebtn->click(); $form->wait(1); return $this->failed('姓名不能为空'); @@ -71,7 +71,7 @@ class batchEditUserTester extends tester $form->dom->realname->setValue($user->realname); $form->dom->verifyPassword->setValue($user->verifyPassword); $form->wait(1); - $form->dom->btn($this->lang->save)->click(); + $form->dom->savebtn->click(); $form->wait(1); return $this->failed('验证失败,请检查您的系统登录密码是否正确'); } diff --git a/module/user/test/ui/page/batchedit.php b/module/user/test/ui/page/batchedit.php index e7e03895ee..77c835343a 100755 --- a/module/user/test/ui/page/batchedit.php +++ b/module/user/test/ui/page/batchedit.php @@ -7,6 +7,7 @@ class batchEditPage extends page $xpath = array( 'realname' => "//*[@id='realname_0']", 'passwordfield' => "//*[@id='passwordfield_0']", + 'savebtn' => "//*[@id='zin_user_batchedit_formBatch']/div[3]/button[1]", ); $this->dom->xpath = array_merge($this->dom->xpath, $xpath); } diff --git a/www/js/zui3/zen-editor/p-b74f15a0.entry.js b/www/js/zui3/zen-editor/p-ca2d167a.entry.js similarity index 69% rename from www/js/zui3/zen-editor/p-b74f15a0.entry.js rename to www/js/zui3/zen-editor/p-ca2d167a.entry.js index 9220cf61c3..8793e00982 100644 --- a/www/js/zui3/zen-editor/p-b74f15a0.entry.js +++ b/www/js/zui3/zen-editor/p-ca2d167a.entry.js @@ -1 +1 @@ -export{M as monaco_editor,Z as zen_editor}from"./p-aa688caf.js";import{r as e,h as t,g as A,c as n,F as i}from"./p-7900c24a.js";import{P as r,a as o,E as s,i as E,b as B,p as c,t as a,M as g,m as l,g as Q,c as h,d as u,e as w,N as R,w as I,f as d,h as k,T as G,D as C,j as f,k as D,l as F,n as Y,o as m,q as U,r as S,s as N,S as b,u as y,v as p,x as T,F as H,y as x,z,A as J,B as j,C as v,G as P,H as L,I as V,J as O,K as _,L as K,O as W,Q as X,R as q}from"./p-fda4ec51.js";import{L as $}from"./p-986e5fe7.js";class ee{constructor({editor:e,element:t,view:A,tippyOptions:n={},updateDelay:i=250,shouldShow:r}){this.preventHide=!1,this.shouldShow=({view:e,state:t,from:A,to:n})=>{const{doc:i,selection:r}=t,{empty:o}=r,s=!i.textBetween(A,n).length&&E(t.selection),B=this.element.contains(document.activeElement);return!(!e.hasFocus()&&!B||o||s||!this.editor.isEditable)},this.mousedownHandler=()=>{this.preventHide=!0},this.dragstartHandler=()=>{this.hide()},this.focusHandler=()=>{setTimeout((()=>this.update(this.editor.view)))},this.blurHandler=({event:e})=>{var t;this.preventHide?this.preventHide=!1:(null==e?void 0:e.relatedTarget)&&(null===(t=this.element.parentNode)||void 0===t?void 0:t.contains(e.relatedTarget))||this.hide()},this.tippyBlurHandler=e=>{this.blurHandler({event:e})},this.handleDebouncedUpdate=(e,t)=>{const A=!(null==t?void 0:t.selection.eq(e.state.selection)),n=!(null==t?void 0:t.doc.eq(e.state.doc));(A||n)&&(this.updateDebounceTimer&&clearTimeout(this.updateDebounceTimer),this.updateDebounceTimer=window.setTimeout((()=>{this.updateHandler(e,A,n,t)}),this.updateDelay))},this.updateHandler=(e,t,A,n)=>{var i,r,o;const{state:s,composing:E}=e,{selection:a}=s;if(E||!t&&!A)return;this.createTooltip();const{ranges:g}=a,l=Math.min(...g.map((e=>e.$from.pos))),Q=Math.max(...g.map((e=>e.$to.pos)));(null===(i=this.shouldShow)||void 0===i?void 0:i.call(this,{editor:this.editor,view:e,state:s,oldState:n,from:l,to:Q}))?(null===(r=this.tippy)||void 0===r||r.setProps({getReferenceClientRect:(null===(o=this.tippyOptions)||void 0===o?void 0:o.getReferenceClientRect)||(()=>{if(B(s.selection)){let t=e.nodeDOM(l);const A=t.dataset.nodeViewWrapper?t:t.querySelector("[data-node-view-wrapper]");if(A&&(t=A.firstChild),t)return t.getBoundingClientRect()}return c(e,l,Q)})}),this.show()):this.hide()},this.editor=e,this.element=t,this.view=A,this.updateDelay=i,r&&(this.shouldShow=r),this.element.addEventListener("mousedown",this.mousedownHandler,{capture:!0}),this.view.dom.addEventListener("dragstart",this.dragstartHandler),this.editor.on("focus",this.focusHandler),this.editor.on("blur",this.blurHandler),this.tippyOptions=n,this.element.remove(),this.element.style.visibility="visible"}createTooltip(){const{element:e}=this.editor.options;!this.tippy&&e.parentElement&&(this.tippy=a(e,{duration:0,getReferenceClientRect:null,content:this.element,interactive:!0,trigger:"manual",placement:"top",hideOnClick:"toggle",...this.tippyOptions}),this.tippy.popper.firstChild&&this.tippy.popper.firstChild.addEventListener("blur",this.tippyBlurHandler))}update(e,t){const{state:A}=e;if(this.updateDelay>0&&A.selection.$from.pos!==A.selection.$to.pos)return void this.handleDebouncedUpdate(e,t);const n=!(null==t?void 0:t.selection.eq(e.state.selection)),i=!(null==t?void 0:t.doc.eq(e.state.doc));this.updateHandler(e,n,i,t)}show(){var e;null===(e=this.tippy)||void 0===e||e.show()}hide(){var e;null===(e=this.tippy)||void 0===e||e.hide()}destroy(){var e,t;(null===(e=this.tippy)||void 0===e?void 0:e.popper.firstChild)&&this.tippy.popper.firstChild.removeEventListener("blur",this.tippyBlurHandler),null===(t=this.tippy)||void 0===t||t.destroy(),this.element.removeEventListener("mousedown",this.mousedownHandler,{capture:!0}),this.view.dom.removeEventListener("dragstart",this.dragstartHandler),this.editor.off("focus",this.focusHandler),this.editor.off("blur",this.blurHandler)}}const te=e=>new r({key:"string"==typeof e.pluginKey?new o(e.pluginKey):e.pluginKey,view:t=>new ee({view:t,...e})}),Ae=s.create({name:"bubbleMenu",addOptions:()=>({element:null,tippyOptions:{},pluginKey:"bubbleMenu",updateDelay:void 0,shouldShow:null}),addProseMirrorPlugins(){return this.options.element?[te({pluginKey:this.options.pluginKey,editor:this.editor,element:this.options.element,tippyOptions:this.options.tippyOptions,updateDelay:this.options.updateDelay,shouldShow:this.options.shouldShow})]:[]}}),ne=g.create({name:"textStyle",addOptions:()=>({HTMLAttributes:{}}),parseHTML:()=>[{tag:"span",getAttrs:e=>!!e.hasAttribute("style")&&{}}],renderHTML({HTMLAttributes:e}){return["span",l(this.options.HTMLAttributes,e),0]},addCommands(){return{removeEmptyTextStyle:()=>({state:e,commands:t})=>{const A=Q(e,this.type);return!!Object.entries(A).some((([,e])=>!!e))||t.unsetMark(this.name)}}}}),ie=[9,13,16,20,24,36,48],re=s.create({name:"fontSize",addOptions:()=>({types:["textStyle"]}),addGlobalAttributes(){return[{types:this.options.types,attributes:{fontSize:{default:null,parseHTML:e=>{var t;return parseInt(null===(t=e.style.fontSize)||void 0===t?void 0:t.replace(/px$/,""))},renderHTML:e=>e.fontSize?{style:`font-size: ${e.fontSize}px`}:{}}}}]},addCommands:()=>({setFontSize:e=>({chain:t})=>t().setMark("textStyle",{fontSize:e}).run(),unsetFontSize:()=>({chain:e})=>e().setMark("textStyle",{fontSize:null}).removeEmptyTextStyle().run(),scaleFontSize:(e="upscale")=>({state:t})=>{const{doc:A,selection:n}=t,{from:i,to:r}=n;return A.slice(i,r).content.descendants(((A,n)=>{var r;if(A.isText){const o=(null===(r=A.marks.find((e=>"textStyle"===e.type.name)))||void 0===r?void 0:r.attrs.fontSize)||13,s=ie.reduce(((e,t)=>Math.abs(t-o)