From 2f62ecb51ed43f6507e224bacd4fd79b808055ca Mon Sep 17 00:00:00 2001 From: wangyidong Date: Sat, 12 Oct 2019 14:50:00 +0800 Subject: [PATCH] * finish task #6444. --- module/caselib/config.php | 16 + module/caselib/control.php | 739 ++++++++++++++++++ .../css/batchcreatecase.css | 0 .../library.css => caselib/css/browse.css} | 0 .../{testsuite => caselib}/css/createcase.css | 0 .../{testsuite => caselib}/css/showimport.css | 0 .../js/library.js => caselib/js/browse.js} | 0 .../{testsuite => caselib}/js/createcase.js | 0 module/caselib/lang/en.php | 37 + module/caselib/lang/zh-cn.php | 37 + module/caselib/model.php | 640 +++++++++++++++ .../view/ajaxgetdropmenu.html.php | 0 .../view/batchcreatecase.html.php | 4 +- .../view/browse.html.php} | 30 +- .../view/create.html.php} | 10 +- .../view/createcase.html.php | 6 +- module/caselib/view/edit.html.php | 41 + .../view/exporttemplet.html.php | 0 .../view/import.html.php | 0 .../view/showimport.html.php | 2 +- .../view/view.html.php} | 14 +- module/common/lang/en.php | 27 +- module/common/lang/menuOrder.php | 1 + module/common/lang/zh-cn.php | 27 +- module/common/model.php | 8 +- module/custom/config.php | 4 +- module/custom/view/required.html.php | 3 +- module/group/control.php | 1 - module/group/lang/resource.php | 14 +- module/group/model.php | 1 - module/group/view/privbygroup.html.php | 1 - module/testsuite/config.php | 9 +- module/testsuite/control.php | 673 +--------------- module/testsuite/lang/en.php | 15 - module/testsuite/lang/zh-cn.php | 15 - module/testsuite/model.php | 574 +------------- module/tree/control.php | 14 +- module/upgrade/model.php | 39 + 38 files changed, 1650 insertions(+), 1352 deletions(-) create mode 100644 module/caselib/config.php create mode 100644 module/caselib/control.php rename module/{testsuite => caselib}/css/batchcreatecase.css (100%) rename module/{testsuite/css/library.css => caselib/css/browse.css} (100%) rename module/{testsuite => caselib}/css/createcase.css (100%) rename module/{testsuite => caselib}/css/showimport.css (100%) rename module/{testsuite/js/library.js => caselib/js/browse.js} (100%) rename module/{testsuite => caselib}/js/createcase.js (100%) create mode 100644 module/caselib/lang/en.php create mode 100644 module/caselib/lang/zh-cn.php create mode 100644 module/caselib/model.php rename module/{testsuite => caselib}/view/ajaxgetdropmenu.html.php (100%) rename module/{testsuite => caselib}/view/batchcreatecase.html.php (98%) rename module/{testsuite/view/library.html.php => caselib/view/browse.html.php} (87%) rename module/{testsuite/view/createlib.html.php => caselib/view/create.html.php} (83%) rename module/{testsuite => caselib}/view/createcase.html.php (98%) create mode 100644 module/caselib/view/edit.html.php rename module/{testsuite => caselib}/view/exporttemplet.html.php (100%) rename module/{testsuite => caselib}/view/import.html.php (100%) rename module/{testsuite => caselib}/view/showimport.html.php (99%) rename module/{testsuite/view/libview.html.php => caselib/view/view.html.php} (75%) diff --git a/module/caselib/config.php b/module/caselib/config.php new file mode 100644 index 0000000000..994c2381b4 --- /dev/null +++ b/module/caselib/config.php @@ -0,0 +1,16 @@ +caselib = new stdclass(); +$config->caselib->create = new stdclass(); +$config->caselib->createcase = new stdclass(); +$config->caselib->create->requiredFields = 'name'; +$config->caselib->createcase->requiredFields = 'title,type'; + +$config->caselib->editor = new stdclass(); +$config->caselib->editor->create = array('id' => 'desc', 'tools' => 'simpleTools'); + +$config->caselib->datatable = new stdclass(); +$config->caselib->datatable->defaultField = array('id', 'pri', 'title', 'type', 'assignedTo', 'lastRunner', 'lastRunDate', 'lastRunResult', 'status', 'bugs', 'results', 'actions'); + +$config->caselib->custom = new stdclass(); +$config->caselib->custom->createFields = 'stage,pri,keywords'; +$config->caselib->customCreateFields = 'stage,pri,keywords'; diff --git a/module/caselib/control.php b/module/caselib/control.php new file mode 100644 index 0000000000..2e2005fbbf --- /dev/null +++ b/module/caselib/control.php @@ -0,0 +1,739 @@ + + * @package caselib + * @version $Id: control.php 5114 2013-07-12 06:02:59Z chencongzhi520@gmail.com $ + * @link http://www.zentao.net + */ +class caselib extends control +{ + public $products = array(); + + /** + * Index page, header to browse. + * + * @access public + * @return void + */ + public function index() + { + $this->locate($this->createLink('caselib', 'browse')); + } + + /** + * Create lib + * + * @access public + * @return void + */ + public function create() + { + if(!empty($_POST)) + { + $response['result'] = 'success'; + $response['message'] = ''; + $libID = $this->caselib->create(); + if(dao::isError()) + { + $response['result'] = 'fail'; + $response['message'] = dao::getError(); + $this->send($response); + } + $this->loadModel('action')->create('caselib', $libID, 'opened'); + $response['locate'] = $this->createLink('caselib', 'browse', "libID=$libID"); + $response['message'] = $this->lang->saveSuccess; + $this->send($response); + } + + /* Set menu. */ + $libraries = $this->caselib->getLibraries(); + $libID = $this->caselib->saveLibState(0, $libraries); + $this->caselib->setLibMenu($libraries, $libID); + + $this->view->title = $this->lang->caselib->common . $this->lang->colon . $this->lang->caselib->create; + $this->view->position[] = $this->lang->caselib->common; + $this->view->position[] = $this->lang->caselib->create; + $this->display(); + } + + /** + * Edit a case lib. + * + * @param int $lib + * @access public + * @return void + */ + public function edit($libID) + { + $lib = $this->caselib->getById($libID); + if(!empty($_POST)) + { + $response['result'] = 'success'; + $response['message'] = ''; + $changes = $this->caselib->update($libID); + if(dao::isError()) + { + $response['result'] = 'fail'; + $response['message'] = dao::getError(); + $this->send($response); + } + if($changes) + { + $actionID = $this->loadModel('action')->create('caselib', $libID, 'edited'); + $this->action->logHistory($actionID, $changes); + } + + $this->executeHooks($libID); + + $response['locate'] = inlink('view', "libID=$libID"); + $response['message'] = $this->lang->saveSuccess; + $this->send($response); + } + + /* Set lib menu. */ + $libraries = $this->caselib->getLibraries(); + $libID = $this->caselib->saveLibState($libID, $libraries); + $this->caselib->setLibMenu($libraries, $libID); + + $this->view->title = $libraries[$libID] . $this->lang->colon . $this->lang->caselib->edit; + $this->view->position[] = html::a($this->createLink('caselib', 'browse', "libID=$libID"), $libraries[$libID]); + $this->view->position[] = $this->lang->caselib->common; + $this->view->position[] = $this->lang->caselib->edit; + + $this->view->lib = $lib; + $this->display(); + } + + /** + * Delete a case lib. + * + * @param int $libID + * @param string $confirm yes|no + * @access public + * @return void + */ + public function delete($libID, $confirm = 'no') + { + if($confirm == 'no') + { + die(js::confirm($this->lang->caselib->libraryDelete, inlink('delete', "libID=$libID&confirm=yes"))); + } + else + { + $this->caselib->delete($libID); + + $this->executeHooks($libID); + + /* if ajax request, send result. */ + if($this->server->ajax) + { + if(dao::isError()) + { + $response['result'] = 'fail'; + $response['message'] = dao::getError(); + } + else + { + $response['result'] = 'success'; + $response['message'] = ''; + } + $this->send($response); + } + die(js::reload('parent')); + } + } + + /** + * 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 browse($libID = 0, $browseType = 'all', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + { + /* Set browse type. */ + $browseType = strtolower($browseType); + + $libraries = $this->caselib->getLibraries(); + if(empty($libraries)) $this->locate(inlink('create')); + + /* Save session. */ + $this->session->set('caseList', $this->app->getURI(true)); + + /* Set menu. */ + $libID = $this->caselib->saveLibState($libID, $libraries); + setcookie('preCaseLibID', $libID, $this->config->cookieLife, $this->config->webRoot); + if($this->cookie->preCaseLibID != $libID) + { + $_COOKIE['libCaseModule'] = 0; + setcookie('libCaseModule', 0, 0, $this->config->webRoot); + } + + if($browseType == 'bymodule') setcookie('libCaseModule', (int)$param, 0, $this->config->webRoot); + if($browseType != 'bymodule') $this->session->set('libBrowseType', $browseType); + $moduleID = ($browseType == 'bymodule') ? (int)$param : ($browseType == 'bysearch' ? 0 : ($this->cookie->libCaseModule ? $this->cookie->libCaseModule : 0)); + $queryID = ($browseType == 'bysearch') ? (int)$param : 0; + + /* Set lib menu. */ + $this->caselib->setLibMenu($libraries, $libID, $moduleID); + + /* Load pager. */ + $this->app->loadClass('pager', $static = true); + $pager = pager::init($recTotal, $recPerPage, $pageID); + + /* Build the search form. */ + $this->loadModel('testcase'); + $actionURL = $this->createLink('caselib', 'browse', "libID=$libID&browseType=bySearch&queryID=myQueryID"); + $this->caselib->buildSearchForm($libID, $libraries, $queryID, $actionURL); + + /* Append id for secend sort. */ + $sort = $this->loadModel('common')->appendOrder($orderBy); + + /* save session .*/ + $cases = $this->caselib->getLibCases($libID, $browseType, $queryID, $moduleID, $sort, $pager); + $this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', true); + + $this->loadModel('datatable'); + $this->loadModel('tree'); + $showModule = !empty($this->config->datatable->caselibLibrary->showModule) ? $this->config->datatable->caselibLibrary->showModule : ''; + $this->view->modulePairs = $showModule ? $this->tree->getModulePairs($libID, 'caselib', $showModule) : array(); + + $this->view->title = $this->lang->caselib->common . $this->lang->colon . $libraries[$libID]; + $this->view->position[] = html::a($this->createLink('caselib', 'browse', "libID=$libID"), $libraries[$libID]); + + $this->view->libID = $libID; + $this->view->libName = $libraries[$libID]; + $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 = 'caselib', $startModuleID = 0); + $this->view->moduleTree = $this->tree->getTreeMenu($libID, $viewType = 'caselib', $startModuleID = 0, array('treeModel', 'createCaseLibLink')); + $this->view->pager = $pager; + $this->view->browseType = $browseType; + $this->view->moduleID = $moduleID; + $this->view->moduleName = $moduleID ? $this->tree->getById($moduleID)->name : $this->lang->tree->all; + $this->view->param = $param; + $this->view->setShowModule = true; + + $this->display(); + } + + /** + * 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)) + { + $this->loadModel('testcase'); + $this->config->testcase->create->requiredFields = $this->config->caselib->createcase->requiredFields; + $caseResult = $this->testcase->create($bugID = 0); + if(!$caseResult or dao::isError()) die(js::error(dao::getError())); + + $caseID = $caseResult['id']; + if($caseResult['status'] == 'exists') + { + echo js::alert(sprintf($this->lang->duplicate, $this->lang->testcase->common)); + die(js::locate($this->createLink('testcase', 'view', "caseID=$caseID"), 'parent')); + } + + $this->loadModel('action')->create('case', $caseID, 'Opened'); + + /* If link from no head then reload. */ + if(isonlybody()) die(js::reload('parent')); + die(js::locate($this->createLink('caselib', 'browse', "libID={$libID}&browseType=byModule¶m={$_POST['module']}"), 'parent')); + } + /* Set lib menu. */ + $libraries = $this->caselib->getLibraries(); + $libID = $this->caselib->saveLibState($libID, $libraries); + $this->caselib->setLibMenu($libraries, $libID); + + $type = 'feature'; + $stage = ''; + $pri = 3; + $caseTitle = ''; + $precondition = ''; + $keywords = ''; + $steps = array(); + + $this->loadModel('testcase'); + 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->type = 'item'; + $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('caselib', 'browse', "libID=$libID"), $libraries[$libID]); + $this->view->position[] = $this->lang->caselib->common; + $this->view->position[] = $this->lang->testcase->create; + + foreach(explode(',', $this->config->caselib->customCreateFields) as $field) $customFields[$field] = $this->lang->testcase->$field; + $this->view->showFields = $this->config->caselib->custom->createFields; + $this->view->customFields = $customFields; + $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 = 'caselib', $startModuleID = 0); + $this->display(); + } + + /** + * Batch create case. + * + * @param int $libID + * @param int $moduleID + * @access public + * @return void + */ + public function batchCreateCase($libID, $moduleID = 0) + { + $this->loadModel('testcase'); + if(!empty($_POST)) + { + $caseID = $this->caselib->batchCreateCase($libID); + if(dao::isError()) die(js::error(dao::getError())); + if(isonlybody()) die(js::closeModal('parent.parent', 'this')); + die(js::locate($this->createLink('caselib', 'browse', "libID=$libID&browseType=byModule¶m=$moduleID"), 'parent')); + } + + $libraries = $this->caselib->getLibraries(); + if(empty($libraries)) $this->locate(inlink('create')); + + /* Set lib menu. */ + $this->caselib->setLibMenu($libraries, $libID); + + $currentModuleID = (int)$moduleID; + + /* Set module option menu. */ + $moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0); + $moduleOptionMenu['ditto'] = $this->lang->testcase->ditto; + + $this->view->title = $libraries[$libID] . $this->lang->colon . $this->lang->testcase->batchCreate; + $this->view->position[] = html::a($this->createLink('caselib', 'browse', "libID=$libID"), $libraries[$libID]); + $this->view->position[] = $this->lang->testcase->batchCreate; + $this->view->libID = $libID; + $this->view->moduleOptionMenu = $moduleOptionMenu; + $this->view->currentModuleID = $currentModuleID; + + $this->display(); + } + + /** + * View library + * + * @param int $libID + * @access public + * @return void + */ + public function view($libID) + { + $lib = $this->caselib->getById($libID, true); + + /* Set lib menu. */ + $libraries = $this->caselib->getLibraries(); + $this->caselib->setLibMenu($libraries, $libID); + + $this->loadModel('testcase'); + $this->view->title = $lib->name . $this->lang->colon . $this->lang->caselib->view; + $this->view->position[] = html::a($this->createLink('caselib', 'browse', "libID=$libID"), $lib->name); + $this->view->position[] = $this->lang->caselib->common; + $this->view->position[] = $this->lang->caselib->view; + + $this->view->lib = $lib; + $this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter'); + $this->view->actions = $this->loadModel('action')->getList('caselib', $libID); + $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->caselib->getLibLink($module, $method, $extra); + $this->view->libID = $libID; + $this->view->module = $module; + $this->view->method = $method; + $this->view->extra = $extra; + + $libraries = $this->caselib->getLibraries(); + + $this->view->libraries = $libraries; + $this->view->librariesPinyin = common::convert2Pinyin($libraries); + $this->display(); + } + + /** + * The results page of search. + * + * @param string $keywords + * @param string $module + * @param string $method + * @param mix $extra + * @access public + * @return void + */ + public function ajaxGetMatchedItems($keywords, $module, $method, $extra) + { + $libraries = $this->dao->select('*')->from(TABLE_TESTSUITE)->where('deleted')->eq(0)->andWhere('name')->like("%$keywords%")->andWhere('type')->eq('library')->orderBy('`id` desc')->fetchAll(); + $this->view->link = $this->caselib->getLibLink($module, $method, $extra); + $this->view->libraries = $libraries; + $this->view->keywords = $keywords; + $this->display(); + } + + /** + * Export templet. + * + * @param int $libID + * @access public + * @return void + */ + public function exportTemplet($libID) + { + $this->loadModel('testcase'); + if($_POST) + { + $fields['module'] = $this->lang->testcase->module; + $fields['title'] = $this->lang->testcase->title; + $fields['precondition'] = $this->lang->testcase->precondition; + $fields['stepDesc'] = $this->lang->testcase->stepDesc; + $fields['stepExpect'] = $this->lang->testcase->stepExpect; + $fields['keywords'] = $this->lang->testcase->keywords; + $fields['pri'] = $this->lang->testcase->pri; + $fields['type'] = $this->lang->testcase->type; + $fields['stage'] = $this->lang->testcase->stage; + + $fields[''] = ''; + $fields['typeValue'] = $this->lang->testcase->lblTypeValue; + $fields['stageValue'] = $this->lang->testcase->lblStageValue; + + $modules = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0); + $rows = array(); + $num = (int)$this->post->num; + for($i = 0; $i < $num; $i++) + { + foreach($modules as $moduleID => $module) + { + $row = new stdclass(); + $row->module = $module . "(#$moduleID)"; + $row->stepDesc = "1. \n2. \n3."; + $row->stepExpect = "1. \n2. \n3."; + + if(empty($rows)) + { + $row->typeValue = join("\n", $this->lang->testcase->typeList); + $row->stageValue = join("\n", $this->lang->testcase->stageList); + } + $rows[] = $row; + } + } + + $this->post->set('fields', $fields); + $this->post->set('kind', 'testcase'); + $this->post->set('rows', $rows); + $this->post->set('extraNum', $num); + $this->post->set('fileName', 'templet'); + $this->fetch('file', 'export2csv', $_POST); + } + + $this->display(); + } + + /** + * Import case csv file. + * + * @param int $libID + * @access public + * @return void + */ + public function import($libID) + { + $this->loadModel('testcase'); + if($_FILES) + { + $file = $this->loadModel('file')->getUpload('file'); + $file = $file[0]; + + $fileName = $this->file->savePath . $this->file->getSaveName($file['pathname']); + move_uploaded_file($file['tmpname'], $fileName); + + $rows = $this->file->parseCSV($fileName); + $fields = $this->testcase->getImportFields($productID); + $fields = array_flip($fields); + $header = array(); + foreach($rows[0] as $i => $rowValue) + { + if(empty($rowValue)) break; + $header[$i] = $rowValue; + } + unset($rows[0]); + + $columnKey = array(); + foreach($header as $title) + { + if(!isset($fields[$title])) continue; + $columnKey[] = $fields[$title]; + } + + if(count($columnKey) != count($header) or $this->post->encode != 'utf-8') + { + $fc = file_get_contents($fileName); + $encode = $this->post->encode != "utf-8" ? $this->post->encode : 'gbk'; + $fc = helper::convertEncoding($fc, $encode, 'utf-8'); + file_put_contents($fileName, $fc); + + $rows = $this->file->parseCSV($fileName); + $columnKey = array(); + $header = array(); + foreach($rows[0] as $i => $rowValue) + { + if(empty($rowValue)) break; + $header[$i] = $rowValue; + } + unset($rows[0]); + foreach($header as $title) + { + if(!isset($fields[$title])) continue; + $columnKey[] = $fields[$title]; + } + if(count($columnKey) != count($header)) die(js::alert($this->lang->testcase->errorEncode)); + } + + $this->session->set('importFile', $fileName); + + die(js::locate(inlink('showImport', "libID=$libID"), 'parent.parent')); + } + $this->display(); + } + + /** + * Show import case. + * + * @param int $libID + * @access public + * @return void + */ + public function showImport($libID) + { + $this->loadModel('testcase'); + if($_POST) + { + $this->caselib->createFromImport($libID); + die(js::locate(inlink('browse', "libID=$libID"), 'parent')); + } + + $libraries = $this->caselib->getLibraries(); + if(empty($libraries)) $this->locate(inlink('create')); + + $this->caselib->setLibMenu($libraries, $libID); + + $file = $this->session->importFile; + $caseLang = $this->lang->testcase; + $caseConfig = $this->config->testcase; + $modules = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0); + + $fields = explode(',', $caseConfig->exportFields); + foreach($fields as $key => $fieldName) + { + $fieldName = trim($fieldName); + $fields[$fieldName] = isset($caseLang->$fieldName) ? $caseLang->$fieldName : $fieldName; + unset($fields[$key]); + } + + $fields = array_flip($fields); + $rows = $this->loadModel('file')->parseCSV($file); + $header = array(); + foreach($rows[0] as $i => $rowValue) + { + if(empty($rowValue)) break; + $header[$i] = $rowValue; + } + unset($rows[0]); + + foreach($header as $title) + { + if(!isset($fields[$title])) continue; + $columnKey[] = $fields[$title]; + } + + $endField = end($fields); + $caseData = array(); + $stepData = array(); + $stepVars = 0; + foreach($rows as $row => $data) + { + $case = new stdclass(); + foreach($columnKey as $key => $field) + { + if(!isset($data[$key])) continue; + $cellValue = $data[$key]; + if($field == 'module') + { + $case->$field = 0; + if(strrpos($cellValue, '(#') !== false) + { + $id = trim(substr($cellValue, strrpos($cellValue,'(#') + 2), ')'); + $case->$field = $id; + } + } + elseif(in_array($field, $caseConfig->export->listFields)) + { + if($field == 'stage') + { + $stages = explode("\n", $cellValue); + foreach($stages as $stage) $case->stage[] = array_search($stage, $caseLang->{$field . 'List'}); + $case->stage = join(',', $case->stage); + } + else + { + $case->$field = array_search($cellValue, $caseLang->{$field . 'List'}); + } + } + elseif($field != 'stepDesc' and $field != 'stepExpect') + { + $case->$field = $cellValue; + } + else + { + $steps = (array)$cellValue; + if(strpos($cellValue, "\n")) + { + $steps = explode("\n", $cellValue); + } + elseif(strpos($cellValue, "\r")) + { + $steps = explode("\r", $cellValue); + } + + $stepKey = str_replace('step', '', strtolower($field)); + $caseStep = array(); + + foreach($steps as $step) + { + $step = trim($step); + if(empty($step)) continue; + if(preg_match('/^(([0-9]+)\.[0-9]+)([.、]{1})/U', $step, $out)) + { + $num = $out[1]; + $parent = $out[2]; + $sign = $out[3]; + $signbit = $sign == '.' ? 1 : 3; + $step = trim(substr($step, strlen($num) + $signbit)); + if(!empty($step)) $caseStep[$num]['content'] = $step; + $caseStep[$num]['type'] = 'item'; + $caseStep[$parent]['type'] = 'group'; + } + elseif(preg_match('/^([0-9]+)([.、]{1})/U', $step, $out)) + { + $num = $out[1]; + $sign = $out[2]; + $signbit = $sign == '.' ? 1 : 3; + $step = trim(substr($step, strlen($num) + $signbit)); + if(!empty($step)) $caseStep[$num]['content'] = $step; + $caseStep[$num]['type'] = 'step'; + } + elseif(isset($num)) + { + if(!isset($caseStep[$num]['content'])) $caseStep[$num]['content'] = ''; + $caseStep[$num]['content'] .= "\n" . $step; + } + else + { + if($field == 'stepDesc') + { + $num = 1; + $caseStep[$num]['content'] = $step; + $caseStep[$num]['type'] = 'step'; + } + if($field == 'stepExpect' and isset($stepData[$row]['desc'])) + { + end($stepData[$row]['desc']); + $num = key($stepData[$row]['desc']); + $caseStep[$num]['content'] = $step; + } + } + } + unset($num); + unset($sign); + $stepVars += count($caseStep, COUNT_RECURSIVE) - count($caseStep); + $stepData[$row][$stepKey] = $caseStep; + } + } + + $caseData[$row] = $case; + unset($case); + } + + if(empty($caseData)) + { + unlink($this->session->importFile); + unset($_SESSION['importFile']); + echo js::alert($this->lang->error->noData); + die(js::locate($this->createLink('caselib', 'browse', "libID=$libID"))); + } + + /* Judge whether the editedTasks is too large and set session. */ + $countInputVars = count($caseData) * 9 + $stepVars; + $showSuhosinInfo = common::judgeSuhosinSetting($countInputVars); + if($showSuhosinInfo) $this->view->suhosinInfo = extension_loaded('suhosin') ? sprintf($this->lang->suhosinInfo, $countInputVars) : sprintf($this->lang->maxVarsInfo, $countInputVars); + + $this->view->title = $this->lang->caselib->common . $this->lang->colon . $this->lang->testcase->showImport; + $this->view->position[] = $this->lang->testcase->showImport; + + $this->view->modules = $modules; + $this->view->cases = $this->dao->select('id,module,stage,status,pri,type')->from(TABLE_CASE)->where('lib')->eq($libID)->andWhere('deleted')->eq(0)->andWhere('product')->eq(0)->fetchAll('id'); + $this->view->caseData = $caseData; + $this->view->stepData = $stepData; + $this->view->libID = $libID; + $this->display(); + } +} diff --git a/module/testsuite/css/batchcreatecase.css b/module/caselib/css/batchcreatecase.css similarity index 100% rename from module/testsuite/css/batchcreatecase.css rename to module/caselib/css/batchcreatecase.css diff --git a/module/testsuite/css/library.css b/module/caselib/css/browse.css similarity index 100% rename from module/testsuite/css/library.css rename to module/caselib/css/browse.css diff --git a/module/testsuite/css/createcase.css b/module/caselib/css/createcase.css similarity index 100% rename from module/testsuite/css/createcase.css rename to module/caselib/css/createcase.css diff --git a/module/testsuite/css/showimport.css b/module/caselib/css/showimport.css similarity index 100% rename from module/testsuite/css/showimport.css rename to module/caselib/css/showimport.css diff --git a/module/testsuite/js/library.js b/module/caselib/js/browse.js similarity index 100% rename from module/testsuite/js/library.js rename to module/caselib/js/browse.js diff --git a/module/testsuite/js/createcase.js b/module/caselib/js/createcase.js similarity index 100% rename from module/testsuite/js/createcase.js rename to module/caselib/js/createcase.js diff --git a/module/caselib/lang/en.php b/module/caselib/lang/en.php new file mode 100644 index 0000000000..429aa86b8b --- /dev/null +++ b/module/caselib/lang/en.php @@ -0,0 +1,37 @@ + + * @package caselib + * @version $Id: zh-cn.php 4490 2013-02-27 03:27:05Z wyd621@gmail.com $ + * @link http://www.zentao.net + */ +$lang->caselib->common = 'Case Library'; +$lang->caselib->all = 'All Case Libraries'; + +$lang->caselib->index = "Library Home"; +$lang->caselib->create = "Create Case Library"; +$lang->caselib->edit = 'Edit Case Library'; +$lang->caselib->browse = 'View Cases in Library'; +$lang->caselib->view = 'Library Detail'; +$lang->caselib->createCase = 'Create Case'; +$lang->caselib->delete = "Delete Suite"; +$lang->caselib->linkVersion = "Version"; +$lang->caselib->deleted = 'Deleted'; +$lang->caselib->exportTemplet = 'Export Template'; +$lang->caselib->batchCreateCase = 'Batch Create'; +$lang->caselib->import = 'Import'; +$lang->caselib->importAction = 'Import Case'; +$lang->caselib->showImport = 'Imported Data'; + +$lang->caselib->id = 'ID'; +$lang->caselib->name = 'Name'; +$lang->caselib->desc = 'Description'; + +$lang->caselib->legendDesc = 'Description'; + +$lang->caselib->libraryDelete = 'Do you want to delete this library?'; +$lang->caselib->noModule = '
You have no modules.
Manage it now.
'; diff --git a/module/caselib/lang/zh-cn.php b/module/caselib/lang/zh-cn.php new file mode 100644 index 0000000000..e22369385b --- /dev/null +++ b/module/caselib/lang/zh-cn.php @@ -0,0 +1,37 @@ + + * @package caselib + * @version $Id: zh-cn.php 4490 2013-02-27 03:27:05Z wyd621@gmail.com $ + * @link http://www.zentao.net + */ +$lang->caselib->common = '用例库'; +$lang->caselib->all = '所有用例库'; + +$lang->caselib->index = "用例库首页"; +$lang->caselib->create = "创建用例库"; +$lang->caselib->edit = '编辑用例库'; +$lang->caselib->browse = '浏览库用例'; +$lang->caselib->view = '查看库概况'; +$lang->caselib->createCase = '创建用例'; +$lang->caselib->delete = "删除"; +$lang->caselib->linkVersion = "版本"; +$lang->caselib->deleted = '已删除'; +$lang->caselib->exportTemplet = '导出模板'; +$lang->caselib->batchCreateCase = '批量创建用例'; +$lang->caselib->import = '导入'; +$lang->caselib->importAction = '导入用例'; +$lang->caselib->showImport = '显示导入数据'; + +$lang->caselib->id = '编号'; +$lang->caselib->name = '名称'; +$lang->caselib->desc = '描述'; + +$lang->caselib->legendDesc = '描述'; + +$lang->caselib->libraryDelete = '您确认要删除该用例库吗?'; +$lang->caselib->noModule = '
您现在还没有模块信息
请维护用例库模块
'; diff --git a/module/caselib/model.php b/module/caselib/model.php new file mode 100644 index 0000000000..ce16fc972c --- /dev/null +++ b/module/caselib/model.php @@ -0,0 +1,640 @@ + + * @package caselib + * @version $Id: model.php 5114 2013-07-12 06:02:59Z chencongzhi520@gmail.com $ + * @link http://www.zentao.net + */ +?> +app->viewType == 'mhtml'; + $selectHtml = ''; + if(!empty($libraries)) + { + if($isMobile) + { + $selectHtml = "{$currentLibName} "; + } + else + { + $dropMenuLink = helper::createLink('caselib', 'ajaxGetDropMenu', "objectID=$libID&module=caselib&method=browse"); + $selectHtml = "
"; + } + } + + if($this->config->global->flow == 'onlyTest') + { + $modules = $this->loadModel('tree')->getModulePairs($libID, 'caselib'); + $moduleName = ($moduleID && isset($modules[$moduleID])) ? $modules[$moduleID] : $this->lang->tree->all; + + if(!$isMobile) + { + $dropMenuLink = helper::createLink('tree', 'ajaxGetDropMenu', "objectID=$libID&module=caselib&method=browse"); + $selectHtml .= "
"; + } + else + { + $selectHtml .= "{$moduleName} "; + } + } + + setCookie("lastCaseLib", $libID, $this->config->cookieLife, $this->config->webRoot); + + $pageNav = ''; + $pageActions = ''; + $isMobile = $this->app->viewType == 'mhtml'; + if($isMobile) + { + $this->app->loadLang('qa'); + $pageNav = html::a(helper::createLink('qa', 'index'), $this->lang->qa->index) . $this->lang->colon; + } + else + { + if($this->config->global->flow == 'full') + { + $this->app->loadLang('qa'); + $pageNav .= '
'; + $pageNav .= '
'; + } + else + { + $this->app->loadLang('testcase'); + $pageActions .= "
"; + if(common::hasPriv('caselib', 'exportTemplet')) + { + $link = helper::createLink('caselib', 'exportTemplet', "libID=$libID"); + $pageActions .= html::a($link, " " . $this->lang->caselib->exportTemplet, '', "class='btn btn-link export'"); + } + if(common::hasPriv('caselib', 'import')) + { + $link = helper::createLink('caselib', 'import', "libID=$libID"); + $pageActions .= html::a($link, " " . $this->lang->testcase->importFile, '', "class='btn btn-link export'"); + } + $pageActions .= '
'; + $params = "libID=$libID&moduleID=" . (isset($moduleID) ? $moduleID : 0); + if(common::hasPriv('caselib', 'batchCreateCase')) + { + $link = helper::createLink('caselib', 'batchCreateCase', $params); + $pageActions .= html::a($link, "" . $this->lang->testcase->batchCreate, '', "class='btn btn-secondary'"); + } + if(common::hasPriv('caselib', 'createCase')) + { + $link = helper::createLink('caselib', 'createCase', $params); + $pageActions .= html::a($link, "" . $this->lang->testcase->create, '', "class='btn btn-primary'"); + } + if(common::hasPriv('caselib', 'create')) + { + $link = helper::createLink('caselib', 'create'); + $pageActions .= html::a($link, "" . $this->lang->caselib->create, '', "class='btn btn-primary'"); + } + } + } + $pageNav .= $selectHtml; + + $this->lang->modulePageNav = $pageNav; + $this->lang->modulePageActions = $pageActions; + foreach($this->lang->caselib->menu as $key => $value) + { + $replace = ''; + if($this->config->global->flow == 'onlyTest') $replace = $libID; + common::setMenuVars($this->lang->caselib->menu, $key, $replace); + } + if($this->config->global->flow != 'full' && $this->app->getMethodName() != 'view') $this->lang->caselib->menu->bysearch = " {$this->lang->testcase->bySearch}"; + } + + /** + * Save lib state. + * + * @param int $libID + * @param array $libraries + * @access public + * @return int + */ + public function saveLibState($libID = 0, $libraries = array()) + { + if($libID > 0) $this->session->set('caseLib', (int)$libID); + if($libID == 0 and $this->cookie->lastCaseLib) $this->session->set('caseLib', $this->cookie->lastCaseLib); + if($libID == 0 and $this->session->caseLib == '') $this->session->set('caseLib', key($libraries)); + if(!isset($libraries[$this->session->caseLib])) + { + $this->session->set('caseLib', key($libraries)); + $libID = $this->session->caseLib; + } + return $this->session->caseLib; + } + + /** + * Get caselib info by id. + * + * @param int $libID + * @param bool $setImgSize + * @access public + * @return object + */ + public function getById($libID, $setImgSize = false) + { + $lib = $this->dao->select('*')->from(TABLE_TESTSUITE)->where('id')->eq((int)$libID)->fetch(); + $lib = $this->loadModel('file')->replaceImgURL($lib, 'desc'); + if($setImgSize) $lib->desc = $this->file->setImgSize($lib->desc); + return $lib; + } + + /** + * Update a caselib. + * + * @param int $libID + * @access public + * @return bool|array + */ + public function update($libID) + { + $oldLib = $this->dao->select("*")->from(TABLE_TESTSUITE)->where('id')->eq((int)$libID)->fetch(); + $lib = fixer::input('post') + ->stripTags($this->config->caselib->editor->edit['id'], $this->config->allowedTags) + ->add('lastEditedBy', $this->app->user->account) + ->add('lastEditedDate', helper::now()) + ->remove('uid') + ->get(); + $lib = $this->loadModel('file')->processImgURL($lib, $this->config->caselib->editor->edit['id'], $this->post->uid); + $this->dao->update(TABLE_TESTSUITE)->data($lib) + ->autoCheck() + ->batchcheck($this->config->caselib->edit->requiredFields, 'notempty') + ->where('id')->eq($libID) + ->exec(); + if(!dao::isError()) + { + $this->file->updateObjectID($this->post->uid, $libID, 'caselib'); + return common::createChanges($oldLib, $lib); + } + return false; + } + + /** + * Delete library. + * + * @param int $libID + * @param string $table + * @access public + * @return bool + */ + public function delete($libID, $table = '') + { + $this->dao->update(TABLE_TESTSUITE)->set('deleted')->eq(1)->where('id')->eq($libID)->exec(); + + $this->loadModel('action'); + $this->action->create('caselib', $libID, 'deleted', '', ACTIONMODEL::CAN_UNDELETED); + } + + /** + * Get libraries. + * + * @access public + * @return array + */ + public function getLibraries() + { + return $this->dao->select("id,name")->from(TABLE_TESTSUITE) + ->where('product')->eq(0) + ->andWhere('deleted')->eq(0) + ->andWhere('type')->eq('library') + ->orderBy('id_desc') + ->fetchPairs('id', 'name'); + } + + /** + * Create lib. + * + * @access public + * @return int + */ + public function create() + { + $lib = fixer::input('post') + ->stripTags($this->config->caselib->editor->create['id'], $this->config->allowedTags) + ->setForce('type', 'library') + ->add('addedBy', $this->app->user->account) + ->add('addedDate', helper::now()) + ->remove('uid') + ->get(); + $lib = $this->loadModel('file')->processImgURL($lib, $this->config->caselib->editor->create['id'], $this->post->uid); + $this->dao->insert(TABLE_TESTSUITE)->data($lib) + ->batchcheck($this->config->caselib->create->requiredFields, 'notempty') + ->check('name', 'unique', "deleted = '0'") + ->exec(); + if(!dao::isError()) + { + $libID = $this->dao->lastInsertID(); + $this->file->updateObjectID($this->post->uid, $libID, 'caselib'); + 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'; + $browseType = ($browseType == 'bymodule' and $this->session->libBrowseType and $this->session->libBrowseType != 'bysearch') ? $this->session->libBrowseType : $browseType; + + $cases = array(); + if($browseType == 'bymodule' or $browseType == 'all' or $browseType == 'wait') + { + $cases = $this->dao->select('*')->from(TABLE_CASE) + ->where('lib')->eq((int)$libID) + ->andWhere('product')->eq(0) + ->beginIF($moduleIdList)->andWhere('module')->in($moduleIdList)->fi() + ->beginIF($browseType == 'wait')->andWhere('status')->eq($browseType)->fi() + ->andWhere('deleted')->eq('0') + ->orderBy($sort)->page($pager)->fetchAll('id'); + } + /* By search. */ + elseif($browseType == 'bysearch') + { + if($queryID) + { + $query = $this->loadModel('search')->getQuery($queryID); + $this->session->set('caselibQuery', ' 1 = 1'); + if($query) + { + $this->session->set('caselibQuery', $query->sql); + $this->session->set('caselibForm', $query->form); + } + } + else + { + if($this->session->caselibQuery == false) $this->session->set('caselibQuery', ' 1 = 1'); + } + + $queryLibID = $libID; + $allLib = "`lib` = 'all'"; + $caseQuery = '(' . $this->session->caselibQuery; + if(strpos($this->session->caselibQuery, $allLib) !== false) + { + $caseQuery = str_replace($allLib, '1', $caseQuery); + $queryLibID = 'all'; + } + $caseQuery .= ')'; + + $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(); + + } + return $cases; + } + + /** + * 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; + $this->config->testcase->search['params']['lib']['values'] = array('' => '', $libID => $libraries[$libID], 'all' => $this->lang->caselib->all); + $this->config->testcase->search['params']['lib']['operator'] = '='; + $this->config->testcase->search['params']['lib']['control'] = 'select'; + $this->config->testcase->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib'); + if(!$this->config->testcase->needReview) unset($this->config->testcase->search['params']['status']['values']['wait']); + unset($this->config->testcase->search['fields']['product']); + unset($this->config->testcase->search['params']['product']); + unset($this->config->testcase->search['fields']['branch']); + unset($this->config->testcase->search['params']['branch']); + unset($this->config->testcase->search['fields']['lastRunner']); + unset($this->config->testcase->search['params']['lastRunner']); + unset($this->config->testcase->search['fields']['lastRunResult']); + unset($this->config->testcase->search['params']['lastRunResult']); + unset($this->config->testcase->search['fields']['lastRunDate']); + unset($this->config->testcase->search['params']['lastRunDate']); + + $this->config->testcase->search['module'] = 'caselib'; + $this->config->testcase->search['actionURL'] = $actionURL; + $this->config->testcase->search['queryID'] = $queryID; + + $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 = ''; + if($module == 'caselib') + { + if($module == 'caselib' && ($method == 'create')) + { + $link = helper::createLink($module, 'browse', "libID=%s"); + } + else + { + $link = helper::createLink($module, $method, "libID=%s"); + } + } + else if($module == 'tree') + { + $link = helper::createLink($module, $method, "libID=%s&type=caselib¤tModuleID=0"); + } + else + { + $link = helper::createLink('caselib', 'browse', "libID=%s"); + } + return $link; + } + + /** + * Create from import. + * + * @param int $libID + * @access public + * @return void + */ + public function createFromImport($libID) + { + $this->loadModel('action'); + $this->loadModel('testcase'); + $this->loadModel('file'); + $now = helper::now(); + $data = fixer::input('post')->get(); + + if(!empty($_POST['id'])) + { + $oldSteps = $this->dao->select('t2.*')->from(TABLE_CASE)->alias('t1') + ->leftJoin(TABLE_CASESTEP)->alias('t2')->on('t1.id = t2.case') + ->where('t1.id')->in(($_POST['id'])) + ->andWhere('t1.version=t2.version') + ->orderBy('t2.id') + ->fetchGroup('case'); + $oldCases = $this->dao->select('*')->from(TABLE_CASE)->where('id')->in($_POST['id'])->fetchAll('id'); + } + + $cases = array(); + foreach($data->lib as $key => $lib) + { + $caseData = new stdclass(); + + $caseData->lib = $lib; + $caseData->module = $data->module[$key]; + $caseData->title = $data->title[$key]; + $caseData->pri = (int)$data->pri[$key]; + $caseData->type = $data->type[$key]; + $caseData->status = $data->status[$key]; + $caseData->stage = join(',', $data->stage[$key]); + $caseData->keywords = $data->keywords[$key]; + $caseData->frequency = 1; + $caseData->precondition = $data->precondition[$key]; + + if(isset($this->config->testcase->create->requiredFields)) + { + $requiredFields = explode(',', $this->config->testcase->create->requiredFields); + foreach($requiredFields as $requiredField) + { + $requiredField = trim($requiredField); + if(empty($caseData->$requiredField)) dao::$errors[] = sprintf($this->lang->testcase->noRequire, $key, $this->lang->testcase->$requiredField); + } + } + + $cases[$key] = $caseData; + } + if(dao::isError()) die(js::error(dao::getError())); + + $forceNotReview = $this->testcase->forceNotReview(); + foreach($cases as $key => $caseData) + { + if(!empty($_POST['id'][$key]) and empty($_POST['insert'])) + { + $caseID = $data->id[$key]; + $stepChanged = false; + $steps = array(); + $oldStep = isset($oldSteps[$caseID]) ? $oldSteps[$caseID] : array(); + $oldCase = $oldCases[$caseID]; + + /* Remove the empty setps in post. */ + $steps = array(); + if(isset($_POST['desc'][$key])) + { + foreach($data->desc[$key] as $id => $desc) + { + $desc = trim($desc); + if(empty($desc)) continue; + $step = new stdclass(); + $step->type = $data->stepType[$key][$id]; + $step->desc = $desc; + $step->expect = trim($data->expect[$key][$id]); + + $steps[] = $step; + } + } + + /* If step count changed, case changed. */ + if((!$oldStep != !$steps) or (count($oldStep) != count($steps))) + { + $stepChanged = true; + } + else + { + /* Compare every step. */ + foreach($oldStep as $id => $oldStep) + { + if(trim($oldStep->desc) != trim($steps[$id]->desc) or trim($oldStep->expect) != $steps[$id]->expect) + { + $stepChanged = true; + break; + } + } + } + + $version = $stepChanged ? $oldCase->version + 1 : $oldCase->version; + $caseData->version = $version; + $changes = common::createChanges($oldCase, $caseData); + if(!$changes and !$stepChanged) continue; + + if($changes or $stepChanged) + { + $caseData->lastEditedBy = $this->app->user->account; + $caseData->lastEditedDate = $now; + if($stepChanged and !$forceNotReview) $caseData->status = 'wait'; + $this->dao->update(TABLE_CASE)->data($caseData)->where('id')->eq($caseID)->autoCheck()->exec(); + if($stepChanged) + { + $parentStepID = 0; + foreach($steps as $id => $step) + { + $step = (array)$step; + if(empty($step['desc'])) continue; + $stepData = new stdclass(); + $stepData->type = ($step['type'] == 'item' and $parentStepID == 0) ? 'step' : $step['type']; + $stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0; + $stepData->case = $caseID; + $stepData->version = $version; + $stepData->desc = $step['desc']; + $stepData->expect = $step['expect']; + $this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec(); + if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID(); + if($stepData->type == 'step') $parentStepID = 0; + } + } + $oldCase->steps = $this->testcase->joinStep($oldStep); + $caseData->steps = $this->testcase->joinStep($steps); + $changes = common::createChanges($oldCase, $caseData); + $actionID = $this->action->create('case', $caseID, 'Edited'); + $this->action->logHistory($actionID, $changes); + } + } + else + { + $caseData->version = 1; + $caseData->openedBy = $this->app->user->account; + $caseData->openedDate = $now; + $caseData->status = $forceNotReview ? 'normal' : 'wait'; + $this->dao->insert(TABLE_CASE)->data($caseData)->autoCheck()->exec(); + + if(!dao::isError()) + { + $caseID = $this->dao->lastInsertID(); + $parentStepID = 0; + foreach($data->desc[$key] as $id => $desc) + { + $desc = trim($desc); + if(empty($desc)) continue; + $stepData = new stdclass(); + $stepData->type = ($data->stepType[$key][$id] == 'item' and $parentStepID == 0) ? 'step' : $data->stepType[$key][$id]; + $stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0; + $stepData->case = $caseID; + $stepData->version = 1; + $stepData->desc = $desc; + $stepData->expect = $data->expect[$key][$id]; + $this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec(); + if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID(); + if($stepData->type == 'step') $parentStepID = 0; + } + $this->action->create('case', $caseID, 'Opened'); + } + } + } + + unlink($this->session->importFile); + unset($_SESSION['importFile']); + } + + /** + * Batch create case for lib. + * + * @param int $libID + * @access public + * @return void + */ + public function batchCreateCase($libID) + { + $this->loadModel('testcase'); + $this->loadModel('action'); + + $now = helper::now(); + $cases = fixer::input('post')->get(); + $batchNum = count(reset($cases)); + + $result = $this->loadModel('common')->removeDuplicate('case', $cases, "lib={$libID}"); + $cases = $result['data']; + + for($i = 0; $i < $batchNum; $i++) + { + if(!empty($cases->title[$i]) and empty($cases->type[$i])) die(js::alert(sprintf($this->lang->error->notempty, $this->lang->testcase->type))); + } + + $module = 0; + $type = ''; + $pri = 3; + for($i = 0; $i < $batchNum; $i++) + { + $module = $cases->module[$i] == 'ditto' ? $module : $cases->module[$i]; + $type = $cases->type[$i] == 'ditto' ? $type : $cases->type[$i]; + $pri = $cases->pri[$i] == 'ditto' ? $pri : $cases->pri[$i]; + $cases->module[$i] = (int)$module; + $cases->type[$i] = $type; + $cases->pri[$i] = $pri; + } + + $forceNotReview = $this->testcase->forceNotReview(); + for($i = 0; $i < $batchNum; $i++) + { + if($cases->type[$i] != '' and $cases->title[$i] != '') + { + $data[$i] = new stdclass(); + $data[$i]->lib = $libID; + $data[$i]->module = $cases->module[$i]; + $data[$i]->type = $cases->type[$i]; + $data[$i]->pri = $cases->pri[$i]; + $data[$i]->stage = empty($cases->stage[$i]) ? '' : implode(',', $cases->stage[$i]); + $data[$i]->color = $cases->color[$i]; + $data[$i]->title = $cases->title[$i]; + $data[$i]->precondition = $cases->precondition[$i]; + $data[$i]->keywords = $cases->keywords[$i]; + $data[$i]->openedBy = $this->app->user->account; + $data[$i]->openedDate = $now; + $data[$i]->status = $forceNotReview ? 'normal' : 'wait'; + $data[$i]->version = 1; + + $this->dao->insert(TABLE_CASE)->data($data[$i]) + ->autoCheck() + ->batchCheck($this->config->testcase->create->requiredFields, 'notempty') + ->exec(); + + if(dao::isError()) + { + echo js::error(dao::getError()); + die(js::reload('parent')); + } + + $caseID = $this->dao->lastInsertID(); + $actionID = $this->action->create('case', $caseID, 'Opened'); + } + } + } +} diff --git a/module/testsuite/view/ajaxgetdropmenu.html.php b/module/caselib/view/ajaxgetdropmenu.html.php similarity index 100% rename from module/testsuite/view/ajaxgetdropmenu.html.php rename to module/caselib/view/ajaxgetdropmenu.html.php diff --git a/module/testsuite/view/batchcreatecase.html.php b/module/caselib/view/batchcreatecase.html.php similarity index 98% rename from module/testsuite/view/batchcreatecase.html.php rename to module/caselib/view/batchcreatecase.html.php index 1c211b319d..86c08b124f 100644 --- a/module/testsuite/view/batchcreatecase.html.php +++ b/module/caselib/view/batchcreatecase.html.php @@ -1,11 +1,11 @@ - * @package testsuite + * @package caselib * @version $Id$ * @link http://www.zentao.net */ diff --git a/module/testsuite/view/library.html.php b/module/caselib/view/browse.html.php similarity index 87% rename from module/testsuite/view/library.html.php rename to module/caselib/view/browse.html.php index 1f1cee3ef4..c989800fac 100644 --- a/module/testsuite/view/library.html.php +++ b/module/caselib/view/browse.html.php @@ -1,11 +1,11 @@ - * @package testsuite + * @package caselib * @version $Id: library.html.php 5108 2013-07-12 01:59:04Z chencongzhi520@gmail.com $ * @link http://www.zentao.net */ @@ -15,7 +15,7 @@ include '../../common/view/header.html.php'; include '../../common/view/datatable.fix.html.php'; js::set('browseType', $browseType); js::set('moduleID', $moduleID); -js::set('confirmDelete', $lang->testsuite->confirmDelete); +js::set('confirmDelete', $lang->testcase->confirmDelete); js::set('batchDelete', $lang->testcase->confirmBatchDelete); js::set('flow', $config->global->flow); ?> @@ -36,29 +36,29 @@ js::set('flow', $config->global->flow);
inlink('library', "libID=$libID&browseType=all"), "{$lang->testcase->allCases}", '', "id='allTab' class='btn btn-link'"); + echo html::a($this->inlink('browse', "libID=$libID&browseType=all"), "{$lang->testcase->allCases}", '', "id='allTab' class='btn btn-link'"); if($config->testcase->needReview or !empty($config->testcase->forceReview)) echo html::a($this->inlink('library', "libID=$libID&browseType=wait"), "" . $lang->testcase->statusList['wait'] . "", '', "id='waitTab' class='btn btn-link'"); } ?> testcase->bySearch;?> " . $this->lang->testsuite->libView, '', "class='btn btn-link'"); + $link = helper::createLink('caselib', 'view', "libID=$libID"); + echo html::a($link, " " . $this->lang->caselib->view, '', "class='btn btn-link'"); } ?>
- " . $lang->testsuite->exportTemplet, '', "class='btn btn-link export' data-width='35%'");?> - " . $lang->testcase->importFile, '', "class='btn btn-link export'");?> + " . $lang->caselib->exportTemplet, '', "class='btn btn-link export' data-width='35%'");?> + " . $lang->testcase->importFile, '', "class='btn btn-link export'");?>
- " . $lang->testcase->batchCreate, '', "class='btn btn-secondary'");?> - " . $lang->testcase->create, '', "class='btn btn-primary'");?> + " . $lang->testcase->batchCreate, '', "class='btn btn-secondary'");?> + " . $lang->testcase->create, '', "class='btn btn-primary'");?>
@@ -69,7 +69,7 @@ js::set('flow', $config->global->flow);
- testsuite->noModule;?> + caselib->noModule;?>

