From 4e84b9cddef02434b14b095405ca26b76fdc3070 Mon Sep 17 00:00:00 2001 From: wangyidong Date: Fri, 24 Feb 2017 16:28:29 +0800 Subject: [PATCH] * finish task #2893,2894. --- config/config.php | 3 + db/update9.0.1.sql | 20 ++ module/common/lang/menuOrder.php | 18 +- module/common/lang/zh-cn.php | 35 +-- module/testsuite/config.php | 13 + module/testsuite/control.php | 334 ++++++++++++++++++++++++ module/testsuite/js/linkcase.js | 1 + module/testsuite/lang/zh-cn.php | 47 ++++ module/testsuite/model.php | 212 +++++++++++++++ module/testsuite/view/browse.html.php | 57 ++++ module/testsuite/view/create.html.php | 42 +++ module/testsuite/view/edit.html.php | 43 +++ module/testsuite/view/linkcase.html.php | 79 ++++++ module/testsuite/view/view.html.php | 157 +++++++++++ module/upgrade/model.php | 3 +- 15 files changed, 1039 insertions(+), 25 deletions(-) create mode 100644 db/update9.0.1.sql create mode 100644 module/testsuite/config.php create mode 100644 module/testsuite/control.php create mode 100644 module/testsuite/js/linkcase.js create mode 100644 module/testsuite/lang/zh-cn.php create mode 100644 module/testsuite/model.php create mode 100644 module/testsuite/view/browse.html.php create mode 100644 module/testsuite/view/create.html.php create mode 100644 module/testsuite/view/edit.html.php create mode 100644 module/testsuite/view/linkcase.html.php create mode 100644 module/testsuite/view/view.html.php diff --git a/config/config.php b/config/config.php index a17812aaf8..8a5199fd84 100644 --- a/config/config.php +++ b/config/config.php @@ -170,6 +170,8 @@ define('TABLE_CRON', '`' . $config->db->prefix . 'cron`'); define('TABLE_MAILQUEUE', '`' . $config->db->prefix . 'mailqueue`'); define('TABLE_BLOCK', '`' . $config->db->prefix . 'block`'); define('TABLE_DOCCONTENT', '`' . $config->db->prefix . 'doccontent`'); +define('TABLE_TESTSUITE', '`' . $config->db->prefix . 'testsuite`'); +define('TABLE_SUITECASE', '`' . $config->db->prefix . 'suitecase`'); if(!defined('TABLE_LANG')) define('TABLE_LANG', '`' . $config->db->prefix . 'lang`'); $config->objectTables['product'] = TABLE_PRODUCT; @@ -183,6 +185,7 @@ $config->objectTables['bug'] = TABLE_BUG; $config->objectTables['case'] = TABLE_CASE; $config->objectTables['testcase'] = TABLE_CASE; $config->objectTables['testtask'] = TABLE_TESTTASK; +$config->objectTables['testsuite'] = TABLE_TESTSUITE; $config->objectTables['user'] = TABLE_USER; $config->objectTables['doc'] = TABLE_DOC; $config->objectTables['doclib'] = TABLE_DOCLIB; diff --git a/db/update9.0.1.sql b/db/update9.0.1.sql new file mode 100644 index 0000000000..7a8b9cd6ff --- /dev/null +++ b/db/update9.0.1.sql @@ -0,0 +1,20 @@ +CREATE TABLE `zt_testsuite` ( + `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, + `product` mediumint(8) unsigned NOT NULL, + `name` varchar(255) NOT NULL, + `desc` text NOT NULL, + `type` varchar(20) NOT NULL, + `addedBy` char(30) NOT NULL, + `addedDate` datetime NOT NULL, + `lastEditedBy` char(30) NOT NULL, + `lastEditedDate` datetime NOT NULL, + `deleted` enum('0','1') NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +CREATE TABLE `zt_suitecase` ( + `suite` mediumint(8) unsigned NOT NULL, + `product` mediumint(8) unsigned NOT NULL, + `case` mediumint(8) unsigned NOT NULL, + `version` smallint(5) unsigned NOT NULL, + UNIQUE KEY `suitecase` (`suite`,`case`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/module/common/lang/menuOrder.php b/module/common/lang/menuOrder.php index 501c91bcd7..59ac4f8bbb 100644 --- a/module/common/lang/menuOrder.php +++ b/module/common/lang/menuOrder.php @@ -66,14 +66,16 @@ $lang->task->menuOrder = $lang->project->menuOrder; $lang->build->menuOrder = $lang->project->menuOrder; /* qa menu order. */ -$lang->qa->menuOrder[5] = 'product'; -$lang->qa->menuOrder[10] = 'index'; -$lang->qa->menuOrder[15] = 'bug'; -$lang->qa->menuOrder[20] = 'testcase'; -$lang->qa->menuOrder[25] = 'testtask'; -$lang->bug->menuOrder = $lang->qa->menuOrder; -$lang->testcase->menuOrder = $lang->bug->menuOrder; -$lang->testtask->menuOrder = $lang->testcase->menuOrder; +$lang->qa->menuOrder[5] = 'product'; +$lang->qa->menuOrder[10] = 'index'; +$lang->qa->menuOrder[15] = 'bug'; +$lang->qa->menuOrder[20] = 'testcase'; +$lang->qa->menuOrder[25] = 'testtask'; +$lang->qa->menuOrder[30] = 'testsuite'; +$lang->bug->menuOrder = $lang->qa->menuOrder; +$lang->testcase->menuOrder = $lang->bug->menuOrder; +$lang->testtask->menuOrder = $lang->testcase->menuOrder; +$lang->testsuite->menuOrder = $lang->testcase->menuOrder; /* doc menu order. */ $lang->doc->menuOrder[5] = 'list'; diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index dfb842a557..699f2a0dca 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -232,32 +232,37 @@ $lang->build->menu = $lang->project->menu; $lang->qa = new stdclass(); $lang->qa->menu = new stdclass(); -$lang->qa->menu->product = array('link' => '%s', 'fixed' => true); -$lang->qa->menu->bug = array('link' => 'Bug|bug|browse|productID=%s'); -$lang->qa->menu->testcase = array('link' => '用例|testcase|browse|productID=%s'); -$lang->qa->menu->testtask = array('link' => '版本|testtask|browse|productID=%s'); -$lang->qa->menu->index = array('link' => "测试主页|qa|index|locate=no&productID=%s", 'float' => 'right'); +$lang->qa->menu->product = array('link' => '%s', 'fixed' => true); +$lang->qa->menu->bug = array('link' => 'Bug|bug|browse|productID=%s'); +$lang->qa->menu->testcase = array('link' => '用例|testcase|browse|productID=%s'); +$lang->qa->menu->testtask = array('link' => '版本|testtask|browse|productID=%s'); +$lang->qa->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s'); +$lang->qa->menu->index = array('link' => "测试主页|qa|index|locate=no&productID=%s", 'float' => 'right'); $lang->bug = new stdclass(); $lang->bug->menu = new stdclass(); -$lang->bug->menu->product = array('link' => '%s', 'fixed' => true); -$lang->bug->menu->bug = array('link' => 'Bug|bug|browse|productID=%s', 'alias' => 'view,create,batchcreate,edit,resolve,close,activate,report,batchedit,confirmbug,assignto', 'subModule' => 'tree'); -$lang->bug->menu->testcase = array('link' => '用例|testcase|browse|productID=%s'); -$lang->bug->menu->testtask = array('link' => '版本|testtask|browse|productID=%s'); -$lang->bug->menu->index = array('link' => "测试主页|qa|index|locate=no&productID=%s", 'float' => 'right'); +$lang->bug->menu->product = array('link' => '%s', 'fixed' => true); +$lang->bug->menu->bug = array('link' => 'Bug|bug|browse|productID=%s', 'alias' => 'view,create,batchcreate,edit,resolve,close,activate,report,batchedit,confirmbug,assignto', 'subModule' => 'tree'); +$lang->bug->menu->testcase = array('link' => '用例|testcase|browse|productID=%s'); +$lang->bug->menu->testtask = array('link' => '版本|testtask|browse|productID=%s'); +$lang->bug->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s'); +$lang->bug->menu->index = array('link' => "测试主页|qa|index|locate=no&productID=%s", 'float' => 'right'); $lang->testcase = new stdclass(); $lang->testcase->menu = new stdclass(); -$lang->testcase->menu->product = array('link' => '%s', 'fixed' => true); -$lang->testcase->menu->bug = array('link' => 'Bug|bug|browse|productID=%s'); -$lang->testcase->menu->testcase = array('link' => '用例|testcase|browse|productID=%s', 'alias' => 'view,create,batchcreate,edit,batchedit,showimport,groupcase', 'subModule' => 'tree'); -$lang->testcase->menu->testtask = array('link' => '版本|testtask|browse|productID=%s', 'alias' => 'view,create,edit,linkcase,cases,start,close,batchrun,groupcase'); -$lang->testcase->menu->index = array('link' => "测试主页|qa|index|locate=no&productID=%s", 'float' => 'right'); +$lang->testcase->menu->product = array('link' => '%s', 'fixed' => true); +$lang->testcase->menu->bug = array('link' => 'Bug|bug|browse|productID=%s'); +$lang->testcase->menu->testcase = array('link' => '用例|testcase|browse|productID=%s', 'alias' => 'view,create,batchcreate,edit,batchedit,showimport,groupcase', 'subModule' => 'tree'); +$lang->testcase->menu->testtask = array('link' => '版本|testtask|browse|productID=%s', 'alias' => 'view,create,edit,linkcase,cases,start,close,batchrun,groupcase'); +$lang->testcase->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s', 'alias' => 'view,create,edit,linkcase,cases'); +$lang->testcase->menu->index = array('link' => "测试主页|qa|index|locate=no&productID=%s", 'float' => 'right'); $lang->testtask = new stdclass(); $lang->testtask->menu = $lang->testcase->menu; +$lang->testsuite = new stdclass(); +$lang->testsuite->menu = $lang->testcase->menu; /* 文档视图菜单设置。*/ $lang->doc = new stdclass(); diff --git a/module/testsuite/config.php b/module/testsuite/config.php new file mode 100644 index 0000000000..4139832dda --- /dev/null +++ b/module/testsuite/config.php @@ -0,0 +1,13 @@ +testsuite = new stdclass(); +$config->testsuite->create = new stdclass(); +$config->testsuite->edit = new stdclass(); +$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->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 new file mode 100644 index 0000000000..d5848baa16 --- /dev/null +++ b/module/testsuite/control.php @@ -0,0 +1,334 @@ + + * @package testsuite + * @version $Id: control.php 5114 2013-07-12 06:02:59Z chencongzhi520@gmail.com $ + * @link http://www.zentao.net + */ +class testsuite extends control +{ + public $products = array(); + + /** + * Construct function, load product module, assign products to view auto. + * + * @access public + * @return void + */ + public function __construct($moduleName = '', $methodName = '') + { + parent::__construct($moduleName, $methodName); + $this->loadModel('product'); + $this->view->products = $this->products = $this->product->getPairs('nocode'); + if(empty($this->products)) die($this->locate($this->createLink('product', 'showErrorNone', "fromModule=testsuite"))); + } + + /** + * Index page, header to browse. + * + * @access public + * @return void + */ + public function index() + { + $this->locate($this->createLink('testsuite', 'browse')); + } + + /** + * Browse test suites. + * + * @param int $productID + * @param string $type + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ + public function browse($productID = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + { + /* Save session. */ + $this->session->set('testsuiteList', $this->app->getURI(true)); + + /* Set menu. */ + $productID = $this->product->saveState($productID, $this->products); + $this->testsuite->setMenu($this->products, $productID); + + /* Load pager. */ + $this->app->loadClass('pager', $static = true); + $pager = pager::init($recTotal, $recPerPage, $pageID); + + /* Append id for secend sort. */ + $sort = $this->loadModel('common')->appendOrder($orderBy); + + $this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testsuite->common; + $this->view->position[] = html::a($this->createLink('testsuite', 'browse', "productID=$productID"), $this->products[$productID]); + $this->view->position[] = $this->lang->testsuite->common; + $this->view->productID = $productID; + $this->view->productName = $this->products[$productID]; + $this->view->orderBy = $orderBy; + $this->view->suites = $this->testsuite->getSuites($productID, $sort, $pager); + $this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter'); + $this->view->pager = $pager; + + $this->display(); + } + + /** + * Create a test suite. + * + * @param int $productID + * @access public + * @return void + */ + public function create($productID) + { + if(!empty($_POST)) + { + $suiteID = $this->testsuite->create($productID); + if(dao::isError()) die(js::error(dao::getError())); + $actionID = $this->loadModel('action')->create('testsuite', $suiteID, 'opened'); + die(js::locate($this->createLink('testsuite', 'browse', "productID=$productID"), 'parent')); + } + + /* Set menu. */ + $productID = $this->product->saveState($productID, $this->products); + $this->testsuite->setMenu($this->products, $productID); + + $this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testsuite->create; + $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->create; + + $this->view->productID = $productID; + $this->display(); + } + + /** + * View a test suite. + * + * @param int $suiteID + * @access public + * @return void + */ + public function view($suiteID, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + { + /* Get test suite, and set menu. */ + $suite = $this->testsuite->getById($suiteID, true); + if(!$suite) die(js::error($this->lang->notFound) . js::locate('back')); + $productID = $suite->product; + + $this->testsuite->setMenu($this->products, $productID); + + /* Append id for secend sort. */ + $sort = $this->loadModel('common')->appendOrder($orderBy); + + /* Load pager. */ + $this->app->loadClass('pager', $static = true); + $pager = pager::init($recTotal, $recPerPage, $pageID); + + $this->view->title = "SUITE #$suite->id $suite->name/" . $this->products[$productID]; + $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->view; + + $this->view->productID = $productID; + $this->view->suite = $suite; + $this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter'); + $this->view->actions = $this->loadModel('action')->getList('testsuite', $suiteID); + $this->view->cases = $this->testsuite->getLinkedCases($suiteID, $sort, $pager); + $this->view->orderBy = $orderBy; + $this->view->pager = $pager; + $this->view->branches = $this->loadModel('branch')->getPairs($suite->product, 'noempty'); + + $this->display(); + } + + /** + * Edit a test suite. + * + * @param int $suiteID + * @access public + * @return void + */ + public function edit($suiteID) + { + if(!empty($_POST)) + { + $changes = $this->testsuite->update($suiteID); + if(dao::isError()) die(js::error(dao::getError())); + if($changes) + { + $actionID = $this->loadModel('action')->create('testsuite', $suiteID, 'edited'); + $this->action->logHistory($actionID, $changes); + } + die(js::locate(inlink('view', "suiteID=$suiteID"), 'parent')); + } + + /* Get suite info. */ + $suite = $this->testsuite->getById($suiteID); + $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; + $this->view->position[] = $this->lang->testsuite->edit; + + $this->view->suite = $suite; + $this->display(); + } + + /** + * Delete a test suite. + * + * @param int $suiteID + * @param string $confirm yes|no + * @access public + * @return void + */ + public function delete($suiteID, $confirm = 'no') + { + if($confirm == 'no') + { + die(js::confirm($this->lang->testsuite->confirmDelete, inlink('delete', "suiteID=$suiteID&confirm=yes"))); + } + else + { + $this->testsuite->delete($suiteID); + + /* 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')); + } + } + + /** + * Link cases to a test suite. + * + * @param int $suiteID + * @access public + * @return void + */ + public function linkCase($suiteID, $param = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1) + { + if(!empty($_POST)) + { + $this->testsuite->linkCase($suiteID); + $this->locate(inlink('view', "suiteID=$suiteID")); + } + + /* Save session. */ + $this->session->set('caseList', $this->app->getURI(true)); + + /* Get suite and product id. */ + $suite = $this->testsuite->getById($suiteID); + $productID = $this->product->saveState($suite->product, $this->products); + + /* Save session. */ + $this->testsuite->setMenu($this->products, $productID); + + /* Load pager. */ + $this->app->loadClass('pager', $static = true); + $pager = pager::init($recTotal, $recPerPage, $pageID); + + /* Build the search form. */ + $this->loadModel('testcase'); + $this->config->testcase->search['params']['product']['values']= array('' => '', $productID => $this->products[$productID], 'all' => $this->lang->testcase->allProduct); + $this->config->testcase->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($productID, $viewType = 'case'); + $this->config->testcase->search['actionURL'] = inlink('linkCase', "suiteID=$suiteID¶m=myQueryID"); + if($this->session->currentProductType == 'normal') + { + unset($this->config->testcase->search['fields']['branch']); + unset($this->config->testcase->search['params']['branch']); + } + else + { + $this->config->testcase->search['fields']['branch'] = $this->lang->product->branch; + $branches = array('' => '') + $this->loadModel('branch')->getPairs($suite->product, 'noempty'); + $this->config->testcase->search['params']['branch']['values'] = $branches; + } + $this->loadModel('search')->setSearchParams($this->config->testcase->search); + + $this->view->title = $suite->name . $this->lang->colon . $this->lang->testsuite->linkCase; + $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->linkCase; + + $this->view->users = $this->loadModel('user')->getPairs('noletter'); + $this->view->cases = $this->testsuite->getUnlinkedCases($suite, $param, $pager); + $this->view->suiteID = $suiteID; + $this->view->pager = $pager; + $this->view->suite = $suite; + + $this->display(); + } + + /** + * Remove a case from test suite. + * + * @param int $rowID + * @access public + * @return void + */ + public function unlinkCase($suiteID, $rowID, $confirm = 'no') + { + if($confirm == 'no') + { + die(js::confirm($this->lang->testsuite->confirmUnlinkCase, $this->createLink('testsuite', 'unlinkCase', "rowID=$rowID&confirm=yes"))); + } + else + { + $response['result'] = 'success'; + $response['message'] = ''; + + $this->dao->delete()->from(TABLE_SUITECASE)->where('`case`')->eq((int)$rowID)->andWhere('suite')->eq($suiteID)->exec(); + if(dao::isError()) + { + $response['result'] = 'fail'; + $response['message'] = dao::getError(); + } + $this->send($response); + } + } + + /** + * Batch unlink cases. + * + * @param int $suiteID + * @access public + * @return void + */ + public function batchUnlinkCases($suiteID) + { + if(isset($_POST['caseIDList'])) + { + $this->dao->delete()->from(TABLE_SUITECASE) + ->where('suite')->eq((int)$suiteID) + ->andWhere('`case`')->in($this->post->caseIDList) + ->exec(); + } + + die(js::locate($this->createLink('testsuite', 'view', "suiteID=$suiteID"))); + } +} diff --git a/module/testsuite/js/linkcase.js b/module/testsuite/js/linkcase.js new file mode 100644 index 0000000000..cc46c2038f --- /dev/null +++ b/module/testsuite/js/linkcase.js @@ -0,0 +1 @@ +$(function(){ajaxGetSearchForm();}) diff --git a/module/testsuite/lang/zh-cn.php b/module/testsuite/lang/zh-cn.php new file mode 100644 index 0000000000..f4f51ff916 --- /dev/null +++ b/module/testsuite/lang/zh-cn.php @@ -0,0 +1,47 @@ + + * @package testsuite + * @version $Id: zh-cn.php 4490 2013-02-27 03:27:05Z wyd621@gmail.com $ + * @link http://www.zentao.net + */ +$lang->testsuite->index = "套件首页"; +$lang->testsuite->create = "建套件"; +$lang->testsuite->delete = "删除"; +$lang->testsuite->view = "概况"; +$lang->testsuite->edit = "编辑"; +$lang->testsuite->browse = "套件列表"; +$lang->testsuite->linkCase = "关联用例"; +$lang->testsuite->linkVersion = "版本"; +$lang->testsuite->unlinkCase = "移除"; +$lang->testsuite->batchUnlinkCases = "批量移除用例"; +$lang->testsuite->cases = '用例'; +$lang->testsuite->pre = '上一个'; +$lang->testsuite->next = '下一个'; + +$lang->testsuite->common = '测试视图套件'; +$lang->testsuite->product = '所属' . $lang->productCommon; +$lang->testsuite->name = '名称'; +$lang->testsuite->desc = '描述'; +$lang->testsuite->author = '访问权限'; +$lang->testsuite->addedBy = '由谁创建'; +$lang->testsuite->addedDate = '创建时间'; + +$lang->testsuite->legendDesc = '版本描述'; +$lang->testsuite->legendReport = '测试总结'; +$lang->testsuite->legendBasicInfo = '基本信息'; + +$lang->testsuite->unlinkedCases = '未关联'; + +$lang->testsuite->confirmDelete = '您确认要删除该套件吗?'; +$lang->testsuite->confirmUnlinkCase = '您确认要移除该用例吗?'; + +$lang->testsuite->lblCases = '用例列表'; +$lang->testsuite->lblUnlinkCase = '移除用例'; + +$lang->testsuite->authorList['private'] = '私有'; +$lang->testsuite->authorList['public'] = '公开'; diff --git a/module/testsuite/model.php b/module/testsuite/model.php new file mode 100644 index 0000000000..b17cd71703 --- /dev/null +++ b/module/testsuite/model.php @@ -0,0 +1,212 @@ + + * @package testsuite + * @version $Id: model.php 5114 2013-07-12 06:02:59Z chencongzhi520@gmail.com $ + * @link http://www.zentao.net + */ +?> +loadModel('product')->setMenu($products, $productID); + $selectHtml = $this->select($products, $productID, 'testsuite', 'browse'); + foreach($this->lang->testsuite->menu as $key => $value) + { + $replace = ($key == 'product') ? $selectHtml : $productID; + common::setMenuVars($this->lang->testsuite->menu, $key, $replace); + } + } + + public function select($products, $productID, $currentModule, $currentMethod, $extra = '') + { + if(!$productID) + { + unset($this->lang->product->menu->branch); + return; + } + + setCookie("lastProduct", $productID, $this->config->cookieLife, $this->config->webRoot); + $currentProduct = $this->product->getById($productID); + $output = "{$currentProduct->name}
"; + return $output; + } + + /** + * Create a test suite. + * + * @param int $productID + * @access public + * @return void + */ + function create($productID) + { + $suite = fixer::input('post') + ->stripTags($this->config->testsuite->editor->create['id'], $this->config->allowedTags) + ->add('product', (int)$productID) + ->add('addedBy', $this->app->user->account) + ->add('addedDate', helper::now()) + ->remove('uid') + ->get(); + $suite = $this->loadModel('file')->processEditor($suite, $this->config->testsuite->editor->create['id'], $this->post->uid); + $this->dao->insert(TABLE_TESTSUITE)->data($suite) + ->batchcheck($this->config->testsuite->create->requiredFields, 'notempty') + ->exec(); + if(!dao::isError()) + { + $suiteID = $this->dao->lastInsertID(); + $this->file->updateObjectID($this->post->uid, $suiteID, 'testsuite'); + return $suiteID; + } + } + + /** + * Get test suites of a product. + * + * @param int $productID + * @param string $orderBy + * @param object $pager + * @access public + * @return array + */ + public function getSuites($productID, $orderBy = 'id_desc', $pager = null) + { + return $this->dao->select("*")->from(TABLE_TESTSUITE) + ->where('product')->eq((int)$productID) + ->andWhere('deleted')->eq(0) + ->andWhere("(`type` = 'public' OR (`type` = 'private' and addedBy = '{$this->app->user->account}'))") + ->orderBy($orderBy) + ->page($pager) + ->fetchAll(); + } + + /** + * Get test suite info by id. + * + * @param int $suiteID + * @param bool $setImgSize + * @access public + * @return void + */ + public function getById($suiteID, $setImgSize = false) + { + $suite = $this->dao->select("*")->from(TABLE_TESTSUITE)->where('id')->eq((int)$suiteID)->fetch(); + if($setImgSize) $suite->desc = $this->loadModel('file')->setImgSize($suite->desc); + return $suite; + } + + /** + * Update a test suite. + * + * @param int $suiteID + * @access public + * @return void + */ + public function update($suiteID) + { + $oldSuite = $this->getById($suiteID); + $suite = fixer::input('post') + ->stripTags($this->config->testsuite->editor->edit['id'], $this->config->allowedTags) + ->add('lastEditedBy', $this->app->user->account) + ->add('lastEditedDate', helper::now()) + ->remove('uid') + ->get(); + $suite = $this->loadModel('file')->processEditor($suite, $this->config->testsuite->editor->edit['id'], $this->post->uid); + $this->dao->update(TABLE_TESTSUITE)->data($suite) + ->autoCheck() + ->batchcheck($this->config->testsuite->edit->requiredFields, 'notempty') + ->where('id')->eq($suiteID) + ->exec(); + if(!dao::isError()) + { + $this->file->updateObjectID($this->post->uid, $suiteID, 'testsuite'); + return common::createChanges($oldSuite, $suite); + } + } + + /** + * Link cases. + * + * @param int $suiteID + * @access public + * @return void + */ + public function linkCase($suiteID) + { + if($this->post->cases == false) return; + $postData = fixer::input('post')->get(); + foreach($postData->cases as $caseID) + { + $row = new stdclass(); + $row->suite = $suiteID; + $row->case = $caseID; + $row->version = $postData->versions[$caseID]; + $this->dao->replace(TABLE_SUITECASE)->data($row)->exec(); + } + } + + public function getLinkedCases($suiteID, $orderBy = 'id_desc', $pager = null, $append = true) + { + $suite = $this->getById($suiteID); + $cases = $this->dao->select('t1.*,t2.version as caseVersion')->from(TABLE_CASE)->alias('t1') + ->leftJoin(TABLE_SUITECASE)->alias('t2')->on('t1.id=t2.case') + ->where('t2.suite')->eq($suiteID) + ->andWhere('t1.product')->eq($suite->product) + ->andWhere('t1.deleted')->eq(0) + ->orderBy($orderBy) + ->page($pager) + ->fetchAll('id'); + if(!$append) return $cases; + return $this->loadModel('testcase')->appendBugAndResults($cases); + } + + public function getUnlinkedCases($suite, $param = 0, $pager = null) + { + if($this->session->testcaseQuery == false) $this->session->set('testcaseQuery', ' 1 = 1'); + $queryID = (int)$param; + if($queryID) + { + $query = $this->loadModel('search')->getQuery($queryID); + if($query) + { + $this->session->set('testcaseQuery', $query->sql); + $this->session->set('testcaseForm', $query->form); + } + } + + $query = $this->session->testcaseQuery; + $allProduct = "`product` = 'all'"; + if(strpos($query, '`product` =') === false) $query .= " AND `product` = {$suite->product}"; + if(strpos($query, $allProduct) !== false) $query = str_replace($allProduct, '1', $query); + + $linkedCases = $this->getLinkedCases($suite->id, 'id_desc', null, $append = false); + $cases = $this->dao->select('*')->from(TABLE_CASE)->where($query) + ->andWhere('id')->notIN($linkedCases) + ->andWhere('deleted')->eq(0) + ->orderBy('id desc') + ->page($pager) + ->fetchAll(); + return $cases; + } + + public function delete($suiteID, $table = '') + { + parent::delete(TABLE_TESTSUITE, $suiteID); + $this->dao->delete()->from(TABLE_SUITECASE)->where('suite')->eq($suiteID)->exec(); + return true; + } +} diff --git a/module/testsuite/view/browse.html.php b/module/testsuite/view/browse.html.php new file mode 100644 index 0000000000..8de663202b --- /dev/null +++ b/module/testsuite/view/browse.html.php @@ -0,0 +1,57 @@ + + * @package testsuite + * @version $Id: browse.html.php 4129 2013-01-18 01:58:14Z wwccss $ + * @link http://www.zentao.net + */ +?> + +testsuite->confirmDelete)?> +
+
testsuite->browse?>
+
+
+ + + recTotal}&recPerPage={$pager->recPerPage}"; ?> + + + + + + + + + + + + + + + + + + + + + + +
idAB);?>testsuite->name);?>testsuite->desc;?>testsuite->addedBy);?>testsuite->addedDate);?>actions;?>
id);?>id"), $suite->name);?>desc;?>addedBy);?>addedDate;?> + id", '', 'list', 'link'); + common::printIcon('testsuite', 'edit', "suiteID=$suite->id", '', 'list'); + + if(common::hasPriv('testsuite', 'delete')) + { + $deleteURL = $this->createLink('testsuite', 'delete', "suiteID=$suite->id&confirm=yes"); + echo html::a("javascript:ajaxDelete(\"$deleteURL\",\"suiteList\",confirmDelete)", '', '', "title='{$lang->testsuite->delete}' class='btn-icon'"); + } + ?> +
show();?>
+ + diff --git a/module/testsuite/view/create.html.php b/module/testsuite/view/create.html.php new file mode 100644 index 0000000000..ec66c7e87f --- /dev/null +++ b/module/testsuite/view/create.html.php @@ -0,0 +1,42 @@ + + * @package testsuite + * @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ + * @link http://www.zentao.net + */ +?> + + + +
+
+
+ icons['create']);?> testsuite->create;?> +
+
+
+ + + + + + + + + + + + + + + + +
testsuite->name;?>
testsuite->desc;?>
testsuite->author;?>testsuite->authorList, 'private');?>
+
+
+ diff --git a/module/testsuite/view/edit.html.php b/module/testsuite/view/edit.html.php new file mode 100644 index 0000000000..9df5b13ee4 --- /dev/null +++ b/module/testsuite/view/edit.html.php @@ -0,0 +1,43 @@ + + * @package testsuite + * @version $Id: edit.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ + * @link http://www.zentao.net + */ +?> + + + +
+
+
+ createLink('testsuite', 'view', 'suiteID=' . $suite->id), $suite->name, '_blank');?> + testsuite->edit;?> icons['edit']);?> +
+
+
+ + + + + + + + + + + + + + + + +
testsuite->name;?>name, "class='form-control' autocomplete='off'");?>
testsuite->desc;?>desc), "rows=10 class='form-control'");?>
testsuite->author;?>testsuite->authorList, $suite->type);?>
+
+
+ diff --git a/module/testsuite/view/linkcase.html.php b/module/testsuite/view/linkcase.html.php new file mode 100644 index 0000000000..85085d0b96 --- /dev/null +++ b/module/testsuite/view/linkcase.html.php @@ -0,0 +1,79 @@ + + * @package testsuite + * @version $Id: linkcase.html.php 4411 2013-02-22 00:56:04Z chencongzhi520@gmail.com $ + * @link http://www.zentao.net + */ +?> + + +
+
+ id;?> + createLink('testsuite', 'view', 'suiteID=' . $suite->id), $suite->name, '_blank');?> + testsuite->linkCase;?> icons['link']);?> +
+
+
session->testsuiteList);?>
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+  testsuite->unlinkedCases;?> (recTotal;?>) +
idAB;?>testsuite->linkVersion;?>priAB;?>testcase->title;?>testcase->type;?>openedByAB;?>statusAB;?>
+ + createLink('testcase', 'view', "testcaseID=$case->id"), sprintf('%03d', $case->id));?> + id]", array_combine(range($case->version, 1), range($case->version, 1)), '', 'class="form-control input-sm" style="padding: 0 5px; height: 20px"');?> testcase->priList, $case->pri, $case->pri)?>'>testcase->priList, $case->pri, $case->pri)?> + title . ' ( '; + for($i = $case->version; $i >= 1; $i --) + { + echo html::a($this->createLink('testcase', 'view', "caseID=$case->id&version=$i"), "#$i", '_blank'); + } + echo ')'; + ?> + testcase->typeList[$case->type];?>openedBy];?>testcase->statusList[$case->status];?>
+ +
+ +
show();?>
+
+
+ diff --git a/module/testsuite/view/view.html.php b/module/testsuite/view/view.html.php new file mode 100644 index 0000000000..b5a9de46b9 --- /dev/null +++ b/module/testsuite/view/view.html.php @@ -0,0 +1,157 @@ + + * @package case + * @version $Id: view.html.php 4141 2013-01-18 06:15:13Z zhujinyonging@gmail.com $ + * @link http://www.zentao.net + */ +?> + + + +testsuite->confirmUnlinkCase)?> +
+
+ id;?> + name;?> + deleted):?> + suite->deleted;?> + +
+
+ session->testsuiteList ? $this->session->testsuiteList : $this->createLink('testsuite', 'browse', "productID=$suite->product"); + $actionLinks = ''; + if(!$suite->deleted) + { + ob_start(); + + echo "
"; + common::printIcon('testsuite', 'linkCase', "suiteID=$suite->id", $suite, 'button', 'link'); + echo '
'; + + echo "
"; + common::printIcon('testsuite', 'edit', "suiteID=$suite->id"); + common::printIcon('testsuite', 'delete', "suiteID=$suite->id", '', 'button', '', 'hiddenwin'); + echo '
'; + + echo "
"; + common::printRPN($browseLink); + echo '
'; + + $actionLinks = ob_get_contents(); + ob_end_clean(); + echo $actionLinks; + } + ?> +
+
+
+
+
+
+
+ testsuite->cases?> +
id", $suite, 'button', 'link');?>
+
+
+ id&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
idAB);?> priAB);?> testcase->title);?> testcase->type);?> statusAB);?> testcase->bugsAB;?> testcase->resultsAB;?> testcase->stepNumberAB;?>actions;?>
+ + + + id);?> + testcase->priList, $case->pri, $case->pri)?>'>testcase->priList, $case->pri, $case->pri)?> + branch) echo "{$branches[$case->branch]}"?> + createLink('testcase', 'view', "caseID=$case->id&version=$case->caseVersion&from=testsuite"), $case->title, '_blank');?> + testcase->typeList[$case->type];?>version < $case->caseVersion) ? "{$lang->testcase->changed}" : $lang->testcase->statusList[$case->status];?>bugs) ? html::a($this->createLink('testcase', 'bugs', "case={$case->id}&caseID={$case->case}"), $case->bugs, '', "class='iframe'") : $case->bugs;?>results) ? html::a($this->createLink('testsuite', 'results', "caseID={$case->id}&caseID={$case->case}"), $case->results, '', "class='iframe'") : $case->results;?>stepNumber;?> + createLink('testsuite', 'unlinkCase', "suiteID=$suite->id&caseID=$case->id&confirm=yes"); + echo html::a("javascript:ajaxDelete(\"$unlinkURL\",\"caseList\",confirmUnlink)", '', '', "title='{$lang->testsuite->unlinkCase}' class='btn-icon'"); + } + ?> +
+ +
+ +
+ createLink('testcase', 'batchEdit', "productID=$productID"); + $misc = $canBatchEdit ? "onclick=\"setFormAction('$actionLink')\"" : "disabled='disabled'"; + echo html::commonButton($lang->edit, $misc); + ?> + + +
+
+ + show();?> +
+
+
+
+
+
+
+
+ testsuite->legendDesc;?> +
desc;?>
+
+ +
+
+
+ diff --git a/module/upgrade/model.php b/module/upgrade/model.php index e74624cc40..2d1ebd53de 100644 --- a/module/upgrade/model.php +++ b/module/upgrade/model.php @@ -1215,8 +1215,7 @@ class upgradeModel extends model } $newPaths = join(',', $newPaths); - $newPaths = ",$newPaths,"; - $this->dao->update(TABLE_MODULE)->set('path')->eq($newPaths)->where('id')->eq($newModuleID)->exec(); + $this->dao->update(TABLE_MODULE)->set('path')->eq($newPaths)->set('parent')->eq($relation[$module->parent])->where('id')->eq($newModuleID)->exec(); $this->dao->update(TABLE_DOC)->set('module')->eq($newModuleID)->where('product')->eq($productID)->andWhere('module')->eq($moduleID)->andWhere('lib')->eq('product')->exec(); } $this->dao->update(TABLE_DOC)->set('lib')->eq($libID)->where('product')->eq($productID)->exec();