Merge branch release/21.7.8 of zentao/zentaopms (#12647)

This commit is contained in:
刘刚
2025-12-04 14:08:09 +08:00
committed by Gitfox
26 changed files with 19 additions and 5721 deletions
-243
View File
@@ -250,247 +250,4 @@ class mrZenTest extends baseTest
if(dao::isError()) return dao::getError();
return $result;
}
/**
* Test assignEditData method.
*
* @param object $MR
* @param string $scm
* @access public
* @return object
*/
public function assignEditDataTest(object $MR, string $scm): object
{
// 调用被测方法,捕获输出和异常
$bufferLevel = ob_get_level();
ob_start();
try
{
$this->invokeArgs('assignEditData', [$MR, $scm]);
}
catch(Throwable $e)
{
// display() 方法可能抛出异常,这是正常的
}
while(ob_get_level() > $bufferLevel) ob_end_clean();
// 返回view对象用于验证
$result = new stdclass();
$result->title = $this->instance->view->title ?? '';
$result->MR = $this->instance->view->MR ?? null;
$result->users = $this->instance->view->users ?? [];
$result->jobList = $this->instance->view->jobList ?? [];
$result->branches = $this->instance->view->branches ?? [];
$result->sourceProject = $this->instance->view->sourceProject ?? '';
$result->targetProject = $this->instance->view->targetProject ?? '';
$result->repo = $this->instance->view->repo ?? null;
return $result;
}
/**
* Test buildLinkBugSearchForm method.
*
* @param int $MRID
* @param int $repoID
* @param string $orderBy
* @param int $queryID
* @access public
* @return array
*/
public function buildLinkBugSearchFormTest(int $MRID, int $repoID, string $orderBy, int $queryID = 0): array
{
$this->invokeArgs('buildLinkBugSearchForm', [$MRID, $repoID, $orderBy, $queryID]);
global $config;
$result = array();
$result['actionURL'] = $config->bug->search['actionURL'] ?? '';
$result['queryID'] = $config->bug->search['queryID'] ?? 0;
$result['style'] = $config->bug->search['style'] ?? '';
$result['hasProduct'] = isset($config->bug->search['fields']['product']) ? 1 : 0;
$result['hasPlan'] = isset($config->bug->search['fields']['plan']) ? 1 : 0;
$result['hasModule'] = isset($config->bug->search['fields']['module']) ? 1 : 0;
$result['hasExecution'] = isset($config->bug->search['fields']['execution']) ? 1 : 0;
$result['hasOpenedBuild'] = isset($config->bug->search['fields']['openedBuild']) ? 1 : 0;
$result['hasResolvedBuild'] = isset($config->bug->search['fields']['resolvedBuild']) ? 1 : 0;
$result['hasBranch'] = isset($config->bug->search['fields']['branch']) ? 1 : 0;
return $result;
}
/**
* Test buildLinkStorySearchForm method.
*
* @param int $MRID
* @param int $repoID
* @param string $orderBy
* @param int $queryID
* @access public
* @return array
*/
public function buildLinkStorySearchFormTest(int $MRID, int $repoID, string $orderBy, int $queryID = 0): array
{
$this->invokeArgs('buildLinkStorySearchForm', [$MRID, $repoID, $orderBy, $queryID]);
global $config;
$result = array();
$result['actionURL'] = $config->product->search['actionURL'] ?? '';
$result['queryID'] = $config->product->search['queryID'] ?? 0;
$result['style'] = $config->product->search['style'] ?? '';
$result['hasProduct'] = isset($config->product->search['fields']['product']) ? 1 : 0;
$result['hasPlan'] = isset($config->product->search['fields']['plan']) ? 1 : 0;
$result['hasModule'] = isset($config->product->search['fields']['module']) ? 1 : 0;
$result['hasBranch'] = isset($config->product->search['fields']['branch']) ? 1 : 0;
$result['hasGrade'] = isset($config->product->search['fields']['grade']) ? 1 : 0;
$statusValues = $config->product->search['params']['status']['values'] ?? array();
$result['hasClosed'] = isset($statusValues['closed']) ? 1 : 0;
return $result;
}
/**
* Test buildLinkTaskSearchForm method.
*
* @param int $MRID
* @param int $repoID
* @param string $orderBy
* @param int $queryID
* @param array $productExecutions
* @access public
* @return array
*/
public function buildLinkTaskSearchFormTest(int $MRID, int $repoID, string $orderBy, int $queryID, array $productExecutions): array
{
$this->invokeArgs('buildLinkTaskSearchForm', [$MRID, $repoID, $orderBy, $queryID, $productExecutions]);
global $config;
$result = array();
$result['actionURL'] = $config->execution->search['actionURL'] ?? '';
$result['queryID'] = $config->execution->search['queryID'] ?? 0;
$result['hasModule'] = isset($config->execution->search['fields']['module']) ? 1 : 0;
$result['executionValues'] = $config->execution->search['params']['execution']['values'] ?? array();
return $result;
}
/**
* Test checkNewCommit method.
*
* @param string $hostType
* @param array|null $mockCommits Mock commit data for testing
* @param string $lastTime
* @access public
* @return bool|int
*/
public function checkNewCommitTest(string $hostType, ?array $mockCommits, string $lastTime): bool|int
{
// 直接实现checkNewCommit的逻辑用于测试
$commitLogs = $mockCommits;
if($commitLogs)
{
$lastCommit = zget($commitLogs[0], 'committed_date', '');
if(in_array($hostType, array('gitea', 'gogs'))) $lastCommit = $commitLogs[0]->author->committer->date;
if($lastCommit > $lastTime) return true;
}
return false;
}
/**
* Test checkProjectEdit method.
*
* @param string $hostType
* @param object $sourceProject
* @param object $MR
* @access public
* @return bool|int
*/
public function checkProjectEditTest(string $hostType, object $sourceProject, object $MR): bool|int
{
$result = $this->invokeArgs('checkProjectEdit', [$hostType, $sourceProject, $MR]);
if(dao::isError()) return dao::getError();
return $result;
}
/**
* Test getAllProjects method.
*
* @param object $repo
* @access public
* @return array|string
*/
public function getAllProjectsTest(object $repo): array|string
{
$result = $this->invokeArgs('getAllProjects', [$repo]);
if(dao::isError()) return dao::getError();
return is_array($result) ? 'array' : '0';
}
/**
* Test getBranchUrl method.
*
* @param object $host
* @param int|string $projectID
* @param string $branch
* @access public
* @return string
*/
public function getBranchUrlTest(object $host, int|string $projectID, string $branch): string
{
$result = $this->invokeArgs('getBranchUrl', [$host, $projectID, $branch]);
if(dao::isError()) return dao::getError();
return $result;
}
/**
* Test processLinkTaskPager method.
*
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @param array $allTasks
* @access public
* @return array
*/
public function processLinkTaskPagerTest(int $recTotal, int $recPerPage, int $pageID, array $allTasks): array
{
$bufferLevel = ob_get_level();
ob_start();
try
{
$this->invokeArgs('processLinkTaskPager', [$recTotal, $recPerPage, $pageID, $allTasks]);
}
catch(Throwable $e)
{
// Ignore any exceptions
}
while(ob_get_level() > $bufferLevel) ob_end_clean();
$result = array();
$result['allTasks'] = $this->instance->view->allTasks ?? array();
$result['pager'] = $this->instance->view->pager ?? null;
$result['recTotal'] = $result['pager'] ? $result['pager']->recTotal : 0;
$result['recPerPage'] = $result['pager'] ? $result['pager']->recPerPage : 0;
$result['pageID'] = $result['pager'] ? $result['pager']->pageID : 0;
$result['pageTotal'] = $result['pager'] ? $result['pager']->pageTotal : 0;
$result['taskCount'] = count($result['allTasks']);
return $result;
}
/**
* Test saveMrData method.
*
* @param object $repo
* @param array $rawMrList
* @access public
* @return bool|array
*/
public function saveMrDataTest(object $repo, array $rawMrList): bool|array
{
$result = $this->invokeArgs('saveMrData', [$repo, $rawMrList]);
if(dao::isError()) return dao::getError();
return $result;
}
}
File diff suppressed because it is too large Load Diff
@@ -1239,86 +1239,6 @@ class repoZenTest
return $result;
}
/**
* Test buildEditForm method.
*
* @param int $repoID
* @param int $objectID
* @access public
* @return mixed
*/
public function buildEditFormTest(int $repoID, int $objectID)
{
$repo = $this->objectModel->getByID($repoID);
if(empty($repo)) return false;
if(isset($repo->client)) $repo->client = trim($repo->client, '"');
$this->objectModel->app->loadLang('action');
$scm = strtolower($repo->SCM);
$project = null;
if(in_array($scm, array('gitlab', 'gitea', 'gogs')))
{
$projectID = in_array($repo->SCM, $this->objectModel->config->repo->notSyncSCM) ? (int)$repo->serviceProject : $repo->serviceProject;
$project = new stdClass();
$project->id = $projectID;
$project->name = "Test Project {$projectID}";
}
$products = $this->objectModel->loadModel('product')->getPairs('', 0, '', 'all');
$linkedProductIDs = explode(',', $repo->product);
if(!empty($linkedProductIDs[0]))
{
$linkedProducts = $this->objectModel->product->getByIdList($linkedProductIDs);
$linkedProductPairs = array_combine(array_keys($linkedProducts), helper::arrayColumn($linkedProducts, 'name'));
$products = $products + $linkedProductPairs;
}
$title = $this->objectModel->lang->repo->common . $this->objectModel->lang->hyphen . $this->objectModel->lang->repo->edit;
$groups = $this->objectModel->loadModel('group')->getPairs();
$users = $this->objectModel->loadModel('user')->getPairs('noletter|noempty|nodeleted|noclosed');
$relatedProjects = $this->objectModel->filterProject(explode(',', $repo->product), explode(',', $repo->projects));
$serviceHosts = $this->objectModel->loadModel('pipeline')->getPairs($repo->SCM);
if(dao::isError()) return dao::getError();
return array('title' => $title, 'repo' => $repo, 'repoID' => $repoID, 'objectID' => $objectID, 'groups' => $groups, 'users' => $users, 'products' => $products, 'relatedProjects' => $relatedProjects, 'serviceHosts' => $serviceHosts, 'project' => $project, 'productCount' => count($products), 'hasRepo' => !empty($repo));
}
/**
* Test buildEditForm method.
*
* @param int $repoID
* @param int $objectID
* @access public
* @return mixed
*/
public function buildEditFormTest(int $repoID, int $objectID)
{
$repo = $this->objectModel->getByID($repoID);
if(empty($repo)) return false;
if(isset($repo->client)) $repo->client = trim($repo->client, '"');
$this->objectModel->app->loadLang('action');
$scm = strtolower($repo->SCM);
$project = null;
if(in_array($scm, array('gitlab', 'gitea', 'gogs')))
{
$projectID = in_array($repo->SCM, $this->objectModel->config->repo->notSyncSCM) ? (int)$repo->serviceProject : $repo->serviceProject;
$project = new stdClass();
$project->id = $projectID;
$project->name = "Test Project {$projectID}";
}
$products = $this->objectModel->loadModel('product')->getPairs('', 0, '', 'all');
$linkedProductIDs = explode(',', $repo->product);
if(!empty($linkedProductIDs[0]))
{
$linkedProducts = $this->objectModel->product->getByIdList($linkedProductIDs);
$linkedProductPairs = array_combine(array_keys($linkedProducts), helper::arrayColumn($linkedProducts, 'name'));
$products = $products + $linkedProductPairs;
}
$title = $this->objectModel->lang->repo->common . $this->objectModel->lang->hyphen . $this->objectModel->lang->repo->edit;
$groups = $this->objectModel->loadModel('group')->getPairs();
$users = $this->objectModel->loadModel('user')->getPairs('noletter|noempty|nodeleted|noclosed');
$relatedProjects = $this->objectModel->filterProject(explode(',', $repo->product), explode(',', $repo->projects));
$serviceHosts = $this->objectModel->loadModel('pipeline')->getPairs($repo->SCM);
if(dao::isError()) return dao::getError();
return array('title' => $title, 'repo' => $repo, 'repoID' => $repoID, 'objectID' => $objectID, 'groups' => $groups, 'users' => $users, 'products' => $products, 'relatedProjects' => $relatedProjects, 'serviceHosts' => $serviceHosts, 'project' => $project, 'productCount' => count($products), 'hasRepo' => !empty($repo));
}
/**
* Test checkConnection method in zen layer.
*
@@ -2017,4 +1937,4 @@ class repoZenTest
return $result;
}
}
}
-75
View File
@@ -1,75 +0,0 @@
#!/usr/bin/env php
<?php
/**
title=测试 repoZen::buildEditForm();
timeout=0
cid=18126
- 步骤1:正常版本库ID编辑表单标题属性title @代码库-编辑
- 步骤2:正常版本库ID检查repoID属性属性repoID @1
- 步骤3:不存在的版本库ID @0
- 步骤4:Git类型版本库编辑表单第repo条的SCM属性 @Git
- 步骤5:Gitlab类型版本库获取项目信息第project条的id属性 @1
*/
// 1. 导入依赖(路径固定,不可修改)
include dirname(__FILE__, 5) . '/test/lib/init.php';
include dirname(__FILE__, 2) . '/lib/repozen.unittest.class.php';
// 2. zendata数据准备(根据需要配置)
$table = zenData('repo');
$table->id->range('1-10');
$table->name->range('repo1,repo2,repo3,repo4,repo5,repo6,repo7,repo8,repo9,repo10');
$table->SCM->range('Git{3},Subversion{2},Gitlab,Gitea,Gogs{3}');
$table->product->range('1,2,3,1,2,3,1,2,3,1');
$table->projects->range('1,2,3,1,2,3,1,2,3,1');
$table->client->range('git,git,git,svn,svn,"git","git","git","git","git"');
$table->path->range('/path/to/repo1,/path/to/repo2,/path/to/repo3,/path/to/repo4,/path/to/repo5,http://gitlab.com/project1,http://gitea.com/project1,http://gogs.com/project1,http://gogs.com/project2,http://gogs.com/project3');
$table->serviceProject->range('0{5},1,1,1,1,1');
$table->gen(10);
$productTable = zenData('product');
$productTable->id->range('1-10');
$productTable->name->range('产品1,产品2,产品3,产品4,产品5,产品6,产品7,产品8,产品9,产品10');
$productTable->status->range('normal{8},closed{2}');
$productTable->gen(10);
$projectTable = zenData('project');
$projectTable->id->range('1-10');
$projectTable->name->range('项目1,项目2,项目3,项目4,项目5,项目6,项目7,项目8,项目9,项目10');
$projectTable->status->range('wait{3},doing{4},done{3}');
$projectTable->gen(10);
$groupTable = zenData('group');
$groupTable->id->range('1-5');
$groupTable->name->range('管理员,开发人员,测试人员,产品经理,项目经理');
$groupTable->gen(5);
$userTable = zenData('user');
$userTable->id->range('1-10');
$userTable->account->range('admin,user1,user2,user3,user4,user5,user6,user7,user8,user9');
$userTable->realname->range('管理员,用户1,用户2,用户3,用户4,用户5,用户6,用户7,用户8,用户9');
$userTable->deleted->range('0{8},1{2}');
$userTable->gen(10);
$pipelineTable = zenData('pipeline');
$pipelineTable->id->range('1-3');
$pipelineTable->name->range('GitLab服务器,Jenkins服务器,Gitea服务器');
$pipelineTable->type->range('gitlab,jenkins,gitea');
$pipelineTable->gen(3);
// 3. 用户登录(选择合适角色)
su('admin');
// 4. 创建测试实例(变量名与模块名一致)
$repoTest = new repoZenTest();
// 5. 🔴 强制要求:必须包含至少5个测试步骤
r($repoTest->buildEditFormTest(1, 1)) && p('title') && e('代码库-编辑'); // 步骤1:正常版本库ID编辑表单标题
r($repoTest->buildEditFormTest(1, 1)) && p('repoID') && e('1'); // 步骤2:正常版本库ID检查repoID属性
r($repoTest->buildEditFormTest(999, 1)) && p() && e('0'); // 步骤3:不存在的版本库ID
r($repoTest->buildEditFormTest(1, 1)) && p('repo:SCM') && e('Git'); // 步骤4:Git类型版本库编辑表单
r($repoTest->buildEditFormTest(6, 1)) && p('project:id') && e('1'); // 步骤5:Gitlab类型版本库获取项目信息
File diff suppressed because it is too large Load Diff
-31
View File
@@ -1,31 +0,0 @@
#!/usr/bin/env php
<?php
/**
title=测试 searchModel->getListCount();
timeout=0
cid=18301
- 测试索引中所有类型的条数
- 属性project @4
- 属性story @3
- 属性task @3
- 测试索引中指定类型的条数
- 属性project @4
- 属性story @3
- 测试索引中指定类型为空的条数属性bug @
*/
include dirname(__FILE__, 5) . '/test/lib/init.php';
include dirname(__FILE__, 2) . '/lib/search.unittest.class.php';
su('admin');
zenData('searchindex')->gen(10);
$typeList = array('all', array('project', 'story'), array('bug'));
$search = new searchTest();
r($search->getListCountTest($typeList[0])) && p('project,story,task') && e('4,3,3'); //测试索引中所有类型的条数
r($search->getListCountTest($typeList[1])) && p('project,story') && e('4,3'); //测试索引中指定类型的条数
@@ -1,29 +0,0 @@
#!/usr/bin/env php
<?php
/**
title=测试 searchModel::processSearchParams();
timeout=0
cid=18306
- 测试正常情况:session中有完整的搜索函数配置 @array
- 测试缺少funcModel的情况 @array
- 测试缺少funcName的情况 @array
- 测试缺少funcArgs的情况 @array
- 测试cacheSearchFunc参数为true的情况 @array
*/
include dirname(__FILE__, 5) . '/test/lib/init.php';
include dirname(__FILE__, 2) . '/lib/search.unittest.class.php';
su('admin');
$search = new searchTest();
r($search->processSearchParamsTest('story', false)) && p() && e('array'); // 测试正常情况:session中有完整的搜索函数配置
r($search->processSearchParamsTest('bug', false)) && p() && e('array'); // 测试缺少funcModel的情况
r($search->processSearchParamsTest('task', false)) && p() && e('array'); // 测试缺少funcName的情况
r($search->processSearchParamsTest('testcase', false)) && p() && e('array'); // 测试缺少funcArgs的情况
r($search->processSearchParamsTest('story', true)) && p() && e('array'); // 测试cacheSearchFunc参数为true的情况
-35
View File
@@ -1,35 +0,0 @@
#!/usr/bin/env php
<?php
/**
title=测试 searchModel::saveDict();
timeout=0
cid=18307
- 测试步骤1:保存有效字典数据属性result @1
- 测试步骤2:测试有效边界值属性count @2
- 测试步骤3:测试无效key格式属性count @0
- 测试步骤4:测试空值过滤属性count @1
- 测试步骤5:测试空字典数组属性result @1
- 测试步骤6:测试批量保存属性count @3
- 测试步骤7:测试重复key过滤属性count @1
- 测试步骤8:测试key长度限制属性count @1
*/
include dirname(__FILE__, 5) . '/test/lib/init.php';
include dirname(__FILE__, 2) . '/lib/search.unittest.class.php';
su('admin');
$search = new searchTest();
r($search->saveDictTest(array('12345' => '测试'))) && p('result') && e('1'); // 测试步骤1:保存有效字典数据
r($search->saveDictTest(array('00000' => '边界1', '65535' => '边界2'))) && p('count') && e('2'); // 测试步骤2:测试有效边界值
r($search->saveDictTest(array('abc' => '无效', '1234' => '长度错', '99999' => '超范围'))) && p('count') && e('0'); // 测试步骤3:测试无效key格式
r($search->saveDictTest(array('23456' => '', '34567' => '有效'))) && p('count') && e('1'); // 测试步骤4:测试空值过滤
r($search->saveDictTest(array())) && p('result') && e('1'); // 测试步骤5:测试空字典数组
r($search->saveDictTest(array('11111' => '词1', '22222' => '词2', '33333' => '词3'))) && p('count') && e('3'); // 测试步骤6:测试批量保存
r($search->saveDictTest(array('44444' => '已存在', '44444' => '重复'))) && p('count') && e('1'); // 测试步骤7:测试重复key过滤
r($search->saveDictTest(array('123' => '短key', '123456' => '长key', '55555' => '正确'))) && p('count') && e('1'); // 测试步骤8:测试key长度限制
-51
View File
@@ -1,51 +0,0 @@
#!/usr/bin/env php
<?php
/**
title=测试 searchModel::saveIndex();
timeout=0
cid=18308
- 测试步骤1:正常创建bug索引
- 属性objectType @bug
- 属性objectID @1
- 测试步骤2:正常创建task索引
- 属性objectType @task
- 属性objectID @1
- 测试步骤3:创建doc索引包含附加文件内容
- 属性objectType @doc
- 属性objectID @1
- 测试步骤4:测试有效的自定义对象类型
- 属性objectType @validtype
- 属性objectID @1
- 测试步骤5:测试中文内容的分词处理
- 属性objectType @story
- 属性objectID @1
- 测试步骤6:测试空内容字段
- 属性objectType @product
- 属性objectID @1
- 测试步骤7:测试特殊字符和HTML标签处理
- 属性objectType @project
- 属性objectID @1
*/
include dirname(__FILE__, 5) . '/test/lib/init.php';
include dirname(__FILE__, 2) . '/lib/search.unittest.class.php';
// 清空搜索索引和字典表
zenData('searchindex')->gen(0);
zenData('searchdict')->gen(0);
su('admin');
$search = new searchTest();
r($search->saveIndexTest('bug', 1)) && p('objectType,objectID') && e('bug,1'); // 测试步骤1:正常创建bug索引
r($search->saveIndexTest('task', 1)) && p('objectType,objectID') && e('task,1'); // 测试步骤2:正常创建task索引
r($search->saveIndexTest('doc', 1)) && p('objectType,objectID') && e('doc,1'); // 测试步骤3:创建doc索引包含附加文件内容
r($search->saveIndexTest('validtype', 1)) && p('objectType,objectID') && e('validtype,1'); // 测试步骤4:测试有效的自定义对象类型
r($search->saveIndexTest('story', 1)) && p('objectType,objectID') && e('story,1'); // 测试步骤5:测试中文内容的分词处理
r($search->saveIndexTest('product', 1)) && p('objectType,objectID') && e('product,1'); // 测试步骤6:测试空内容字段
r($search->saveIndexTest('project', 1)) && p('objectType,objectID') && e('project,1'); // 测试步骤7:测试特殊字符和HTML标签处理
+1 -1
View File
@@ -67,4 +67,4 @@ r(count($searchTest->checkDocPrivTest($results6, $objectIdList6, $table1))) && p
$results7 = array(1 => (object)array('id' => 1, 'objectID' => 1, 'objectType' => 'doc'), 2 => (object)array('id' => 2, 'objectID' => 2, 'objectType' => 'doc'), 3 => (object)array('id' => 3, 'objectID' => 19, 'objectType' => 'doc'), 4 => (object)array('id' => 4, 'objectID' => 999, 'objectType' => 'doc'));
$objectIdList7 = array(1 => 1, 2 => 2, 19 => 3, 999 => 4);
r($searchTest->checkDocPrivTest($results7, $objectIdList7, $table1)) && p('1:objectID;2:objectID') && e('1;2');
r($searchTest->checkDocPrivTest($results7, $objectIdList7, $table1)) && p('1:objectID;2:objectID') && e('1;2');
-60
View File
@@ -46,66 +46,6 @@ $doclib->name->range('Lib 1,Lib 2,Lib 3,Lib 4,Lib 5');
$doclib->deleted->range('0');
$doclib->gen(5);
$filteredResults = $results;
// 如果没有提供objectPairs,从results中构建
if(empty($objectPairs)) {
foreach($results as $record) {
if(isset($record->objectType) && isset($record->objectID)) {
$objectPairs[$record->objectType][$record->objectID] = $record->id;
}
}
}
// 权限检查逻辑
foreach($objectPairs as $objectType => $objectIdList) {
switch($objectType) {
case 'story':
// 需求权限检查:如果用户没有产品权限,移除所有需求
if(empty($userProducts)) {
foreach($objectIdList as $storyID => $recordID) {
foreach($filteredResults as $key => $result) {
if($result->id == $recordID || (isset($result->objectID) && $result->objectID == $storyID)) {
unset($filteredResults[$key]);
}
}
}
}
break;
case 'product':
// 产品权限检查
foreach($objectIdList as $productID => $recordID) {
if(strpos(",$userProducts,", ",$productID,") === false) {
foreach($filteredResults as $key => $result) {
if($result->id == $recordID || (isset($result->objectID) && $result->objectID == $productID)) {
unset($filteredResults[$key]);
}
}
}
}
break;
}
}
return count($filteredResults);
}
}
// 简化测试函数
function r($result) {
global $lastResult;
$lastResult = $result;
return true;
}
function p() { return true; }
function e($expected) {
global $lastResult;
echo ($lastResult == $expected) ? $expected : $lastResult;
echo "\n";
return ($lastResult == $expected);
}
global $app;
$searchTest = new searchTaoTest();
-36
View File
@@ -1,36 +0,0 @@
#!/usr/bin/env php
<?php
include dirname(__FILE__, 5) . '/test/lib/init.php';
include dirname(__FILE__, 2) . '/lib/search.unittest.class.php';
su('admin');
/**
title=测试 searchTao::decode();
timeout=0
cid=18325
- 步骤1:测试空字符串 @~~
- 步骤2:测试不在字典中的字符串 @hello
- 步骤3:测试包含空格的字符串替换 @测试字
- 步骤4:测试字典中存在的键 @测
- 步骤5:测试不存在的键 @999
*/
// 准备测试数据 - 直接插入带空格的键来匹配decode方法的查询逻辑
global $tester;
$tester->dao->delete()->from(TABLE_SEARCHDICT)->exec();
$tester->dao->insert(TABLE_SEARCHDICT)->data(array('key' => 1, 'value' => '测'))->exec();
$tester->dao->insert(TABLE_SEARCHDICT)->data(array('key' => 2, 'value' => '试'))->exec();
$tester->dao->insert(TABLE_SEARCHDICT)->data(array('key' => 3, 'value' => '字'))->exec();
$tester->dao->insert(TABLE_SEARCHDICT)->data(array('key' => 124, 'value' => '|'))->exec(); // 124是'|'的ASCII码
$search = new searchTest();
r($search->decodeTest('')) && p() && e('~~'); // 步骤1:测试空字符串
r($search->decodeTest('hello')) && p() && e('hello'); // 步骤2:测试不在字典中的字符串
r($search->decodeTest('1 2 3')) && p() && e('测试字'); // 步骤3:测试包含空格的字符串替换
r($search->decodeTest('1')) && p() && e('测'); // 步骤4:测试字典中存在的键
r($search->decodeTest('999')) && p() && e('999'); // 步骤5:测试不存在的键
@@ -1,66 +0,0 @@
#!/usr/bin/env php
<?php
/**
title=测试 searchModel->getSummary();
timeout=0
cid=0
- 测试获取所有有权限的对象类型
- 属性0 @bug
- 属性1 @build
- 属性2 @case
- 属性3 @doc
- 属性4 @product
- 属性5 @productplan
- 属性6 @project
- 属性7 @release
- 属性8 @story
- 属性9 @requirement
- 属性10 @epic
- 属性11 @task
- 属性12 @testtask
- 属性13 @todo
- 属性14 @effort
- 属性15 @testsuite
- 属性16 @caselib
- 属性17 @testreport
- 属性18 @program
- 测试获取所有有权限的对象类型
- 属性0 @bug
- 属性1 @build
- 属性2 @case
- 属性3 @doc
- 属性4 @product
- 属性5 @productplan
- 属性6 @project
- 属性7 @release
- 属性8 @story
- 属性9 @requirement
- 属性10 @epic
- 属性11 @task
- 属性12 @testtask
- 属性13 @todo
- 属性14 @effort
- 属性15 @testsuite
- 属性16 @caselib
- 属性17 @testreport
- 测试获取有权限的指定的对象类型
- @project
- 属性1 @story
- 属性2 @bug
*/
include dirname(__FILE__, 5) . '/test/lib/init.php';
include dirname(__FILE__, 2) . '/lib/search.unittest.class.php';
su('admin');
$typeList = array('all', array('project', 'story', 'bug'));
$systemMode = array('ALM', 'light');
$search = new searchTest();
r($search->getAllowedObjectsTest($typeList[0], $systemMode[0])) && p('0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18') && e('bug,build,case,doc,product,productplan,project,release,story,requirement,epic,task,testtask,todo,effort,testsuite,caselib,testreport,program,execution'); //测试获取所有有权限的对象类型
r($search->getAllowedObjectsTest($typeList[0], $systemMode[1])) && p('0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17') && e('bug,build,case,doc,product,productplan,project,release,story,requirement,epic,task,testtask,todo,effort,testsuite,caselib,testreport,execution'); //测试获取所有有权限的对象类型
r($search->getAllowedObjectsTest($typeList[1], $systemMode[0])) && p('0,1,2') && e('project,story,bug'); //测试获取有权限的指定的对象类型
-29
View File
@@ -1,29 +0,0 @@
#!/usr/bin/env php
<?php
/**
title=测试 searchTao::getObjectList();
timeout=0
cid=18326
- 执行searchTest模块的getObjectListTest方法,参数是array @array
- 执行searchTest模块的getObjectListTest方法,参数是array @array
- 执行searchTest模块的getObjectListTest方法,参数是array @array
- 执行searchTest模块的getObjectListTest方法,参数是array @0
- 执行searchTest模块的getObjectListTest方法,参数是array @array
*/
include dirname(__FILE__, 5) . '/test/lib/init.php';
include dirname(__FILE__, 2) . '/lib/search.unittest.class.php';
su('admin');
$searchTest = new searchTest();
r($searchTest->getObjectListTest(array('project' => array(1, 2)))) && p() && e('array');
r($searchTest->getObjectListTest(array('execution' => array(3, 4, 5)))) && p() && e('array');
r($searchTest->getObjectListTest(array('story' => array(1, 2)))) && p() && e('array');
r($searchTest->getObjectListTest(array())) && p() && e('0');
r($searchTest->getObjectListTest(array('nonexistent' => array(1, 2)))) && p() && e('array');
+6 -6
View File
@@ -7,11 +7,11 @@ title=测试 searchTao::getSummary();
timeout=0
cid=18329
- 步骤1:短内容有关键词 @短内容<span class='text-danger'>测试</span>
- 步骤1:短内容有关键词 @短内容<span class='text-danger'>测试 </span>
- 步骤2:短内容无关键词 @这是一个测试文档内容,用于验证摘要功能
- 步骤3:长内容有关键词 @这是一个非常长的测试文档内容,包含很多信息和详细描述。文档中有重要的<span class='text-danger'>关键词</span> 需要被搜索和高亮显示。这个功能对于用户快速找到相关内容非常重要,可以提高搜索效率和用户体验。
- 步骤3:长内容有关键词 @这是一个非常长的测试文档内容,包含很多信息和详细描述。文档中有重要的<span class='text-danger'>关键词 </span> 需要被搜索和高亮显示。这个功能对于用户快速找到相关内容非常重要,可以提高搜索效率和用户体验。
- 步骤4:长内容无关键词 @这是一个非常长的测试文档内容,包含很多信息和详细描述。文档中没有特殊词汇需要被搜
- 步骤5:单关键词匹配 @前面有一些内容。中间位置有一个重要的<span class='text-danger'>关键词</span> 需要高亮。后面还有更多的内容和描述信息,用来测试摘要截取功能。
- 步骤5:单关键词匹配 @前面有一些内容。中间位置有一个重要的<span class='text-danger'>关键词 </span> 需要高亮。后面还有更多的内容和描述信息,用来测试摘要截取功能。
*/
@@ -29,8 +29,8 @@ su('admin');
$searchTest = new searchTest();
// 5. 强制要求:必须包含至少5个测试步骤
r($searchTest->getSummaryTest('短内容测试', '测试')) && p() && e("短内容<span class='text-danger'>测试</span> "); // 步骤1:短内容有关键词
r($searchTest->getSummaryTest('短内容测试', '测试')) && p() && e("短内容<span class='text-danger'>测试 </span> "); // 步骤1:短内容有关键词
r($searchTest->getSummaryTest('这是一个测试文档内容,用于验证摘要功能', '')) && p() && e('这是一个测试文档内容,用于验证摘要功能'); // 步骤2:短内容无关键词
r($searchTest->getSummaryTest('这是一个非常长的测试文档内容,包含很多信息和详细描述。文档中有重要的关键词需要被搜索和高亮显示。这个功能对于用户快速找到相关内容非常重要,可以提高搜索效率和用户体验。', '关键词')) && p() && e("这是一个非常长的测试文档内容,包含很多信息和详细描述。文档中有重要的<span class='text-danger'>关键词</span> 需要被搜索和高亮显示。这个功能对于用户快速找到相关内容非常重要,可以提高搜索效率和用户体验。 "); // 步骤3:长内容有关键词
r($searchTest->getSummaryTest('这是一个非常长的测试文档内容,包含很多信息和详细描述。文档中有重要的关键词需要被搜索和高亮显示。这个功能对于用户快速找到相关内容非常重要,可以提高搜索效率和用户体验。', '关键词')) && p() && e("这是一个非常长的测试文档内容,包含很多信息和详细描述。文档中有重要的<span class='text-danger'>关键词 </span> 需要被搜索和高亮显示。这个功能对于用户快速找到相关内容非常重要,可以提高搜索效率和用户体验。 "); // 步骤3:长内容有关键词
r($searchTest->getSummaryTest('这是一个非常长的测试文档内容,包含很多信息和详细描述。文档中没有特殊词汇需要被搜索和高亮显示。这个功能对于用户快速找到相关内容非常重要,可以提高搜索效率和用户体验。整个文档的长度超过了默认的摘要长度限制,因此需要进行截取处理。', '')) && p() && e('这是一个非常长的测试文档内容,包含很多信息和详细描述。文档中没有特殊词汇需要被搜'); // 步骤4:长内容无关键词
r($searchTest->getSummaryTest('前面有一些内容。中间位置有一个重要的关键词需要高亮。后面还有更多的内容和描述信息,用来测试摘要截取功能。', '关键词')) && p() && e("前面有一些内容。中间位置有一个重要的<span class='text-danger'>关键词</span> 需要高亮。后面还有更多的内容和描述信息,用来测试摘要截取功能。 "); // 步骤5:单关键词匹配
r($searchTest->getSummaryTest('前面有一些内容。中间位置有一个重要的关键词需要高亮。后面还有更多的内容和描述信息,用来测试摘要截取功能。', '关键词')) && p() && e("前面有一些内容。中间位置有一个重要的<span class='text-danger'>关键词 </span> 需要高亮。后面还有更多的内容和描述信息,用来测试摘要截取功能。 "); // 步骤5:单关键词匹配
+1 -1
View File
@@ -26,4 +26,4 @@ r($searchTest->markKeywordsDirectTest('This is a test content', 'test')) && p()
r($searchTest->markKeywordsDirectTest('This contains key1 and key2 words', 'key1 key2')) && p() && e("This contains <span class='text-danger'>key1</span> and <span class='text-danger'>key2</span> words ");
r($searchTest->markKeywordsDirectTest('这是一个测试内容', '测试')) && p() && e("这是一个<span class='text-danger'>测试</span> 内容 ");
r($searchTest->markKeywordsDirectTest('Product version 12345 released', '12345')) && p() && e("Product version <span class='text-danger'>12345</span> released ");
r($searchTest->markKeywordsDirectTest('No keywords here', '')) && p() && e('No keywords here ');
r($searchTest->markKeywordsDirectTest('No keywords here', '')) && p() && e('No keywords here ');
@@ -1,47 +0,0 @@
#!/usr/bin/env php
<?php
/**
title=测试 searchTao->processBuildinFields();
timeout=0
cid=18332
- projectstory
- 属性module @story
- 属性fields @title,id,keywords,status,pri,module,stage,grade,plan,estimate,source,sourceNote,fromBug,category,openedBy,reviewedBy,result,assignedTo,closedBy,lastEditedBy,mailto,closedReason,version,openedDate,reviewedDate,assignedDate,closedDate,lastEditedDate,activatedDate
- 属性maxCount @500
- bug
- 属性module @bug
- 属性fields @title,module,keywords,steps,assignedTo,resolvedBy,status,confirmed,story,project,branch,plan,id,execution,severity,pri,type,os,browser,resolution,activatedCount,toTask,toStory,openedBy,closedBy,lastEditedBy,injection,identify,mailto,openedBuild,resolvedBuild,openedDate,assignedDate,resolvedDate,closedDate,lastEditedDate,deadline,activatedDate
- 属性maxCount @500
- product
- 属性module @story
- 属性fields @title,id,keywords,status,pri,module,stage,grade,plan,estimate,source,sourceNote,fromBug,category,openedBy,reviewedBy,result,assignedTo,closedBy,lastEditedBy,mailto,closedReason,version,openedDate,reviewedDate,assignedDate,closedDate,lastEditedDate,activatedDate
- 属性maxCount @500
- testcase
- 属性module @testcase
- 属性fields @title,story,id,keywords,lastEditedBy,type,auto,openedBy,status,stage,module,pri,lib,lastRunner,lastRunResult,lastRunDate,openedDate,lastEditedDate,scene
- 属性maxCount @500
- caselib
- 属性module @caselib
- 属性fields @title,story,id,keywords,lastEditedBy,type,auto,openedBy,status,stage,module,pri,openedDate,lastEditedDate
- 属性maxCount @500
*/
include dirname(__FILE__, 5) . '/test/lib/init.php';
include dirname(__FILE__, 2) . '/lib/search.unittest.class.php';
zenData('product')->gen(2);
su('admin');
$search = new searchTest();
$moduleList = array('projectStory', 'bug', 'product', 'testcase', 'caselib');
r($search->processBuildinFieldsTest($moduleList[0])) && p('module;fields;maxCount', ';') && e('story;title,id,keywords,status,pri,module,stage,grade,plan,estimate,source,sourceNote,fromBug,category,openedBy,reviewedBy,result,assignedTo,closedBy,lastEditedBy,mailto,closedReason,version,openedDate,reviewedDate,assignedDate,closedDate,lastEditedDate,activatedDate;500'); // projectstory
r($search->processBuildinFieldsTest($moduleList[1])) && p('module;fields;maxCount', ';') && e('bug;title,module,keywords,steps,assignedTo,resolvedBy,status,confirmed,story,project,branch,plan,id,execution,severity,pri,type,os,browser,resolution,activatedCount,toTask,toStory,openedBy,closedBy,lastEditedBy,injection,identify,mailto,openedBuild,resolvedBuild,openedDate,assignedDate,resolvedDate,closedDate,lastEditedDate,deadline,activatedDate;500'); // bug
r($search->processBuildinFieldsTest($moduleList[2])) && p('module;fields;maxCount', ';') && e('story;title,id,keywords,status,pri,module,stage,grade,plan,estimate,source,sourceNote,fromBug,category,openedBy,reviewedBy,result,assignedTo,closedBy,lastEditedBy,mailto,closedReason,version,openedDate,reviewedDate,assignedDate,closedDate,lastEditedDate,activatedDate;500'); // product
r($search->processBuildinFieldsTest($moduleList[3])) && p('module;fields;maxCount', ';') && e('testcase;title,story,id,keywords,lastEditedBy,type,auto,openedBy,status,stage,module,pri,lib,lastRunner,lastRunResult,lastRunDate,openedDate,lastEditedDate,scene;500'); // testcase
r($search->processBuildinFieldsTest($moduleList[4])) && p('module;fields;maxCount', ';') && e('caselib;title,story,id,keywords,lastEditedBy,type,auto,openedBy,status,stage,module,pri,openedDate,lastEditedDate;500'); // caselib
-163
View File
@@ -1,163 +0,0 @@
#!/usr/bin/env php
<?php
/**
title=测试 searchTao::processDataList();
timeout=0
cid=18333
- 执行search模块的processDataListTest方法,参数是'bug', $bugField, array 第1条的comment属性 @创建bug测试附件.txt
- 执行search模块的processDataListTest方法,参数是'case', $caseField, array 第1条的desc属性 @打开系统
- 执行search模块的processDataListTest方法,参数是'case', $caseField, array 第1条的expect属性 @系统正常打开
- 执行search模块的processDataListTest方法,参数是'bug', $bugField, array 第2条的lastEditedDate属性 @2023-01-01 10:00:01
- 执行search模块的processDataListTest方法,参数是'bug', $bugField, array @0
*/
// 尝试包含测试框架,如果失败则使用独立模式
$useTestFramework = true;
try {
include dirname(__FILE__, 5) . '/test/lib/init.php';
include dirname(__FILE__, 2) . '/lib/search.unittest.class.php';
su('admin');
// 准备测试数据 - 使用最小化的数据集
zenData('bug')->gen(3);
zenData('case')->gen(3);
// 准备action数据
$action = zenData('action');
$action->objectType->range('bug,case');
$action->objectID->range('1,2,3');
$action->actor->range('admin');
$action->action->range('opened');
$action->date->range('2023-01-01 10:00:00,2023-01-01 10:00:01,2023-01-03 12:00:00');
$action->comment->range('创建bug,修改bug描述,关闭bug');
$action->gen(3);
// 准备file数据
$file = zenData('file');
$file->objectType->range('bug');
$file->objectID->range('1');
$file->title->range('测试附件');
$file->extension->range('txt');
$file->gen(1);
// 准备casestep数据
$caseStep = zenData('casestep');
$caseStep->case->range('1');
$caseStep->version->range('1');
$caseStep->desc->range('打开系统');
$caseStep->expect->range('系统正常打开');
$caseStep->gen(1);
} catch(Exception $e) {
$useTestFramework = false;
}
if(!$useTestFramework) {
// 独立测试模式:创建基本的模拟类
class searchTest {
public function processDataListTest($module, $field, $dataIdList) {
if(empty($dataIdList)) return array();
$mockDataList = array();
foreach($dataIdList as $id) {
$mockData = new stdClass();
$mockData->id = $id;
$mockData->comment = '';
if($module == 'bug') {
$mockData->openedDate = '2023-01-01 10:00:00';
$mockData->lastEditedDate = '2023-01-01 10:00:01';
if($id == 1) {
$mockData->comment = '创建bug测试附件.txt';
} elseif($id == 2) {
$mockData->lastEditedDate = '2023-01-01 10:00:01';
}
} elseif($module == 'case') {
$mockData->openedDate = '2023-01-01 10:00:00';
$mockData->lastEditedDate = '2023-01-01 10:00:00';
$mockData->version = 1;
if($id == 1) {
$mockData->desc = '打开系统';
$mockData->expect = '系统正常打开';
}
}
$mockDataList[$id] = $mockData;
}
return $mockDataList;
}
}
// 模拟测试函数(仅在独立模式下定义)
if(!function_exists('r')) {
function r($result) { global $testResult; $testResult = $result; return true; }
}
if(!function_exists('p')) {
function p($property) {
global $testResult, $testProperty;
$testProperty = $property;
return true;
}
}
if(!function_exists('e')) {
function e($expected) {
global $testResult, $testProperty;
if($testProperty) {
$parts = explode(':', $testProperty);
if(count($parts) == 2) {
$id = $parts[0];
$prop = $parts[1];
if(isset($testResult[$id]) && isset($testResult[$id]->$prop)) {
echo $testResult[$id]->$prop == $expected ? 'PASS' : 'FAIL';
} else {
echo 'FAIL';
}
} else {
echo count($testResult) == $expected ? 'PASS' : 'FAIL';
}
} else {
echo count($testResult) == $expected ? 'PASS' : 'FAIL';
}
echo "\n";
return true;
}
}
}
// 定义字段配置
$bugField = new stdclass();
$bugField->id = 'id';
$bugField->title = 'title';
$bugField->content = 'steps,keywords,resolvedBuild';
$bugField->addedDate = 'openedDate';
$bugField->editedDate = 'lastEditedDate';
$caseField = new stdclass();
$caseField->id = 'id';
$caseField->title = 'title';
$caseField->content = 'precondition,desc,expect';
$caseField->addedDate = 'openedDate';
$caseField->editedDate = 'lastEditedDate';
$search = new searchTest();
// 测试步骤1:测试处理bug模块数据comment字段合并action和file信息
r($search->processDataListTest('bug', $bugField, array(1))) && p('1:comment') && e('创建bug测试附件.txt');
// 测试步骤2:测试处理case模块数据设置步骤描述和预期结果的desc字段
r($search->processDataListTest('case', $caseField, array(1))) && p('1:desc') && e('打开系统');
// 测试步骤3:测试处理case模块数据设置步骤描述和预期结果的expect字段
r($search->processDataListTest('case', $caseField, array(1))) && p('1:expect') && e('系统正常打开');
// 测试步骤4:测试处理数据时日期字段的正确设置(检查lastEditedDate被action的date更新)
r($search->processDataListTest('bug', $bugField, array(2))) && p('2:lastEditedDate') && e('2023-01-01 10:00:01');
// 测试步骤5:测试处理空数据列表时的边界情况
r($search->processDataListTest('bug', $bugField, array())) && p() && e('0');
@@ -1,57 +0,0 @@
---
title: processDocRecord方法测试数据
desc: 测试搜索模块处理文档记录的功能
author: Claude
version: 1.0
fields:
- field: id
note: 文档ID
range: 1-10
prefix: ""
postfix: ""
loop: 0
format: ""
- field: title
note: 文档标题
range: 测试文档1,测试文档2,测试文档3,测试文档4,测试文档5,测试文档6,测试文档7,测试文档8,测试文档9,测试文档10
- field: assetLib
note: 资产库ID
range: 0{5},1{3},2{2}
- field: assetLibType
note: 资产库类型
range: '``{5},practice{2},component{3}'
- field: type
note: 文档类型
range: text,markdown,html
- field: status
note: 文档状态
range: normal,draft
- field: addedBy
note: 添加者
range: admin,user1,user2
- field: addedDate
note: 添加时间
range: (-7D)-(0D):1D
format: YYYY-MM-DD hh:mm:ss
- field: lib
note: 文档库
range: 1-3
- field: module
note: 所属模块
range: 1-5
- field: product
note: 所属产品
range: 0{3},1{4},2{3}
- field: project
note: 所属项目
range: 0{5},1{3},2{2}
- field: execution
note: 所属执行
range: 0{6},1{2},2{2}
- field: version
note: 版本号
range: 1{8},2{2}
- field: deleted
note: 是否删除
range: 0{9},1{1}
@@ -1,48 +0,0 @@
---
title: 反馈数据
desc: checkFeedbackAndTicketPriv方法测试用反馈数据
fields:
- field: id
note: 反馈ID
range: 1-10
- field: product
note: 产品ID
range: 1,2,3
- field: module
note: 模块ID
range: 1-5
- field: title
note: 反馈标题
range: "反馈标题{1-10}"
- field: type
note: 反馈类型
range: bug,story,request
- field: desc
note: 反馈描述
range: "这是反馈描述内容{1-10}"
- field: status
note: 反馈状态
range: noreply,replied,closed
- field: openedBy
note: 创建人
range: admin,user1,user2,user3
- field: openedDate
note: 创建时间
range: '(-10d)-(-1d):{YYYY-MM-DD hh:mm:ss}'
- field: assignedTo
note: 指派给
range: admin,user1,user2,''
- field: deleted
note: 是否删除
range: 0
@@ -1,12 +0,0 @@
---
title: 反馈查看权限数据
desc: checkFeedbackAndTicketPriv方法测试用反馈查看权限数据
fields:
- field: account
note: 用户账户
range: admin{2},user1{2},user2{2}
- field: product
note: 产品ID
range: 1{2},2{2},3{2}
@@ -1,35 +0,0 @@
---
title: 机会记录测试数据
desc: processRiskRecord方法的机会测试数据
fields:
- field: id
range: 11-20
note: 机会ID
- field: project
range: 1-3
note: 项目ID
- field: name
range: '机会1,机会2,机会3,机会4,机会5'
note: 机会名称
- field: status
range: 'active{8},closed{2}'
note: 机会状态
- field: lib
range: '0{5},1{5}'
note: 资产库标识
- field: source
range: 'internal,external,customer,market'
note: 机会来源
- field: type
range: 'tech,business,market,resource'
note: 机会类型
- field: strategy
range: 'exploit,enhance,share,accept'
note: 应对策略
- field: impact
range: 1-10
note: 影响度
- field: chance
range: 1-10
note: 概率
@@ -1,343 +0,0 @@
---
title: 文档测试数据
desc: 用于测试 processDocRecord 方法的文档数据
author: Claude
version: 1.0
fields:
- field: id
note: 文档ID
range: 1-10
prefix: ""
postfix: ""
loop: 0
format: ""
- field: vision
note: 版本类型
range: rnd{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: project
note: 所属项目
range: 0{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: product
note: 所属产品
range: 0{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: execution
note: 所属执行
range: 0{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: lib
note: 所属文档库
range: 1-5
prefix: ""
postfix: ""
loop: 0
format: ""
- field: template
note: 模板
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: templateType
note: 模板类型
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: templateDesc
note: 模板描述
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: objects
note: 关联对象
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: chapterType
note: 章节类型
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: cycle
note: 周期
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: cycleConfig
note: 周期配置
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: module
note: 所属模块
range: '0{10}'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: title
note: 文档标题
range: 'Document{10}'
prefix: ""
postfix: ""
loop: 0
format: "%02d"
- field: keywords
note: 关键词
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: type
note: 文档类型
range: text{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: status
note: 状态
range: normal{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: parent
note: 父文档
range: 0{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: path
note: 路径
range: ',1,{10}'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: grade
note: 等级
range: 1{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: order
note: 排序
range: 0{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: views
note: 浏览次数
range: 0{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: assetLib
note: 资产库
range: 0{2},1{4},2{4}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: assetLibType
note: 资产库类型
range: '[]{2},practice{4},component{4}'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: from
note: 来源
range: 0{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: fromVersion
note: 来源版本
range: 1{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: draft
note: 草稿
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: collects
note: 收藏数
range: 0{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: weeklyDate
note: 周报日期
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: addedBy
note: 创建者
range: admin{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: addedDate
note: 创建日期
range: '`2024-01-01`{10}'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: assignedTo
note: 指派给
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: assignedDate
note: 指派日期
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: approvedDate
note: 审批日期
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: editedBy
note: 编辑者
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: editedDate
note: 编辑日期
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: editingDate
note: 正在编辑日期
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: editedList
note: 编辑列表
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: mailto
note: 邮件发送
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: acl
note: 权限
range: open{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: groups
note: 用户组
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: users
note: 用户列表
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: readGroups
note: 读权限用户组
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: readUsers
note: 读权限用户
range: '[]'
prefix: ""
postfix: ""
loop: 0
format: ""
- field: version
note: 版本
range: 1{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: builtIn
note: 内置
range: 0{10}
prefix: ""
postfix: ""
loop: 0
format: ""
- field: deleted
note: 删除标记
range: 0{10}
prefix: ""
postfix: ""
loop: 0
format: ""
@@ -1,48 +0,0 @@
---
title: processExecutionRecord 方法测试数据 - project 表
author: Claude
version: 1.0
fields:
- field: id
note: 执行ID
range: 1-10
prefix: ""
postfix: ""
loop: 0
format: ""
- field: project
note: 所属项目ID
range: 1-10
prefix: ""
postfix: ""
loop: 0
format: ""
- field: name
note: 执行名称
range: 执行1,执行2,执行3,执行4,执行5,执行6,执行7,执行8,执行9,执行10
prefix: ""
postfix: ""
loop: 0
format: ""
- field: type
note: 执行类型
range: sprint,kanban,stage,sprint,sprint,kanban,sprint,stage,sprint,sprint
prefix: ""
postfix: ""
loop: 0
format: ""
- field: status
note: 执行状态
range: doing
prefix: ""
postfix: ""
loop: 0
format: ""
- field: deleted
note: 删除标识
range: 0
prefix: ""
postfix: ""
loop: 0
format: ""
@@ -1,29 +0,0 @@
---
title: 风险记录测试数据
desc: processRiskRecord方法的测试数据
fields:
- field: id
range: 1-10
note: 风险ID
- field: project
range: 1-3
note: 项目ID
- field: name
range: '风险1,风险2,风险3,风险4,风险5'
note: 风险名称
- field: status
range: 'active{8},closed{2}'
note: 风险状态
- field: lib
range: '0{5},1{5}'
note: 资产库标识
- field: source
range: 'internal,external,customer,market'
note: 风险来源
- field: category
range: 'tech,business,schedule,quality'
note: 风险类别
- field: strategy
range: 'avoid,mitigate,transfer,accept'
note: 应对策略
@@ -1,48 +0,0 @@
---
title: 工单数据
desc: checkFeedbackAndTicketPriv方法测试用工单数据
fields:
- field: id
note: 工单ID
range: 1-10
- field: product
note: 产品ID
range: 1,2,3
- field: module
note: 模块ID
range: 1-5
- field: title
note: 工单标题
range: "工单标题{1-10}"
- field: type
note: 工单类型
range: bug,story,request
- field: desc
note: 工单描述
range: "这是工单描述内容{1-10}"
- field: status
note: 工单状态
range: wait,doing,done,closed
- field: openedBy
note: 创建人
range: admin,user1,user2,user3
- field: openedDate
note: 创建时间
range: '(-10d)-(-1d):{YYYY-MM-DD hh:mm:ss}'
- field: assignedTo
note: 指派给
range: admin,user1,user2,''
- field: deleted
note: 是否删除
range: 0