@@ -86,8 +86,8 @@ js::set('flow', $config->global->flow);

testcase->noCase;?> - - createLink('testsuite', 'createCase', "libID=$libID&moduleID=" . (isset($moduleID) ? $moduleID : 0)), " " . $lang->testcase->create, '', "class='btn btn-info'");?> + + createLink('caselib', 'createCase', "libID=$libID&moduleID=" . (isset($moduleID) ? $moduleID : 0)), " " . $lang->testcase->create, '', "class='btn btn-info'");?>

diff --git a/module/testsuite/view/createlib.html.php b/module/caselib/view/create.html.php similarity index 83% rename from module/testsuite/view/createlib.html.php rename to module/caselib/view/create.html.php index f1b96e6ffe..21d55a3eac 100644 --- a/module/testsuite/view/createlib.html.php +++ b/module/caselib/view/create.html.php @@ -1,11 +1,11 @@ - * @package testsuite + * @package caselib * @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ * @link http://www.zentao.net */ @@ -15,16 +15,16 @@
-

testsuite->createLib;?>

+

caselib->create;?>

- + - + diff --git a/module/testsuite/view/createcase.html.php b/module/caselib/view/createcase.html.php similarity index 98% rename from module/testsuite/view/createcase.html.php rename to module/caselib/view/createcase.html.php index 2ab7777d28..396f973840 100644 --- a/module/testsuite/view/createcase.html.php +++ b/module/caselib/view/createcase.html.php @@ -1,11 +1,11 @@ - * @package testsuite + * @package caselib * @version $Id: createcase.html.php 4904 2013-06-26 05:37:45Z wyd621@gmail.com $ * @link http://www.zentao.net */ @@ -19,7 +19,7 @@

