From 4c3ebc9cc71b4ae31fe85e674ac6ed03d0fee27a Mon Sep 17 00:00:00 2001 From: wyd621 Date: Thu, 25 Jul 2013 13:46:02 +0800 Subject: [PATCH] * finish task #1591 1590. --- module/testcase/config.php | 3 + module/testcase/control.php | 192 +++++++++++++++++++++++++++ module/testcase/model.php | 150 +++++++++++++++++++++ module/testcase/view/import.html.php | 44 ++---- 4 files changed, 358 insertions(+), 31 deletions(-) diff --git a/module/testcase/config.php b/module/testcase/config.php index fa2dbc6348..7aff20f527 100644 --- a/module/testcase/config.php +++ b/module/testcase/config.php @@ -14,6 +14,9 @@ $config->testcase->editor = new stdclass(); $config->testcase->editor->edit = array('id' => 'comment', 'tools' => 'simpleTools'); $config->testcase->editor->view = array('id' => 'comment', 'tools' => 'simpleTools'); +$config->testcase->export = new stdclass(); +$config->testcase->export->listFields = array('type', 'stage', 'pri', 'status'); + $config->testcase->exportFields = ' id, product, module, story, title, precondition, stepDesc, stepExpect, keywords, diff --git a/module/testcase/control.php b/module/testcase/control.php index 9c48fb1c86..0a2c72142f 100644 --- a/module/testcase/control.php +++ b/module/testcase/control.php @@ -661,4 +661,196 @@ class testcase extends control $this->display(); } + + /** + * Export templet + * + * @param int $productID + * @access public + * @return void + */ + public function exportTemplet($productID) + { + if($_POST) + { + $fields['module'] = $this->lang->testcase->module; + $fields['story'] = $this->lang->testcase->story; + $fields['title'] = $this->lang->testcase->title; + $fields['stepDesc'] = $this->lang->testcase->stepDesc; + $fields['stepExpect'] = $this->lang->testcase->stepExpect; + $fields['keywords'] = $this->lang->testcase->keywords; + $fields['type'] = $this->lang->testcase->type; + $fields['pri'] = $this->lang->testcase->pri; + $fields['stage'] = $this->lang->testcase->stage; + $fields['precondition'] = $this->lang->testcase->precondition; + $this->post->set('fields', $fields); + $this->post->set('kind', 'testcase'); + $this->post->set('rows', array()); + $this->post->set('extraNum', $this->post->num); + $this->post->set('fileName', 'templet'); + $this->fetch('file', 'export2csv', $_POST); + } + + $this->display(); + } + + /** + * Import csv + * + * @param int $productID + * @access public + * @return void + */ + public function import($productID) + { + if($_FILES) + { + $file = $this->loadModel('file')->getUpload('file'); + $file = $file[0]; + + $fc = file_get_contents($file['tmpname']); + if( $this->post->encode != "utf-8") + { + if(function_exists('mb_convert_encoding')) + { + $fc = @mb_convert_encoding($fc, 'utf-8', $this->post->encode); + } + elseif(function_exists('iconv')) + { + $fc = @iconv($this->post->encode, 'utf-8', $fc); + } + } + file_put_contents($this->file->savePath . $file['pathname'], $fc); + + $fileName = $this->file->savePath . $file['pathname']; + $this->session->set('importFile', $fileName); + + die(js::locate(inlink('showImport', "productID=$productID"), 'parent.parent')); + } + $this->display(); + } + + /** + * Show import data + * + * @param int $productID + * @access public + * @return void + */ + public function showImport($productID) + { + if($_POST) + { + $this->testcase->createFromImport($productID); + die(js::locate(inlink('browse', "productID=$productID"), 'parent')); + } + $this->testcase->setMenu($this->products, $productID); + + $file = $this->session->importFile; + $caseLang = $this->lang->testcase; + $caseConfig = $this->config->testcase; + $fields = explode(',', $caseConfig->exportFields); + $modules = $this->loadModel('tree')->getOptionMenu($productID, 'case'); + foreach($fields as $key => $fieldName) + { + $fieldName = trim($fieldName); + $fields[$fieldName] = isset($caseLang->$fieldName) ? $caseLang->$fieldName : $fieldName; + unset($fields[$key]); + } + + $csv = file_get_contents($file); + $header = substr($csv, 0, strpos($csv, "\n")); + $csv = substr($csv, strpos($csv, "\n") + 1); + + foreach(explode(',', $header) as $title) + { + $field = array_search(trim($title), $fields); + $columnKey[] = $field ? $field : ''; + } + + $row = 1; + $endField = $field; + $caseData = array(); + $stepData = array(); + while($csv) + { + $case = new stdclass(); + foreach($columnKey as $field) + { + $delimiter = $field == $endField ? "\n" : ','; + $pos = strpos($csv, $delimiter); + $cellValue = substr($csv, 0, $pos); + if($field == 'story') + { + $case->$field = substr($cellValue, 1); + } + elseif($field == 'module') + { + $case->$field = array_search($cellValue, $modules); + } + elseif(in_array($field, $caseConfig->export->listFields)) + { + $case->$field = array_search($cellValue, $caseLang->{$field . 'List'}); + } + elseif($field != 'stepDesc' and $field != 'stepExpect') + { + $case->$field = $cellValue; + } + + else + { + $delimiter = $csv[0] == '"' ? '",' : ','; + $pos = strpos($csv, $delimiter); + $cellValue = substr($csv, 0, $pos); + if($cellValue[0] == '"')$cellValue = substr($cellValue, 1); + + $steps = explode("\n", $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]+)([.、]{1})/U', $step, $out)) + { + $num = $out[1]; + $sign = $out[2]; + $signbit = $sign == '.' ? 1 : 3; + $step = trim(substr($step, strpos($step, $sign) + $signbit)); + if(!empty($step)) $caseStep[$num] = $step; + } + else + { + if(isset($num)) $caseStep[$num] .= "\n" . $step; + } + } + unset($num); + unset($sign); + $stepData[$row][$stepKey] = $caseStep; + } + $csv = substr($csv, $pos + strlen($delimiter)); + } + $caseData[$row] = $case; + unset($case); + $row++; + } + + if(empty($caseData)) + { + echo js::alert($this->lang->excel->noData); + die(js::locate($this->createLink('testcase', 'browse'))); + } + + $this->view->title = $this->lang->testcase->common . $this->lang->colon . $this->lang->testcase->showImport; + $this->view->position[] = $this->lang->testcase->showImport; + + $this->view->stories = $this->loadModel('story')->getProductStoryPairs($productID); + $this->view->modules = $modules; + $this->view->cases = $this->dao->select('id, module, story')->from(TABLE_CASE)->where('product')->eq($productID)->andWhere('deleted')->eq(0)->fetchAll('id'); + $this->view->caseData = $caseData; + $this->view->stepData = $stepData; + $this->view->productID = $productID; + $this->view->product = $this->products[$productID]; + $this->display(); + } } diff --git a/module/testcase/model.php b/module/testcase/model.php index c0240b6836..02ac94668f 100644 --- a/module/testcase/model.php +++ b/module/testcase/model.php @@ -388,4 +388,154 @@ class testcaseModel extends model return true; } + + /** + * Create from import + * + * @param int $productID + * @access public + * @return void + */ + public function createFromImport($productID) + { + $this->loadModel('action'); + $this->loadModel('story'); + $this->loadModel('file'); + $now = helper::now(); + + 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.product')->eq($productID) + ->andWhere('t1.version=t2.version') + ->orderBy('t2.id') + ->fetchGroup('case'); + $oldCases = $this->dao->select('*')->from(TABLE_CASE)->where('id')->in($_POST['id'])->fetchAll('id'); + } + + foreach($this->post->product as $key => $product) + { + dao::getError(); + $caseData = new stdclass(); + + $caseData->product = $product; + $caseData->module = $this->post->module[$key]; + $caseData->story = (int)$this->post->story[$key]; + $caseData->title = $this->post->title[$key]; + $caseData->pri = (int)$this->post->pri[$key]; + $caseData->type = $this->post->type[$key]; + $caseData->status = $this->post->status[$key]; + $caseData->stage = join(',', $this->post->stage[$key]); + $caseData->frequency = $this->post->frequency[$key]; + $caseData->linkCase = $this->post->linkCase[$key]; + $caseData->precondition = $this->post->precondition[$key]; + + if(isset($this->config->testcase->create->requiredFields)) + { + $requiredFields = explode(',', $this->config->testcase->create->requiredFields); + $invalid = false; + foreach($requiredFields as $requiredField) + { + $requiredField = trim($requiredField); + if(empty($caseData->$requiredField)) $invalid = true; + } + if($invalid) continue; + } + + if(!empty($_POST['id'][$key])) + { + $caseID = $this->post->id[$key]; + $stepChanged = false; + $steps = array(); + if(!isset($oldSteps[$caseID])) continue; + $oldStep = $oldSteps[$caseID]; + + /* Remove the empty setps in post. */ + foreach($this->post->desc[$key] as $id => $desc) + { + $desc = trim($desc); + if(empty($desc))continue; + $step = new stdclass(); + $step->desc = $desc; + $step->expect = trim($this->post->expect[$key][$id]); + $steps[] = $step; + unset($step); + } + + /* If step count changed, case changed. */ + if(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 ? $oldStep->version + 1 : $oldStep->version; + $caseData->version = $version; + $changes = common::createChanges($oldCases[$caseID], $caseData); + if(!$changes and !$stepChanged) continue; + + if($changes or $stepChanged) + { + $caseData->lastEditedBy = $this->app->user->account; + $caseData->lastEditedDate = $now; + $this->dao->update(TABLE_CASE)->data($caseData)->where('id')->eq($caseID)->autoCheck()->exec(); + if($stepChanged) + { + foreach($steps as $id => $step) + { + $step = (array)$step; + if(empty($step['desc'])) continue; + $stepData = ''; + $stepData->case = $caseID; + $stepData->version = $version; + $stepData->desc = htmlspecialchars($step['desc']); + $stepData->expect = htmlspecialchars($step['expect']); + $this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec(); + } + } + $oldCases[$caseID]->steps = $this->joinStep($oldSteps[$caseID]); + $caseData->steps = $this->joinStep($steps); + $changes = common::createChanges($oldCases[$caseID], $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; + $this->dao->insert(TABLE_CASE)->data($caseData)->autoCheck()->exec(); + + if(!dao::isError()) + { + $caseID = $this->dao->lastInsertID(); + foreach($this->post->desc[$key] as $id => $desc) + { + $desc = trim($desc); + if(empty($desc)) continue; + $stepData->case = $caseID; + $stepData->version = 1; + $stepData->desc = htmlspecialchars($desc); + $stepData->expect = htmlspecialchars($this->post->expect[$key][$id]); + $this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec(); + } + $this->action->create('case', $caseID, 'Opened'); + } + } + } + } } diff --git a/module/testcase/view/import.html.php b/module/testcase/view/import.html.php index 09cbd1e625..6b4f5fcfc7 100755 --- a/module/testcase/view/import.html.php +++ b/module/testcase/view/import.html.php @@ -1,32 +1,14 @@ - - * @package file - * @version $Id$ - * @link http://www.zentao.net - */ -?> - -
- - importEncodeList,'gbk');?> - + + + + + + + +
testcase->importCase?>
+ + charsets[$this->cookie->lang], 'utf-8');?> + +
-
- - - - - - - - -
- -
-
- +