Merge branch 'release/21.7.5' into feature/workflowgroup
This commit is contained in:
@@ -6,13 +6,13 @@
|
||||
},
|
||||
"zentaoext": {
|
||||
"gitRepo": "zentao/zentaoext",
|
||||
"gitVersion": "release/12.3"
|
||||
"gitVersion": "release/12.4"
|
||||
},
|
||||
"zentaomax": {
|
||||
"gitVersion": "release/7.3"
|
||||
"gitVersion": "release/7.4"
|
||||
},
|
||||
"zentaoipd": {
|
||||
"gitVersion": "release/4.3"
|
||||
"gitVersion": "release/4.4"
|
||||
},
|
||||
"devops": {
|
||||
"gitRepo": "zentao/devops"
|
||||
@@ -43,7 +43,7 @@
|
||||
}
|
||||
},
|
||||
"downgrade": {
|
||||
"versions": "8.1,7.2,7.1,7.0"
|
||||
"versions": "8.4,8.1,7.2,7.1,7.0"
|
||||
},
|
||||
"upload": {
|
||||
"bucket": "download",
|
||||
|
||||
+7
-17
@@ -16,6 +16,11 @@ ALTER TABLE `zt_bug`
|
||||
CHANGE `injection` `injection` varchar(30) NOT NULL DEFAULT '',
|
||||
CHANGE `identify` `identify` varchar(30) NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE `zt_task` MODIFY `path` varchar(255) NOT NULL DEFAULT '';
|
||||
|
||||
CREATE INDEX `parent` ON `zt_story` (`parent`);
|
||||
CREATE INDEX `path` ON `zt_task` (`path`);
|
||||
|
||||
UPDATE `zt_project` SET `workflowGroup` = (SELECT `id` FROM `zt_workflowgroup` WHERE `code` = 'kanbanproduct' AND `main` = '1' LIMIT 1) WHERE `type` = 'project' AND `model` = 'kanban' AND `hasProduct` = '1';
|
||||
UPDATE `zt_project` SET `workflowGroup` = (SELECT `id` FROM `zt_workflowgroup` WHERE `code` = 'kanbanproject' AND `main` = '1' LIMIT 1) WHERE `type` = 'project' AND `model` = 'kanban' AND `hasProduct` = '0';
|
||||
|
||||
@@ -70,20 +75,5 @@ WHERE `bug`.`identify` != 0 AND `object`.`category` NOT IN ('HLDS', 'DDS', 'DBDS
|
||||
UPDATE `zt_bug` SET `injection` = '' WHERE `injection` = '0';
|
||||
UPDATE `zt_bug` SET `identify` = '' WHERE `identify` = '0';
|
||||
|
||||
ALTER TABLE `zt_doc` ADD `isDeliverable` tinyint(1) NOT NULL DEFAULT 0 AFTER `acl`;
|
||||
ALTER TABLE `zt_deliverable` ADD `workflowGroup` int(8) NOT NULL DEFAULT '0' AFTER `id`;
|
||||
ALTER TABLE `zt_deliverable` ADD `activity` int(8) unsigned NOT NULL DEFAULT '0' AFTER `name`;
|
||||
ALTER TABLE `zt_deliverable` ADD `trimmable` char(30) NOT NULL DEFAULT '0' AFTER `activity`;
|
||||
ALTER TABLE `zt_deliverable` ADD `trimRule` varchar(255) NOT NULL AFTER `trimmable`;
|
||||
ALTER TABLE `zt_deliverable` ADD `template` text NOT NULL AFTER `trimRule`;
|
||||
ALTER TABLE `zt_deliverable` ADD `status` varchar(30) NOT NULL DEFAULT 'enabled' AFTER `name`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `zt_deliverablestage` (
|
||||
`id` int(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`deliverable` int(8) unsigned NOT NULL DEFAULT 0,
|
||||
`stage` varchar(30) NOT NULL,
|
||||
`required` varchar(30) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
CREATE UNIQUE INDEX `unique` ON `zt_deliverablestage`(`deliverable`,`stage`);
|
||||
ALTER TABLE `zt_module` ADD `extra` varchar(30) NOT NULL DEFAULT '';
|
||||
INSERT INTO `zt_workflowaction` (`group`, `module`, `action`, `method`, `name`, `type`, `batchMode`, `extensionType`, `open`, `position`, `layout`, `show`, `order`, `buildin`, `role`, `virtual`, `conditions`, `verifications`, `hooks`, `linkages`, `js`, `css`, `toList`, `blocks`, `desc`, `status`, `vision`, `createdBy`, `createdDate`, `editedBy`, `editedDate`) VALUES
|
||||
(0, 'project', 'execution', 'browse', '执行列表', 'single', 'different', 'none', 'normal', 'browse', 'normal', 'direct', 0, 1, 'buildin', 0, NULL, NULL, NULL, NULL, NULL, NULL, '', NULL, NULL, 'enable', 'rnd', 'admin', '2025-01-08 09:41:02', '', NULL);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
ALTER TABLE `zt_doc` ADD `isDeliverable` tinyint(1) NOT NULL DEFAULT 0 AFTER `acl`;
|
||||
ALTER TABLE `zt_deliverable` ADD `workflowGroup` int(8) NOT NULL DEFAULT '0' AFTER `id`;
|
||||
ALTER TABLE `zt_deliverable` ADD `activity` int(8) unsigned NOT NULL DEFAULT '0' AFTER `name`;
|
||||
ALTER TABLE `zt_deliverable` ADD `trimmable` char(30) NOT NULL DEFAULT '0' AFTER `activity`;
|
||||
ALTER TABLE `zt_deliverable` ADD `trimRule` varchar(255) NOT NULL AFTER `trimmable`;
|
||||
ALTER TABLE `zt_deliverable` ADD `template` text NOT NULL AFTER `trimRule`;
|
||||
ALTER TABLE `zt_deliverable` ADD `status` varchar(30) NOT NULL DEFAULT 'enabled' AFTER `name`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `zt_deliverablestage` (
|
||||
`id` int(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`deliverable` int(8) unsigned NOT NULL DEFAULT 0,
|
||||
`stage` varchar(30) NOT NULL,
|
||||
`required` varchar(30) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
CREATE UNIQUE INDEX `unique` ON `zt_deliverablestage`(`deliverable`,`stage`);
|
||||
ALTER TABLE `zt_module` ADD `extra` varchar(30) NOT NULL DEFAULT '';
|
||||
+3
-1
@@ -2019,6 +2019,7 @@ CREATE TABLE IF NOT EXISTS `zt_story` (
|
||||
`deleted` enum('0','1') NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
CREATE INDEX `parent` ON `zt_story` (`parent`);
|
||||
CREATE INDEX `product` ON `zt_story` (`product`);
|
||||
CREATE INDEX `root` ON `zt_story` (`root`);
|
||||
CREATE INDEX `status` ON `zt_story` (`status`);
|
||||
@@ -2092,7 +2093,7 @@ CREATE TABLE IF NOT EXISTS `zt_task` (
|
||||
`parent` mediumint(8) NOT NULL DEFAULT '0',
|
||||
`isParent` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`isTpl` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
||||
`path` text NULL,
|
||||
`path` varchar(255) NOT NULL DEFAULT '',
|
||||
`execution` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
`module` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
`design` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
@@ -2152,6 +2153,7 @@ CREATE TABLE IF NOT EXISTS `zt_task` (
|
||||
CREATE INDEX `execution` ON `zt_task` (`execution`);
|
||||
CREATE INDEX `story` ON `zt_task` (`story`);
|
||||
CREATE INDEX `parent` ON `zt_task` (`parent`);
|
||||
CREATE INDEX `path` ON `zt_task` (`path`);
|
||||
CREATE INDEX `assignedTo` ON `zt_task` (`assignedTo`);
|
||||
CREATE INDEX `order` ON `zt_task` (`order`);
|
||||
|
||||
|
||||
@@ -812,11 +812,19 @@ function getVisions(): array
|
||||
/**
|
||||
* Save debug log to the php log file which prefix with 'debug.<today>'.
|
||||
*
|
||||
* @param mixed $message
|
||||
* @param mixed ...$messages
|
||||
* @return void
|
||||
*/
|
||||
function debug($message = ''): void
|
||||
function debug(mixed ...$messages): void
|
||||
{
|
||||
if(count($messages) > 1)
|
||||
{
|
||||
foreach($messages as $message) debug($message);
|
||||
return;
|
||||
}
|
||||
|
||||
$message = current($messages);
|
||||
|
||||
static $times = [];
|
||||
$time = microtime(true);
|
||||
$duration = $times ? $time - end($times) : 0;
|
||||
|
||||
@@ -899,7 +899,7 @@ class baseDAO
|
||||
{
|
||||
$alias = preg_match("/`$table`\s+as\s+(\w+)/i", $sql, $matches) ? $matches[1] : '';
|
||||
|
||||
$replace = $alias ? "wHeRe ($alias.`isTpl` = '0' OR $alias.`isTpl` IS NULL) AND" : "wHeRe (`isTpl` = '0' OR `isTpl` IS NULL) AND";
|
||||
$replace = $alias ? "wHeRe ($alias.`isTpl` = '0' OR $alias.`isTpl` IS NULL) AND" : "wHeRe `isTpl` = '0' AND";
|
||||
$sql = preg_replace("/wHeRE/i", $replace, $sql, 1);
|
||||
}
|
||||
else
|
||||
@@ -912,7 +912,7 @@ class baseDAO
|
||||
if(strpos($sql, "`$table`") !== false)
|
||||
{
|
||||
$alias = preg_match("/`$table`\s+as\s+(\w+)/i", $sql, $mainMatches) ? $mainMatches[1] : '';
|
||||
$replace = $alias ? "wHeRe ($alias.`isTpl` = '0' OR $alias.`isTpl` IS NULL) AND" : "wHeRe (`isTpl` = '0' OR `isTpl` IS NULL) AND";
|
||||
$replace = $alias ? "wHeRe ($alias.`isTpl` = '0' OR $alias.`isTpl` IS NULL) AND" : "wHeRe `isTpl` = '0' AND";
|
||||
$sql = preg_replace("/wHeRE/i", $replace, $sql, 1);
|
||||
}
|
||||
|
||||
@@ -921,7 +921,7 @@ class baseDAO
|
||||
if(strpos($sql, "`$table`") !== false && !preg_match("/`isTpl`\s*=\s*('1'|1)/", $subSQL))
|
||||
{
|
||||
$alias = preg_match("/`$table`\s+as\s+(\w+)/i", $subSQL, $subMatches) ? $subMatches[1] : '';
|
||||
$replace = $alias ? "wHeRe ($alias.`isTpl` = '0' OR $alias.`isTpl` IS NULL) AND" : "wHeRe (`isTpl` = '0' OR `isTpl` IS NULL) AND";
|
||||
$replace = $alias ? "wHeRe ($alias.`isTpl` = '0' OR $alias.`isTpl` IS NULL) AND" : "wHeRe `isTpl` = '0' AND";
|
||||
$subSQL = preg_replace("/wHeRE/i", $replace, $subSQL, 1);
|
||||
}
|
||||
$sql = str_ireplace("$$index", $subSQL, $sql);
|
||||
|
||||
@@ -44,11 +44,11 @@ class backBtn extends btn
|
||||
|
||||
$backs = array(
|
||||
'task' => 'execution-task,my-work,my-contribute,execution-tree,execution-grouptask,project-execution,product-track,repo-view,story-change,execution-kanban,execution-taskkanban,my-index,feedback-adminview,projectstory-track,execution-calendar,my-effort,company-effort,company-calendar,product-dynamic,project-dynamic,execution-dynamic,project-view,execution-view,task-view',
|
||||
'story' => 'product-browse,projectstory-story,execution-story,my-work,my-contribute,productplan-view,build-view,projectbuild-view,product-track,repo-view,testcase-zerocase,my-index,feedback-adminview,projectstory-track,task-view,my-effort,company-effort,company-calendar,demandpool-track,product-dynamic,project-dynamic,execution-dynamic,project-view,execution-view,ticket-browse,ticket-view,roadmap-view,charter-view,demand-view,review-assess,review-audit,action-trash',
|
||||
'story' => 'product-browse,projectstory-story,execution-story,my-work,my-contribute,productplan-view,build-view,projectbuild-view,product-track,repo-view,testcase-zerocase,my-index,feedback-adminview,projectstory-track,task-view,my-effort,company-effort,company-calendar,demandpool-track,product-dynamic,project-dynamic,execution-dynamic,project-view,execution-view,ticket-browse,ticket-view,roadmap-view,charter-view,demand-view,review-assess,review-audit,action-trash,execution-task,testcase-browse',
|
||||
'bug' => 'bug-browse,project-bug,my-work,my-contribute,execution-bug,bug-view,qa-index,execution-task,product-track,execution-task,task-view,repo-view,story-change,repo-review,feedback-adminview,my-index,projectstory-track,my-effort,company-effort,company-calendar,product-dynamic,project-dynamic,execution-dynamic,project-view,execution-view,ticket-browse,ticket-view,productplan-view',
|
||||
'testcase' => 'testcase-browse,testcase-browseScene,project-testcase,my-work,my-contribute,execution-testcase,testtask-cases,testsuite-view,product-browse,testcase-view,qa-index,caselib-browse,product-track,story-change,my-index,projectstory-track,my-effort,company-effort,company-calendar,product-dynamic,project-dynamic,execution-dynamic,project-view,execution-view,testreport-view,bug-browse,project-bug,bug-view',
|
||||
'testsuite' => 'testsuite-browse,testsuite-view,testtask-cases,my-index,product-dynamic,project-dynamic,execution-dynamic,project-view,execution-view',
|
||||
'testtask' => 'testtask-browse,testtask-cases,qa-index,testcase-browse,execution-build,my-index,my-effort,company-effort,company-calendar,product-dynamic,project-dynamic,execution-dynamic,project-view,execution-view,project-testcase',
|
||||
'testtask' => 'testtask-browse,testtask-cases,qa-index,testcase-browse,execution-build,my-index,my-effort,company-effort,company-calendar,product-dynamic,project-dynamic,execution-dynamic,project-view,execution-view,project-testcase,project-testtask,execution-testtask',
|
||||
'testreport' => 'testreport-browse,project-testreport,execution-testreport,execution-testtask',
|
||||
'tree' => 'product-browse,project-browse,execution-task,bug-browse,projectstory-story,host-browse,execution-story,feedback-admin,ticket-browse,testcase-browse,caselib-browse,dataview-browse,deliverable-browse',
|
||||
'doc' => 'doc-mySpace,doc-productSpace,doc-projectSpace,doc-teamSpace,doc-view,execution-doc',
|
||||
|
||||
@@ -644,6 +644,7 @@ function handleSaveDoc(doc)
|
||||
space : spaceType,
|
||||
uid : (doc.uid || `doc${doc.id}`),
|
||||
};
|
||||
if(Array.isArray(doc.files)) docData.files = doc.files.map(f => typeof f === 'object' ? f.id : f).join(',');
|
||||
if(doc.fromVersion) docData.fromVersion = doc.fromVersion;
|
||||
|
||||
if(savingDocData[doc.id])
|
||||
|
||||
@@ -695,20 +695,18 @@ function initGantt()
|
||||
/* 添加关联关系前的校验。 */
|
||||
gantt.attachEvent("onBeforeLinkAdd", function(id, link)
|
||||
{
|
||||
const source = link.source;
|
||||
const target = link.target;
|
||||
if(source.indexOf('-') === -1 || target.indexOf('-') === -1)
|
||||
const sourceTask = gantt.getTask(link.source);
|
||||
const targetTask = gantt.getTask(link.target);
|
||||
if(sourceTask.type != 'task' || targetTask.type != 'task')
|
||||
{
|
||||
let message = ganttLang.wrongRelation;
|
||||
if(source.indexOf('-') === -1) message += ganttLang.wrongRelationSource;
|
||||
if(target.indexOf('-') === -1) message += ganttLang.wrongRelationTarget;
|
||||
if(sourceTask.type != 'task') message += ganttLang.wrongRelationSource;
|
||||
if(targetTask.type != 'task') message += ganttLang.wrongRelationTarget;
|
||||
zui.Messager.show({content: message, type: 'danger-outline', icon: 'exclamation-sign'});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const sourceTask = gantt.getTask(link.source);
|
||||
const targetTask = gantt.getTask(link.target);
|
||||
if(sourceTask.allowLinks === false || targetTask.allowLinks === false)
|
||||
{
|
||||
zui.Messager.show({content: ganttLang.wrongKanbanTasks, type: 'danger-outline', icon: 'exclamation-sign'});
|
||||
|
||||
@@ -73,7 +73,6 @@ $lang->admin->menuList->feature['subMenu']['project'] = array('link' => "{$l
|
||||
$lang->admin->menuList->feature['subMenu']['execution'] = array('link' => "{$lang->execution->common}|custom|required|module=execution", 'exclude' => 'required,set', 'alias' => 'execution,limittaskdate', 'subModule' => 'stage');
|
||||
$lang->admin->menuList->feature['subMenu']['qa'] = array('link' => "{$lang->qa->common}|custom|required|module=bug", 'exclude' => 'set,required');
|
||||
$lang->admin->menuList->feature['subMenu']['kanban'] = array('link' => "{$lang->kanban->common}|custom|kanban|");
|
||||
$lang->admin->menuList->feature['subMenu']['doc'] = array('link' => "{$lang->doc->common}|custom|required|module=doc", 'exclude' => 'required');
|
||||
$lang->admin->menuList->feature['subMenu']['user'] = array('link' => "{$lang->user->common}|custom|required|module=user", 'links' => array('custom|set|module=user&field=roleList'), 'exclude' => 'set,required');
|
||||
|
||||
$lang->admin->menuList->feature['tabMenu']['my']['todo'] = array('link' => "{$lang->todo->common}|custom|set|module=todo&field=priList", 'exclude' => 'custom-set');
|
||||
|
||||
@@ -793,7 +793,7 @@ $lang->navGroup->featureconfig = 'admin';
|
||||
$lang->navGroup->doctemplate = 'admin';
|
||||
$lang->navGroup->notifysetting = 'admin';
|
||||
$lang->navGroup->holidayseason = 'admin';
|
||||
$lang->navGroup->system = 'devops';
|
||||
$lang->navGroup->system = 'system';
|
||||
$lang->navGroup->serverroom = 'devops';
|
||||
$lang->navGroup->holiday = 'admin';
|
||||
$lang->navGroup->cache = 'admin';
|
||||
|
||||
@@ -1143,6 +1143,7 @@ class commonModel extends model
|
||||
if(empty($maintenance)) return true;
|
||||
|
||||
$maintenance = json_decode($maintenance);
|
||||
if($this->app->moduleName == 'user' && $this->app->methodName == 'login') return true;
|
||||
if(!empty($this->app->user->admin)) return true;
|
||||
|
||||
if(isset($maintenance->action) && in_array($maintenance->action, array('upgrade', 'downgrade', 'restore'))) helper::setStatus(503);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(__FILE__, 5) . '/test/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 commonModel::checkMaintenance();
|
||||
timeout=0
|
||||
cid=1
|
||||
|
||||
- 检查是否处于维护状态 @0
|
||||
- 检查是否处于维护状态 @0
|
||||
- 检查是否处于维护状态 @0
|
||||
- 检查是否处于维护状态 @0
|
||||
- 检查是否处于维护状态 @0
|
||||
|
||||
*/
|
||||
|
||||
global $tester;
|
||||
$tester->loadModel('common');
|
||||
|
||||
$app->moduleName = 'user';
|
||||
$app->methodName = 'login';
|
||||
r($tester->common->checkMaintenance()) && p() && e('1'); // 检查是否处于维护状态
|
||||
|
||||
$app->moduleName = 'execution';
|
||||
$app->methodName = 'task';
|
||||
r($tester->common->checkMaintenance()) && p() && e('1'); // 检查是否处于维护状态
|
||||
|
||||
$app->moduleName = 'program';
|
||||
$app->methodName = 'view';
|
||||
r($tester->common->checkMaintenance()) && p() && e('1'); // 检查是否处于维护状态
|
||||
|
||||
$app->moduleName = 'bug';
|
||||
$app->methodName = 'view';
|
||||
r($tester->common->checkMaintenance()) && p() && e('1'); // 检查是否处于维护状态
|
||||
|
||||
$app->moduleName = 'task';
|
||||
$app->methodName = 'view';
|
||||
r($tester->common->checkMaintenance()) && p() && e('1'); // 检查是否处于维护状态
|
||||
@@ -51,41 +51,3 @@ window.changeUnit = function()
|
||||
$defaultCurrencyPicker.render({items: defaultCurrencyItems});
|
||||
$defaultCurrencyPicker.$.setValue(defaultCurrency);
|
||||
}
|
||||
|
||||
window.savaTestcaseReview = function()
|
||||
{
|
||||
const url = $("#settingForm").attr('action');
|
||||
const form = new FormData($("#settingForm")[0]);
|
||||
if(stopSubmit && oldNeedReview)
|
||||
{
|
||||
stopSubmit = false;
|
||||
|
||||
const needReview = $('input[name="needReview"]:checked').val();
|
||||
if(needReview == 0)
|
||||
{
|
||||
$.ajaxSubmit({
|
||||
url: $.createLink('testcase', 'ajaxGetReviewAmount'),
|
||||
onComplete: function(count)
|
||||
{
|
||||
stopSubmit = true;
|
||||
|
||||
if(count == 0)
|
||||
{
|
||||
$.ajaxSubmit({url, data:form});
|
||||
return true;
|
||||
}
|
||||
|
||||
zui.Modal.confirm(confirmReviewCase).then((result) =>
|
||||
{
|
||||
if(result) form.append('reviewCase', '1');
|
||||
$.ajaxSubmit({url, data:form});
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$.ajaxSubmit({url, data:form});
|
||||
}
|
||||
|
||||
@@ -274,12 +274,6 @@ elseif(in_array($module, array('epic', 'story', 'requirement', 'demand', 'testca
|
||||
);
|
||||
|
||||
$actionWidth = 'w-2/3';
|
||||
$formActions = array(array(
|
||||
'text' => $lang->save,
|
||||
'type' => 'primary',
|
||||
'btnType' => 'button',
|
||||
'onclick' => 'savaTestcaseReview()'
|
||||
));
|
||||
}
|
||||
}
|
||||
elseif($module == 'bug' && $field == 'longlife')
|
||||
|
||||
@@ -388,15 +388,6 @@ class customZen extends custom
|
||||
}
|
||||
$this->loadModel('setting')->setItems("system.testcase", $data);
|
||||
|
||||
$reviewCase = isset($data['reviewCase']) ? $data['reviewCase'] : 0;
|
||||
if($data['needReview'] == 0 && $reviewCase)
|
||||
{
|
||||
$waitProductCases = $this->loadModel('testcase')->getByStatus(0, 0, 'all', 'wait');
|
||||
$waitLibCases = $this->loadModel('caselib')->getLibCases(0, 'wait');
|
||||
$waitCaseIdList = array_merge(array_keys($waitProductCases), array_keys($waitLibCases));
|
||||
$this->testcase->batchReview($waitCaseIdList, 'pass');
|
||||
}
|
||||
|
||||
return !dao::isError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,8 @@ $config->doc->form->edit['mailto'] = array('type' => 'array', 'require
|
||||
$config->doc->form->edit['editedBy'] = array('type' => 'string', 'required' => false, 'default' => '');
|
||||
$config->doc->form->edit['editedDate'] = array('type' => 'datetime', 'required' => false, 'default' => $now);
|
||||
$config->doc->form->edit['isDeliverable'] = array('type' => 'string', 'required' => false);
|
||||
$config->doc->form->edit['fromVersion'] = array('type' => 'string', 'required' => false, 'default' => '');
|
||||
$config->doc->form->edit['files'] = array('type' => 'string', 'required' => false, 'default' => '');
|
||||
|
||||
$config->doc->form->edittemplate = $config->doc->form->edit;
|
||||
$config->doc->form->edittemplate['templateDesc'] = array('type' => 'string', 'required' => false, 'default' => '');
|
||||
|
||||
@@ -2330,6 +2330,7 @@ class doc extends control
|
||||
$data = array('spaceID' => (int)$spaceID);
|
||||
$libs = $this->doc->getLibsOfSpace($type, $spaceID);
|
||||
$libIds = array_keys($libs);
|
||||
foreach($libs as $lib) $lib->order = (int)$lib->order;
|
||||
|
||||
if($noPicks || strpos($picks, ',space,') !== false) $data['spaces'] = $spaces;
|
||||
if($noPicks || strpos($picks, ',lib,') !== false) $data['libs'] = array_values($libs);
|
||||
|
||||
@@ -1678,8 +1678,9 @@ class docModel extends model
|
||||
$docContent->doc = $docID;
|
||||
$docContent->addedBy = $docContent->editedBy;
|
||||
$docContent->addedDate = $docContent->editedDate;
|
||||
$docContent->files = implode(',', $files);
|
||||
$docContent->files = (!empty($docData->files) && is_string($docData->files)) ? (',' . $docData->files) : implode(',', $files);
|
||||
$docContent->fromVersion = isset($docData->fromVersion) ? $docData->fromVersion : max(0, ($version - 1));
|
||||
|
||||
$this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec();
|
||||
$docContent->id = $this->dao->lastInsertID();
|
||||
}
|
||||
@@ -1752,6 +1753,7 @@ class docModel extends model
|
||||
$doc->path = $path;
|
||||
}
|
||||
|
||||
unset($doc->files);
|
||||
$this->dao->update(TABLE_DOC)->data($doc, 'content,contentType,rawContent,fromVersion')
|
||||
->autoCheck()
|
||||
->batchCheck($requiredFields, 'notempty')
|
||||
|
||||
@@ -49,26 +49,27 @@ $config->execution->form->create['whitelist'] = array('type' => 'array', 'r
|
||||
$config->execution->form->create['openedVersion'] = array('type' => 'string', 'required' => false, 'control' => 'text', 'default' => $config->version);
|
||||
$config->execution->form->create['vision'] = array('type' => 'string', 'required' => false, 'control' => 'text', 'default' => $config->vision);
|
||||
|
||||
$config->execution->form->edit['project'] = array('type' => 'int', 'required' => false, 'control' => 'select', 'default' => 0);
|
||||
$config->execution->form->edit['name'] = array('type' => 'string', 'required' => true, 'control' => 'text', 'default' => '', 'filter' => 'trim');
|
||||
$config->execution->form->edit['begin'] = array('type' => 'date', 'required' => true, 'control' => 'date', 'default' => null);
|
||||
$config->execution->form->edit['end'] = array('type' => 'date', 'required' => true, 'control' => 'date', 'default' => null);
|
||||
$config->execution->form->edit['days'] = array('type' => 'int', 'required' => false, 'control' => 'text', 'default' => 0);
|
||||
$config->execution->form->edit['lifetime'] = array('type' => 'string', 'required' => false, 'control' => 'text', 'default' => '');
|
||||
$config->execution->form->edit['attribute'] = array('type' => 'string', 'required' => false, 'control' => 'text', 'default' => '');
|
||||
$config->execution->form->edit['percent'] = array('type' => 'float', 'required' => false, 'control' => 'text', 'default' => 0);
|
||||
$config->execution->form->edit['products'] = array('type' => 'array', 'required' => false, 'default' => array());
|
||||
$config->execution->form->edit['branch'] = array('type' => 'array', 'required' => false, 'default' => array());
|
||||
$config->execution->form->edit['plans'] = array('type' => 'array', 'required' => false, 'default' => array());
|
||||
$config->execution->form->edit['team'] = array('type' => 'string', 'required' => false, 'control' => 'text', 'default' => '');
|
||||
$config->execution->form->edit['status'] = array('type' => 'string', 'required' => false, 'control' => 'text', 'default' => 'wait');
|
||||
$config->execution->form->edit['PM'] = array('type' => 'string', 'required' => false, 'control' => 'select', 'default' => '');
|
||||
$config->execution->form->edit['PO'] = array('type' => 'string', 'required' => false, 'control' => 'select', 'default' => '');
|
||||
$config->execution->form->edit['QD'] = array('type' => 'string', 'required' => false, 'control' => 'select', 'default' => '');
|
||||
$config->execution->form->edit['RD'] = array('type' => 'string', 'required' => false, 'control' => 'select', 'default' => '');
|
||||
$config->execution->form->edit['desc'] = array('type' => 'string', 'required' => false, 'control' => 'editor', 'default' => '');
|
||||
$config->execution->form->edit['acl'] = array('type' => 'string', 'required' => false, 'control' => 'radio', 'default' => '');
|
||||
$config->execution->form->edit['whitelist'] = array('type' => 'array', 'required' => false, 'control' => 'select', 'default' => array(), 'filter' => 'join');
|
||||
$config->execution->form->edit['project'] = array('type' => 'int', 'required' => false, 'control' => 'select', 'default' => 0);
|
||||
$config->execution->form->edit['name'] = array('type' => 'string', 'required' => true, 'control' => 'text', 'default' => '', 'filter' => 'trim');
|
||||
$config->execution->form->edit['begin'] = array('type' => 'date', 'required' => true, 'control' => 'date', 'default' => null);
|
||||
$config->execution->form->edit['end'] = array('type' => 'date', 'required' => true, 'control' => 'date', 'default' => null);
|
||||
$config->execution->form->edit['days'] = array('type' => 'int', 'required' => false, 'control' => 'text', 'default' => 0);
|
||||
$config->execution->form->edit['lifetime'] = array('type' => 'string', 'required' => false, 'control' => 'text', 'default' => '');
|
||||
$config->execution->form->edit['attribute'] = array('type' => 'string', 'required' => false, 'control' => 'text', 'default' => '');
|
||||
$config->execution->form->edit['percent'] = array('type' => 'float', 'required' => false, 'control' => 'text', 'default' => 0);
|
||||
$config->execution->form->edit['products'] = array('type' => 'array', 'required' => false, 'default' => array());
|
||||
$config->execution->form->edit['branch'] = array('type' => 'array', 'required' => false, 'default' => array());
|
||||
$config->execution->form->edit['plans'] = array('type' => 'array', 'required' => false, 'default' => array());
|
||||
$config->execution->form->edit['team'] = array('type' => 'string', 'required' => false, 'control' => 'text', 'default' => '');
|
||||
$config->execution->form->edit['status'] = array('type' => 'string', 'required' => false, 'control' => 'text', 'default' => 'wait');
|
||||
$config->execution->form->edit['PM'] = array('type' => 'string', 'required' => false, 'control' => 'select', 'default' => '');
|
||||
$config->execution->form->edit['PO'] = array('type' => 'string', 'required' => false, 'control' => 'select', 'default' => '');
|
||||
$config->execution->form->edit['QD'] = array('type' => 'string', 'required' => false, 'control' => 'select', 'default' => '');
|
||||
$config->execution->form->edit['RD'] = array('type' => 'string', 'required' => false, 'control' => 'select', 'default' => '');
|
||||
$config->execution->form->edit['desc'] = array('type' => 'string', 'required' => false, 'control' => 'editor', 'default' => '');
|
||||
$config->execution->form->edit['acl'] = array('type' => 'string', 'required' => false, 'control' => 'radio', 'default' => '');
|
||||
$config->execution->form->edit['whitelist'] = array('type' => 'array', 'required' => false, 'control' => 'select', 'default' => array(), 'filter' => 'join');
|
||||
$config->execution->form->edit['syncStories'] = array('type' => 'string', 'required' => false, 'default' => 'no');
|
||||
if(!empty($config->setCode)) $config->execution->form->edit['code'] = array('type' => 'string', 'required' => false, 'control' => 'text', 'default' => '', 'filter' => 'trim');
|
||||
|
||||
$config->execution->form->importBug['id'] = array('type' => 'int', 'required' => false, 'default' => 0, 'base' => true);
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
include dirname(__FILE__, 5) . '/test/lib/ui.php';
|
||||
class grouptaskTester extends tester
|
||||
{
|
||||
/**
|
||||
* 检查全部展开时分组下数据。
|
||||
* Check the data of the group.
|
||||
*
|
||||
* @param string $groupData story|status|pri|assignedTo|finishedBy|closedBy|type
|
||||
* @param array $nums
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function checkGroupData($groupData, $nums)
|
||||
{
|
||||
$this->switchVision('lite', 5);
|
||||
$form = $this->initForm('execution', 'grouptask', array('execution' => '2', 'groupBy' => $groupData ), 'appIframe-project');
|
||||
preg_match_all('/\d+(?:\.\d+)?/', $form->dom->task->getText(), $matches);
|
||||
if($matches[0][0] != $nums['tasks']) return $this->failed('总任务数目错误');
|
||||
if($matches[0][1] != $nums['waiting']) return $this->failed('未开始任务数目错误');
|
||||
if($matches[0][2] != $nums['doing']) return $this->failed('进行中任务数目错误');
|
||||
preg_match_all('/\d+(?:\.\d+)?/', $form->dom->time->getText(), $params);
|
||||
if($params[0][0] != $nums['estimates']) return $this->failed('总预计工时错误');
|
||||
if($params[0][1] != $nums['cost']) return $this->failed('已消耗工时错误');
|
||||
if($params[0][2] != $nums['left']) return $this->failed('剩余工时错误');
|
||||
return $this->success('数据正确');
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查已关联研发需求的任务数据统计。
|
||||
* Check the data of the group.
|
||||
*
|
||||
* @param array $nums
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function checkTaskLinkedStory($nums)
|
||||
{
|
||||
$form = $this->initForm('execution', 'grouptask', array('execution' => '2', 'groupBy' => 'story' ), 'appIframe-project');
|
||||
$form->dom->taskLinkedStoryBtn->click();
|
||||
$form->wait(1);
|
||||
preg_match_all('/\d+(?:\.\d+)?/', $form->dom->task->getText(), $matches);
|
||||
if($matches[0][0] != $nums['tasks']) return $this->failed('总任务数目错误');
|
||||
if($matches[0][1] != $nums['waiting']) return $this->failed('未开始任务数目错误');
|
||||
if($matches[0][2] != $nums['doing']) return $this->failed('进行中任务数目错误');
|
||||
preg_match_all('/\d+(?:\.\d+)?/', $form->dom->time->getText(), $params);
|
||||
if($params[0][0] != $nums['estimates']) return $this->failed('总预计工时错误');
|
||||
if($params[0][1] != $nums['cost']) return $this->failed('已消耗工时错误');
|
||||
if($params[0][2] != $nums['left']) return $this->failed('剩余工时错误');
|
||||
return $this->success('数据正确');
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查折叠后的数据统计。
|
||||
* Check the data of the group.
|
||||
*
|
||||
* @param array $nums
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function checkCollapse($nums)
|
||||
{
|
||||
$form = $this->initForm('execution', 'grouptask', array('execution' => '2', 'groupBy' => 'story' ), 'appIframe-project');
|
||||
$form->dom->collapseBtn->click();
|
||||
$form->wait(1);
|
||||
if($form->dom->rtask->getText() != $nums['tasks']) return $this->failed('总任务数目错误');
|
||||
if($form->dom->rdoing->getText() != $nums['doing']) return $this->failed('进行中任务数目错误');
|
||||
if($form->dom->rwaiting->getText() != $nums['waiting']) return $this->failed('未开始任务数目错误');
|
||||
if($form->dom->restimates->getText() != $nums['estimates']) return $this->failed('总预计工时错误');
|
||||
if($form->dom->rcost->getText() != $nums['cost']) return $this->failed('已消耗工时错误');
|
||||
if($form->dom->rleft->getText() != $nums['left']) return $this->failed('剩余工时错误');
|
||||
return $this->success('数据正确');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
include dirname(__FILE__, 5) . '/test/lib/ui.php';
|
||||
class treeTester extends tester
|
||||
{
|
||||
/**
|
||||
* 检查树状图数据。
|
||||
* Check tree data.
|
||||
*
|
||||
* @param string $level
|
||||
* @param string $num
|
||||
* @param bool $click
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function checkTreeData($level, $num, $click = false)
|
||||
{
|
||||
$this->switchVision('lite', 5);
|
||||
$form = $this->initForm('execution', 'tree', array('kanbanID' => '2'), 'appIframe-project');
|
||||
$form->wait(1);
|
||||
if($click) $form->dom->onlyStoryBtn->click();
|
||||
$form->wait(1);
|
||||
if(count($form->dom->getElementList($form->dom->xpath[$level])->element) != $num) return $this->failed('数据错误');
|
||||
return $this->success('数据正确');
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查树状图中的任务、目标详情显示。
|
||||
* Check detail data.
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function checkDetail()
|
||||
{
|
||||
$form = $this->initForm('execution', 'tree', array('kanbanID' => '2'), 'appIframe-project');
|
||||
$form->wait(1);
|
||||
$form->dom->detail->click();
|
||||
$form->wait(1);
|
||||
|
||||
if($form->dom->detail->getText() == $form->dom->titleInLite->getText()) return $this->success('详情数据正确');
|
||||
return $this->failed('详情数据错误');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
title=执行下的分组视图
|
||||
timeout=0
|
||||
cid=1
|
||||
|
||||
- 执行tester模块的checkGroupData方法,参数是'story', $nums['story']▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkGroupData方法,参数是'status', $nums['status']▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkGroupData方法,参数是'pri', $nums['pri']▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkGroupData方法,参数是'assignedTo', $nums['assignedTo']▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkGroupData方法,参数是'finishedBy', $nums['finishedBy']▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkGroupData方法,参数是'closedBy', $nums['closedBy']▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkGroupData方法,参数是'type', $nums['type']▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkTaskLinkedStory方法,参数是$nums['linked']▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkCollapse方法,参数是$nums['collapse']▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
|
||||
*/
|
||||
|
||||
chdir(__DIR__);
|
||||
include '../lib/grouptaskinlite.ui.class.php';
|
||||
global $config;
|
||||
|
||||
$user = zenData('user');
|
||||
$user->id->range('1-100');
|
||||
$user->account->range('admin, user1, user2, user3, user4, user5');
|
||||
$user->realname->range('admin, USER1, USER2, USER3, USER4, USER5');
|
||||
$user->password->range($config->uitest->defaultPassword)->format('md5');
|
||||
$user->visions->range('`rnd,lite`');
|
||||
$user->gen(6);
|
||||
|
||||
$product = zenData('product');
|
||||
$product->id->range('1-100');
|
||||
$product->name->range('运营');
|
||||
$product->shadow->range('1');
|
||||
$product->bind->range('1');
|
||||
$product->type->range('normal');
|
||||
$product->vision->range('lite');
|
||||
$product->gen(1);
|
||||
|
||||
$project = zenData('project');
|
||||
$project->id->range('1-100');
|
||||
$project->project->range('0, 1');
|
||||
$project->model->range('kanban, []');
|
||||
$project->type->range('project, kanban');
|
||||
$project->auth->range('[]');
|
||||
$project->storyType->range('[]');
|
||||
$project->parent->range('0, 1');
|
||||
$project->path->range('`,1,`, `,1,2,`');
|
||||
$project->grade->range('1');
|
||||
$project->name->range('运营项目, 看板');
|
||||
$project->begin->range('(-2M)-(-M):1D')->type('timestamp')->format('YY/MM/DD');
|
||||
$project->end->range('(+2M)-(+3M):1D')->type('timestamp')->format('YY/MM/DD');
|
||||
$project->openedBy->range('user1');
|
||||
$project->acl->range('open');
|
||||
$project->status->range('doing');
|
||||
$project->vision->range('lite');
|
||||
$project->gen(2);
|
||||
|
||||
$projectProduct = zenData('projectproduct');
|
||||
$projectProduct->project->range('1, 2');
|
||||
$projectProduct->product->range('1');
|
||||
$projectProduct->branch->range('0');
|
||||
$projectProduct->plan->range('0');
|
||||
$projectProduct->gen(2);
|
||||
|
||||
$story = zenData('story');
|
||||
$story->id->range('1-100');
|
||||
$story->vision->range('lite');
|
||||
$story->parent->range('0');
|
||||
$story->isParent->range('0');
|
||||
$story->root->range('1-100');
|
||||
$story->path->range('`,1,`, `,2,`, `,3,`');
|
||||
$story->grade->range('1');
|
||||
$story->product->range('1');
|
||||
$story->module->range('0');
|
||||
$story->plan->range('0');
|
||||
$story->title->range('1-100');
|
||||
$story->type->range('story');
|
||||
$story->estimate->range('0');
|
||||
$story->status->range('active');
|
||||
$story->stage->range('projected');
|
||||
$story->assignedTo->range('[]');
|
||||
$story->version->range('1');
|
||||
$story->gen(2);
|
||||
|
||||
$storySpec = zenData('storyspec');
|
||||
$storySpec->story->range('1-100');
|
||||
$storySpec->version->range('1');
|
||||
$storySpec->title->range('1-100');
|
||||
$storySpec->gen(2);
|
||||
|
||||
$projectStory = zenData('projectstory');
|
||||
$projectStory->project->range('1{2}, 2');
|
||||
$projectStory->product->range('1');
|
||||
$projectStory->branch->range('0');
|
||||
$projectStory->story->range('1, 2, 1');
|
||||
$projectStory->version->range('1');
|
||||
$projectStory->order->range('1, 2, 1');
|
||||
$projectStory->gen(3);
|
||||
|
||||
$task = zenData('task');
|
||||
$task->id->range('1-100');
|
||||
$task->project->range('1');
|
||||
$task->execution->range('2');
|
||||
$task->story->range('1{5}, 0{99}');
|
||||
$task->storyVersion->range('1');
|
||||
$task->name->range('1-100');
|
||||
$task->type->range('devel, study, affair{100}');
|
||||
$task->estimate->range('1');
|
||||
$task->consumed->range('0{3}, 1-100');
|
||||
$task->left->range('1{3}, 2{3}, 0{2}, 2{100}');
|
||||
$task->deadline->range(' (-5D)-(-4D):1D, []{11}')->type('timestamp')->format('YY/MM/DD');
|
||||
$task->status->range('wait{3}, doing{3}, done{2}, cancel, closed{3}');
|
||||
$task->openedBy->range('admin{6}, user1{6}');
|
||||
$task->assignedTo->range('[]{2}, user1{5}, admin{2}, closed{3}');
|
||||
$task->finishedBy->range('[]{6}, admin, user1{2}, admin, user1{2}');
|
||||
$task->canceledBy->range('[]{8}, admin, []{3}');
|
||||
$task->closedBy->range('[]{9}, admin{2}, user1');
|
||||
$task->deleted->range('0{11}, 1');
|
||||
$task->vision->range('lite');
|
||||
$task->gen(12);
|
||||
|
||||
$taskSpec = zenData('taskspec');
|
||||
$taskSpec->task->range('1-100');
|
||||
$taskSpec->version->range('0');
|
||||
$taskSpec->name->range('1-100');
|
||||
$taskSpec->gen(12);
|
||||
|
||||
zenData('taskteam')->gen(0);
|
||||
|
||||
$tester = new grouptaskTester();
|
||||
$tester->login();
|
||||
|
||||
$nums = array(
|
||||
'story' => array(
|
||||
'tasks' => '6',
|
||||
'waiting' => '0',
|
||||
'doing' => '1',
|
||||
'estimates' => '6',
|
||||
'cost' => '33',
|
||||
'left' => '2',
|
||||
),
|
||||
'status' => array(
|
||||
'tasks' => '3',
|
||||
'waiting' => '3',
|
||||
'doing' => '0',
|
||||
'estimates' => '3',
|
||||
'cost' => '0',
|
||||
'left' => '3',
|
||||
),
|
||||
'pri' => array(
|
||||
'tasks' => '3',
|
||||
'waiting' => '1',
|
||||
'doing' => '1',
|
||||
'estimates' => '3',
|
||||
'cost' => '8',
|
||||
'left' => '3',
|
||||
),
|
||||
'assignedTo' => array(
|
||||
'tasks' => '2',
|
||||
'waiting' => '2',
|
||||
'doing' => '0',
|
||||
'estimates' => '2',
|
||||
'cost' => '0',
|
||||
'left' => '2',
|
||||
),
|
||||
'finishedBy' => array(
|
||||
'tasks' => '6',
|
||||
'waiting' => '3',
|
||||
'doing' => '3',
|
||||
'estimates' => '6',
|
||||
'cost' => '6',
|
||||
'left' => '9',
|
||||
),
|
||||
'closedBy' => array(
|
||||
'tasks' => '9',
|
||||
'waiting' => '3',
|
||||
'doing' => '3',
|
||||
'estimates' => '9',
|
||||
'cost' => '21',
|
||||
'left' => '9',
|
||||
),
|
||||
'type' => array(
|
||||
'tasks' => '9',
|
||||
'waiting' => '1',
|
||||
'doing' => '3',
|
||||
'estimates' => '9',
|
||||
'cost' => '36',
|
||||
'left' => '7',
|
||||
),
|
||||
'linked' => array(
|
||||
'tasks' => '5',
|
||||
'waiting' => '3',
|
||||
'doing' => '2',
|
||||
'estimates' => '5',
|
||||
'cost' => '3',
|
||||
'left' => '7',
|
||||
),
|
||||
'collapse' => array(
|
||||
'tasks' => '6',
|
||||
'waiting' => '0',
|
||||
'doing' => '1',
|
||||
'estimates' => '6h',
|
||||
'cost' => '33h',
|
||||
'left' => '2h',
|
||||
)
|
||||
);
|
||||
|
||||
r($tester->checkGroupData('story',$nums['story'])) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkGroupData('status',$nums['status'])) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkGroupData('pri',$nums['pri'])) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkGroupData('assignedTo',$nums['assignedTo'])) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkGroupData('finishedBy',$nums['finishedBy'])) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkGroupData('closedBy',$nums['closedBy'])) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkGroupData('type',$nums['type'])) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkTaskLinkedStory($nums['linked'])) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkCollapse($nums['collapse'])) && p('status,message') && e('SUCCESS,数据正确');
|
||||
$tester->closeBrowser();
|
||||
@@ -11,8 +11,9 @@ class treePage extends page
|
||||
'thirdLevelB' => "//*[@id='mainContent']/div/div[1]/div/menu/li[2]/menu/li[1]/menu/li[@z-type='item']",
|
||||
'fourthLevelB' => "//*[@id='mainContent']/div/div[1]/div/menu/li[2]/menu/li[1]/menu/li[1]/menu/li[@z-type='item']",
|
||||
'onlyStoryBtn' => "//*[@id='featureBar']/menu/div/label",
|
||||
'detail' => "//*[@id='mainContent']/div/div[1]/div/menu/li[2]/menu/li/menu/li[1]/div/div/div/div/span[3]",
|
||||
'title' => "//*[@id='detailBlock']/div[1]/div[1]/span[2]"
|
||||
'detail' => "//*[@id='mainContent']/div/div[1]/div/menu/li[1]/menu/li/menu/li[1]//span[3]",
|
||||
'title' => "//*[@id='detailBlock']/div[1]/div[1]/span[2]",
|
||||
'titleInLite' => "//*[@id='detailBlock']/div[1]/div[1]/span[3]"
|
||||
);
|
||||
$this->dom->xpath = array_merge($this->dom->xpath, $xpath);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
title=运营界面树状图
|
||||
timeout=0
|
||||
cid=1
|
||||
|
||||
- 执行tester模块的checkTreeData方法,参数是'firstLevel', '3'▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkTreeData方法,参数是'secondLevelA', '7'▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkTreeData方法,参数是'secondLevelB', '2'▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkTreeData方法,参数是'thirdLevelB', '2'▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkTreeData方法,参数是'fourthLevelB', '1'▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkTreeData方法,参数是'firstLevel', '1', true▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkTreeData方法,参数是'secondLevelA', '2')▫▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @数据正确
|
||||
- 执行tester模块的checkDetail方法▫
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 测试结果 @详情数据正确
|
||||
|
||||
*/
|
||||
|
||||
chdir(__DIR__);
|
||||
include '../lib/treeinlite.ui.class.php';
|
||||
|
||||
$product = zenData('product');
|
||||
$product->id->range('1-100');
|
||||
$product->name->range('运营项目');
|
||||
$product->shadow->range('1');
|
||||
$product->bind->range('1');
|
||||
$product->type->range('normal');
|
||||
$product->vision->range('lite');
|
||||
$product->gen(1);
|
||||
|
||||
$project = zenData('project');
|
||||
$project->id->range('1-100');
|
||||
$project->project->range('0, 1');
|
||||
$project->model->range('kanban, []');
|
||||
$project->type->range('project, kanban');
|
||||
$project->auth->range('[]');
|
||||
$project->storyType->range('[]');
|
||||
$project->parent->range('0, 1');
|
||||
$project->path->range('`,1,`, `,1,2,`');
|
||||
$project->grade->range('1');
|
||||
$project->name->range('运营项目, 看板');
|
||||
$project->hasProduct->range('0');
|
||||
$project->begin->range('(-2M)-(-M):1D')->type('timestamp')->format('YY/MM/DD');
|
||||
$project->end->range('(+2M)-(+3M):1D')->type('timestamp')->format('YY/MM/DD');
|
||||
$project->openedBy->range('user1');
|
||||
$project->acl->range('open');
|
||||
$project->status->range('doing');
|
||||
$project->vision->range('lite');
|
||||
$project->gen(2);
|
||||
|
||||
$projectProduct = zenData('projectproduct');
|
||||
$projectProduct->project->range('1, 2');
|
||||
$projectProduct->product->range('1');
|
||||
$projectProduct->branch->range('0');
|
||||
$projectProduct->plan->range('0');
|
||||
$projectProduct->gen(2);
|
||||
|
||||
$story = zenData('story');
|
||||
$story->id->range('1-100');
|
||||
$story->vision->range('lite');
|
||||
$story->parent->range('0');
|
||||
$story->isParent->range('0');
|
||||
$story->root->range('1-100');
|
||||
$story->path->range('`,1,`, `,2,`, `,3,`');
|
||||
$story->grade->range('1');
|
||||
$story->product->range('1');
|
||||
$story->module->range('1{2}, 2');
|
||||
$story->plan->range('0');
|
||||
$story->title->range('1-100');
|
||||
$story->type->range('story');
|
||||
$story->estimate->range('0');
|
||||
$story->status->range('active');
|
||||
$story->stage->range('projected');
|
||||
$story->assignedTo->range('[]');
|
||||
$story->version->range('1');
|
||||
$story->gen(3);
|
||||
|
||||
$storySpec = zenData('storyspec');
|
||||
$storySpec->story->range('1-100');
|
||||
$storySpec->version->range('1');
|
||||
$storySpec->title->range('1-100');
|
||||
$storySpec->gen(3);
|
||||
|
||||
$projectStory = zenData('projectstory');
|
||||
$projectStory->project->range('1{3}, 2{2}');
|
||||
$projectStory->product->range('1');
|
||||
$projectStory->branch->range('0');
|
||||
$projectStory->story->range('1, 2, 3');
|
||||
$projectStory->version->range('1');
|
||||
$projectStory->order->range('1, 2, 3');
|
||||
$projectStory->gen(5);
|
||||
|
||||
$module = zenData('module');
|
||||
$module->id->range('1-100');
|
||||
$module->root->range('1, 1, 2');
|
||||
$module->branch->range('0');
|
||||
$module->name->range('产品模块1, 产品模块2, 看板模块1');
|
||||
$module->parent->range('0');
|
||||
$module->path->range('`,1,`, `,2,`, `,3,`');
|
||||
$module->grade->range('1');
|
||||
$module->type->range('story{2}, task');
|
||||
$module->short->range('0');
|
||||
$module->gen(3);
|
||||
|
||||
$task = zenData('task');
|
||||
$task->id->range('1-100');
|
||||
$task->project->range('1');
|
||||
$task->execution->range('2');
|
||||
$task->module->range('1{3}, 2, 3, 0{99}');
|
||||
$task->story->range('1, 1, 2, 3, 0{99}');
|
||||
$task->storyVersion->range('1');
|
||||
$task->name->range('1-100');
|
||||
$task->vision->range('lite');
|
||||
$task->gen(12);
|
||||
|
||||
$taskSpec = zenData('taskspec');
|
||||
$taskSpec->task->range('1-100');
|
||||
$taskSpec->version->range('0');
|
||||
$taskSpec->name->range('1-100');
|
||||
$taskSpec->gen(12);
|
||||
|
||||
$tester = new treeTester();
|
||||
$tester->login();
|
||||
|
||||
r($tester->checkTreeData('firstLevel', '3')) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkTreeData('secondLevelA', '7')) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkTreeData('secondLevelB', '2')) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkTreeData('thirdLevelB', '2')) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkTreeData('fourthLevelB', '1')) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkTreeData('firstLevel', '1', true)) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkTreeData('secondLevelA', '2') ) && p('status,message') && e('SUCCESS,数据正确');
|
||||
r($tester->checkDetail()) && p('status,message') && e('SUCCESS,详情数据正确');
|
||||
$tester->closeBrowser();
|
||||
@@ -3,15 +3,15 @@
|
||||
include dirname(__FILE__, 5) . '/test/lib/init.php';
|
||||
|
||||
/**
|
||||
|
||||
title=测试 gitlabModel::apiDeleteProject();
|
||||
timeout=0
|
||||
cid=1
|
||||
|
||||
- 使用空的projectID删除项目 @0
|
||||
- 使用错误gitlabID删除项目 @0
|
||||
- 使用空的GitlabID和空的projectID删除项目 @0
|
||||
- 使用错误projectID删除项目 @0
|
||||
- 通过gitlabID,项目id正确删除项目属性message @202 Accepted
|
||||
|
||||
*/
|
||||
|
||||
zenData('pipeline')->gen(5);
|
||||
@@ -32,13 +32,11 @@ $gitlab->apiCreateProject($gitlabID, $project);
|
||||
|
||||
/* Get projectID. */
|
||||
$gitlabProjects = $gitlab->apiGetProjects($gitlabID);
|
||||
$unitTestList = array();
|
||||
foreach($gitlabProjects as $gitlabProject)
|
||||
{
|
||||
if($gitlabProject->name == $projectName)
|
||||
{
|
||||
$projectID = $gitlabProject->id;
|
||||
break;
|
||||
}
|
||||
if($gitlabProject->name == $projectName) $projectID = $gitlabProject->id;
|
||||
if(strpos($gitlabProject->name, 'unitTest') === 0 || strpos($gitlabProject->name, 'unitest') === 0) $unitTestList[] = $gitlabProject;
|
||||
}
|
||||
|
||||
$project = new stdclass();
|
||||
@@ -46,5 +44,15 @@ $project->description = 'apiUpdatedProject';
|
||||
|
||||
r($gitlab->apiDeleteProject($gitlabID, 0)) && p() && e('0'); //使用空的projectID删除项目
|
||||
r($gitlab->apiDeleteProject(0, $projectID)) && p() && e('0'); //使用错误gitlabID删除项目
|
||||
r($gitlab->apiDeleteProject(0, 0)) && p() && e('0'); //使用空的GitlabID和空的projectID删除项目
|
||||
r($gitlab->apiDeleteProject(0, 99999)) && p() && e('0'); //使用错误projectID删除项目
|
||||
|
||||
r($gitlab->apiDeleteProject($gitlabID, $projectID)) && p('message') && e('202 Accepted'); //通过gitlabID,项目id正确删除项目
|
||||
//删除测试数据
|
||||
if(!empty($unitTestList))
|
||||
{
|
||||
foreach($unitTestList as $unitTestProject)
|
||||
{
|
||||
$gitlab->apiDeleteProject($gitlabID, $unitTestProject->id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ class metric extends control
|
||||
|
||||
$dateBegin = str_replace('_', '-', $dateBegin);
|
||||
$dateEnd = str_replace('_', '-', $dateEnd);
|
||||
$options = array_filter(array('scope' => $scope, 'dateLabel' => $dateLabel, 'dateBegin' => $dateBegin, 'dateEnd' => $dateEnd));
|
||||
$options = array_filter(array('scope' => $scope, 'calcDate' => $dateLabel, 'dateBegin' => $dateBegin, 'dateEnd' => $dateEnd));
|
||||
|
||||
$this->app->loadClass('pager', true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
@@ -410,7 +410,7 @@ window.handleQueryClick = function(id, viewType = 'single')
|
||||
|
||||
var formData = window.getFormData($form);
|
||||
var scopeValue = formData.get('scope') === null ? '' : formData.get('scope');
|
||||
var dateLabel = formData.get('dateLabel') === null ? '' : formData.get('dateLabel');
|
||||
var dateLabel = formData.get('calcDate') === null ? '' : formData.get('calcDate');
|
||||
var dateBegin = formData.get('dateBegin') === null ? '' : formData.get('dateBegin').replace(/-/g, '_');
|
||||
var dateEnd = formData.get('dateEnd') === null ? '' : formData.get('dateEnd').replace(/-/g, '_');
|
||||
|
||||
|
||||
@@ -2304,6 +2304,7 @@ class pivotModel extends model
|
||||
{
|
||||
if($this->config->edition != 'open')
|
||||
{
|
||||
$this->app->loadConfig('dataview');
|
||||
static $workflowFields = array();
|
||||
if(!isset($workflowFields[$object])) $workflowFields[$object] = $this->loadModel('workflowfield')->getList($object);
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
include dirname(__FILE__, 5) . '/test/lib/ui.php';
|
||||
class unlinkStakeholderTester extends tester
|
||||
{
|
||||
/**
|
||||
* Unlink a stakeholder of program.
|
||||
* 单个移除干系人
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function unlinkStakeholder()
|
||||
{
|
||||
$form = $this->initForm('program', 'stakeholder', array('programID' => 1), 'appIframe-program');
|
||||
$linkNumBefore = $form->dom->stakeholderNum->getText();
|
||||
$form->dom->unlinkFirBtn->click(); // 点击第一行的单个移除按钮
|
||||
$form->wait(1);
|
||||
$form->dom->alertModal(); // 模态框中点击确定
|
||||
$form->wait(2);
|
||||
$linkNumAfter = $form->dom->stakeholderNum->getText(); // 移除干系人后数量
|
||||
return ($linkNumAfter == $linkNumBefore - 1) ? $this->success('单个移除干系人成功') : $this->failed('单个移除干系人失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch unlink stakeholder of program.
|
||||
* 批量移除全部干系人
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function batchUnlinkStakeholders()
|
||||
{
|
||||
$form = $this->initForm('program', 'stakeholder', array('programID' => 1), 'appIframe-program');
|
||||
$form->dom->selectAllBtn->click(); // 全选干系人
|
||||
$form->dom->batchUnlinkBtn->click(); // 点击批量移除按钮
|
||||
$form->wait(1);
|
||||
$form->dom->alertModal(); // 模态框中点击确定
|
||||
$form->wait(2);
|
||||
return ($form->dom->stakeholderNum === false) ? $this->success('批量移除干系人成功') : $this->failed('批量移除干系人失败');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
class stakeholderPage extends page
|
||||
{
|
||||
public function __construct($webdriver)
|
||||
{
|
||||
parent::__construct($webdriver);
|
||||
$xpath = array(
|
||||
'unlinkFirBtn' => "//*[@id='table-program-stakeholder']/div[2]/div[3]/div/div[1]/div/nav/a/i",
|
||||
'stakeholderNum' => "//*[@id='table-program-stakeholder']/div[3]/div[2]/strong",
|
||||
'selectAllBtn' => "//*[@id='table-program-stakeholder']/div[1]/div[1]/div/div[1]/div/div/label",
|
||||
'batchUnlinkBtn' => "//*[@id='table-program-stakeholder']/div[3]/nav[1]/button",
|
||||
);
|
||||
$this->dom->xpath = array_merge($this->dom->xpath, $xpath);
|
||||
}
|
||||
}
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
title=移除项目集下干系人测试
|
||||
timeout=0
|
||||
cid=73
|
||||
|
||||
- 单个移除干系人成功
|
||||
- 测试结果 @单个移除干系人成功
|
||||
- 最终测试状态 @ SUCCESS
|
||||
- 批量移除干系人成功
|
||||
- 测试结果 @批量移除干系人成功
|
||||
- 最终测试状态 @ SUCCESS
|
||||
|
||||
*/
|
||||
chdir(__DIR__);
|
||||
include '../lib/unlinkstakeholder.ui.class.php';
|
||||
global $config;
|
||||
|
||||
$stakeholder = zenData('stakeholder');
|
||||
$stakeholder->id->range('1-3');
|
||||
$stakeholder->objectID->range('1');
|
||||
$stakeholder->objectType->range('program');
|
||||
$stakeholder->user->range('user1, user2, user3');
|
||||
$stakeholder->type->range('inside');
|
||||
$stakeholder->key->range('0');
|
||||
$stakeholder->from->range('company');
|
||||
$stakeholder->gen(3);
|
||||
|
||||
$user = zenData('user');
|
||||
$user->id->range('1-5');
|
||||
$user->type->range('inside{4}, outside{1}');
|
||||
$user->dept->range('1');
|
||||
$user->account->range('admin, user1, user2, user3, user4');
|
||||
$user->realname->range('admin, user1, user2, user3, user4');
|
||||
$user->password->range($config->uitest->defaultPassword)->format('md5');
|
||||
$user->visions->range('rnd');
|
||||
$user->gen(5);
|
||||
|
||||
$project = zenData('project');
|
||||
$project->id->range('1');
|
||||
$project->project->range('0');
|
||||
$project->type->range('program');
|
||||
$project->model->range('[]');
|
||||
$project->path->range('`,1,`');
|
||||
$project->grade->range('1');
|
||||
$project->name->range('项目集A');
|
||||
$project->hasProduct->range('1');
|
||||
$project->status->range('wait');
|
||||
$project->begin->range('(-72w)-(-71w):1D')->type('timestamp')->format('YY/MM/DD');
|
||||
$project->end->range('(+72w)-(+73w):1D')->type('timestamp')->format('YY/MM/DD');
|
||||
$project->acl->range('open');
|
||||
$project->gen(1);
|
||||
|
||||
$tester = new unlinkStakeholderTester();
|
||||
$tester->login();
|
||||
|
||||
r($tester->unlinkStakeholder()) && p('message,status') && e('单个移除干系人成功, SUCCESS'); //单个移除干系人成功
|
||||
r($tester->batchUnlinkStakeholders()) && p('message,status') && e('批量移除干系人成功, SUCCESS'); //批量移除干系人成功
|
||||
|
||||
$tester->closeBrowser();
|
||||
@@ -216,7 +216,7 @@ class programplanTao extends programplanModel
|
||||
{
|
||||
$this->app->loadLang('stage');
|
||||
|
||||
$datas = $stageIndex = $planIdList = $reviewDeadline = array();
|
||||
$datas = $stageIndex = $planIdList = $reviewDeadline = array();
|
||||
$today = helper::today();
|
||||
$isMilestone = "<icon class='icon icon-flag icon-sm red'></icon> ";
|
||||
foreach($plans as $plan)
|
||||
|
||||
@@ -288,7 +288,7 @@ row
|
||||
),
|
||||
div
|
||||
(
|
||||
set::className('detail-content mt-4 overflow-hidden desc-box'),
|
||||
set::className('detail-content mt-4 overflow-hidden desc-box overflow-y-scroll scrollbar-thin scrollbar-hover'),
|
||||
set::title(strip_tags($project->desc)),
|
||||
html($project->desc)
|
||||
)
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
include dirname(__FILE__, 5) . '/test/lib/ui.php';
|
||||
class batchCreateStory extends tester
|
||||
{
|
||||
/**
|
||||
* 运营界面批量创建目标
|
||||
* batch create story in lite
|
||||
*
|
||||
* @param array $project
|
||||
* @param array $storyUrl
|
||||
* @param object $story
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function batchCreateStory($project, $storyUrl, $story)
|
||||
{
|
||||
$this->switchVision('lite', 5);
|
||||
$this->page->waitElement('//*[@id="app-project"]', 5);
|
||||
$this->openURL('projectstory', 'story', $project, 'appIframe-project');
|
||||
$this->page->waitElement('//*[@id="app-project"]', 5);
|
||||
$form = $this->initForm('story', 'batchCreate', $storyUrl, 'appIframe-project');
|
||||
$form->wait(2);
|
||||
//设置表单内容
|
||||
if (isset($story->name)) $form->dom->title_0->setValue($story->name);
|
||||
if (isset($story->reviewer)) $form->dom->reviewerPick->multiPicker($story->reviewer);
|
||||
$form->dom->btn($this->lang->story->saveDraft)->click();
|
||||
$form->wait(2);
|
||||
return $this->checkBatchCreate($project, $storyUrl, $story, $form);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查批量创建目标的结果
|
||||
* Check the result of batch create story
|
||||
*
|
||||
* @param array $project
|
||||
* @param array $storyUrl
|
||||
* @param object $story
|
||||
* @param object $form
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function checkBatchCreate($project, $storyUrl, $story, $form)
|
||||
{
|
||||
//创建失败时的校验
|
||||
if ($this->response('method') == 'batchCreate')
|
||||
{
|
||||
if (!isset($story->name) || $story->name == '')
|
||||
{
|
||||
$nameTip = $this->lang->story->errorEmptyStory;
|
||||
return ($form->dom->alertModal('text') == $nameTip)
|
||||
? $this->success('目标名称必填提示信息正确')
|
||||
: $this->failed('目标名称必填提示信息不正确');
|
||||
}
|
||||
if (!isset($story->reviewer) || $story->reviewer == '')
|
||||
{
|
||||
$reviewerTip = sprintf($this->lang->error->notempty, $this->lang->story->reviewer);
|
||||
return ($reviewerTip == $form->dom->reviewerTip->getText())
|
||||
? $this->success('评审人必填提示信息正确')
|
||||
: $this->failed('评审人必填提示信息不正确');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$storyList = $this->initForm('projectstory', 'story', $project, 'appIframe-project');
|
||||
$storyList->dom->search(array("{$this->lang->story->name},=,{$story->name}"));
|
||||
return ($storyList->dom->firstStory->getText() == $story->name)
|
||||
? $this->success('批量创建目标成功')
|
||||
: $this->failed('批量创建目标失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* The control file of example module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
|
||||
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author lijie
|
||||
* @package story
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
include dirname(__FILE__, 5).'/test/lib/ui.php';
|
||||
class changeStoryInLiteTester extends tester
|
||||
{
|
||||
/**
|
||||
* Create a default story.
|
||||
*
|
||||
* @param string $storyName
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function changeStoryInLite($storyName, $reviewer)
|
||||
{
|
||||
$this->switchVision('lite', 8);
|
||||
if($this->page->getCookie('vision') != 'lite')
|
||||
{
|
||||
$this->switchVision('lite', 8);
|
||||
}
|
||||
$form = $this->initForm('projectstory', 'story', array('projectID' => '1'), 'appIframe-project'); //变更目标前需要进入列表页面,获取项目ID
|
||||
$form = $this->initForm('story', 'change', array('storyID' => '1', 'from' => 'project'), 'appIframe-project');
|
||||
$form->dom->title->setValue($storyName);
|
||||
if($reviewer != NULL)
|
||||
{
|
||||
$form->dom->reviewer->click();
|
||||
$form->dom->reviewerAdmin->click();
|
||||
}
|
||||
$form->dom->btn($this->lang->save)->click();
|
||||
$form->wait(3);
|
||||
|
||||
//创建失败检查提示是否正确,名称为空和评审人为空提示
|
||||
if($this->response('method') != 'view')
|
||||
{
|
||||
$form = $this->loadPage('story', 'change');
|
||||
if($storyName == '')
|
||||
{
|
||||
$srCommon = $form->dom->srCommon->getText();
|
||||
$nameTip = sprintf($this->lang->error->notempty, $srCommon);
|
||||
if($form->dom->alertModal('text') == $nameTip) return $this->success('变更目标页面名称为空提示正确');
|
||||
}
|
||||
|
||||
if(empty($reviewer))
|
||||
{
|
||||
$reviwerTip = sprintf($this->lang->error->notempty, $this->lang->story->reviewers);
|
||||
if($form->dom->alertModal('text') == $reviwerTip) return $this->success('变更目标页面评审人为空提示正确');
|
||||
}
|
||||
return $this->failed('变更目标页面提示信息不正确');
|
||||
}
|
||||
|
||||
$viewPage = $this->loadPage('projectstory', 'view');
|
||||
if($viewPage->dom->storyName->getText() != $storyName) return $this->failed('目标名称不正确');
|
||||
if($viewPage->dom->storyStatus->getText() != $this->lang->story->statusList->reviewing) return $this->failed('目标状态不正确');
|
||||
|
||||
return $this->success('变更目标成功');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* The control file of example module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
|
||||
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author lijie
|
||||
* @package story
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
include dirname(__FILE__, 5).'/test/lib/ui.php';
|
||||
class createStoryInLiteTester extends tester
|
||||
{
|
||||
/**
|
||||
* Create a default story.
|
||||
*
|
||||
* @param string $storyName
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function createDefault($storyName, $reviewer)
|
||||
{
|
||||
$createStoryParam = array(
|
||||
'product' => '1',
|
||||
'branch' => '',
|
||||
'moduleID' => '0',
|
||||
'storyID' => '0',
|
||||
'projectID' => '1',
|
||||
'bugID' => '0',
|
||||
'planID' => '0',
|
||||
'todoID' => '0',
|
||||
'extra' => '',
|
||||
'storyType' => 'story'
|
||||
);
|
||||
|
||||
$this->switchVision('lite', 8);
|
||||
if($this->page->getCookie('vision') != 'lite')
|
||||
{
|
||||
$this->switchVision('lite', 8);
|
||||
}
|
||||
$form = $this->initForm('projectstory', 'story', array('projectID' => '1'), 'appIframe-project'); //由于创建目标后会跳转到记录了session的页面,所以先进入一次对应目标的列表页面
|
||||
$form = $this->initForm('story', 'create', $createStoryParam, 'appIframe-project'); //再进入创建目标页面
|
||||
$form->dom->titleInLite->setValue($storyName);
|
||||
if($reviewer != NULL)
|
||||
{
|
||||
$form->dom->reviewer->click();
|
||||
$form->dom->reviewerAdmin->click();
|
||||
}
|
||||
$form->dom->saveInLite->click();
|
||||
$form->wait(1);
|
||||
|
||||
//创建失败检查提示是否正确,名称为空和评审人为空提示
|
||||
if($this->response('method') != 'story')
|
||||
{
|
||||
$form = $this->loadPage('story', 'create');
|
||||
if($storyName == '')
|
||||
{
|
||||
$srCommen = $form->dom->srCommen->getText();
|
||||
$nameTip = sprintf($this->lang->error->notempty, $srCommen);
|
||||
if($form->dom->titleTip->getText() == $nameTip) return $this->success('创建目标页面名称为空提示正确');
|
||||
}
|
||||
|
||||
if(empty($reviewer))
|
||||
{
|
||||
$reviwerTip = sprintf($this->lang->error->notempty, $this->lang->story->reviewer);
|
||||
if($form->dom->reviewerTip->getText() == $reviwerTip) return $this->success('创建目标页面评审人为空提示正确');
|
||||
}
|
||||
return $this->failed('创建目标页面提示信息不正确');
|
||||
}
|
||||
|
||||
$viewPage = $this->initForm('projectstory', 'view', array('storyID' => '1', 'projectID' => '1'), 'appIframe-project');
|
||||
if($viewPage->dom->storyName->getText() != $storyName) return $this->failed('目标名称不正确');
|
||||
if($viewPage->dom->storyStatus->getText() != $this->lang->story->statusList->reviewing) return $this->failed('目标状态不正确');
|
||||
$viewPage->dom->TargetLife->click();
|
||||
if(strpos($viewPage->dom->openedBy->getText() , 'admin') === false) return $this->failed('创建人不正确');
|
||||
|
||||
return $this->success('创建'.$storyName.'成功');
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
title=运营界面批量创建目标
|
||||
timeout=0
|
||||
cid=0
|
||||
- 目标名称必填校验
|
||||
- 测试结果 @目标名称必填提示信息正确
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 评审人必填校验
|
||||
- 测试结果 @评审人必填提示信息正确
|
||||
- 最终测试状态 @SUCCESS
|
||||
|
||||
*/
|
||||
chdir(__DIR__);
|
||||
include '../lib/batchcreateinlite.ui.class.php';
|
||||
|
||||
$project = zenData('project');
|
||||
$project->id->range('1');
|
||||
$project->model->range('kanban');
|
||||
$project->type->range('project');
|
||||
$project->name->range('运营项目');
|
||||
$project->hasProduct->range('0');
|
||||
$project->acl->range('open');
|
||||
$project->vision->range('lite');
|
||||
$project->gen(1);
|
||||
|
||||
$product = zenData('product');
|
||||
$product->id->range('1');
|
||||
$product->program->range('0');
|
||||
$product->name->range('运营项目');
|
||||
$product->shadow->range('1');
|
||||
$product->type->range('normal');
|
||||
$product->acl->range('open');
|
||||
$product->vision->range('lite');
|
||||
$product->gen(1);
|
||||
|
||||
$projectproduct = zenData('projectproduct');
|
||||
$projectproduct->project->range('1');
|
||||
$projectproduct->product->range('1');
|
||||
$projectproduct->branch->range('0');
|
||||
$projectproduct->plan->range('0');
|
||||
$projectproduct->gen(1);
|
||||
|
||||
$team = ZenData('team');
|
||||
$team->id->range('1');
|
||||
$team->root->range('1');
|
||||
$team->type->range('project');
|
||||
$team->account->range('admin');
|
||||
$team->gen(1);
|
||||
|
||||
$projectadmin = ZenData('projectadmin');
|
||||
$projectadmin->group->range('1');
|
||||
$projectadmin->account->range('admin');
|
||||
$projectadmin->projects->range('1');
|
||||
$projectadmin->gen(1);
|
||||
|
||||
zendata('story')->loadYaml('story', false, 2)->gen(0);
|
||||
zendata('storyspec')->loadYaml('storyspec', false, 2)->gen(0);
|
||||
zendata('storyreview')->loadYaml('storyreview', false, 2)->gen(0);
|
||||
|
||||
$storyUrl = array(
|
||||
'productID' => '1',
|
||||
'branch' => '',
|
||||
'moduleID' => '0',
|
||||
'storyID' => '0',
|
||||
'project' => 1,
|
||||
'plan' => '0',
|
||||
'storyType' => 'story'
|
||||
);
|
||||
$project = array(
|
||||
'projectID' => 1
|
||||
);
|
||||
|
||||
$tester = new batchCreateStory();
|
||||
$tester->login();
|
||||
|
||||
$story = new stdClass();
|
||||
$story->name = '';
|
||||
r($tester->batchCreateStory($project, $storyUrl, $story)) && p('message,status') && e('目标名称必填提示信息正确,SUCCESS');//目标名称必填校验
|
||||
|
||||
$story->name = '目标A';
|
||||
r($tester->batchCreateStory($project, $storyUrl, $story)) && p('message,status') && e('评审人必填提示信息正确,SUCCESS');//评审人必填校验
|
||||
|
||||
$tester->closeBrowser();
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
|
||||
title=运营界面变更目标测试
|
||||
timeout=0
|
||||
cid=0
|
||||
- 目标名称必填校验
|
||||
- 测试结果 @目标名称必填提示信息正确
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 评审人必填校验
|
||||
- 测试结果 @评审人必填提示信息正确
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 正常创建目标校验
|
||||
- 测试结果 @批量创建目标成功
|
||||
- 最终测试状态 @SUCCESS
|
||||
|
||||
*/
|
||||
chdir(__DIR__);
|
||||
include '../lib/changestoryinlite.ui.class.php';
|
||||
|
||||
$product = zenData('product');
|
||||
$product->id->range('1');
|
||||
$product->program->range('0');
|
||||
$product->name->range('产品1');
|
||||
$product->shadow->range('1');
|
||||
$product->bind->range('0');
|
||||
$product->acl->range('open');
|
||||
$product->createdBy->range('admin');
|
||||
$product->vision->range('lite');
|
||||
$product->gen(1);
|
||||
|
||||
$story = zenData('story');
|
||||
$story->id->range('1');
|
||||
$story->vision->range('lite');
|
||||
$story->root->range('1');
|
||||
$story->path->range('`,1,`');
|
||||
$story->grade->range('1');
|
||||
$story->product->range('1');
|
||||
$story->module->range('0');
|
||||
$story->plan->range('0');
|
||||
$story->source->range('[]');
|
||||
$story->title->range('运营界面目标1');
|
||||
$story->type->range('story');
|
||||
$story->stage->range('wait');
|
||||
$story->status->range('active');
|
||||
$story->openedBy->range('admin');
|
||||
$story->version->range('1');
|
||||
$story->assignedTo->range('[]');
|
||||
$story->reviewedBy->range('[]');
|
||||
$story->closedBy->range('[]');
|
||||
$story->closedReason->range('[]');
|
||||
$story->gen(1);
|
||||
|
||||
$storyspec = zenData('storyspec');
|
||||
$storyspec->story->range('1');
|
||||
$storyspec->version->range('1');
|
||||
$storyspec->title->range('运营界面目标1');
|
||||
$storyspec->gen(1);
|
||||
|
||||
$storyreview = zenData('storyreview');
|
||||
$storyreview->gen(0);
|
||||
|
||||
$project = zenData('project');
|
||||
$project->id->range('1');
|
||||
$project->model->range('kanban');
|
||||
$project->type->range('project');
|
||||
$project->path->range('`,1,`');
|
||||
$project->team->range('运营项目1');
|
||||
$project->acl->range('open');
|
||||
$project->vision->range('lite');
|
||||
$project->name->range('运营项目1');
|
||||
$project->gen(1);
|
||||
|
||||
$projectadmin = zenData('projectadmin');
|
||||
$projectadmin->group->range('1');
|
||||
$projectadmin->account->range('admin');
|
||||
$projectadmin->projects->range('`,`1`,`');
|
||||
$projectadmin->gen(1);
|
||||
|
||||
$projectproduct = zenData('projectproduct');
|
||||
$projectproduct->project->range('1');
|
||||
$projectproduct->product->range('1');
|
||||
$projectproduct->gen(1);
|
||||
|
||||
$action = zenData('action')->gen(0);
|
||||
|
||||
$projectstory = zenData('projectstory');
|
||||
$projectstory->project->range('1');
|
||||
$projectstory->product->range('1');
|
||||
$projectstory->branch->range('0');
|
||||
$projectstory->story->range('1');
|
||||
$projectstory->version->range('1');
|
||||
$projectstory->order->range('1');
|
||||
$projectstory->gen(1);
|
||||
|
||||
$team = zenData('team');
|
||||
$team->id->range('1');
|
||||
$team->root->range('1');
|
||||
$team->type->range('project');
|
||||
$team->account->range('admin');
|
||||
$team->limited->range('no');
|
||||
$team->gen(1);
|
||||
|
||||
$tester = new changeStoryInLiteTester();
|
||||
$tester->login();
|
||||
|
||||
$storys = array();
|
||||
$storys['null'] = '';
|
||||
$storys['default'] = '变更后目标名称';
|
||||
|
||||
$reviewer = array();
|
||||
$reviewer['null'] = array();
|
||||
$reviewer['default'] = array('admin');
|
||||
|
||||
r($tester->changeStoryInLite($storys['default'], $reviewer['null'])) && p('message,status') && e('变更目标页面评审人为空提示正确,SUCCESS'); // 评审人不为空校验,变更失败
|
||||
r($tester->changeStoryInLite($storys['null'], $reviewer['default'])) && p('message,status') && e('变更目标页面名称为空提示正确,SUCCESS'); // 目标名称不为空校验,变更失败
|
||||
r($tester->changeStoryInLite($storys['default'], $reviewer['default'])) && p('message,status') && e('变更目标成功,SUCCESS'); // 使用默认选项变更需求,详情页信息对应
|
||||
|
||||
$tester->closeBrowser();
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
title=运营界面创建目标测试
|
||||
timeout=0
|
||||
cid=0
|
||||
|
||||
- 目标名称必填校验
|
||||
- 测试结果 @目标名称必填提示信息正确
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 评审人必填校验
|
||||
- 测试结果 @评审人必填提示信息正确
|
||||
- 最终测试状态 @SUCCESS
|
||||
- 正常创建目标校验
|
||||
- 测试结果 @创建目标成功
|
||||
- 最终测试状态 @SUCCESS
|
||||
|
||||
*/
|
||||
chdir(__DIR__);
|
||||
include '../lib/createstoryinlite.ui.class.php';
|
||||
|
||||
$product = zenData('product');
|
||||
$product->id->range('1');
|
||||
$product->program->range('0');
|
||||
$product->name->range('产品1');
|
||||
$product->shadow->range('0');
|
||||
$product->bind->range('0');
|
||||
$product->acl->range('open');
|
||||
$product->createdBy->range('admin');
|
||||
$product->vision->range('lite');
|
||||
$product->gen(1);
|
||||
|
||||
$story = zenData('story');
|
||||
$story->gen(0);
|
||||
|
||||
$storyspec = zenData('storyspec');
|
||||
$storyspec->gen(0);
|
||||
|
||||
$storyreview = zenData('storyreview');
|
||||
$storyreview->gen(0);
|
||||
|
||||
$project = zenData('project');
|
||||
$project->id->range('1');
|
||||
$project->model->range('kanban');
|
||||
$project->type->range('project');
|
||||
$project->path->range('`,1,`');
|
||||
$project->team->range('运营项目1');
|
||||
$project->acl->range('open');
|
||||
$project->vision->range('lite');
|
||||
$project->name->range('运营项目1');
|
||||
$project->gen(1);
|
||||
|
||||
$projectadmin = zenData('projectadmin');
|
||||
$projectadmin->group->range('1');
|
||||
$projectadmin->account->range('admin');
|
||||
$projectadmin->projects->range('`,`1`,`');
|
||||
$projectadmin->gen(1);
|
||||
|
||||
$projectproduct = zenData('projectproduct');
|
||||
$projectproduct->project->range('1');
|
||||
$projectproduct->product->range('1');
|
||||
$projectproduct->gen(1);
|
||||
|
||||
$projectstory = zenData('projectstory')->gen(0);
|
||||
|
||||
$action = zenData('action');
|
||||
$action->gen(0);
|
||||
|
||||
$tester = new createStoryInLiteTester();
|
||||
$tester->login();
|
||||
|
||||
$storys = array(
|
||||
'null' => '',
|
||||
'story' => '运营界面目标'
|
||||
);
|
||||
|
||||
$reviewers = array(
|
||||
'null' => array(),
|
||||
'admin' => array('admin')
|
||||
);
|
||||
|
||||
r($tester->createDefault($storys['null'], $reviewers['admin'])) && p('message,status') && e('创建目标页面名称为空提示正确,SUCCESS'); // 名称必填校验,创建失败
|
||||
r($tester->createDefault($storys['story'], $reviewers['null'])) && p('message,status') && e('创建目标页面评审人为空提示正确,SUCCESS'); // 评审人必填校验,创建失败
|
||||
r($tester->createDefault($storys['story'], $reviewers['admin'])) && p('message,status') && e('创建运营界面目标成功,SUCCESS'); // 创建成功
|
||||
|
||||
$tester->closeBrowser();
|
||||
@@ -34,21 +34,9 @@ class search extends control
|
||||
$module = empty($module) ? $this->session->searchParams['module'] : $module;
|
||||
$searchParams = $module . 'searchParams';
|
||||
$searchForm = $module . 'Form';
|
||||
$funcName = $_SESSION[$searchParams]['funcName'] ?? '';
|
||||
$funcArgs = $_SESSION[$searchParams]['funcArgs'] ?? [];
|
||||
|
||||
if($funcName)
|
||||
{
|
||||
$funcArgs[] = true; // 处理选项列表。
|
||||
$this->loadModel($module)->$funcName(...$funcArgs);
|
||||
$fields = empty($fields) ? $this->config->$module->search['fields'] : $fields;
|
||||
$params = empty($params) ? $this->config->$module->search['params'] : $params;
|
||||
}
|
||||
else
|
||||
{
|
||||
$fields = empty($fields) ? json_decode($_SESSION[$searchParams]['searchFields'], true) : $fields;
|
||||
$params = empty($params) ? json_decode($_SESSION[$searchParams]['fieldParams'], true) : $params;
|
||||
}
|
||||
$fields = empty($fields) ? json_decode($_SESSION[$searchParams]['searchFields'], true) : $fields;
|
||||
$params = empty($params) ? json_decode($_SESSION[$searchParams]['fieldParams'], true) : $params;
|
||||
|
||||
$_SESSION['searchParams']['module'] = $module;
|
||||
if(empty($_SESSION[$searchForm])) $this->search->initSession($module, $fields, $params);
|
||||
@@ -94,21 +82,9 @@ class search extends control
|
||||
$module = empty($module) ? $this->session->searchParams['module'] : $module;
|
||||
$searchParams = $module . 'searchParams';
|
||||
$searchForm = $module . 'Form';
|
||||
$funcName = $_SESSION[$searchParams]['funcName'] ?? '';
|
||||
$funcArgs = $_SESSION[$searchParams]['funcArgs'] ?? [];
|
||||
|
||||
if($funcName)
|
||||
{
|
||||
$funcArgs[] = true; // 处理选项列表。
|
||||
$this->loadModel($module)->$funcName(...$funcArgs);
|
||||
$fields = empty($fields) ? $this->config->$module->search['fields'] : $fields;
|
||||
$params = empty($params) ? $this->config->$module->search['params'] : $params;
|
||||
}
|
||||
else
|
||||
{
|
||||
$fields = empty($fields) ? json_decode($_SESSION[$searchParams]['searchFields'], true) : $fields;
|
||||
$params = empty($params) ? json_decode($_SESSION[$searchParams]['fieldParams'], true) : $params;
|
||||
}
|
||||
$fields = empty($fields) ? json_decode($_SESSION[$searchParams]['searchFields'], true) : $fields;
|
||||
$params = empty($params) ? json_decode($_SESSION[$searchParams]['fieldParams'], true) : $params;
|
||||
|
||||
$_SESSION['searchParams']['module'] = $module;
|
||||
if(empty($_SESSION[$searchForm])) $this->search->initOldSession($module, $fields, $params);
|
||||
|
||||
+9
-34
@@ -28,26 +28,13 @@ class searchModel extends model
|
||||
|
||||
if($this->config->edition != 'open') $searchConfig = $this->searchTao->processBuildinFields($module, $searchConfig);
|
||||
|
||||
$searchParams['module'] = $searchConfig['module'];
|
||||
$searchParams['actionURL'] = $searchConfig['actionURL'];
|
||||
$searchParams['style'] = zget($searchConfig, 'style', 'full');
|
||||
$searchParams['onMenuBar'] = zget($searchConfig, 'onMenuBar', 'no');
|
||||
$searchParams['queryID'] = isset($searchConfig['queryID']) ? $searchConfig['queryID'] : 0;
|
||||
|
||||
$funcArgs = func_get_args();
|
||||
$funcName = $funcArgs[1] ?? '';
|
||||
unset($funcArgs[0], $funcArgs[1]);
|
||||
|
||||
if($funcName)
|
||||
{
|
||||
$searchParams['funcName'] = $funcName;
|
||||
$searchParams['funcArgs'] = $funcArgs;
|
||||
}
|
||||
else
|
||||
{
|
||||
$searchParams['searchFields'] = json_encode($searchConfig['fields']);
|
||||
$searchParams['fieldParams'] = json_encode($searchConfig['params']);
|
||||
}
|
||||
$searchParams['module'] = $searchConfig['module'];
|
||||
$searchParams['searchFields'] = json_encode($searchConfig['fields']);
|
||||
$searchParams['fieldParams'] = json_encode($searchConfig['params']);
|
||||
$searchParams['actionURL'] = $searchConfig['actionURL'];
|
||||
$searchParams['style'] = zget($searchConfig, 'style', 'full');
|
||||
$searchParams['onMenuBar'] = zget($searchConfig, 'onMenuBar', 'no');
|
||||
$searchParams['queryID'] = isset($searchConfig['queryID']) ? $searchConfig['queryID'] : 0;
|
||||
|
||||
$this->session->set($module . 'searchParams', $searchParams);
|
||||
}
|
||||
@@ -110,23 +97,11 @@ class searchModel extends model
|
||||
/* Init vars. */
|
||||
$module = $this->post->module;
|
||||
$searchParams = $module . 'searchParams';
|
||||
$searchFields = json_decode($_SESSION[$searchParams]['searchFields']);
|
||||
$fieldParams = json_decode($_SESSION[$searchParams]['fieldParams']);
|
||||
$groupItems = $this->config->search->groupItems;
|
||||
$groupAndOr = strtoupper($this->post->groupAndOr);
|
||||
if($groupAndOr != 'AND' && $groupAndOr != 'OR') $groupAndOr = 'AND';
|
||||
$funcName = $_SESSION[$searchParams]['funcName'] ?? '';
|
||||
$funcArgs = $_SESSION[$searchParams]['funcArgs'] ?? [];
|
||||
if($funcName)
|
||||
{
|
||||
$funcArgs[] = true; // 处理选项列表。
|
||||
$this->loadModel($module)->$funcName(...$funcArgs);
|
||||
$searchFields = json_decode(json_encode($this->config->$module->search['fields']));
|
||||
$fieldParams = json_decode(json_encode($this->config->$module->search['params']));
|
||||
}
|
||||
else
|
||||
{
|
||||
$searchFields = json_decode($_SESSION[$searchParams]['searchFields']);
|
||||
$fieldParams = json_decode($_SESSION[$searchParams]['fieldParams']);
|
||||
}
|
||||
|
||||
$queryForm = $this->searchTao->initSession($module, $searchFields, $fieldParams);
|
||||
|
||||
|
||||
@@ -1317,6 +1317,9 @@ class taskZen extends task
|
||||
$task->canceledDate = helper::isZeroDate($task->canceledDate) ? '' : substr($task->canceledDate, 0, 10);
|
||||
$task->closedDate = helper::isZeroDate($task->closedDate) ? '' : substr($task->closedDate, 0, 10);
|
||||
$task->lastEditedDate = helper::isZeroDate($task->lastEditedDate) ? '' : substr($task->lastEditedDate, 0, 10);
|
||||
$task->rawEstimate = $task->estimate;
|
||||
$task->rawConsumed = $task->consumed;
|
||||
$task->rawLeft = $task->left;
|
||||
$task->estimate = $task->estimate . $this->lang->execution->workHourUnit;
|
||||
$task->consumed = $task->consumed . $this->lang->execution->workHourUnit;
|
||||
$task->left = $task->left . $this->lang->execution->workHourUnit;
|
||||
|
||||
@@ -17,6 +17,12 @@ window.handleRenderRow = function($row, index, row)
|
||||
$module.$.setValue(row.module);
|
||||
});
|
||||
|
||||
$row.find('.form-batch-control[data-name="story"] .picker-box').on('inited', function(e, info)
|
||||
{
|
||||
let $story = info[0];
|
||||
$story.render({limitValueInList: false});
|
||||
});
|
||||
|
||||
/* Set the scenes for the row. */
|
||||
$row.find('.form-batch-control[data-name="scene"] .picker-box').on('inited', function(e, info)
|
||||
{
|
||||
|
||||
@@ -1039,6 +1039,8 @@ class testcaseZen extends testcase
|
||||
$scenePairs = array();
|
||||
foreach($cases as $case)
|
||||
{
|
||||
$case->story = $case->story ? $case->story : '';
|
||||
|
||||
/* 设置用例模块。 */
|
||||
/* Set case module. */
|
||||
$objectID = $case->lib > 0 ? $case->lib : $case->product;
|
||||
|
||||
Regular → Executable
+8
-1
@@ -4,11 +4,14 @@
|
||||
/**
|
||||
|
||||
title=测试 userModel->checkBeforeCreateOrEdit();
|
||||
timeout=0
|
||||
cid=0
|
||||
|
||||
- 使用系统预留用户名返回 false。属性result @0
|
||||
- 使用系统预留用户名提示信息。第errors条的account属性 @用户名已被系统预留
|
||||
- 使用正常用户名返回 true。属性result @1
|
||||
- 执行$user3属性account @user1
|
||||
- 执行$user3属性verifyPassword @8e2803f8b0a6fcbb9501f3799795c736
|
||||
|
||||
*/
|
||||
include dirname(__FILE__, 5) . '/test/lib/init.php';
|
||||
@@ -22,11 +25,15 @@ $random = updateSessionRandom();
|
||||
|
||||
$user1 = (object)array('account' => 'guest', 'verifyPassword' => '');
|
||||
$user2 = (object)array('account' => 'admin', 'verifyPassword' => md5(md5('123456') . $random));
|
||||
$user3 = (object)array('account' => 'user1', 'verifyPassword' => md5(md5('Asd@123') . 'test'));
|
||||
|
||||
$userTest = new userTest();
|
||||
|
||||
$result1 = $userTest->checkBeforeCreateOrEditTest($user1);
|
||||
r($result1) && p('result') && e(0); // 使用系统预留用户名返回 false。
|
||||
r($result1) && p('result') && e(0); // 使用系统预留用户名返回 false。
|
||||
r($result1) && p('errors:account') && e('用户名已被系统预留'); // 使用系统预留用户名提示信息。
|
||||
|
||||
r($userTest->checkBeforeCreateOrEditTest($user2, true)) && p('result') && e(1); // 使用正常用户名返回 true。
|
||||
|
||||
r($user3) && p('account') && e('user1'); // 查看$user3属性account @user1
|
||||
r($user3) && p('verifyPassword') && e('8e2803f8b0a6fcbb9501f3799795c736'); // 查看$user3属性verifyPassword @8e2803f8b0a6fcbb9501f3799795c736
|
||||
@@ -4,9 +4,13 @@
|
||||
/**
|
||||
|
||||
title=测试 userModel->getCommiters();
|
||||
timeout=0
|
||||
cid=0
|
||||
|
||||
- 获取源代码账号为user1的用户真实姓名属性user1 @用户1
|
||||
- 获取源代码账号为user2的用户真实姓名属性user2 @用户2
|
||||
- 获取源代码账号为user10的用户真实姓名属性user10 @用户10
|
||||
- 获取源代码账号为admin的用户真实姓名属性admin @admin
|
||||
- 获取系统中源代码账号不为空的用户数量 @30
|
||||
|
||||
*/
|
||||
@@ -19,5 +23,8 @@ zenData('user')->gen(30);
|
||||
$user = new userTest();
|
||||
$commiters = $user->getCommitersTest();
|
||||
|
||||
r($commiters) && p('user1') && e('用户1'); //获取源代码账号为user1的用户真实姓名
|
||||
r($commiters) && p('user2') && e('用户2'); //获取源代码账号为user2的用户真实姓名
|
||||
r($commiters) && p('user10') && e('用户10'); //获取源代码账号为user10的用户真实姓名
|
||||
r(count($commiters)) && p() && e('30'); //获取系统中源代码账号不为空的用户数量
|
||||
r($commiters) && p('admin') && e('admin'); //获取源代码账号为admin的用户真实姓名
|
||||
r(count($commiters)) && p() && e('30'); //获取系统中源代码账号不为空的用户数量
|
||||
@@ -4,11 +4,14 @@
|
||||
/**
|
||||
|
||||
title=测试 userModel->getParentStageAuthedUsers();
|
||||
timeout=0
|
||||
cid=0
|
||||
|
||||
- 传入阶段ID为0获取有权限的用户 @0
|
||||
- 传入一个阶段ID为212获取有权限的用户属性dev12 @dev12
|
||||
- 传入一个阶段ID为1获取有权限的用户 @0
|
||||
- 传入一个阶段ID为212获取有权限的用户属性dev12 @dev12
|
||||
- 传入一个阶段ID为100获取有权限的用户 @0
|
||||
- 传入一个阶段ID为999获取有权限的用户 @0
|
||||
|
||||
*/
|
||||
include dirname(__FILE__, 5) . '/test/lib/init.php';
|
||||
@@ -22,5 +25,7 @@ $userView->gen(400);
|
||||
$user = new userTest();
|
||||
|
||||
r($user->getParentStageAuthedUsersTest(0)) && p() && e('0'); //传入阶段ID为0获取有权限的用户
|
||||
r($user->getParentStageAuthedUsersTest(212)) && p('dev12') && e('dev12'); //传入一个阶段ID为212获取有权限的用户
|
||||
r($user->getParentStageAuthedUsersTest(1)) && p() && e('0'); //传入一个阶段ID为1获取有权限的用户
|
||||
r($user->getParentStageAuthedUsersTest(212)) && p('dev12') && e('dev12'); //传入一个阶段ID为212获取有权限的用户
|
||||
r($user->getParentStageAuthedUsersTest(100)) && p() && e('0'); //传入一个阶段ID为100获取有权限的用户
|
||||
r($user->getParentStageAuthedUsersTest(999)) && p() && e('0'); //传入一个阶段ID为999获取有权限的用户
|
||||
@@ -4,20 +4,29 @@
|
||||
/**
|
||||
|
||||
title=测试 userModel->getTeamMemberPairs();
|
||||
timeout=0
|
||||
cid=0
|
||||
|
||||
- 获取ID为11的项目的团队成员数量 @1
|
||||
- 获取ID为11的项目的团队成员数量,追加用户user1 @2
|
||||
- 获取ID为12的项目的团队成员数量 @1
|
||||
- 获取ID为13的项目的团队成员数量,追加用户user1 @2
|
||||
- 获取ID为14的项目的团队成员数量 @1
|
||||
- 获取ID为14的项目的团队成员用户名属性user5 @U:用户5
|
||||
|
||||
*/
|
||||
|
||||
include dirname(__FILE__, 5) . '/test/lib/init.php';
|
||||
include dirname(__FILE__, 2) . '/lib/user.unittest.class.php';
|
||||
zenData('project')->gen(11);
|
||||
zenData('team')->gen(10);
|
||||
zenData('user')->gen(10);
|
||||
zenData('project')->gen(20);
|
||||
zenData('team')->gen(20);
|
||||
zenData('user')->gen(20);
|
||||
su('admin');
|
||||
|
||||
$user = new userTest();
|
||||
r(count($user->getTeamMemberPairsTest(11, 'project'))) && p() && e('1'); //获取ID为11的项目的团队成员数量
|
||||
r(count($user->getTeamMemberPairsTest(11, 'project', '', array('user1')))) && p() && e('2'); //获取ID为11的项目的团队成员数量,追加用户user1
|
||||
r(count($user->getTeamMemberPairsTest(11, 'project'))) && p() && e('1'); //获取ID为11的项目的团队成员数量
|
||||
r(count($user->getTeamMemberPairsTest(11, 'project', '', array('user1')))) && p() && e('2'); //获取ID为11的项目的团队成员数量,追加用户user1
|
||||
r(count($user->getTeamMemberPairsTest(12, 'project'))) && p() && e('1'); //获取ID为12的项目的团队成员数量
|
||||
r(count($user->getTeamMemberPairsTest(13, 'project', '', array('user1')))) && p() && e('2'); //获取ID为13的项目的团队成员数量,追加用户user1
|
||||
r(count($user->getTeamMemberPairsTest(14, 'project'))) && p() && e('1'); //获取ID为14的项目的团队成员数量
|
||||
r($user->getTeamMemberPairsTest(14, 'project')) && p('user5') && e('U:用户5'); //获取ID为14的项目的团队成员用户名
|
||||
Reference in New Issue
Block a user