testcase->create;?>

- createLink('custom', 'ajaxSaveCustomFields', 'module=testsuite§ion=custom&key=createFields');?> + createLink('custom', 'ajaxSaveCustomFields', 'module=caselib§ion=custom&key=createFields');?>
diff --git a/module/caselib/view/edit.html.php b/module/caselib/view/edit.html.php new file mode 100644 index 0000000000..2b21f4aad9 --- /dev/null +++ b/module/caselib/view/edit.html.php @@ -0,0 +1,41 @@ + + * @package caselib + * @version $Id: edit.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ + * @link http://www.zentao.net + */ +?> + + +
+
+
+

caselib->edit;?>

+
+ +
testsuite->name;?>caselib->name;?>
testsuite->desc;?>caselib->desc;?>
+ + + + + + + + + printExtendFields($lib, 'table');?> + + + +
caselib->name;?>name, "class='form-control'");?>
caselib->desc;?>desc), "rows=10 class='form-control'");?>
+ + +
+
+
+
+ diff --git a/module/testsuite/view/exporttemplet.html.php b/module/caselib/view/exporttemplet.html.php similarity index 100% rename from module/testsuite/view/exporttemplet.html.php rename to module/caselib/view/exporttemplet.html.php diff --git a/module/testsuite/view/import.html.php b/module/caselib/view/import.html.php similarity index 100% rename from module/testsuite/view/import.html.php rename to module/caselib/view/import.html.php diff --git a/module/testsuite/view/showimport.html.php b/module/caselib/view/showimport.html.php similarity index 99% rename from module/testsuite/view/showimport.html.php rename to module/caselib/view/showimport.html.php index 2e34529c00..202e99a182 100644 --- a/module/testsuite/view/showimport.html.php +++ b/module/caselib/view/showimport.html.php @@ -7,7 +7,7 @@
-

