znt/module/testcase/tao.php

834 lines
30 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
class testcaseTao extends testcaseModel
{
/**
* 获取用例的基础数据。
* Fetch base info of a case.
*
* @param int $caseID
* @access protected
* @return object|false
*/
protected function fetchBaseInfo(int $caseID): object|false
{
return $this->dao->select('*')->from(TABLE_CASE)->where('id')->eq($caseID)->fetch();
}
/**
* 查询场景名称。
* Fetch scene name.
*
* @param int $sceneID
* @access protected
* @return void
*/
protected function fetchSceneName(int $sceneID): string|null
{
return $this->dao->findByID($sceneID)->from(TABLE_SCENE)->fetch('title');
}
/**
* 通过用例的 id 列表查询步骤。
* Fetch step by id list.
*
* @param array $caseIdList
* @access protected
* @return array
*/
protected function fetchStepsByList(array $caseIdList): array
{
return $this->dao->select('t2.*')->from(TABLE_CASE)->alias('t1')
->leftJoin(TABLE_CASESTEP)->alias('t2')->on('t1.id = t2.case')
->where('t1.id')->in($caseIdList)
->andWhere('t1.version=t2.version')
->orderBy('t2.id')
->fetchGroup('case');
}
/**
* 获取某个项目下某个模块的用例列表。
* Get project cases of a module.
*
* @param int|array $productID
* @param int|string $branch
* @param int $moduleIdList
* @param string $browseType
* @param string $auto no|unit
* @param string $caseType
* @param string $orderBy
* @param object $pager
* @access protected
* @return array
*/
protected function getModuleProjectCases(int|array $productID, int|string $branch = 0, int|array $moduleIdList = 0, string $browseType = '', string $auto = 'no', string $caseType = '', string $orderBy = 'id_desc', ?object $pager = null): array
{
return $this->dao->select('DISTINCT t1.product, t1.case, t1.version, t2.*, t4.title AS storyTitle')->from(TABLE_PROJECTCASE)->alias('t1')
->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case = t2.id')
->leftJoin(TABLE_PROJECTSTORY)->alias('t3')->on('t3.story = t2.story')
->leftJoin(TABLE_STORY)->alias('t4')->on('t3.story = t4.id')
->where('t1.project')->eq((int)$this->session->project)
->beginIF(!empty($productID))->andWhere('t2.product')->in($productID)->fi()
->beginIF(!empty($productID) && $branch !== 'all')->andWhere('t2.branch')->eq($branch)->fi()
->beginIF($moduleIdList)->andWhere('t2.module')->in($moduleIdList)->fi()
->beginIF($browseType == 'wait')->andWhere('t2.status')->eq($browseType)->fi()
->beginIF($auto == 'auto' || $auto == 'unit')->andWhere('t2.auto')->eq($auto)->fi()
->beginIF($auto != 'auto' && $auto != 'unit')->andWhere('t2.auto')->ne('unit')->fi()
->beginIF($caseType)->andWhere('t2.type')->eq($caseType)->fi()
->andWhere('t2.deleted')->eq('0')
->orderBy($orderBy)
->page($pager, 't1.`case`')
->fetchAll('id');
}
/**
* 获取待确认的用例列表。
* Get need confirm case list.
*
* @param int|array $productID
* @param string|int $branch
* @param array $modules
* @param string $auto
* @param string $caseType
* @param string $sort
* @param object $pager
* @access protected
* @return array
*/
protected function getNeedConfirmList(int|array $productID, string|int $branch, array $modules, string $auto, string $caseType, string $sort, ?object $pager = null): array
{
return $this->dao->select('distinct t1.*, t2.title AS storyTitle')->from(TABLE_CASE)->alias('t1')
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
->leftJoin(TABLE_PROJECTCASE)->alias('t3')->on('t1.id = t3.case')
->where('t2.status')->eq('active')
->andWhere('t1.deleted')->eq('0')
->andWhere('t2.version > t1.storyVersion')
->beginIF(!empty($productID))->andWhere('t1.product')->in($productID)->fi()
->beginIF(!empty($productID) && $branch !== 'all')->andWhere('t1.branch')->eq($branch)->fi()
->beginIF($this->app->tab == 'project')->andWhere('t3.project')->eq($this->session->project)->fi()
->beginIF($modules)->andWhere('t1.module')->in($modules)->fi()
->beginIF($auto == 'auto' || $auto == 'unit')->andWhere('t1.auto')->eq($auto)->fi()
->beginIF($auto != 'auto' && $auto != 'unit')->andWhere('t1.auto')->ne('unit')->fi()
->beginIF($caseType)->andWhere('t1.type')->eq($caseType)->fi()
->orderBy($sort)
->page($pager, 't1.id')
->fetchAll();
}
/**
* 根据套件获取用例。
* Get cases by suite.
*
* @param int $productID
* @param int|string $branch
* @param int $suiteID
* @param array $moduleIdList
* @param string $auto no|unit
* @param string $orderBy
* @param object $pager
* @access public
* @return array
*/
public function getBySuite(int $productID, int|string $branch = 0, int $suiteID = 0, array|int $moduleIdList = 0, string $auto = 'no', string $orderBy = 'id_desc', ?object $pager = null): array
{
return $this->dao->select('t1.*, t2.title AS storyTitle, t3.version AS version')->from(TABLE_CASE)->alias('t1')
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
->leftJoin(TABLE_SUITECASE)->alias('t3')->on('t1.id = t3.case')
->where('t1.product')->eq($productID)
->beginIF($branch !== 'all')->andWhere('t1.branch')->eq($branch)->fi()
->beginIF($this->app->tab == 'project')->andWhere('t1.project')->eq($this->session->project)->fi()
->andWhere('t3.suite')->eq($suiteID)
->beginIF($moduleIdList)->andWhere('t1.module')->in($moduleIdList)->fi()
->beginIF($auto == 'auto' || $auto == 'unit')->andWhere('t1.auto')->eq($auto)->fi()
->beginIF($auto != 'auto' && $auto != 'unit')->andWhere('t1.auto')->ne('unit')->fi()
->andWhere('t1.deleted')->eq('0')
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
}
/**
* 插入用例的步骤。
* Insert the steps of the case.
*
* @param int $caseID
* @param array $steps
* @param array $expects
* @param array $stepTypes
* @access protected
* @return void
*/
protected function insertSteps(int $caseID, array $steps, array $expects, array $stepTypes, int $version = 1)
{
$preGrade = 0;
$parentStepID = $grandPaStepID = 0;
foreach($steps as $stepKey => $stepDesc)
{
/* 跳过步骤描述为空的步骤。 */
/* If step desc is empty, skip it. */
if(empty($stepDesc)) continue;
/* 计算步骤类型和层级。 */
/* Set step type and step grade. */
$stepType = $stepTypes[$stepKey];
$grade = substr_count((string)$stepKey, '.');
/* 如果当前步骤层级为0父ID和祖父ID清0。 */
/* If step grade is zero, set parent step id and grand step id to zero. */
if($grade == 0)
{
$parentStepID = $grandPaStepID = 0;
}
/* 如果前一个步骤的层级比当前步骤的层级大将父ID设置为祖父ID祖父ID清0。 */
/* If previous step grade is greater than current step grade, set parent step id to grand step id, and set grand step id to zero. */
elseif($preGrade > $grade)
{
$parentStepID = $grandPaStepID;
$grandPaStepID = 0;
}
/* 构建步骤数据,插入步骤。 */
/* Build step data, and insert it. */
$step = new stdClass();
$step->type = $stepType;
$step->parent = $parentStepID;
$step->case = $caseID;
$step->version = $version;
$step->desc = rtrim(htmlSpecialString($stepDesc));
$step->expect = $stepType == 'group' ? '' : rtrim(htmlSpecialString(zget($expects, $stepKey, '')));
$this->dao->insert(TABLE_CASESTEP)->data($step)->autoCheck()->exec();
/* 如果步骤类型是group将祖父ID设置为父ID父ID设置为当前步骤ID。 */
/* If step type is group, set grand step id to parent step id and set parent step id to current step id. */
if($stepType == 'group')
{
$grandPaStepID = $parentStepID;
$parentStepID = $this->dao->lastInsertID();
}
$preGrade = $grade;
}
}
/**
* 获取用例步骤。
* Get case steps.
*
* @param int $caseID
* @param int $version
* @access public
* @return array
*/
public function getSteps(int $caseID, int $version): array
{
$steps = $this->dao->select('`id`,`desc`,`expect`,`type`,`parent`')->from(TABLE_CASESTEP)->where('`case`')->eq($caseID)->andWhere('version')->eq($version)->orderBy('id')->fetchAll('id');
return $this->processSteps($steps);
}
/**
* 处理用例步骤。
* Process case steps.
*
* @param array $steps
* @access public
* @return array
*/
public function processSteps(array $steps): array
{
$caseSteps = array();
$preGrade = 1;
$parentSteps = array();
$key = array(0, 0, 0);
foreach($steps as $step)
{
$parentSteps[$step->id] = $step->parent;
$grade = 1;
if(isset($parentSteps[$step->parent])) $grade = isset($parentSteps[$parentSteps[$step->parent]]) ? 3 : 2;
if($grade > $preGrade)
{
$key[$grade - 1] = 1;
}
else
{
if($grade < $preGrade)
{
if($grade < 2) $key[1] = 0;
if($grade < 3) $key[2] = 0;
}
$key[$grade - 1] ++;
}
$name = implode('.', $key);
$name = str_replace('.0', '', $name);
$data = new stdclass();
$data->name = str_replace('.0', '', $name);
$data->id = $step->id;
$data->step = htmlspecialchars_decode($step->desc);
$data->desc = htmlspecialchars_decode($step->desc);
$data->expect = htmlspecialchars_decode($step->expect);
$data->type = $step->type;
$data->parent = $step->parent;
$data->grade = $grade;
$caseSteps[] = $data;
$preGrade = $grade;
}
return $caseSteps;
}
/**
* 获取相关的需求。
* Get related stories.
*
* @param array $cases
* @access public
* @return array
*/
protected function getRelatedStories(array $cases): array
{
$relatedStoryIdList = array();
foreach($cases as $case) $relatedStoryIdList[$case->story] = $case->story;
return $this->dao->select('id, title')->from(TABLE_STORY)->where('id')->in($relatedStoryIdList)->fetchPairs();
}
/**
* 获取相关的用例。
* Get related cases.
*
* @param array $cases
* @access public
* @return array
*/
protected function getRelatedCases(array $cases): array
{
$relatedCaseIdList = array();
foreach($cases as $case)
{
$linkCases = explode(',', $case->linkCase);
foreach($linkCases as $linkCaseID)
{
if($linkCaseID) $relatedCaseIdList[$linkCaseID] = trim($linkCaseID);
}
}
return $this->dao->select('id, title')->from(TABLE_CASE)->where('id')->in($relatedCaseIdList)->fetchPairs();
}
/**
* 获取相关的步骤。
* Get related steps.
*
* @param array $caseIdList
* @access public
* @return array
*/
protected function getRelatedSteps(array $caseIdList): array
{
return $this->dao->select('DISTINCT t2.id, t2.parent, t2.`case`, t2.version, t2.type, t2.`desc`, t2.expect')
->from(TABLE_CASE)->alias('t1')
->leftJoin(TABLE_CASESTEP)->alias('t2')->on('t1.id = t2.`case` and t1.version = t2.version')
->where('t1.id')->in($caseIdList)
->orderBy('t2.id')
->fetchGroup('case', 'id');
}
/**
* 获取相关的附件。
* Get related files.
*
* @param array $caseIdList
* @access public
* @return array
*/
protected function getRelatedFiles(array $caseIdList): array
{
return $this->dao->select('*')->from(TABLE_FILE)->where('objectType')->eq('testcase')->andWhere('objectID')->in($caseIdList)->andWhere('extra')->ne('editor')->fetchGroup('objectID', 'id');
}
/**
* 创建一个测试用例。
* Create a test case.
*
* @param object $case
* @access protected
* @return bool
*/
protected function doCreate(object $case): bool
{
if(empty($case->product)) $this->config->testcase->create->requiredFields = str_replace(array('story', 'scene'), '', $this->config->testcase->create->requiredFields);
if(!empty($case->lib)) $this->config->testcase->create->requiredFields = str_replace('product', '', $this->config->testcase->create->requiredFields);
$this->dao->insert(TABLE_CASE)->data($case, 'steps,expects,files,labels,stepType,needReview,scriptFile,scriptName')
->autoCheck()
->batchCheck($this->config->testcase->create->requiredFields, 'notempty')
->checkFlow()
->exec();
return !dao::isError();
}
/**
* 创建一个测试用例名称和前置条件。
* Create a test case spec.
*
* @param int $caseID
* @param object $case
* @param array|string $files
* @access protected
* @return void
*/
protected function doCreateSpec(int $caseID, object $case, array|string $files = array()): void
{
if(empty($caseID)) return;
$spec = new stdclass();
$spec->case = $caseID;
$spec->version = zget($case, 'version', 1);
$spec->title = $case->title;
$spec->precondition = zget($case, 'precondition', '');
$spec->files = is_string($files) ? $files : implode(',', array_keys($files));
$this->dao->insert(TABLE_CASESPEC)->data($spec)->exec();
}
/**
* 更新一个测试用例。
* Update a test case.
*
* @param object $case
* @access protected
* @return bool
*/
protected function doUpdate(object $case): bool
{
/* Remove the require field named story when the case is a lib case.*/
$requiredFields = $this->config->testcase->edit->requiredFields;
if(!empty($case->lib)) $requiredFields = str_replace(array('story', 'scene'), '', $requiredFields);
$this->dao->update(TABLE_CASE)->data($case, 'deleteFiles,uid,stepChanged,comment,steps,expects,stepType,linkBug,renameFiles,addedFiles,files')
->autoCheck()
->batchCheck($requiredFields, 'notempty')
->checkFlow()
->where('id')->eq((int)$case->id)
->exec();
return !dao::isError();
}
/*
* 处理用例和项目的关系。
* Deal with the relationship between the case and project when edit the case.
*
* @param object $oldCase
* @param object $case
* @access public
* @return void
*/
protected function updateCase2Project(object $oldCase, object $case): bool
{
$productChanged = $oldCase->product != $case->product;
$storyChanged = $oldCase->story != zget($case, 'story', $oldCase->story);
if(!$productChanged && !$storyChanged) return true;
if($productChanged) $this->dao->update(TABLE_PROJECTCASE)->set('product')->eq($case->product)->set('version')->eq($case->version)->where('`case`')->eq($oldCase->id)->exec();
if($storyChanged)
{
/* 取消之前需求对应项目和用例的关联关系。*/
/* If the new related story isn't linked the project, unlink the case. */
$projects = $this->dao->select('project')->from(TABLE_PROJECTSTORY)->where('story')->eq($oldCase->story)->fetchAll('project');
$this->dao->delete()->from(TABLE_PROJECTCASE)->where('project')->in(array_keys($projects))->andWhere('`case`')->eq($oldCase->id)->exec();
/* 设置需求对应项目和用例的关联关系。*/
/* If the new related story is not null, make the case link the project which link the new related story. */
if(!empty($case->story))
{
$projects = $this->dao->select('project')->from(TABLE_PROJECTSTORY)->where('story')->eq($case->story)->fetchAll('project');
if($projects)
{
$projects = array_keys($projects);
$lastOrders = $this->dao->select('project, MAX(`order`) AS lastOrder')->from(TABLE_PROJECTCASE)->where('project')->in($projects)->groupBy('project')->fetchPairs();
foreach($projects as $projectID)
{
$lastOrder = isset($lastOrders[$projectID]) ? $lastOrders[$projectID] : 0;
$data = new stdclass();
$data->project = $projectID;
$data->product = $case->product;
$data->case = $oldCase->id;
$data->version = $oldCase->version;
$data->order = ++ $lastOrder;
$this->dao->replace(TABLE_PROJECTCASE)->data($data)->autoCheck()->exec();
}
}
}
}
return !dao::isError();
}
/**
* 更新用例步骤。
* Update step.
*
* @param object $case
* @param object $oldCase
* @access protected
* @return bool
*/
protected function updateStep(object $case, object $oldCase): bool
{
if($oldCase->lib && empty($oldCase->product))
{
$fromcaseVersion = $this->dao->select('fromCaseVersion')->from(TABLE_CASE)->where('fromCaseID')->eq($case->id)->fetch('fromCaseVersion');
$fromcaseVersion = (int)$fromcaseVersion + 1;
$this->dao->update(TABLE_CASE)->set('`fromCaseVersion`')->eq($fromcaseVersion)->where('`fromCaseID`')->eq($case->id)->exec();
}
if($case->steps)
{
$this->insertSteps($oldCase->id, $case->steps, $case->expects, (array)$case->stepType, $case->version);
}
else
{
foreach($oldCase->steps as $step)
{
unset($step->id);
unset($step->name);
unset($step->step);
unset($step->grade);
$step->case = $oldCase->id;
$step->version = $case->version;
$this->dao->insert(TABLE_CASESTEP)->data($step)->autoCheck()->exec();
}
}
return !dao::isError();
}
/**
* 更新用例和 bug 的关联关系。
* Link bugs with case.
*
* @param int $caseID
* @param array $linkedBugs
* @param object $case
* @access protected
* @return bool
*/
protected function linkBugs(int $caseID, array $linkedBugs, object $case): bool
{
$toLinkBugs = $case->linkBug;
$newBugs = array_diff($toLinkBugs, $linkedBugs);
$removeBugs = array_diff($linkedBugs, $toLinkBugs);
foreach($newBugs as $bugID)
{
$this->dao->update(TABLE_BUG)->set('`case`')->eq($caseID)->set('caseVersion')->eq($case->version)->set('`story`')->eq($case->story)->set('storyVersion')->eq($case->storyVersion)->where('id')->eq($bugID)->exec();
if($this->config->edition != 'open')
{
$relation = new stdClass();
$relation->relation = 'generated';
$relation->AID = $bugID;
$relation->AType = 'bug';
$relation->BID = $caseID;
$relation->BType = 'testcase';
$relation->product = 0;
$this->dao->replace(TABLE_RELATION)->data($relation)->exec();
}
}
foreach($removeBugs as $bugID)
{
$this->dao->update(TABLE_BUG)->set('`case`')->eq(0)->set('caseVersion')->eq(0)->set('`story`')->eq(0)->set('storyVersion')->eq(0)->where('id')->eq($bugID)->exec();
if($this->config->edition != 'open')
{
$this->dao->delete()->from(TABLE_RELATION)
->where('relation')->eq('generated')
->andWhere('AID')->eq($bugID)
->andWhere('AType')->eq('bug')
->andWhere('BID')->eq($caseID)
->andWhere('BType')->eq('testcase')
->exec();
}
}
return !dao::isError();
}
/**
* 解除用例和测试单的关联。
* Unlink case from test task.
*
* @param int $caseID
* @param array $testtasks
* @access protected
* @return bool
*/
protected function unlinkCaseFromTesttask(int $caseID, int $branch, array $testtasks): bool
{
$this->loadModel('action');
foreach($testtasks as $taskID => $testtask)
{
if(strpos(",{$testtask->branch},", ",{$branch},") === false && $taskID)
{
$this->dao->delete()->from(TABLE_TESTRUN)->where('task')->eq($taskID)->andWhere('`case`')->eq($caseID)->exec();
$this->action->create('case' ,$caseID, 'unlinkedfromtesttask', '', $taskID);
}
}
return !dao::isError();
}
/**
* 获取待评审的用例数量。
* Get the amount of cases pending review.
*
* @access protected
* @return int
*/
protected function getReviewAmount(): int
{
return $this->dao->select('COUNT(id) AS count')->from(TABLE_CASE)->where('status')->eq('wait')->fetch('count');
}
/**
* 导入步骤。
* Import steps.
*
* @param int $caseID
* @param array $steps
* @access public
* @return bool
*/
public function importSteps(int $caseID, array $steps): bool
{
/* 插入步骤。 */
/* Insert steps. */
$parentSteps = array();
foreach($steps as $stepID => $step)
{
$step->case = $caseID;
if(!empty($parentSteps[$step->parent])) $step->parent = $parentSteps[$step->parent];
unset($step->id);
$this->dao->insert(TABLE_CASESTEP)->data($step)->exec();
$parentSteps[$stepID] = $this->dao->lastInsertID();
}
return !dao::isError();
}
/**
* 导入文件。
* Import files.
*
* @param int $caseID
* @param array $files
* @access public
* @return bool
*/
public function importFiles(int $caseID, array $files): bool
{
/* 插入文件。 */
/* Insert files. */
foreach($files as $fileID => $file)
{
if(isset($file->oldpathname))
{
$file->pathname = str_replace('.', "copy{$caseID}.", $file->oldpathname);
if(!empty($file->oldpathname))
{
$originName = pathinfo($file->oldpathname, PATHINFO_FILENAME);
$datePath = substr($file->oldpathname, 0, 6);
$originFile = $this->app->getAppRoot() . "www/data/upload/{$this->app->company->id}/" . "{$datePath}/" . $originName;
$copyName = $originName . 'copy' . $caseID;
$copyFile = $this->app->getAppRoot() . "www/data/upload/{$this->app->company->id}/" . "{$datePath}/" . $copyName;
copy($originFile, $copyFile);
}
unset($file->oldpathname);
}
$file->objectID = $caseID;
$file->addedBy = $this->app->user->account;
$file->addedDate = helper::now();
$file->downloads = 0;
unset($file->id);
$this->dao->insert(TABLE_FILE)->data($file)->exec();
}
return !dao::isError();
}
/**
* 保存场景。
* Save scene.
*
* @param array $sceneData
* @param array $sceneList
* @access protected
* @return array
*/
protected function saveScene(array $sceneData, array $sceneList): array
{
$scene = new stdclass();
$scene->title = $sceneData['name'];
$scene->product = $sceneData['product'];
$scene->branch = $sceneData['branch'];
$scene->module = $sceneData['module'] ?? 0;
if(!isset($sceneData['id']))
{
$scene->openedBy = $this->app->user->account;
$scene->openedDate = helper::now();
$this->dao->insert(TABLE_SCENE)->data($scene)->autoCheck()->exec();
$sceneID = $this->dao->lastInsertID();
$this->dao->update(TABLE_SCENE)->set('sort')->eq($sceneID)->where('id')->eq($sceneID)->exec();
}
else
{
$sceneID = $sceneData['id'];
$scene->lastEditedBy = $this->app->user->account;
$scene->lastEditedDate = helper::now();
$affectedRows = $this->dao->update(TABLE_SCENE)->data($scene)->where('id')->eq($sceneID)->exec();
if(empty($affectedRows)) return array('result' => 'fail', 'message' => sprintf($this->lang->testcase->errorSceneNotExist, $sceneID));
}
if(dao::isError()) return array('result' => 'fail', 'message' => dao::getError());
$tmpPId = $sceneData['tmpPId'];
$pScene = zget($sceneList, $tmpPId, array());
$this->fixScenePath($sceneID, $pScene);
if(dao::isError()) return array('result' => 'fail', 'message' => dao::getError());
return array('result' => 'success', 'message' => $this->lang->saveSuccess, 'sceneID' => $sceneID);
}
/**
* 调整场景的路径。
* Fix the scene path.
*
* @param int $sceneID
* @param array $pScene
* @access protected
* @return bool
*/
protected function fixScenePath(int $sceneID, array $pScene = array()): bool
{
$parent = 0;
$grade = 1;
$path = ",{$sceneID},";
if(!empty($pScene))
{
$parent = $pScene['id'];
$parentScene = $this->dao->findById((int)$parent)->from(TABLE_SCENE)->fetch();
$path = $parentScene->path . "{$sceneID},";
$grade = $parentScene->grade + 1;
}
$this->dao->update(TABLE_SCENE)->set('parent')->eq($parent)->set('path')->eq($path)->set('grade')->eq($grade)->where('id')->eq($sceneID)->exec();
return !dao::isError();
}
/**
* 基于用例构建场景数据。
* Build scene base on case.
*
* @param object $scene
* @param array $fieldTypes
* @access public
* @return object
*/
public function buildSceneBaseOnCase(object $scene, array $fieldTypes): object
{
/* Set default value for the fields exist in TABLE_CASE but not in TABLE_SCENE. */
foreach($fieldTypes as $field => $type)
{
if(!isset($scene->{$field})) $scene->{$field} = $type['rule'] == 'int' ? '0' : '';
}
$scene->caseID = $scene->id;
$scene->bugs = 0;
$scene->results = 0;
$scene->caseFails = 0;
$scene->stepNumber = 0;
$scene->isScene = true;
return $scene;
}
/**
* 通过搜索获取执行的用例。
* Get execution cases by search.
*
* @param int $executionID
* @param int $productID
* @param int $branchID
* @param int $paramID
* @param string $orderBy
* @param object $pager
* @access public
* @return array
* */
public function getExecutionCasesBySearch(int $executionID = 0, int $productID = 0, int|string $branchID = 0, int $paramID = 0, string $orderBy = 'id_desc', ?object $pager = null): array
{
if($paramID)
{
$query = $this->loadModel('search')->getQuery($paramID);
if($query)
{
$this->session->set('executionCaseQuery', $query->sql);
$this->session->set('executionCaseForm', $query->form);
}
}
if($this->session->executionCaseQuery === false) $this->session->set('executionCaseQuery', ' 1 = 1');
$caseQuery = '(' . $this->session->executionCaseQuery;
/* 处理用例查询中的产品条件。*/
if(strpos($this->session->executionCaseQuery, "`product` = 'all'") !== false)
{
$caseQuery = str_replace("`product` = 'all'", '1 = 1', $caseQuery);
$caseQuery .= ' AND t2.`product` ' . helper::dbIN($this->app->user->view->products);
}
elseif($productID)
{
$caseQuery .= " AND t2.`product` ='$productID'";
}
/* 处理用例查询中的产品分支条件。*/
if(strpos($caseQuery, "`branch` = 'all'") !== false) $caseQuery = str_replace("`branch` = 'all'", '1 = 1', $caseQuery);
if($branchID !== 'all' && strpos($caseQuery, '`branch` =') === false) $caseQuery .= " AND t2.`branch` in ('$branchID')";
/* 处理用例查询中的版本条件。*/
$caseQuery = str_replace(array('`version`', ' `product`', ' `project`'), array('t2.`version`', ' t2.`product`', ' t1.`project`'), $caseQuery);
$caseQuery .= ')';
return $this->dao->select('distinct t1.*, t2.*')->from(TABLE_PROJECTCASE)->alias('t1')
->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case = t2.id')
->where('t1.project')->eq($executionID)
->andWhere('t2.deleted')->eq('0')
->andWhere($caseQuery)
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
}
}