diff --git a/module/action/model.php b/module/action/model.php index 418d435c13..35a9537750 100755 --- a/module/action/model.php +++ b/module/action/model.php @@ -290,6 +290,11 @@ class actionModel extends model $name = $this->dao->select('name')->from(TABLE_TESTTASK)->where('id')->eq($action->objectID)->fetch('name'); if($name) $action->extra = html::a(helper::createLink('testtask', 'view', "testtaskID=$action->objectID"), "#$action->objectID " . $name); } + elseif($actionName == 'fromlib' and $action->objectType == 'case') + { + $name = $this->dao->select('name')->from(TABLE_TESTSUITE)->where('id')->eq($action->extra)->fetch('name'); + if($name) $action->extra = html::a(helper::createLink('testsuite', 'library', "libID=$action->extra"), $name); + } elseif(($actionName == 'closed' and $action->objectType == 'story') or ($actionName == 'resolved' and $action->objectType == 'bug')) { $action->appendLink = ''; diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index ce606c000b..7042f7dd17 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -256,7 +256,7 @@ $lang->testcase->menu = new stdclass(); $lang->testcase->menu->product = array('link' => '%s', 'fixed' => true); $lang->testcase->menu->bug = array('link' => 'Bug|bug|browse|productID=%s'); -$lang->testcase->menu->testcase = array('link' => '用例|testcase|browse|productID=%s', 'alias' => 'view,create,batchcreate,edit,batchedit,showimport,groupcase', 'subModule' => 'tree'); +$lang->testcase->menu->testcase = array('link' => '用例|testcase|browse|productID=%s', 'alias' => 'view,create,batchcreate,edit,batchedit,showimport,groupcase,importlib,report', 'subModule' => 'tree'); $lang->testcase->menu->testtask = array('link' => '版本|testtask|browse|productID=%s', 'alias' => 'view,create,edit,linkcase,cases,start,close,batchrun,groupcase'); $lang->testcase->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s', 'alias' => 'view,create,edit,linkcase'); $lang->testcase->menu->testlib = array('link' => '公共库|testsuite|library'); diff --git a/module/testcase/control.php b/module/testcase/control.php index 42cb6cce05..9f624961bc 100644 --- a/module/testcase/control.php +++ b/module/testcase/control.php @@ -110,8 +110,17 @@ class testcase extends control $this->config->testcase->search['onMenuBar'] = 'yes'; $this->testcase->buildSearchForm($productID, $this->products, $queryID, $actionURL); - $showModule = !empty($this->config->datatable->testcaseBrowse->showModule) ? $this->config->datatable->testcaseBrowse->showModule : ''; - $this->view->modulePairs = $showModule ? $this->tree->getModulePairs($productID, 'case', $showModule) : array(); + $linkedLibs = array(); + foreach($cases as $case) + { + if($case->lib and $case->fromLib) $linkedLibs[$case->lib] = $case->lib; + } + $showModule = !empty($this->config->datatable->testcaseBrowse->showModule) ? $this->config->datatable->testcaseBrowse->showModule : ''; + $this->view->modulePairs = $showModule ? $this->tree->getModulePairs($productID, 'case', $showModule, $linkedLibs) : array(); + + $moduleTree = $this->tree->getTreeMenu($productID, $viewType = 'case', $startModuleID = 0, array('treeModel', 'createCaseLink'), '', $branch); + $libModuleTree = $this->tree->getTestLibTreeInCase('case', $productID, array('treeModel', 'createCaseLink')); + if($libModuleTree) $moduleTree = substr($moduleTree, 0, strrpos($moduleTree, '')) . $libModuleTree . ''; /* Assign. */ $this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testcase->common; @@ -121,7 +130,7 @@ class testcase extends control $this->view->product = $this->product->getById($productID); $this->view->productName = $this->products[$productID]; $this->view->modules = $this->tree->getOptionMenu($productID, $viewType = 'case', $startModuleID = 0, $branch); - $this->view->moduleTree = $this->tree->getTreeMenu($productID, $viewType = 'case', $startModuleID = 0, array('treeModel', 'createCaseLink'), '', $branch); + $this->view->moduleTree = $moduleTree; $this->view->moduleName = $moduleID ? $this->tree->getById($moduleID)->name : $this->lang->tree->all; $this->view->moduleID = $moduleID; $this->view->pager = $pager; @@ -360,18 +369,18 @@ class testcase extends control $this->view->customFields = $customFields; $this->view->showFields = $this->config->testcase->custom->createFields; - $this->view->caseTitle = $caseTitle; + $this->view->title = $title; $this->view->position = $position; $this->view->productID = $productID; $this->view->productName = $this->products[$productID]; $this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'case', $startModuleID = 0, $branch); $this->view->currentModuleID = $currentModuleID ? $currentModuleID : (isset($story->module) ? $story->module : 0); $this->view->stories = $stories; + $this->view->caseTitle = $caseTitle; $this->view->type = $type; $this->view->stage = $stage; $this->view->pri = $pri; $this->view->storyID = $storyID; - $this->view->title = $title; $this->view->precondition = $precondition; $this->view->keywords = $keywords; $this->view->steps = $steps; @@ -615,10 +624,22 @@ class testcase extends control /* Set menu. */ $this->testcase->setMenu($this->products, $productID, $case->branch); + $moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'case', $startModuleID = 0, $case->branch); + if($case->lib and $case->fromLib) + { + $libName = $this->loadModel('testsuite')->getById($case->lib)->name; + $libModules = $this->tree->getOptionMenu($case->lib, 'testlib'); + foreach($libModules as $moduleID => $moduleName) + { + if($moduleID == 0) continue; + $moduleOptionMenu[$moduleID] = $libName . $moduleName; + } + } + $this->view->productID = $productID; $this->view->branches = $this->session->currentProductType == 'normal' ? array() : $this->loadModel('branch')->getPairs($productID); $this->view->productName = $this->products[$productID]; - $this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'case', $startModuleID = 0, $case->branch); + $this->view->moduleOptionMenu = $moduleOptionMenu; $this->view->stories = $this->story->getProductStoryPairs($productID, $case->branch); } $position[] = $this->lang->testcase->common; @@ -690,7 +711,15 @@ class testcase extends control $this->testcase->setMenu($this->products, $productID, $branch); /* Set modules. */ + $libs = array(); + $existModules = array(); + foreach($cases as $case) + { + if($case->lib and $case->fromLib) $libs[$case->lib] = $case->lib; + $existModules[$case->module] = $case->module; + } $modules = $this->tree->getOptionMenu($productID, $viewType = 'case', $startModuleID = 0, $branch); + if($libs) $modules += $this->tree->getExistLibModules($libs, $existModules); $modules = array('ditto' => $this->lang->testcase->ditto) + $modules; $this->view->modules = $modules; @@ -1391,4 +1420,64 @@ class testcase extends control $this->view->users = $this->loadModel('user')->getPairs('noletter'); $this->display(); } + + /** + * Import case from lib. + * + * @param int $productID + * @param int $branch + * @param int $libID + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ + public function importLib($productID, $branch = 0, $libID = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + { + if($_POST) + { + $this->testcase->importLib($productID); + die(js::reload('parent')); + } + + $this->testcase->setMenu($this->products, $productID, $branch); + + $libraries = $this->loadModel('testsuite')->getLibraries(); + if(empty($libraries)) + { + echo js::alert($this->lang->testcase->noLibrary); + die(js::locate(inlink('browse'))); + } + if(empty($libID) or !isset($libraries[$libID])) $libID = key($libraries); + + /* Load pager. */ + $this->app->loadClass('pager', $static = true); + $pager = pager::init($recTotal, $recPerPage, $pageID); + + $modules = $this->loadModel('tree')->getOptionMenu($productID, 'case', 0, $branch); + $libName = $libraries[$libID]; + $libModules = $this->tree->getOptionMenu($libID, 'testlib'); + foreach($libModules as $moduleID => $moduleName) + { + if($moduleID == 0) continue; + $modules[$moduleID] = $libName . $moduleName; + } + + $this->view->title = $this->lang->testcase->common . $this->lang->colon . $this->lang->testcase->importFromLib; + $this->view->position[] = $this->lang->testcase->importFromLib; + + $this->view->libraries = $libraries; + $this->view->libID = $libID; + $this->view->productID = $productID; + $this->view->branch = $branch; + $this->view->cases = $this->testsuite->getNotImportedCases($productID, $libID, $orderBy, $pager); + $this->view->modules = $modules; + $this->view->pager = $pager; + $this->view->orderBy = $orderBy; + $this->view->branches = $this->loadModel('branch')->getPairs($productID); + + $this->display(); + } } diff --git a/module/testcase/css/importlib.css b/module/testcase/css/importlib.css new file mode 100644 index 0000000000..9c7db148a6 --- /dev/null +++ b/module/testcase/css/importlib.css @@ -0,0 +1,2 @@ +#titlebar .input-group {position: relative; top: -6px; margin-left: 10px; width: 300px;} +#titlebar .input-group-addon, #titlebar .form-control {font-size: 12px; padding: 5px 10px; line-height: 18px; height: 30px} diff --git a/module/testcase/js/importlib.js b/module/testcase/js/importlib.js new file mode 100644 index 0000000000..856cca551c --- /dev/null +++ b/module/testcase/js/importlib.js @@ -0,0 +1,9 @@ +function reload(libID) +{ + link = createLink('testcase','importLib','productID='+ productID + '&branch=' + branch + '&libID='+libID); + location.href = link; +} +$(function() +{ + setTimeout(function(){fixedTfootAction('#importFromLib')}, 500); +}); diff --git a/module/testcase/lang/zh-cn.php b/module/testcase/lang/zh-cn.php index 575692b04d..d72d529004 100644 --- a/module/testcase/lang/zh-cn.php +++ b/module/testcase/lang/zh-cn.php @@ -74,6 +74,8 @@ $lang->testcase->batchStoryChange = "确认变更"; $lang->testcase->browse = "用例列表"; $lang->testcase->groupCase = "分组浏览用例"; $lang->testcase->import = "导入"; +$lang->testcase->importFile = "导入CSV"; +$lang->testcase->importFromLib = "从库中导入"; $lang->testcase->showImport = "显示导入内容"; $lang->testcase->exportTemplet = "导出模板"; $lang->testcase->export = "导出数据"; @@ -156,8 +158,13 @@ $lang->testcase->buttonToList = '返回'; $lang->testcase->errorEncode = '无数据,请选择正确的编码重新上传!'; $lang->testcase->noFunction = '不存在iconv和mb_convert_encoding转码方法,不能将数据转成想要的编码!'; $lang->testcase->noRequire = "%s行的“%s”是必填字段,不能为空"; +$lang->testcase->noLibrary = "现在还没有公共库,请先创建!"; $lang->testcase->searchStories = '键入来搜索需求'; +$lang->testcase->selectLib = '请选择库'; + +$lang->testcase->action = new stdclass(); +$lang->testcase->action->fromlib = array('main' => '$date, 由 $actor 从公共库 $extra导入。'); $lang->testcase->featureBar['browse']['all'] = $lang->testcase->allCases; $lang->testcase->featureBar['browse']['needconfirm'] = $lang->testcase->needConfirm; diff --git a/module/testcase/model.php b/module/testcase/model.php index 6e4103d1f1..ef4777e6fd 100644 --- a/module/testcase/model.php +++ b/module/testcase/model.php @@ -251,7 +251,7 @@ class testcaseModel extends model $toBugs = $this->dao->select('id, title')->from(TABLE_BUG)->where('`case`')->eq($caseID)->fetchAll(); foreach($toBugs as $toBug) $case->toBugs[$toBug->id] = $toBug->title; - if($case->linkCase) $case->linkCaseTitles = $this->dao->select('id,title')->from(TABLE_CASE)->where('id')->in($case->linkCase)->fetchPairs(); + if($case->linkCase or $case->fromLib) $case->linkCaseTitles = $this->dao->select('id,title')->from(TABLE_CASE)->where('id')->in($case->linkCase)->orWhere('id')->eq($case->fromLib)->fetchPairs(); if($version == 0) $version = $case->version; $case->steps = $this->dao->select('*')->from(TABLE_CASESTEP)->where('`case`')->eq($caseID)->andWhere('version')->eq($version)->orderBy('id')->fetchAll(); $case->files = $this->loadModel('file')->getByObject('testcase', $caseID); @@ -984,6 +984,46 @@ class testcaseModel extends model return $fields; } + /** + * Import case from Lib. + * + * @param int $productID + * @access public + * @return void + */ + public function importLib($productID) + { + $data = fixer::input('post')->get(); + $libCases = $this->dao->select('*')->from(TABLE_CASE)->where('deleted')->eq(0)->andWhere('id')->in($data->caseIdList)->fetchAll('id'); + $libSteps = $this->dao->select('*')->from(TABLE_CASESTEP)->where('`case`')->in($data->caseIdList)->orderBy('id')->fetchGroup('case'); + foreach($libCases as $libCaseID => $case) + { + $case->fromLib = $case->id; + $case->product = $productID; + if(isset($data->module[$case->id])) $case->module = $data->module[$case->id]; + if(isset($data->branch[$case->id])) $case->branch = $data->branch[$case->id]; + unset($case->id); + $this->dao->insert(TABLE_CASE)->data($case) + ->autoCheck() + ->batchCheck($this->config->testcase->create->requiredFields, 'notempty') + ->exec(); + if(!dao::isError()) + { + $caseID = $this->dao->lastInsertID(); + if(isset($libSteps[$libCaseID])) + { + foreach($libSteps[$libCaseID] as $step) + { + $step->case = $caseID; + unset($step->id); + $this->dao->insert(TABLE_CASESTEP)->data($step)->exec(); + } + } + $this->loadModel('action')->create('case', $caseID, 'fromlib', '', $case->lib); + } + } + } + /** * Build search form. * diff --git a/module/testcase/view/caseheader.html.php b/module/testcase/view/caseheader.html.php index ccbc52523a..41ef274182 100644 --- a/module/testcase/view/caseheader.html.php +++ b/module/testcase/view/caseheader.html.php @@ -93,7 +93,23 @@ ?> - +
+ + +
diff --git a/module/testcase/view/importlib.html.php b/module/testcase/view/importlib.html.php new file mode 100644 index 0000000000..1aa64836d1 --- /dev/null +++ b/module/testcase/view/importlib.html.php @@ -0,0 +1,73 @@ + + * @package testcase + * @version $Id: importlib.html.php 4669 2013-04-23 02:28:08Z chencongzhi520@gmail.com $ + * @link http://www.zentao.net + */ +?> + +
+
+ icons['testcase']);?> + icons['import']);?> testcase->importFromLib;?> +
+ testcase->selectLib;?> + +
+
+
+
+ + + recTotal}&recPerPage={$pager->recPerPage}";?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
idAB);?>testcase->branch ?> priAB);?> testcase->title);?>testcase->module ?>testcase->type)?>
+ + id", sprintf('%03d', $case->id))) printf('%03d', $case->id);?> + id}]", $branches, $branch, "class='form-control'")?>testcase->priList, $case->pri, $case->pri)?>'>pri == '0' ? '' : zget($lang->testcase->priList, $case->pri, $case->pri);?>id", $case->title)) echo $case->title;?>id}]", $modules, $case->module, "class='from-control chosen'");?> + testcase->typeList, $case->type);?> +
+
+ + testcase->import);?> + goback, $this->session->caseList);?> +
+ show();?> +
+
+
+ + + diff --git a/module/testcase/view/view.html.php b/module/testcase/view/view.html.php index 4cbb2031ea..78fae91acb 100644 --- a/module/testcase/view/view.html.php +++ b/module/testcase/view/view.html.php @@ -45,8 +45,8 @@ if(!$isLibCase) { echo "
"; - common::printIcon('testtask', 'runCase', "runID=$runID&caseID=$case->id&version=$case->currentVersion", '', 'button', '', '', 'runCase'); - common::printIcon('testtask', 'results', "runID=$runID&caseID=$case->id&version=$case->version", '', 'button', '', '', 'results'); + common::printIcon('testtask', 'runCase', "runID=$runID&caseID=$case->id&version=$case->currentVersion", '', 'button', '', '', 'runCase', false, "data-width='95%'"); + common::printIcon('testtask', 'results', "runID=$runID&caseID=$case->id&version=$case->version", '', 'button', '', '', 'results', false, "data-width='95%'"); if($case->lastRunResult == 'fail') common::printIcon('testcase', 'createBug', "product=$case->product&branch=$case->branch&extra=caseID=$case->id,version=$case->version,runID=$runID", '', 'button', 'bug', '', 'iframe'); echo '
'; @@ -54,8 +54,9 @@ echo "
"; common::printIcon('testcase', 'edit',"caseID=$case->id"); - if(!$isLibCase) common::printCommentIcon('testcase'); + common::printCommentIcon('testcase'); if(!$isLibCase) common::printIcon('testcase', 'create', "productID=$case->product&branch=$case->branch&moduleID=$case->module&from=testcase¶m=$case->id", '', 'button', 'copy'); + if($isLibCase and common::hasPriv('testsuite', 'createCase')) echo html::a($this->createLink('testsuite', 'createCase', "libID=$case->lib&moduleID=$case->module¶m=$case->id"), "", '', "class='btn' title='{$lang->testcase->copy}'"); common::printIcon('testcase', 'delete', "caseID=$case->id", '', 'button', '', 'hiddenwin'); echo '
'; diff --git a/module/testsuite/control.php b/module/testsuite/control.php index 7a2519604e..a6f1b76c14 100644 --- a/module/testsuite/control.php +++ b/module/testsuite/control.php @@ -28,7 +28,6 @@ class testsuite extends control * Browse test suites. * * @param int $productID - * @param string $type * @param string $orderBy * @param int $recTotal * @param int $recPerPage @@ -102,6 +101,10 @@ class testsuite extends control * View a test suite. * * @param int $suiteID + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID * @access public * @return void */ @@ -238,6 +241,10 @@ class testsuite extends control * Link cases to a test suite. * * @param int $suiteID + * @param int $param + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID * @access public * @return void */ @@ -300,7 +307,9 @@ class testsuite extends control /** * Remove a case from test suite. * + * @param int $suiteID * @param int $rowID + * @param string $confirm * @access public * @return void */ @@ -345,6 +354,19 @@ class testsuite extends control die(js::locate($this->createLink('testsuite', 'view', "suiteID=$suiteID"))); } + /** + * Show library case. + * + * @param int $libID + * @param string $browseType + * @param int $param + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ public function library($libID = 0, $browseType = 'all', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) { /* Set browse type. */ @@ -394,7 +416,6 @@ class testsuite extends control $showModule = !empty($this->config->datatable->testsuiteLibrary->showModule) ? $this->config->datatable->testsuiteLibrary->showModule : ''; $this->view->modulePairs = $showModule ? $this->tree->getModulePairs($libID, 'testlib', $showModule) : array(); - $this->view->title = $this->lang->testlib->common . $this->lang->colon . $libraries[$libID]; $this->view->position[] = html::a($this->createLink('testsuite', 'library', "libID=$libID"), $libraries[$libID]); @@ -403,6 +424,7 @@ class testsuite extends control $this->view->cases = $cases; $this->view->orderBy = $orderBy; $this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter'); + $this->view->modules = $this->tree->getOptionMenu($libID, $viewType = 'testlib', $startModuleID = 0); $this->view->moduleTree = $this->tree->getTreeMenu($libID, $viewType = 'testlib', $startModuleID = 0, array('treeModel', 'createTestLibLink'), ''); $this->view->pager = $pager; $this->view->browseType = $browseType; @@ -414,6 +436,12 @@ class testsuite extends control $this->display(); } + /** + * Create lib + * + * @access public + * @return void + */ public function createLib() { if(!empty($_POST)) @@ -435,7 +463,15 @@ class testsuite extends control $this->display(); } - public function createCase($libID, $moduleID = 0) + /** + * Create case for library. + * + * @param int $libID + * @param int $moduleID + * @access public + * @return void + */ + public function createCase($libID, $moduleID = 0, $param = 0) { if(!empty($_POST)) { @@ -460,11 +496,36 @@ class testsuite extends control $libID = $this->testsuite->saveLibState($libID, $libraries); $this->testsuite->setLibMenu($libraries, $libID); + $type = 'feature'; + $stage = ''; + $pri = 3; + $caseTitle = ''; + $precondition = ''; + $keywords = ''; + $steps = array(); + $this->loadModel('testcase'); - $step = new stdclass(); - $step->desc = ''; - $step->expect = ''; - for($i = 1; $i <= $this->config->testcase->defaultSteps; $i ++) $steps[] = $step; + if($param) + { + $testcase = $this->testcase->getById((int)$param); + $type = $testcase->type ? $testcase->type : 'feature'; + $stage = $testcase->stage; + $pri = $testcase->pri; + $storyID = $testcase->story; + $caseTitle = $testcase->title; + $precondition = $testcase->precondition; + $keywords = $testcase->keywords; + $steps = $testcase->steps; + } + + if(count($steps) < $this->config->testcase->defaultSteps) + { + $paddingCount = $this->config->testcase->defaultSteps - count($steps); + $step = new stdclass(); + $step->desc = ''; + $step->expect = ''; + for($i = 1; $i <= $paddingCount; $i ++) $steps[] = $step; + } $this->view->title = $libraries[$libID] . $this->lang->colon . $this->lang->testcase->create; $this->view->position[] = html::a($this->createLink('testsuite', 'library', "libID=$libID"), $libraries[$libID]); @@ -474,11 +535,24 @@ class testsuite extends control $this->view->libraries = $libraries; $this->view->libID = $libID; $this->view->currentModuleID = (int)$moduleID; + $this->view->caseTitle = $caseTitle; + $this->view->type = $type; + $this->view->stage = $stage; + $this->view->pri = $pri; + $this->view->precondition = $precondition; + $this->view->keywords = $keywords; $this->view->steps = $steps; $this->view->moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'testlib', $startModuleID = 0); $this->display(); } + /** + * View library + * + * @param int $libID + * @access public + * @return void + */ public function libView($libID) { $lib = $this->testsuite->getById($libID); @@ -498,6 +572,16 @@ class testsuite extends control $this->display(); } + /** + * Ajax get drop menu. + * + * @param int $libID + * @param string $module + * @param string $method + * @param string $extra + * @access public + * @return void + */ public function ajaxGetDropMenu($libID, $module, $method, $extra) { $this->view->link = $this->testsuite->getLibLink($module, $method, $extra); diff --git a/module/testsuite/model.php b/module/testsuite/model.php index 986a2894a3..0beb5a5eff 100644 --- a/module/testsuite/model.php +++ b/module/testsuite/model.php @@ -32,6 +32,17 @@ class testsuiteModel extends model } } + /** + * Build select string. + * + * @param array $products + * @param int $productID + * @param string $currentModule + * @param string $currentMethod + * @param string $extra + * @access public + * @return string + */ public function select($products, $productID, $currentModule, $currentMethod, $extra = '') { if(!$productID) @@ -53,6 +64,14 @@ class testsuiteModel extends model return $output; } + /** + * Set library menu. + * + * @param array $libraries + * @param int $libID + * @access public + * @return void + */ public function setLibMenu($libraries, $libID) { $currentLibName = zget($libraries, $libID, ''); @@ -84,7 +103,7 @@ class testsuiteModel extends model * * @param int $productID * @access public - * @return void + * @return bool|int */ public function create($productID) { @@ -105,13 +124,13 @@ class testsuiteModel extends model $this->file->updateObjectID($this->post->uid, $suiteID, 'testsuite'); return $suiteID; } + return false; } /** * Get test suites of a product. * * @param int $productID - * r * @param string $orderBy * @param object $pager * @access public @@ -134,7 +153,7 @@ class testsuiteModel extends model * @param int $suiteID * @param bool $setImgSize * @access public - * @return void + * @return object */ public function getById($suiteID, $setImgSize = false) { @@ -148,7 +167,7 @@ class testsuiteModel extends model * * @param int $suiteID * @access public - * @return void + * @return bool|array */ public function update($suiteID) { @@ -170,6 +189,7 @@ class testsuiteModel extends model $this->file->updateObjectID($this->post->uid, $suiteID, 'testsuite'); return common::createChanges($oldSuite, $suite); } + return false; } /** @@ -193,6 +213,16 @@ class testsuiteModel extends model } } + /** + * Get linked cases for suite. + * + * @param int $suiteID + * @param string $orderBy + * @param object $pager + * @param bool $append + * @access public + * @return array + */ public function getLinkedCases($suiteID, $orderBy = 'id_desc', $pager = null, $append = true) { $suite = $this->getById($suiteID); @@ -210,6 +240,15 @@ class testsuiteModel extends model return $this->loadModel('testcase')->appendBugAndResults($cases); } + /** + * Get unlinked cases for suite. + * + * @param object $suite + * @param int $param + * @param object $pager + * @access public + * @return array + */ public function getUnlinkedCases($suite, $param = 0, $pager = null) { if($this->session->testsuiteQuery == false) $this->session->set('testsuiteQuery', ' 1 = 1'); @@ -239,6 +278,14 @@ class testsuiteModel extends model return $cases; } + /** + * Delete suite and library. + * + * @param int $suiteID + * @param string $table + * @access public + * @return bool + */ public function delete($suiteID, $table = '') { $suite = $this->getById($suiteID); @@ -251,9 +298,15 @@ class testsuiteModel extends model { $this->dao->delete()->from(TABLE_SUITECASE)->where('suite')->eq($suiteID)->exec(); } - return true; + return !dao::isError(); } + /** + * Get libraries. + * + * @access public + * @return array + */ public function getLibraries() { return $this->dao->select("id,name")->from(TABLE_TESTSUITE) @@ -264,6 +317,12 @@ class testsuiteModel extends model ->fetchPairs('id', 'name'); } + /** + * Create lib. + * + * @access public + * @return int + */ public function createLib() { $lib = fixer::input('post') @@ -283,8 +342,21 @@ class testsuiteModel extends model $this->file->updateObjectID($this->post->uid, $libID, 'testlib'); return $libID; } + return false; } + /** + * Get lib cases. + * + * @param int $libID + * @param string $browseType + * @param int $queryID + * @param int $moduleID + * @param string $sort + * @param object $pager + * @access public + * @return array + */ public function getLibCases($libID, $browseType, $queryID = 0, $moduleID = 0, $sort = 'id_desc', $pager = null) { $moduleIdList = $moduleID ? $this->loadModel('tree')->getAllChildId($moduleID) : '0'; @@ -295,6 +367,7 @@ class testsuiteModel extends model { $cases = $this->dao->select('*')->from(TABLE_CASE) ->where('lib')->eq((int)$libID) + ->andWhere('product')->eq(0) ->beginIF($moduleIdList)->andWhere('module')->in($moduleIdList)->fi() ->andWhere('deleted')->eq('0') ->orderBy($sort)->page($pager)->fetchAll('id'); @@ -329,6 +402,7 @@ class testsuiteModel extends model $cases = $this->dao->select('*')->from(TABLE_CASE)->where($caseQuery) ->beginIF($queryLibID != 'all')->andWhere('lib')->eq((int)$libID)->fi() + ->andWhere('product')->eq(0) ->andWhere('deleted')->eq(0) ->orderBy($sort)->page($pager)->fetchAll(); @@ -336,6 +410,44 @@ class testsuiteModel extends model return $cases; } + /** + * Get not imported cases. + * + * @param int $productID + * @param int $libID + * @param string $orderBy + * @param object $pager + * @access public + * @return array + */ + public function getNotImportedCases($productID, $libID, $orderBy = 'id_desc', $pager = null) + { + $importedCases = $this->dao->select('fromLib')->from(TABLE_CASE) + ->where('product')->eq($productID) + ->andWhere('lib')->eq($libID) + ->andWhere('fromLib')->ne('') + ->andWhere('deleted')->eq(0) + ->fetchPairs('fromLib', 'fromLib'); + return $this->dao->select('*')->from(TABLE_CASE) + ->where('lib')->eq($libID) + ->andWhere('product')->eq(0) + ->andWhere('id')->notIN($importedCases) + ->andWhere('deleted')->eq(0) + ->orderBy($orderBy) + ->page($pager) + ->fetchAll('id'); + } + + /** + * Build search form. + * + * @param int $libID + * @param array $libraries + * @param int $queryID + * @param string $actionURL + * @access public + * @return void + */ public function buildSearchForm($libID, $libraries, $queryID, $actionURL) { $this->config->testcase->search['fields']['lib'] = $this->lang->testcase->lib; @@ -361,6 +473,15 @@ class testsuiteModel extends model $this->loadModel('search')->setSearchParams($this->config->testcase->search); } + /** + * Get lib link. + * + * @param string $module + * @param string $method + * @param string $extra + * @access public + * @return string + */ public function getLibLink($module, $method, $extra) { $link = ''; diff --git a/module/testsuite/view/createcase.html.php b/module/testsuite/view/createcase.html.php index 7c5e451f29..036287d87e 100644 --- a/module/testsuite/view/createcase.html.php +++ b/module/testsuite/view/createcase.html.php @@ -50,11 +50,11 @@ testcase->type;?> - testcase->typeList, '', "class='form-control chosen'");?> + testcase->typeList, $type, "class='form-control chosen'");?>
testcase->stage?> - testcase->stageList, '', "class='form-control chosen' multiple='multiple'");?> + testcase->stageList, $stage, "class='form-control chosen' multiple='multiple'");?>
@@ -65,7 +65,7 @@
- +
@@ -83,14 +83,14 @@ } ?> - testcase->priList, '', "class='form-control minw-80px'");?> + testcase->priList, $pri, "class='form-control minw-80px'");?>
@@ -100,7 +100,7 @@ testcase->precondition;?> - + testcase->steps;?> diff --git a/module/testsuite/view/library.html.php b/module/testsuite/view/library.html.php index fe7125da85..f4a790cf93 100644 --- a/module/testsuite/view/library.html.php +++ b/module/testsuite/view/library.html.php @@ -173,6 +173,6 @@ js::set('batchDelete', $lang->testcase->confirmBatchDelete);
diff --git a/module/testtask/control.php b/module/testtask/control.php index 8cf5a9f2f8..c54e96b89b 100644 --- a/module/testtask/control.php +++ b/module/testtask/control.php @@ -268,6 +268,10 @@ class testtask extends control /* Append bugs and results. */ $runs = $this->testcase->appendBugAndResults($runs, 'run'); + $moduleTree = $this->loadModel('tree')->getTreeMenu($productID, $viewType = 'case', $startModuleID = 0, array('treeModel', 'createTestTaskLink'), $extra = $taskID); + $libModuleTree = $this->tree->getTestLibTreeInCase('testtask', $taskID, array('treeModel', 'createTestTaskLink')); + if($libModuleTree) $moduleTree = substr($moduleTree, 0, strrpos($moduleTree, '')) . $libModuleTree . ''; + $this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testtask->cases; $this->view->position[] = html::a($this->createLink('testtask', 'browse', "productID=$productID"), $this->products[$productID]); $this->view->position[] = $this->lang->testtask->common; @@ -279,7 +283,7 @@ class testtask extends control $this->view->runs = $runs; $this->view->users = $this->loadModel('user')->getPairs('noclosed,qafirst'); $this->view->assignedTos = $this->loadModel('user')->getPairs('noclosed,nodeleted,qafirst'); - $this->view->moduleTree = $this->loadModel('tree')->getTreeMenu($productID, $viewType = 'case', $startModuleID = 0, array('treeModel', 'createTestTaskLink'), $extra = $taskID); + $this->view->moduleTree = $moduleTree; $this->view->browseType = $browseType; $this->view->param = $param; $this->view->orderBy = $orderBy; diff --git a/module/tree/model.php b/module/tree/model.php index 6e04ab7e40..35ce895ac5 100644 --- a/module/tree/model.php +++ b/module/tree/model.php @@ -130,7 +130,7 @@ class treeModel extends model * @access public * @return array */ - public function getModulePairs($rootID, $viewType = 'story', $showModule = 'end') + public function getModulePairs($rootID, $viewType = 'story', $showModule = 'end', $extra = '') { if($viewType == 'task') { @@ -151,8 +151,14 @@ class treeModel extends model } else { + /* When case with libIdList then append lib modules. */ + $modules = array(); + if($viewType == 'case' and $extra) + { + $modules += $this->dao->select('id,name,path,short')->from(TABLE_MODULE)->where('root')->in($extra)->andWhere('type')->eq('testlib')->andWhere('deleted')->eq(0)->fetchAll('id'); + } if($this->isMergeModule($rootID, $viewType)) $viewType .= ',story'; - $modules = $this->dao->select('id,name,path,short')->from(TABLE_MODULE)->where('root')->eq($rootID)->andWhere('type')->in($viewType)->andWhere('deleted')->eq(0)->fetchAll('id'); + $modules += $this->dao->select('id,name,path,short')->from(TABLE_MODULE)->where('root')->eq($rootID)->andWhere('type')->in($viewType)->andWhere('deleted')->eq(0)->fetchAll('id'); } $modulePairs = array(); @@ -649,14 +655,8 @@ class treeModel extends model } else { - if(isset($treeMenu[$module->parent]) and !empty($treeMenu[$module->parent])) - { - $treeMenu[$module->parent] .= "
  • $linkHtml\n"; - } - else - { - $treeMenu[$module->parent] = "
  • $linkHtml\n"; - } + if(!isset($treeMenu[$module->parent])) $treeMenu[$module->parent] = ""; + $treeMenu[$module->parent] .= "
  • $linkHtml\n"; } $treeMenu[$module->parent] .= "
  • \n"; } @@ -1496,4 +1496,100 @@ class treeModel extends model } return $tree; } + + /** + * Get testlib tree in case view. + * + * @param string $objectType + * @param int $objectID + * @param array $userFunc + * @access public + * @return string + */ + public function getTestLibTreeInCase($objectType, $objectID, $userFunc) + { + if($objectType == 'case') + { + $cases = $this->dao->select('*')->from(TABLE_CASE)->where('product')->eq($objectID)->andWhere('deleted')->eq(0)->fetchAll(); + } + elseif($objectType == 'testtask') + { + $cases = $this->dao->select('t2.*')->from(TABLE_TESTRUN)->alias('t1') + ->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case=t2.id') + ->where('t1.task')->eq($objectID) + ->andWhere('t2.deleted')->eq(0) + ->fetchAll(); + } + $existModules = array(); + $libs = array(); + foreach($cases as $case) + { + $existModules[$case->module] = $case->module; + if($case->lib and $case->fromLib) $libs[$case->lib] = $case->lib; + } + if(empty($libs)) return null; + + $libs = $this->dao->select('*')->from(TABLE_TESTSUITE)->where('type')->eq('library')->andWhere('id')->in($libs)->andWhere('deleted')->eq(0)->fetchAll('id'); + $moduleGroup = $this->dao->select('*')->from(TABLE_MODULE)->where('root')->in(array_keys($libs))->andWhere('type')->eq('testlib')->andWhere('deleted')->eq(0)->orderBy('grade desc, `order`')->fetchGroup('root'); + $lastMenu = ''; + $keepModules = array(); + foreach($libs as $lib) + { + if(!isset($moduleGroup[$lib->id])) continue; + $modules = $moduleGroup[$lib->id]; + $treeMenu = array(); + foreach($modules as $module) + { + $module->root = $objectID; + if(!isset($existModules[$module->id]) and !isset($keepModules[$module->id])) continue; + $keepModules[$module->parent] = true; + + $linkHtml = call_user_func($userFunc, 'case', $module, $objectType == 'testtask' ? $objectID : ''); + if(isset($treeMenu[$module->id]) and !empty($treeMenu[$module->id])) + { + if(!isset($treeMenu[$module->parent])) $treeMenu[$module->parent] = ''; + $treeMenu[$module->parent] .= "
  • $linkHtml"; + $treeMenu[$module->parent] .= "\n"; + } + else + { + if(!isset($treeMenu[$module->parent])) $treeMenu[$module->parent] = ""; + $treeMenu[$module->parent] .= "
  • $linkHtml\n"; + } + $treeMenu[$module->parent] .= "
  • \n"; + } + if(empty($treeMenu)) continue; + ksort($treeMenu); + $lastMenu .= "
  • {$lib->name}
  • \n"; + } + return $lastMenu; + } + + /** + * Get exist lib modules + * + * @param array $libs + * @param array $modules + * @access public + * @return array + */ + public function getExistLibModules($libs, $modules) + { + $libs = $this->dao->select('*')->from(TABLE_TESTSUITE)->where('type')->eq('library')->andWhere('id')->in($libs)->andWhere('deleted')->eq(0)->fetchAll('id'); + $libModules = $this->dao->select('*')->from(TABLE_MODULE)->where('root')->in(array_keys($libs))->andWhere('type')->eq('testlib')->andWhere('deleted')->eq(0)->andWhere('id')->in($modules)->orderBy('grade,`order`')->fetchAll(); + $modulePath = array(); + foreach($libModules as $module) + { + foreach(explode(',', trim($module->path, ',')) as $moduleID)$modulePath[$moduleID] = $moduleID; + } + $allModules = $this->dao->select('*')->from(TABLE_MODULE)->where('id')->in($modulePath)->fetchPairs('id', 'name'); + $modulePairs = array(); + foreach($libModules as $module) + { + $moduleName = $libs[$module->root]->name; + foreach(explode(',', trim($module->path, ',')) as $moduleID) $moduleName .= '/' . $allModules[$moduleID]; + $modulePairs[$module->id] = $moduleName; + } + return $modulePairs; + } }