testsuite->import;?>

+

caselib->import;?>

diff --git a/module/testsuite/view/libview.html.php b/module/caselib/view/view.html.php similarity index 75% rename from module/testsuite/view/libview.html.php rename to module/caselib/view/view.html.php index 9cf3b019be..f9eb466230 100644 --- a/module/testsuite/view/libview.html.php +++ b/module/caselib/view/view.html.php @@ -1,11 +1,11 @@ - * @package testsuite + * @package caselib * @version $Id: view.html.php 4141 2013-01-18 06:15:13Z zhujinyonging@gmail.com $ * @link http://www.zentao.net */ @@ -13,14 +13,14 @@
- $actionLabel):?> $moduleName->menus) and $action == 'browse') continue;;?> diff --git a/module/testsuite/config.php b/module/testsuite/config.php index 4e325d3cf8..4a93268ced 100644 --- a/module/testsuite/config.php +++ b/module/testsuite/config.php @@ -2,17 +2,12 @@ $config->testsuite = new stdclass(); $config->testsuite->create = new stdclass(); $config->testsuite->edit = new stdclass(); -$config->testsuite->createlib = new stdclass(); -$config->testsuite->createcase = new stdclass(); -$config->testsuite->create->requiredFields = 'name'; -$config->testsuite->edit->requiredFields = 'name'; -$config->testsuite->createlib->requiredFields = 'name'; -$config->testsuite->createcase->requiredFields = 'title,type'; +$config->testsuite->create->requiredFields = 'name'; +$config->testsuite->edit->requiredFields = 'name'; $config->testsuite->editor = new stdclass(); $config->testsuite->editor->create = array('id' => 'desc', 'tools' => 'simpleTools'); $config->testsuite->editor->edit = array('id' => 'desc', 'tools' => 'simpleTools'); -$config->testsuite->editor->createlib = array('id' => 'desc', 'tools' => 'simpleTools'); $config->testsuite->datatable = new stdclass(); $config->testsuite->datatable->defaultField = array('id', 'pri', 'title', 'type', 'assignedTo', 'lastRunner', 'lastRunDate', 'lastRunResult', 'status', 'bugs', 'results', 'actions'); diff --git a/module/testsuite/control.php b/module/testsuite/control.php index 19239badf1..578d79ecd2 100644 --- a/module/testsuite/control.php +++ b/module/testsuite/control.php @@ -186,47 +186,29 @@ class testsuite extends control } if($changes) { - $objectType = $suite->type == 'library' ? 'caselib' : 'testsuite'; - $actionID = $this->loadModel('action')->create($objectType, $suiteID, 'edited'); + $actionID = $this->loadModel('action')->create('testsuite', $suiteID, 'edited'); $this->action->logHistory($actionID, $changes); } $this->executeHooks($suiteID); - $method = $suite->type == 'library' ? 'libView' : 'view'; - $response['locate'] = inlink($method, "suiteID=$suiteID"); + $response['locate'] = inlink('view', "suiteID=$suiteID"); $response['message'] = $this->lang->testsuite->successSaved; $this->send($response); } - if($suite->type == 'library') - { - /* Set lib menu. */ - if($this->config->global->flow == 'onlyTest') $this->lang->menugroup->testsuite = 'caselib'; - $libraries = $this->testsuite->getLibraries(); - $suiteID = $this->testsuite->saveLibState($suiteID, $libraries); - $this->testsuite->setLibMenu($libraries, $suiteID); + if($suite->type == 'private' and $suite->addedBy != $this->app->user->account and !$this->app->user->admin) die(js::error($this->lang->error->accessDenied) . js::locate('back')); - $this->view->title = $libraries[$suiteID] . $this->lang->colon . $this->lang->testsuite->edit; - $this->view->position[] = html::a($this->createLink('testsuite', 'library', "libID=$suiteID"), $libraries[$suiteID]); - $this->view->position[] = $this->lang->caselib->common; - } - else - { - if($suite->type == 'private' and $suite->addedBy != $this->app->user->account and !$this->app->user->admin) die(js::error($this->lang->error->accessDenied) . js::locate('back')); + /* Get suite info. */ + $this->view->products = $this->products = $this->loadModel('product')->getPairs('nocode'); + $productID = $this->product->saveState($suite->product, $this->products); - /* Get suite info. */ - $this->view->products = $this->products = $this->loadModel('product')->getPairs('nocode'); - $productID = $this->product->saveState($suite->product, $this->products); - - /* Set menu. */ - $this->testsuite->setMenu($this->products, $productID); - - $this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testsuite->edit; - $this->view->position[] = html::a($this->createLink('testsuite', 'browse', "productID=$productID"), $this->products[$productID]); - $this->view->position[] = $this->lang->testsuite->common; - } + /* Set menu. */ + $this->testsuite->setMenu($this->products, $productID); + $this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testsuite->edit; + $this->view->position[] = html::a($this->createLink('testsuite', 'browse', "productID=$productID"), $this->products[$productID]); + $this->view->position[] = $this->lang->testsuite->common; $this->view->position[] = $this->lang->testsuite->edit; $this->view->suite = $suite; @@ -245,7 +227,7 @@ class testsuite extends control { if($confirm == 'no') { - die(js::confirm($this->lang->testsuite->libraryDelete, inlink('delete', "suiteID=$suiteID&confirm=yes"))); + die(js::confirm($this->lang->testsuite->confirmDelete, inlink('delete', "suiteID=$suiteID&confirm=yes"))); } else { @@ -384,635 +366,4 @@ 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. */ - $browseType = strtolower($browseType); - - $libraries = $this->testsuite->getLibraries(); - if(empty($libraries)) $this->locate(inlink('createLib')); - - /* Save session. */ - $this->session->set('caseList', $this->app->getURI(true)); - - /* Set menu. */ - $libID = $this->testsuite->saveLibState($libID, $libraries); - setcookie('preCaseLibID', $libID, $this->config->cookieLife, $this->config->webRoot); - if($this->cookie->preCaseLibID != $libID) - { - $_COOKIE['libCaseModule'] = 0; - setcookie('libCaseModule', 0, 0, $this->config->webRoot); - } - - if($browseType == 'bymodule') setcookie('libCaseModule', (int)$param, 0, $this->config->webRoot); - if($browseType != 'bymodule') $this->session->set('libBrowseType', $browseType); - $moduleID = ($browseType == 'bymodule') ? (int)$param : ($browseType == 'bysearch' ? 0 : ($this->cookie->libCaseModule ? $this->cookie->libCaseModule : 0)); - $queryID = ($browseType == 'bysearch') ? (int)$param : 0; - - /* Set lib menu. */ - $this->testsuite->setLibMenu($libraries, $libID, $moduleID); - if($this->config->global->flow == 'onlyTest') $this->lang->menugroup->testsuite = 'caselib'; - - /* Load pager. */ - $this->app->loadClass('pager', $static = true); - $pager = pager::init($recTotal, $recPerPage, $pageID); - - /* Build the search form. */ - $this->loadModel('testcase'); - $actionURL = $this->createLink('testsuite', 'library', "libID=$libID&browseType=bySearch&queryID=myQueryID"); - $this->testsuite->buildSearchForm($libID, $libraries, $queryID, $actionURL); - - /* Append id for secend sort. */ - $sort = $this->loadModel('common')->appendOrder($orderBy); - - /* save session .*/ - $cases = $this->testsuite->getLibCases($libID, $browseType, $queryID, $moduleID, $sort, $pager); - $this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', true); - - $this->loadModel('datatable'); - $this->loadModel('tree'); - $showModule = !empty($this->config->datatable->testsuiteLibrary->showModule) ? $this->config->datatable->testsuiteLibrary->showModule : ''; - $this->view->modulePairs = $showModule ? $this->tree->getModulePairs($libID, 'caselib', $showModule) : array(); - - $this->view->title = $this->lang->caselib->common . $this->lang->colon . $libraries[$libID]; - $this->view->position[] = html::a($this->createLink('testsuite', 'library', "libID=$libID"), $libraries[$libID]); - - $this->view->libID = $libID; - $this->view->libName = $libraries[$libID]; - $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 = 'caselib', $startModuleID = 0); - $this->view->moduleTree = $this->tree->getTreeMenu($libID, $viewType = 'caselib', $startModuleID = 0, array('treeModel', 'createCaseLibLink')); - $this->view->pager = $pager; - $this->view->browseType = $browseType; - $this->view->moduleID = $moduleID; - $this->view->moduleName = $moduleID ? $this->tree->getById($moduleID)->name : $this->lang->tree->all; - $this->view->param = $param; - $this->view->setShowModule = true; - - $this->display(); - } - - /** - * Create lib - * - * @access public - * @return void - */ - public function createLib() - { - if(!empty($_POST)) - { - $response['result'] = 'success'; - $response['message'] = ''; - $libID = $this->testsuite->createLib(); - if(dao::isError()) - { - $response['result'] = 'fail'; - $response['message'] = dao::getError(); - $this->send($response); - } - $this->loadModel('action')->create('caselib', $libID, 'opened'); - $response['locate'] = $this->createLink('testsuite', 'library', "libID=$libID"); - $response['message'] = $this->lang->testsuite->successSaved; - $this->send($response); - } - - /* Set menu. */ - $libraries = $this->testsuite->getLibraries(); - $libID = $this->testsuite->saveLibState(0, $libraries); - $this->testsuite->setLibMenu($libraries, $libID); - if($this->config->global->flow == 'onlyTest') $this->lang->menugroup->testsuite = 'caselib'; - - $this->view->title = $this->lang->caselib->common . $this->lang->colon . $this->lang->testsuite->createLib; - $this->view->position[] = $this->lang->caselib->common; - $this->view->position[] = $this->lang->testsuite->createLib; - $this->display(); - } - - /** - * 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)) - { - $this->loadModel('testcase'); - $this->config->testcase->create->requiredFields = $this->config->testsuite->createcase->requiredFields; - $caseResult = $this->testcase->create($bugID = 0); - if(!$caseResult or dao::isError()) die(js::error(dao::getError())); - - $caseID = $caseResult['id']; - if($caseResult['status'] == 'exists') - { - echo js::alert(sprintf($this->lang->duplicate, $this->lang->testcase->common)); - die(js::locate($this->createLink('testcase', 'view', "caseID=$caseID"), 'parent')); - } - - $this->loadModel('action')->create('case', $caseID, 'Opened'); - - /* If link from no head then reload. */ - if(isonlybody()) die(js::reload('parent')); - die(js::locate($this->createLink('testsuite', 'library', "libID={$libID}&browseType=byModule¶m={$_POST['module']}"), 'parent')); - } - /* Set lib menu. */ - $libraries = $this->testsuite->getLibraries(); - $libID = $this->testsuite->saveLibState($libID, $libraries); - $this->testsuite->setLibMenu($libraries, $libID); - if($this->config->global->flow == 'onlyTest') $this->lang->menugroup->testsuite = 'caselib'; - - $type = 'feature'; - $stage = ''; - $pri = 3; - $caseTitle = ''; - $precondition = ''; - $keywords = ''; - $steps = array(); - - $this->loadModel('testcase'); - 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->type = 'item'; - $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]); - $this->view->position[] = $this->lang->testsuite->common; - $this->view->position[] = $this->lang->testcase->create; - - foreach(explode(',', $this->config->testsuite->customCreateFields) as $field) $customFields[$field] = $this->lang->testcase->$field; - $this->view->showFields = $this->config->testsuite->custom->createFields; - $this->view->customFields = $customFields; - $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 = 'caselib', $startModuleID = 0); - $this->display(); - } - - /** - * Batch create case. - * - * @param int $libID - * @param int $moduleID - * @access public - * @return void - */ - public function batchCreateCase($libID, $moduleID = 0) - { - $this->loadModel('testcase'); - if(!empty($_POST)) - { - $caseID = $this->testsuite->batchCreateCase($libID); - if(dao::isError()) die(js::error(dao::getError())); - if(isonlybody()) die(js::closeModal('parent.parent', 'this')); - die(js::locate($this->createLink('testsuite', 'library', "libID=$libID&browseType=byModule¶m=$moduleID"), 'parent')); - } - - $libraries = $this->testsuite->getLibraries(); - if(empty($libraries)) $this->locate(inlink('createLib')); - - /* Set lib menu. */ - $this->testsuite->setLibMenu($libraries, $libID); - if($this->config->global->flow == 'onlyTest') $this->lang->menugroup->testsuite = 'caselib'; - - $currentModuleID = (int)$moduleID; - - /* Set module option menu. */ - $moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0); - $moduleOptionMenu['ditto'] = $this->lang->testcase->ditto; - - $this->view->title = $libraries[$libID] . $this->lang->colon . $this->lang->testcase->batchCreate; - $this->view->position[] = html::a($this->createLink('testsuite', 'library', "libID=$libID"), $libraries[$libID]); - $this->view->position[] = $this->lang->testcase->batchCreate; - $this->view->libID = $libID; - $this->view->moduleOptionMenu = $moduleOptionMenu; - $this->view->currentModuleID = $currentModuleID; - - $this->display(); - } - - /** - * View library - * - * @param int $libID - * @access public - * @return void - */ - public function libView($libID) - { - $lib = $this->testsuite->getById($libID, true); - - /* Set lib menu. */ - $libraries = $this->testsuite->getLibraries(); - $this->testsuite->setLibMenu($libraries, $libID); - if($this->config->global->flow == 'onlyTest') $this->lang->menugroup->testsuite = 'caselib'; - - $this->loadModel('testcase'); - $this->view->title = $lib->name . $this->lang->colon . $this->lang->testsuite->view; - $this->view->position[] = html::a($this->createLink('testsuite', 'library', "libID=$libID"), $lib->name); - $this->view->position[] = $this->lang->testsuite->common; - $this->view->position[] = $this->lang->testsuite->view; - - $this->view->lib = $lib; - $this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter'); - $this->view->actions = $this->loadModel('action')->getList('caselib', $libID); - $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); - $this->view->libID = $libID; - $this->view->module = $module; - $this->view->method = $method; - $this->view->extra = $extra; - - $libraries = $this->testsuite->getLibraries(); - - $this->view->libraries = $libraries; - $this->view->librariesPinyin = common::convert2Pinyin($libraries); - $this->display(); - } - - /** - * The results page of search. - * - * @param string $keywords - * @param string $module - * @param string $method - * @param mix $extra - * @access public - * @return void - */ - public function ajaxGetMatchedItems($keywords, $module, $method, $extra) - { - $libraries = $this->dao->select('*')->from(TABLE_TESTSUITE)->where('deleted')->eq(0)->andWhere('name')->like("%$keywords%")->andWhere('type')->eq('library')->orderBy('`id` desc')->fetchAll(); - $this->view->link = $this->testsuite->getLibLink($module, $method, $extra); - $this->view->libraries = $libraries; - $this->view->keywords = $keywords; - $this->display(); - } - - /** - * Export templet. - * - * @param int $libID - * @access public - * @return void - */ - public function exportTemplet($libID) - { - $this->loadModel('testcase'); - if($_POST) - { - $fields['module'] = $this->lang->testcase->module; - $fields['title'] = $this->lang->testcase->title; - $fields['precondition'] = $this->lang->testcase->precondition; - $fields['stepDesc'] = $this->lang->testcase->stepDesc; - $fields['stepExpect'] = $this->lang->testcase->stepExpect; - $fields['keywords'] = $this->lang->testcase->keywords; - $fields['pri'] = $this->lang->testcase->pri; - $fields['type'] = $this->lang->testcase->type; - $fields['stage'] = $this->lang->testcase->stage; - - $fields[''] = ''; - $fields['typeValue'] = $this->lang->testcase->lblTypeValue; - $fields['stageValue'] = $this->lang->testcase->lblStageValue; - - $modules = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0); - $rows = array(); - $num = (int)$this->post->num; - for($i = 0; $i < $num; $i++) - { - foreach($modules as $moduleID => $module) - { - $row = new stdclass(); - $row->module = $module . "(#$moduleID)"; - $row->stepDesc = "1. \n2. \n3."; - $row->stepExpect = "1. \n2. \n3."; - - if(empty($rows)) - { - $row->typeValue = join("\n", $this->lang->testcase->typeList); - $row->stageValue = join("\n", $this->lang->testcase->stageList); - } - $rows[] = $row; - } - } - - $this->post->set('fields', $fields); - $this->post->set('kind', 'testcase'); - $this->post->set('rows', $rows); - $this->post->set('extraNum', $num); - $this->post->set('fileName', 'templet'); - $this->fetch('file', 'export2csv', $_POST); - } - - $this->display(); - } - - /** - * Import case csv file. - * - * @param int $libID - * @access public - * @return void - */ - public function import($libID) - { - $this->loadModel('testcase'); - if($_FILES) - { - $file = $this->loadModel('file')->getUpload('file'); - $file = $file[0]; - - $fileName = $this->file->savePath . $this->file->getSaveName($file['pathname']); - move_uploaded_file($file['tmpname'], $fileName); - - $rows = $this->file->parseCSV($fileName); - $fields = $this->testcase->getImportFields($productID); - $fields = array_flip($fields); - $header = array(); - foreach($rows[0] as $i => $rowValue) - { - if(empty($rowValue)) break; - $header[$i] = $rowValue; - } - unset($rows[0]); - - $columnKey = array(); - foreach($header as $title) - { - if(!isset($fields[$title])) continue; - $columnKey[] = $fields[$title]; - } - - if(count($columnKey) != count($header) or $this->post->encode != 'utf-8') - { - $fc = file_get_contents($fileName); - $encode = $this->post->encode != "utf-8" ? $this->post->encode : 'gbk'; - $fc = helper::convertEncoding($fc, $encode, 'utf-8'); - file_put_contents($fileName, $fc); - - $rows = $this->file->parseCSV($fileName); - $columnKey = array(); - $header = array(); - foreach($rows[0] as $i => $rowValue) - { - if(empty($rowValue)) break; - $header[$i] = $rowValue; - } - unset($rows[0]); - foreach($header as $title) - { - if(!isset($fields[$title])) continue; - $columnKey[] = $fields[$title]; - } - if(count($columnKey) != count($header)) die(js::alert($this->lang->testcase->errorEncode)); - } - - $this->session->set('importFile', $fileName); - - die(js::locate(inlink('showImport', "libID=$libID"), 'parent.parent')); - } - $this->display(); - } - - /** - * Show import case. - * - * @param int $libID - * @access public - * @return void - */ - public function showImport($libID) - { - $this->loadModel('testcase'); - if($_POST) - { - $this->testsuite->createFromImport($libID); - die(js::locate(inlink('library', "libID=$libID"), 'parent')); - } - - $libraries = $this->testsuite->getLibraries(); - if(empty($libraries)) $this->locate(inlink('createLib')); - - $this->testsuite->setLibMenu($libraries, $libID); - - $file = $this->session->importFile; - $caseLang = $this->lang->testcase; - $caseConfig = $this->config->testcase; - $modules = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0); - - $fields = explode(',', $caseConfig->exportFields); - foreach($fields as $key => $fieldName) - { - $fieldName = trim($fieldName); - $fields[$fieldName] = isset($caseLang->$fieldName) ? $caseLang->$fieldName : $fieldName; - unset($fields[$key]); - } - - $fields = array_flip($fields); - $rows = $this->loadModel('file')->parseCSV($file); - $header = array(); - foreach($rows[0] as $i => $rowValue) - { - if(empty($rowValue)) break; - $header[$i] = $rowValue; - } - unset($rows[0]); - - foreach($header as $title) - { - if(!isset($fields[$title])) continue; - $columnKey[] = $fields[$title]; - } - - $endField = end($fields); - $caseData = array(); - $stepData = array(); - $stepVars = 0; - foreach($rows as $row => $data) - { - $case = new stdclass(); - foreach($columnKey as $key => $field) - { - if(!isset($data[$key])) continue; - $cellValue = $data[$key]; - if($field == 'module') - { - $case->$field = 0; - if(strrpos($cellValue, '(#') !== false) - { - $id = trim(substr($cellValue, strrpos($cellValue,'(#') + 2), ')'); - $case->$field = $id; - } - } - elseif(in_array($field, $caseConfig->export->listFields)) - { - if($field == 'stage') - { - $stages = explode("\n", $cellValue); - foreach($stages as $stage) $case->stage[] = array_search($stage, $caseLang->{$field . 'List'}); - $case->stage = join(',', $case->stage); - } - else - { - $case->$field = array_search($cellValue, $caseLang->{$field . 'List'}); - } - } - elseif($field != 'stepDesc' and $field != 'stepExpect') - { - $case->$field = $cellValue; - } - else - { - $steps = (array)$cellValue; - if(strpos($cellValue, "\n")) - { - $steps = explode("\n", $cellValue); - } - elseif(strpos($cellValue, "\r")) - { - $steps = explode("\r", $cellValue); - } - - $stepKey = str_replace('step', '', strtolower($field)); - $caseStep = array(); - - foreach($steps as $step) - { - $step = trim($step); - if(empty($step)) continue; - if(preg_match('/^(([0-9]+)\.[0-9]+)([.、]{1})/U', $step, $out)) - { - $num = $out[1]; - $parent = $out[2]; - $sign = $out[3]; - $signbit = $sign == '.' ? 1 : 3; - $step = trim(substr($step, strlen($num) + $signbit)); - if(!empty($step)) $caseStep[$num]['content'] = $step; - $caseStep[$num]['type'] = 'item'; - $caseStep[$parent]['type'] = 'group'; - } - elseif(preg_match('/^([0-9]+)([.、]{1})/U', $step, $out)) - { - $num = $out[1]; - $sign = $out[2]; - $signbit = $sign == '.' ? 1 : 3; - $step = trim(substr($step, strlen($num) + $signbit)); - if(!empty($step)) $caseStep[$num]['content'] = $step; - $caseStep[$num]['type'] = 'step'; - } - elseif(isset($num)) - { - if(!isset($caseStep[$num]['content'])) $caseStep[$num]['content'] = ''; - $caseStep[$num]['content'] .= "\n" . $step; - } - else - { - if($field == 'stepDesc') - { - $num = 1; - $caseStep[$num]['content'] = $step; - $caseStep[$num]['type'] = 'step'; - } - if($field == 'stepExpect' and isset($stepData[$row]['desc'])) - { - end($stepData[$row]['desc']); - $num = key($stepData[$row]['desc']); - $caseStep[$num]['content'] = $step; - } - } - } - unset($num); - unset($sign); - $stepVars += count($caseStep, COUNT_RECURSIVE) - count($caseStep); - $stepData[$row][$stepKey] = $caseStep; - } - } - - $caseData[$row] = $case; - unset($case); - } - - if(empty($caseData)) - { - unlink($this->session->importFile); - unset($_SESSION['importFile']); - echo js::alert($this->lang->error->noData); - die(js::locate($this->createLink('testsuite', 'library', "libID=$libID"))); - } - - /* Judge whether the editedTasks is too large and set session. */ - $countInputVars = count($caseData) * 9 + $stepVars; - $showSuhosinInfo = common::judgeSuhosinSetting($countInputVars); - if($showSuhosinInfo) $this->view->suhosinInfo = extension_loaded('suhosin') ? sprintf($this->lang->suhosinInfo, $countInputVars) : sprintf($this->lang->maxVarsInfo, $countInputVars); - - $this->view->title = $this->lang->caselib->common . $this->lang->colon . $this->lang->testcase->showImport; - $this->view->position[] = $this->lang->testcase->showImport; - - $this->view->modules = $modules; - $this->view->cases = $this->dao->select('id,module,stage,status,pri,type')->from(TABLE_CASE)->where('lib')->eq($libID)->andWhere('deleted')->eq(0)->andWhere('product')->eq(0)->fetchAll('id'); - $this->view->caseData = $caseData; - $this->view->stepData = $stepData; - $this->view->libID = $libID; - $this->display(); - } } diff --git a/module/testsuite/lang/en.php b/module/testsuite/lang/en.php index 12b8e00358..5a69a3ac69 100644 --- a/module/testsuite/lang/en.php +++ b/module/testsuite/lang/en.php @@ -21,11 +21,6 @@ $lang->testsuite->unlinkCase = "Unlink"; $lang->testsuite->unlinkCaseAction = "Unlink Case"; $lang->testsuite->batchUnlinkCases = "Batch Unlink Cases"; $lang->testsuite->deleted = 'Deleted'; -$lang->testsuite->exportTemplet = 'Export Template'; -$lang->testsuite->batchCreateCase = 'Batch Create'; -$lang->testsuite->import = 'Import'; -$lang->testsuite->importAction = 'Import Case'; -$lang->testsuite->showImport = 'Imported Data'; $lang->testsuite->successSaved = 'Saved'; $lang->testsuite->id = 'ID'; @@ -46,7 +41,6 @@ $lang->testsuite->legendBasicInfo = 'Basic Info'; $lang->testsuite->unlinkedCases = 'Unlinked Cases'; $lang->testsuite->confirmDelete = 'Do you want to delete this test suite?'; -$lang->testsuite->libraryDelete = 'Do you want to delete this library?'; $lang->testsuite->confirmUnlinkCase = 'Do you want to unlink this Case?'; $lang->testsuite->noticeNone = 'You have not created any suite yet.'; $lang->testsuite->noModule = '
You have no modules.
Manage it now.
'; @@ -57,12 +51,3 @@ $lang->testsuite->lblUnlinkCase = 'Unlink Case'; $lang->testsuite->authorList['private'] = 'Private'; $lang->testsuite->authorList['public'] = 'Public'; - -$lang->caselib->common = 'Case Library'; -$lang->caselib->all = 'All Case Libraries'; - -$lang->testsuite->createLib = 'Create Case Library'; -$lang->testsuite->editLib = 'Edit Case Library'; -$lang->testsuite->library = 'View Cases in Library'; -$lang->testsuite->createCase = 'Create Case'; -$lang->testsuite->libView = 'Library Detail'; diff --git a/module/testsuite/lang/zh-cn.php b/module/testsuite/lang/zh-cn.php index 097bdc9db0..05a4bcfb24 100644 --- a/module/testsuite/lang/zh-cn.php +++ b/module/testsuite/lang/zh-cn.php @@ -21,11 +21,6 @@ $lang->testsuite->unlinkCase = "移除"; $lang->testsuite->unlinkCaseAction = "移除用例"; $lang->testsuite->batchUnlinkCases = "批量移除用例"; $lang->testsuite->deleted = '已删除'; -$lang->testsuite->exportTemplet = '导出模板'; -$lang->testsuite->batchCreateCase = '批量创建用例'; -$lang->testsuite->import = '导入'; -$lang->testsuite->importAction = '导入用例'; -$lang->testsuite->showImport = '显示导入数据'; $lang->testsuite->successSaved = '保存成功'; $lang->testsuite->id = '编号'; @@ -46,7 +41,6 @@ $lang->testsuite->legendBasicInfo = '基本信息'; $lang->testsuite->unlinkedCases = '未关联'; $lang->testsuite->confirmDelete = '您确认要删除该套件吗?'; -$lang->testsuite->libraryDelete = '您确认要删除该用例库吗?'; $lang->testsuite->confirmUnlinkCase = '您确认要移除该用例吗?'; $lang->testsuite->noticeNone = '您还没有创建套件'; $lang->testsuite->noModule = '
您现在还没有模块信息
请维护用例库模块
'; @@ -57,12 +51,3 @@ $lang->testsuite->lblUnlinkCase = '移除用例'; $lang->testsuite->authorList['private'] = '私有'; $lang->testsuite->authorList['public'] = '公开'; - -$lang->caselib->common = '公共用例库'; -$lang->caselib->all = '所有用例库'; - -$lang->testsuite->createLib = '创建用例库'; -$lang->testsuite->editLib = '编辑用例库'; -$lang->testsuite->library = '浏览库用例'; -$lang->testsuite->createCase = '创建用例'; -$lang->testsuite->libView = '查看库概况'; diff --git a/module/testsuite/model.php b/module/testsuite/model.php index 9bada58ab6..1c17664957 100644 --- a/module/testsuite/model.php +++ b/module/testsuite/model.php @@ -99,140 +99,6 @@ class testsuiteModel extends model return $output; } - /** - * Set library menu. - * - * @param array $libraries - * @param int $libID - * @access public - * @return void - */ - public function setLibMenu($libraries, $libID, $moduleID = 0) - { - $currentLibName = zget($libraries, $libID, ''); - $isMobile = $this->app->viewType == 'mhtml'; - $selectHtml = ''; - if(!empty($libraries)) - { - if($isMobile) - { - $selectHtml = "{$currentLibName} "; - } - else - { - $dropMenuLink = helper::createLink('testsuite', 'ajaxGetDropMenu', "objectID=$libID&module=testsuite&method=library"); - $selectHtml = "
"; - } - } - - if($this->config->global->flow == 'onlyTest') - { - $modules = $this->loadModel('tree')->getModulePairs($libID, 'caselib'); - $moduleName = ($moduleID && isset($modules[$moduleID])) ? $modules[$moduleID] : $this->lang->tree->all; - - if(!$isMobile) - { - $dropMenuLink = helper::createLink('tree', 'ajaxGetDropMenu', "objectID=$libID&module=testsuite&method=library"); - $selectHtml .= "
"; - } - else - { - $selectHtml .= "{$moduleName} "; - } - } - - setCookie("lastCaseLib", $libID, $this->config->cookieLife, $this->config->webRoot); - - $pageNav = ''; - $pageActions = ''; - $isMobile = $this->app->viewType == 'mhtml'; - if($isMobile) - { - $this->app->loadLang('qa'); - $pageNav = html::a(helper::createLink('qa', 'index'), $this->lang->qa->index) . $this->lang->colon; - } - else - { - if($this->config->global->flow == 'full') - { - $this->app->loadLang('qa'); - $pageNav .= '
'; - $pageNav .= '
'; - } - else - { - $this->app->loadLang('testcase'); - $pageActions .= "
"; - if(common::hasPriv('testsuite', 'exportTemplet')) - { - $link = helper::createLink('testsuite', 'exportTemplet', "libID=$libID"); - $pageActions .= html::a($link, " " . $this->lang->testsuite->exportTemplet, '', "class='btn btn-link export'"); - } - if(common::hasPriv('testsuite', 'import')) - { - $link = helper::createLink('testsuite', 'import', "libID=$libID"); - $pageActions .= html::a($link, " " . $this->lang->testcase->importFile, '', "class='btn btn-link export'"); - } - $pageActions .= '
'; - $params = "libID=$libID&moduleID=" . (isset($moduleID) ? $moduleID : 0); - if(common::hasPriv('testsuite', 'batchCreateCase')) - { - $link = helper::createLink('testsuite', 'batchCreateCase', $params); - $pageActions .= html::a($link, "" . $this->lang->testcase->batchCreate, '', "class='btn btn-secondary'"); - } - if(common::hasPriv('testsuite', 'createCase')) - { - $link = helper::createLink('testsuite', 'createCase', $params); - $pageActions .= html::a($link, "" . $this->lang->testcase->create, '', "class='btn btn-primary'"); - } - if(common::hasPriv('testsuite', 'createLib')) - { - $link = helper::createLink('testsuite', 'createLib'); - $pageActions .= html::a($link, "" . $this->lang->testsuite->createLib, '', "class='btn btn-primary'"); - } - } - } - $pageNav .= $selectHtml; - - $this->lang->modulePageNav = $pageNav; - $this->lang->modulePageActions = $pageActions; - foreach($this->lang->caselib->menu as $key => $value) - { - $replace = ''; - if($this->config->global->flow == 'onlyTest') $replace = $libID; - common::setMenuVars($this->lang->caselib->menu, $key, $replace); - } - $this->lang->testsuite->menu = $this->lang->caselib->menu; - if($this->config->global->flow != 'full' && $this->app->getMethodName() != 'libview') $this->lang->testsuite->menu->bysearch = " {$this->lang->testcase->bySearch}"; - } - - /** - * Save lib state. - * - * @param int $libID - * @param array $libraries - * @access public - * @return int - */ - public function saveLibState($libID = 0, $libraries = array()) - { - if($libID > 0) $this->session->set('caseLib', (int)$libID); - if($libID == 0 and $this->cookie->lastCaseLib) $this->session->set('caseLib', $this->cookie->lastCaseLib); - if($libID == 0 and $this->session->caseLib == '') $this->session->set('caseLib', key($libraries)); - if(!isset($libraries[$this->session->caseLib])) - { - $this->session->set('caseLib', key($libraries)); - $libID = $this->session->caseLib; - } - return $this->session->caseLib; - } - /** * Create a test suite. * @@ -424,130 +290,11 @@ class testsuiteModel extends model */ public function delete($suiteID, $table = '') { - $suite = $this->getById($suiteID); parent::delete(TABLE_TESTSUITE, $suiteID); - if($suite->type == 'library') - { - $this->dao->update(TABLE_ACTION)->set('objectType')->eq('caselib')->where('objectID')->eq($suiteID)->andWhere('objectType')->eq('testsuite')->exec(); - } - else - { - $this->dao->delete()->from(TABLE_SUITECASE)->where('suite')->eq($suiteID)->exec(); - } + $this->dao->delete()->from(TABLE_SUITECASE)->where('suite')->eq($suiteID)->exec(); return !dao::isError(); } - /** - * Get libraries. - * - * @access public - * @return array - */ - public function getLibraries() - { - return $this->dao->select("id,name")->from(TABLE_TESTSUITE) - ->where('product')->eq(0) - ->andWhere('deleted')->eq(0) - ->andWhere('type')->eq('library') - ->orderBy('id_desc') - ->fetchPairs('id', 'name'); - } - - /** - * Create lib. - * - * @access public - * @return int - */ - public function createLib() - { - $lib = fixer::input('post') - ->stripTags($this->config->testsuite->editor->create['id'], $this->config->allowedTags) - ->setForce('type', 'library') - ->add('addedBy', $this->app->user->account) - ->add('addedDate', helper::now()) - ->remove('uid') - ->get(); - $lib = $this->loadModel('file')->processImgURL($lib, $this->config->testsuite->editor->create['id'], $this->post->uid); - $this->dao->insert(TABLE_TESTSUITE)->data($lib) - ->batchcheck($this->config->testsuite->createlib->requiredFields, 'notempty') - ->check('name', 'unique', "deleted = '0'") - ->exec(); - if(!dao::isError()) - { - $libID = $this->dao->lastInsertID(); - $this->file->updateObjectID($this->post->uid, $libID, 'caselib'); - 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'; - $browseType = ($browseType == 'bymodule' and $this->session->libBrowseType and $this->session->libBrowseType != 'bysearch') ? $this->session->libBrowseType : $browseType; - - $cases = array(); - if($browseType == 'bymodule' or $browseType == 'all' or $browseType == 'wait') - { - $cases = $this->dao->select('*')->from(TABLE_CASE) - ->where('lib')->eq((int)$libID) - ->andWhere('product')->eq(0) - ->beginIF($moduleIdList)->andWhere('module')->in($moduleIdList)->fi() - ->beginIF($browseType == 'wait')->andWhere('status')->eq($browseType)->fi() - ->andWhere('deleted')->eq('0') - ->orderBy($sort)->page($pager)->fetchAll('id'); - } - /* By search. */ - elseif($browseType == 'bysearch') - { - if($queryID) - { - $query = $this->loadModel('search')->getQuery($queryID); - $this->session->set('caselibQuery', ' 1 = 1'); - if($query) - { - $this->session->set('caselibQuery', $query->sql); - $this->session->set('caselibForm', $query->form); - } - } - else - { - if($this->session->caselibQuery == false) $this->session->set('caselibQuery', ' 1 = 1'); - } - - $queryLibID = $libID; - $allLib = "`lib` = 'all'"; - $caseQuery = '(' . $this->session->caselibQuery; - if(strpos($this->session->caselibQuery, $allLib) !== false) - { - $caseQuery = str_replace($allLib, '1', $caseQuery); - $queryLibID = 'all'; - } - $caseQuery .= ')'; - - $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(); - - } - return $cases; - } - /** * Get not imported cases. * @@ -601,323 +348,4 @@ class testsuiteModel extends model ->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; - $this->config->testcase->search['params']['lib']['values'] = array('' => '', $libID => $libraries[$libID], 'all' => $this->lang->caselib->all); - $this->config->testcase->search['params']['lib']['operator'] = '='; - $this->config->testcase->search['params']['lib']['control'] = 'select'; - $this->config->testcase->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib'); - if(!$this->config->testcase->needReview) unset($this->config->testcase->search['params']['status']['values']['wait']); - unset($this->config->testcase->search['fields']['product']); - unset($this->config->testcase->search['params']['product']); - unset($this->config->testcase->search['fields']['branch']); - unset($this->config->testcase->search['params']['branch']); - unset($this->config->testcase->search['fields']['lastRunner']); - unset($this->config->testcase->search['params']['lastRunner']); - unset($this->config->testcase->search['fields']['lastRunResult']); - unset($this->config->testcase->search['params']['lastRunResult']); - unset($this->config->testcase->search['fields']['lastRunDate']); - unset($this->config->testcase->search['params']['lastRunDate']); - - $this->config->testcase->search['module'] = 'caselib'; - $this->config->testcase->search['actionURL'] = $actionURL; - $this->config->testcase->search['queryID'] = $queryID; - - $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 = ''; - if($module == 'testsuite') - { - if($module == 'testsuite' && ($method == 'createlib')) - { - $link = helper::createLink($module, 'library', "libID=%s"); - } - else - { - $link = helper::createLink($module, $method, "libID=%s"); - } - } - else if($module == 'tree') - { - $link = helper::createLink($module, $method, "libID=%s&type=caselib¤tModuleID=0"); - } - else - { - $link = helper::createLink('testsuite', 'library', "libID=%s"); - } - return $link; - } - - /** - * Create from import. - * - * @param int $libID - * @access public - * @return void - */ - public function createFromImport($libID) - { - $this->loadModel('action'); - $this->loadModel('testcase'); - $this->loadModel('file'); - $now = helper::now(); - $data = fixer::input('post')->get(); - - if(!empty($_POST['id'])) - { - $oldSteps = $this->dao->select('t2.*')->from(TABLE_CASE)->alias('t1') - ->leftJoin(TABLE_CASESTEP)->alias('t2')->on('t1.id = t2.case') - ->where('t1.id')->in(($_POST['id'])) - ->andWhere('t1.version=t2.version') - ->orderBy('t2.id') - ->fetchGroup('case'); - $oldCases = $this->dao->select('*')->from(TABLE_CASE)->where('id')->in($_POST['id'])->fetchAll('id'); - } - - $cases = array(); - foreach($data->lib as $key => $lib) - { - $caseData = new stdclass(); - - $caseData->lib = $lib; - $caseData->module = $data->module[$key]; - $caseData->title = $data->title[$key]; - $caseData->pri = (int)$data->pri[$key]; - $caseData->type = $data->type[$key]; - $caseData->status = $data->status[$key]; - $caseData->stage = join(',', $data->stage[$key]); - $caseData->keywords = $data->keywords[$key]; - $caseData->frequency = 1; - $caseData->precondition = $data->precondition[$key]; - - if(isset($this->config->testcase->create->requiredFields)) - { - $requiredFields = explode(',', $this->config->testcase->create->requiredFields); - foreach($requiredFields as $requiredField) - { - $requiredField = trim($requiredField); - if(empty($caseData->$requiredField)) dao::$errors[] = sprintf($this->lang->testcase->noRequire, $key, $this->lang->testcase->$requiredField); - } - } - - $cases[$key] = $caseData; - } - if(dao::isError()) die(js::error(dao::getError())); - - $forceNotReview = $this->testcase->forceNotReview(); - foreach($cases as $key => $caseData) - { - if(!empty($_POST['id'][$key]) and empty($_POST['insert'])) - { - $caseID = $data->id[$key]; - $stepChanged = false; - $steps = array(); - $oldStep = isset($oldSteps[$caseID]) ? $oldSteps[$caseID] : array(); - $oldCase = $oldCases[$caseID]; - - /* Remove the empty setps in post. */ - $steps = array(); - if(isset($_POST['desc'][$key])) - { - foreach($data->desc[$key] as $id => $desc) - { - $desc = trim($desc); - if(empty($desc)) continue; - $step = new stdclass(); - $step->type = $data->stepType[$key][$id]; - $step->desc = $desc; - $step->expect = trim($data->expect[$key][$id]); - - $steps[] = $step; - } - } - - /* If step count changed, case changed. */ - if((!$oldStep != !$steps) or (count($oldStep) != count($steps))) - { - $stepChanged = true; - } - else - { - /* Compare every step. */ - foreach($oldStep as $id => $oldStep) - { - if(trim($oldStep->desc) != trim($steps[$id]->desc) or trim($oldStep->expect) != $steps[$id]->expect) - { - $stepChanged = true; - break; - } - } - } - - $version = $stepChanged ? $oldCase->version + 1 : $oldCase->version; - $caseData->version = $version; - $changes = common::createChanges($oldCase, $caseData); - if(!$changes and !$stepChanged) continue; - - if($changes or $stepChanged) - { - $caseData->lastEditedBy = $this->app->user->account; - $caseData->lastEditedDate = $now; - if($stepChanged and !$forceNotReview) $caseData->status = 'wait'; - $this->dao->update(TABLE_CASE)->data($caseData)->where('id')->eq($caseID)->autoCheck()->exec(); - if($stepChanged) - { - $parentStepID = 0; - foreach($steps as $id => $step) - { - $step = (array)$step; - if(empty($step['desc'])) continue; - $stepData = new stdclass(); - $stepData->type = ($step['type'] == 'item' and $parentStepID == 0) ? 'step' : $step['type']; - $stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0; - $stepData->case = $caseID; - $stepData->version = $version; - $stepData->desc = $step['desc']; - $stepData->expect = $step['expect']; - $this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec(); - if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID(); - if($stepData->type == 'step') $parentStepID = 0; - } - } - $oldCase->steps = $this->testcase->joinStep($oldStep); - $caseData->steps = $this->testcase->joinStep($steps); - $changes = common::createChanges($oldCase, $caseData); - $actionID = $this->action->create('case', $caseID, 'Edited'); - $this->action->logHistory($actionID, $changes); - } - } - else - { - $caseData->version = 1; - $caseData->openedBy = $this->app->user->account; - $caseData->openedDate = $now; - $caseData->status = $forceNotReview ? 'normal' : 'wait'; - $this->dao->insert(TABLE_CASE)->data($caseData)->autoCheck()->exec(); - - if(!dao::isError()) - { - $caseID = $this->dao->lastInsertID(); - $parentStepID = 0; - foreach($data->desc[$key] as $id => $desc) - { - $desc = trim($desc); - if(empty($desc)) continue; - $stepData = new stdclass(); - $stepData->type = ($data->stepType[$key][$id] == 'item' and $parentStepID == 0) ? 'step' : $data->stepType[$key][$id]; - $stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0; - $stepData->case = $caseID; - $stepData->version = 1; - $stepData->desc = $desc; - $stepData->expect = $data->expect[$key][$id]; - $this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec(); - if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID(); - if($stepData->type == 'step') $parentStepID = 0; - } - $this->action->create('case', $caseID, 'Opened'); - } - } - } - - unlink($this->session->importFile); - unset($_SESSION['importFile']); - } - - /** - * Batch create case for lib. - * - * @param int $libID - * @access public - * @return void - */ - public function batchCreateCase($libID) - { - $this->loadModel('testcase'); - $this->loadModel('action'); - - $now = helper::now(); - $cases = fixer::input('post')->get(); - $batchNum = count(reset($cases)); - - $result = $this->loadModel('common')->removeDuplicate('case', $cases, "lib={$libID}"); - $cases = $result['data']; - - for($i = 0; $i < $batchNum; $i++) - { - if(!empty($cases->title[$i]) and empty($cases->type[$i])) die(js::alert(sprintf($this->lang->error->notempty, $this->lang->testcase->type))); - } - - $module = 0; - $type = ''; - $pri = 3; - for($i = 0; $i < $batchNum; $i++) - { - $module = $cases->module[$i] == 'ditto' ? $module : $cases->module[$i]; - $type = $cases->type[$i] == 'ditto' ? $type : $cases->type[$i]; - $pri = $cases->pri[$i] == 'ditto' ? $pri : $cases->pri[$i]; - $cases->module[$i] = (int)$module; - $cases->type[$i] = $type; - $cases->pri[$i] = $pri; - } - - $forceNotReview = $this->testcase->forceNotReview(); - for($i = 0; $i < $batchNum; $i++) - { - if($cases->type[$i] != '' and $cases->title[$i] != '') - { - $data[$i] = new stdclass(); - $data[$i]->lib = $libID; - $data[$i]->module = $cases->module[$i]; - $data[$i]->type = $cases->type[$i]; - $data[$i]->pri = $cases->pri[$i]; - $data[$i]->stage = empty($cases->stage[$i]) ? '' : implode(',', $cases->stage[$i]); - $data[$i]->color = $cases->color[$i]; - $data[$i]->title = $cases->title[$i]; - $data[$i]->precondition = $cases->precondition[$i]; - $data[$i]->keywords = $cases->keywords[$i]; - $data[$i]->openedBy = $this->app->user->account; - $data[$i]->openedDate = $now; - $data[$i]->status = $forceNotReview ? 'normal' : 'wait'; - $data[$i]->version = 1; - - $this->dao->insert(TABLE_CASE)->data($data[$i]) - ->autoCheck() - ->batchCheck($this->config->testcase->create->requiredFields, 'notempty') - ->exec(); - - if(dao::isError()) - { - echo js::error(dao::getError()); - die(js::reload('parent')); - } - - $caseID = $this->dao->lastInsertID(); - $actionID = $this->action->create('case', $caseID, 'Opened'); - } - } - } } diff --git a/module/tree/control.php b/module/tree/control.php index 8fef7d1d4f..059b5e3aee 100644 --- a/module/tree/control.php +++ b/module/tree/control.php @@ -54,8 +54,8 @@ class tree extends control } elseif(strpos($viewType, 'caselib') !== false) { - $this->loadModel('testsuite'); - $lib = $this->testsuite->getById($rootID); + $this->loadModel('caselib'); + $lib = $this->caselib->getById($rootID); $this->view->root = $lib; } @@ -116,13 +116,13 @@ class tree extends control } elseif($viewType == 'caselib') { - $this->testsuite->setLibMenu($this->testsuite->getLibraries(), $rootID); - $this->lang->tree->menu = $this->lang->testsuite->menu; - $this->lang->tree->menuOrder = $this->lang->testsuite->menuOrder; + $this->caselib->setLibMenu($this->caselib->getLibraries(), $rootID); + $this->lang->tree->menu = $this->lang->caselib->menu; + $this->lang->tree->menuOrder = $this->lang->caselib->menuOrder; $this->lang->set('menugroup.tree', 'qa'); $title = $this->lang->tree->manageCaseLib; - $position[] = html::a($this->createLink('testsuite', 'library', "libID=$rootID"), $lib->name); + $position[] = html::a($this->createLink('caselib', 'browse', "libID=$rootID"), $lib->name); $position[] = $this->lang->tree->manageCaseLib; } elseif(strpos($viewType, 'doc') !== false) @@ -438,9 +438,9 @@ class tree extends control $this->view->method = $method; $this->view->extra = $extra; + $viewType = $module; if($module == 'bug') $viewType = 'bug'; if($module == 'testcase') $viewType = 'case'; - if($module == 'testsuite') $viewType = 'caselib'; $modules = $this->tree->getOptionMenu($rootID, $viewType); $modulesPinyin = common::convert2Pinyin($modules); diff --git a/module/upgrade/model.php b/module/upgrade/model.php index a5a978c595..a13f1ce053 100644 --- a/module/upgrade/model.php +++ b/module/upgrade/model.php @@ -3321,6 +3321,45 @@ class upgradeModel extends model return true; } + /** + * Adjust priv for 11.6.4. + * + * @access public + * @return void + */ + public function adjustPriv11_6_4() + { + $this->saveLogs('Run Method ' . __FUNCTION__); + + $this->dao->update(TABLE_GROUPPRIV)->set('module')->eq('caselib')->set('method')->eq('browse')->where('module')->eq('testsuite')->andWhere('method')->eq('library')->exec(); + $this->dao->update(TABLE_GROUPPRIV)->set('module')->eq('caselib')->set('method')->eq('create')->where('module')->eq('testsuite')->andWhere('method')->eq('createLib')->exec(); + $this->dao->update(TABLE_GROUPPRIV)->set('module')->eq('caselib')->set('method')->eq('view')->where('module')->eq('testsuite')->andWhere('method')->eq('libView')->exec(); + $this->dao->update(TABLE_GROUPPRIV)->set('module')->eq('caselib')->where('module')->eq('testsuite')->andWhere('method')->in('exportTemplet,import,showImport,batchCreateCase,createCase')->exec(); + + $groups = $this->dao->select('*')->from(TABLE_GROUPPRIV)->where('module')->eq('testsuite')->andWhere('method')->eq('edit')->fetchPairs('group', 'group'); + foreach($groups as $groupID) + { + $groupPriv = new stdclass(); + $groupPriv->group = $groupID; + $groupPriv->module = 'caselib'; + $groupPriv->method = 'edit'; + $this->dao->replace(TABLE_GROUPPRIV)->data($groupPriv)->exec(); + $this->saveLogs($this->dao->get()); + } + + $groups = $this->dao->select('*')->from(TABLE_GROUPPRIV)->where('module')->eq('testsuite')->andWhere('method')->eq('delete')->fetchPairs('group', 'group'); + foreach($groups as $groupID) + { + $groupPriv = new stdclass(); + $groupPriv->group = $groupID; + $groupPriv->module = 'caselib'; + $groupPriv->method = 'delete'; + $this->dao->replace(TABLE_GROUPPRIV)->data($groupPriv)->exec(); + $this->saveLogs($this->dao->get()); + } + return true; + } + /** * Save Logs. *