function saveImportedTCData(&$db, $tcData, $tproject_id, $container_id, $userID, $kwMap, $duplicatedLogic = array('hitCriteria' => 'name', 'actionOnHit' => null)) { static $messages; static $fieldSizeCfg; static $feedbackMsg; static $tcase_mgr; static $tproject_mgr; static $req_spec_mgr; static $req_mgr; static $safeSizeCfg; static $linkedCustomFields; static $tprojectHas; static $reqSpecSet; static $getVersionOpt; static $userObj; if (!$tcData) { return; } // $tprojectHas = array('customFields' => false, 'reqSpec' => false); $hasCustomFieldsInfo = false; $hasRequirements = false; if (is_null($messages)) { $feedbackMsg = array(); $messages = array(); $fieldSizeCfg = config_get('field_size'); $tcase_mgr = new testcase($db); $tproject_mgr = new testproject($db); $req_spec_mgr = new requirement_spec_mgr($db); $req_mgr = new requirement_mgr($db); $userObj = new tlUser(); $k2l = array('already_exists_updated', 'original_name', 'testcase_name_too_long', 'start_warning', 'end_warning', 'testlink_warning', 'hit_with_same_external_ID'); foreach ($k2l as $k) { $messages[$k] = lang_get($k); } $messages['start_feedback'] = $messages['start_warning'] . "\n" . $messages['testlink_warning'] . "\n"; $messages['cf_warning'] = lang_get('no_cf_defined_can_not_import'); $messages['reqspec_warning'] = lang_get('no_reqspec_defined_can_not_import'); $feedbackMsg['cfield'] = lang_get('cf_value_not_imported_missing_cf_on_testproject'); $feedbackMsg['tcase'] = lang_get('testcase'); $feedbackMsg['req'] = lang_get('req_not_in_req_spec_on_tcimport'); $feedbackMsg['req_spec'] = lang_get('req_spec_ko_on_tcimport'); // because name can be changed automatically during item creation // to avoid name conflict adding a suffix automatically generated, // is better to use a max size < max allowed size $safeSizeCfg = new stdClass(); $safeSizeCfg->testcase_name = $fieldSizeCfg->testcase_name * 0.8; // Get CF with scope design time and allowed for test cases linked to this test project $linkedCustomFields = $tcase_mgr->cfield_mgr->get_linked_cfields_at_design($tproject_id, 1, null, 'testcase', null, 'name'); $tprojectHas['customFields'] = !is_null($linkedCustomFields); $reqSpecSet = $tproject_mgr->getReqSpec($tproject_id, null, array('RSPEC.id', 'NH.name AS title', 'RSPEC.doc_id as rspec_doc_id', 'REQ.req_doc_id'), 'req_doc_id'); $tprojectHas['reqSpec'] = !is_null($reqSpecSet) && count($reqSpecSet) > 0; $getVersionOpt = array('output' => 'minimun'); $tcasePrefix = $tproject_mgr->getTestCasePrefix($tproject_id); } $resultMap = array(); $tc_qty = sizeof($tcData); $userIDCache = array(); for ($idx = 0; $idx < $tc_qty; $idx++) { $tc = $tcData[$idx]; $name = $tc['name']; $summary = $tc['summary']; $steps = $tc['steps']; // I've changed value to use when order has not been provided // from testcase:DEFAULT_ORDER to a counter, because with original solution // an issue arise with 'save execution and go next' // if use has not provided order I think is OK TestLink make any choice. $node_order = isset($tc['node_order']) ? intval($tc['node_order']) : $idx + 1; $internalid = $tc['internalid']; $preconditions = $tc['preconditions']; $exec_type = isset($tc['execution_type']) ? $tc['execution_type'] : TESTCASE_EXECUTION_TYPE_MANUAL; $importance = isset($tc['importance']) ? $tc['importance'] : MEDIUM; $externalid = $tc['externalid']; if (intval($externalid) <= 0) { $externalid = null; } $personID = $userID; if (!is_null($tc['author_login'])) { if (isset($userIDCache[$tc['author_login']])) { $personID = $userIDCache[$tc['author_login']]; } else { $userObj->login = $tc['author_login']; if ($userObj->readFromDB($db, tlUser::USER_O_SEARCH_BYLOGIN) == tl::OK) { $personID = $userObj->dbID; } // I will put always a valid userID on this cache, // this way if author_login does not exit, and is used multiple times // i will do check for existence JUST ONCE. $userIDCache[$tc['author_login']] = $personID; } } $name_len = tlStringLen($name); if ($name_len > $fieldSizeCfg->testcase_name) { // Will put original name inside summary $xx = $messages['start_feedback']; $xx .= sprintf($messages['testcase_name_too_long'], $name_len, $fieldSizeCfg->testcase_name) . "\n"; $xx .= $messages['original_name'] . "\n" . $name . "\n" . $messages['end_warning'] . "\n"; $summary = nl2br($xx) . $summary; $name = tlSubStr($name, 0, $safeSizeCfg->testcase_name); } $kwIDs = null; if (isset($tc['keywords']) && $tc['keywords']) { $kwIDs = implode(",", buildKeywordList($kwMap, $tc['keywords'])); } $doCreate = true; if ($duplicatedLogic['actionOnHit'] == 'update_last_version') { switch ($duplicatedLogic['hitCriteria']) { case 'name': $info = $tcase_mgr->getDuplicatesByName($name, $container_id); break; case 'internalID': $dummy = $tcase_mgr->tree_manager->get_node_hierarchy_info($internalid, $container_id); if (!is_null($dummy)) { $info = null; $info[$internalid] = $dummy; } break; case 'externalID': $info = $tcase_mgr->get_by_external($externalid, $container_id); break; } if (!is_null($info)) { $tcase_qty = count($info); switch ($tcase_qty) { case 1: $doCreate = false; $tcase_id = key($info); $last_version = $tcase_mgr->get_last_version_info($tcase_id, $getVersionOpt); $tcversion_id = $last_version['id']; $ret = $tcase_mgr->update($tcase_id, $tcversion_id, $name, $summary, $preconditions, $steps, $personID, $kwIDs, $node_order, $exec_type, $importance); $ret['id'] = $tcase_id; $ret['tcversion_id'] = $tcversion_id; $resultMap[] = array($name, $messages['already_exists_updated']); break; case 0: $doCreate = true; break; default: $doCreate = false; break; } } } if ($doCreate) { // Want to block creation of with existent EXTERNAL ID, if containers ARE DIFFERENT. $item_id = intval($tcase_mgr->getInternalID($externalid, array('tproject_id' => $tproject_id))); if ($item_id > 0) { // who is his parent ? $owner = $tcase_mgr->getTestSuite($item_id); if ($owner != $container_id) { // Get full path of existent Test Cases $stain = $tcase_mgr->tree_manager->get_path($item_id, null, 'name'); $n = count($stain); $stain[$n - 1] = $tcasePrefix . config_get('testcase_cfg')->glue_character . $externalid . ':' . $stain[$n - 1]; $stain = implode('/', $stain); $resultMap[] = array($name, $messages['hit_with_same_external_ID'] . $stain); $doCreate = false; } } } if ($doCreate) { $createOptions = array('check_duplicate_name' => testcase::CHECK_DUPLICATE_NAME, 'action_on_duplicate_name' => $duplicatedLogic['actionOnHit'], 'external_id' => $externalid); if ($ret = $tcase_mgr->create($container_id, $name, $summary, $preconditions, $steps, $personID, $kwIDs, $node_order, testcase::AUTOMATIC_ID, $exec_type, $importance, $createOptions)) { $resultMap[] = array($name, $ret['msg']); } } } return $resultMap; }
function create_tc_from_requirement($mixIdReq, $srs_id, $user_id, $tproject_id = null, $tc_count = null) { $debugMsg = 'Class:' . __CLASS__ . ' - Method: ' . __FUNCTION__; $tcase_mgr = new testcase($this->db); $tsuite_mgr = new testsuite($this->db); $req_cfg = config_get('req_cfg'); $field_size = config_get('field_size'); $auto_testsuite_name = $req_cfg->default_testsuite_name; $node_descr_type = $this->tree_mgr->get_available_node_types(); $empty_steps = null; $empty_preconditions = ''; // fix for BUGID 2995 $labels['tc_created'] = lang_get('tc_created'); $output = null; $reqSet = is_array($mixIdReq) ? $mixIdReq : array($mixIdReq); /* contribution BUGID 2996, testcase creation */ if (is_null($tproject_id) || $tproject_id == 0) { $tproject_id = $this->tree_mgr->getTreeRoot($srs_id); } if ($req_cfg->use_req_spec_as_testsuite_name) { $full_path = $this->tree_mgr->get_path($srs_id); $addition = " (" . lang_get("testsuite_title_addition") . ")"; $truncate_limit = $field_size->testsuite_name - strlen($addition); // REQ_SPEC_A // |-- REQ_SPEC_A1 // |-- REQ_SPEC_A2 // |- REQ100 // |- REQ101 // // We will try to check if a test suite has already been created for // top REQ_SPEC_A (we do search using automatic generated name as search criteria). // If not => we need to create all path till leaves (REQ100 and REQ200) // // // First search: we use test project $parent_id = $tproject_id; $deep_create = false; foreach ($full_path as $key => $node) { // follow hierarchy of test suites to create $tsuiteInfo = null; $testsuite_name = substr($node['name'], 0, $truncate_limit) . $addition; if (!$deep_create) { // child test suite with this name, already exists on current parent ? // At first a failure we will not check anymore an proceed with deep create $sql = "/* {$debugMsg} */ SELECT id,name FROM {$this->tables['nodes_hierarchy']} NH " . " WHERE name='" . $this->db->prepare_string($testsuite_name) . "' " . " AND node_type_id=" . $node_descr_type['testsuite'] . " AND parent_id = {$parent_id} "; // If returns more that one record use ALWAYS first $tsuiteInfo = $this->db->fetchRowsIntoMap($sql, 'id'); } if (is_null($tsuiteInfo)) { $tsuiteInfo = $tsuite_mgr->create($parent_id, $testsuite_name, $req_cfg->testsuite_details); $output[] = sprintf(lang_get('testsuite_name_created'), $testsuite_name); $deep_create = true; } else { $tsuiteInfo = current($tsuiteInfo); $tsuite_id = $tsuiteInfo['id']; } $tsuite_id = $tsuiteInfo['id']; // last value here will be used as parent for test cases $parent_id = $tsuite_id; } $output[] = sprintf(lang_get('created_on_testsuite'), $testsuite_name); } else { // don't use req_spec as testsuite name // Warning: // We are not maintaining hierarchy !!! $sql = " SELECT id FROM {$this->tables['nodes_hierarchy']} NH " . " WHERE name='" . $this->db->prepare_string($auto_testsuite_name) . "' " . " AND parent_id=" . $testproject_id . " " . " AND node_type_id=" . $node_descr_type['testsuite']; $result = $this->db->exec_query($sql); if ($this->db->num_rows($result) == 1) { $row = $this->db->fetch_array($result); $tsuite_id = $row['id']; $label = lang_get('created_on_testsuite'); } else { // not found -> create tLog('test suite:' . $auto_testsuite_name . ' was not found.'); $new_tsuite = $tsuite_mgr->create($testproject_id, $auto_testsuite_name, $req_cfg->testsuite_details); $tsuite_id = $new_tsuite['id']; $label = lang_get('testsuite_name_created'); } $output[] = sprintf($label, $auto_testsuite_name); } /* end contribution */ // create TC $createOptions = array(); $createOptions['check_names_for_duplicates'] = config_get('check_names_for_duplicates'); $createOptions['action_on_duplicate_name'] = config_get('action_on_duplicate_name'); $testcase_importance_default = config_get('testcase_importance_default'); // compute test case order $testcase_order = config_get('treemenu_default_testcase_order'); $nt2exclude = array('testplan' => 'exclude_me', 'requirement_spec' => 'exclude_me', 'requirement' => 'exclude_me'); $siblings = $this->tree_mgr->get_children($tsuite_id, $nt2exclude); if (!is_null($siblings)) { $dummy = end($siblings); $testcase_order = $dummy['node_order']; } foreach ($reqSet as $reqID) { $reqData = $this->get_by_id($reqID, requirement_mgr::LATEST_VERSION); $count = !is_null($tc_count) ? $tc_count[$reqID] : 1; $reqData = $reqData[0]; // Generate name with progessive $instance = 1; $getOptions = array('check_criteria' => 'like', 'access_key' => 'name'); $itemSet = $tcase_mgr->getDuplicatesByName($reqData['title'], $tsuite_id, $getOptions); $nameSet = null; if (!is_null($itemSet)) { $nameSet = array_flip(array_keys($itemSet)); } for ($idx = 0; $idx < $count; $idx++) { $testcase_order++; // We have a little problem to work on: // suppose you have created: // TC [1] // TC [2] // TC [3] // If we delete TC [2] // When I got siblings il will got 2, if I create new progressive using next, // it will be 3 => I will get duplicated name. // // Seems better option can be: // Get all siblings names, put on array, create name an check if exists, if true // generate a new name. // This may be at performance level is better than create name then check on db, // because this approach will need more queries to DB // $tcase_name = $reqData['title'] . " [{$instance}]"; if (!is_null($nameSet)) { while (isset($nameSet[$tcase_name])) { $instance++; $tcase_name = $reqData['title'] . " [{$instance}]"; } } $nameSet[$tcase_name] = $tcase_name; // 20100106 - franciscom - multiple test case steps feature - removed expected_results // Julian - BUGID 2995 $tcase = $tcase_mgr->create($tsuite_id, $tcase_name, $req_cfg->testcase_summary_prefix . $reqData['scope'], $empty_preconditions, $empty_steps, $user_id, null, $testcase_order, testcase::AUTOMATIC_ID, TESTCASE_EXECUTION_TYPE_MANUAL, $testcase_importance_default, $createOptions); $tcase_name = $tcase['new_name'] == '' ? $tcase_name : $tcase['new_name']; $output[] = sprintf($labels['tc_created'], $tcase_name); // create coverage dependency if (!$this->assign_to_tcase($reqData['id'], $tcase['id'])) { $output[] = 'Test case: ' . $tcase_name . " was not created"; } } } return $output; }
function saveImportedTCData(&$db, $tcData, $tproject_id, $container_id, $userID, $kwMap, $duplicatedLogic = array('hitCriteria' => 'name', 'actionOnHit' => null)) { static $messages; static $fieldSizeCfg; static $feedbackMsg; static $tcase_mgr; static $tproject_mgr; static $req_spec_mgr; static $req_mgr; static $safeSizeCfg; static $linkedCustomFields; static $tprojectHas; static $reqSpecSet; static $getVersionOpt; if (!$tcData) { return; } // $tprojectHas = array('customFields' => false, 'reqSpec' => false); $hasCustomFieldsInfo = false; $hasRequirements = false; if (is_null($messages)) { $feedbackMsg = array(); $messages = array(); $fieldSizeCfg = config_get('field_size'); $tcase_mgr = new testcase($db); $tproject_mgr = new testproject($db); $req_spec_mgr = new requirement_spec_mgr($db); $req_mgr = new requirement_mgr($db); $messages['cf_warning'] = lang_get('no_cf_defined_can_not_import'); $messages['reqspec_warning'] = lang_get('no_reqspec_defined_can_not_import'); $messages['already_exists_updated'] = lang_get('already_exists_updated'); $messages['original_name'] = lang_get('original_name'); $messages['testcase_name_too_long'] = lang_get('testcase_name_too_long'); $messages['start_warning'] = lang_get('start_warning'); $messages['end_warning'] = lang_get('end_warning'); $messages['testlink_warning'] = lang_get('testlink_warning'); $messages['start_feedback'] = $messages['start_warning'] . "\n" . $messages['testlink_warning'] . "\n"; $feedbackMsg['cfield'] = lang_get('cf_value_not_imported_missing_cf_on_testproject'); $feedbackMsg['tcase'] = lang_get('testcase'); $feedbackMsg['req'] = lang_get('req_not_in_req_spec_on_tcimport'); $feedbackMsg['req_spec'] = lang_get('req_spec_ko_on_tcimport'); // because name can be changed automatically during item creation // to avoid name conflict adding a suffix automatically generated, // is better to use a max size < max allowed size $safeSizeCfg = new stdClass(); $safeSizeCfg->testcase_name = $fieldSizeCfg->testcase_name * 0.8; // Get CF with scope design time and allowed for test cases linked to this test project // $customFields=$tproject_mgr->get_linked_custom_fields($tproject_id,'testcase','name'); // function get_linked_cfields_at_design($tproject_id,$enabled,$filters=null, // $node_type=null,$node_id=null,$access_key='id') // $linkedCustomFields = $tcase_mgr->cfield_mgr->get_linked_cfields_at_design($tproject_id, 1, null, 'testcase', null, 'name'); $tprojectHas['customFields'] = !is_null($linkedCustomFields); // BUGID - 20090205 - franciscom $reqSpecSet = $tproject_mgr->getReqSpec($tproject_id, null, array('RSPEC.id', 'NH.name AS title', 'RSPEC.doc_id as rspec_doc_id', 'REQ.req_doc_id'), 'req_doc_id'); $tprojectHas['reqSpec'] = !is_null($reqSpecSet) && count($reqSpecSet) > 0; $getVersionOpt = array('output' => 'minimun'); } $resultMap = array(); $tc_qty = sizeof($tcData); for ($idx = 0; $idx < $tc_qty; $idx++) { $tc = $tcData[$idx]; $name = $tc['name']; $summary = $tc['summary']; $steps = $tc['steps']; $node_order = isset($tc['node_order']) ? intval($tc['node_order']) : testcase::DEFAULT_ORDER; $externalid = $tc['externalid']; $internalid = $tc['internalid']; $preconditions = $tc['preconditions']; $exec_type = isset($tc['execution_type']) ? $tc['execution_type'] : TESTCASE_EXECUTION_TYPE_MANUAL; $importance = isset($tc['importance']) ? $tc['importance'] : MEDIUM; $name_len = tlStringLen($name); if ($name_len > $fieldSizeCfg->testcase_name) { // Will put original name inside summary $xx = $messages['start_feedback']; $xx .= sprintf($messages['testcase_name_too_long'], $name_len, $fieldSizeCfg->testcase_name) . "\n"; $xx .= $messages['original_name'] . "\n" . $name . "\n" . $messages['end_warning'] . "\n"; $summary = nl2br($xx) . $summary; $name = tlSubStr($name, 0, $safeSizeCfg->testcase_name); } $kwIDs = null; if (isset($tc['keywords']) && $tc['keywords']) { $kwIDs = implode(",", buildKeywordList($kwMap, $tc['keywords'])); } $doCreate = true; if ($duplicatedLogic['actionOnHit'] == 'update_last_version') { switch ($duplicatedLogic['hitCriteria']) { case 'name': $info = $tcase_mgr->getDuplicatesByName($name, $container_id); break; case 'internalID': $dummy = $tcase_mgr->tree_manager->get_node_hierarchy_info($internalid, $container_id); if (!is_null($dummy)) { $info[$internalid] = $dummy; } break; case 'externalID': $info = $tcase_mgr->get_by_external($externalid, $container_id); break; } if (!is_null($info)) { $tcase_qty = count($info); switch ($tcase_qty) { case 1: $doCreate = false; $tcase_id = key($info); $last_version = $tcase_mgr->get_last_version_info($tcase_id, $getVersionOpt); $tcversion_id = $last_version['id']; $ret = $tcase_mgr->update($tcase_id, $tcversion_id, $name, $summary, $preconditions, $steps, $userID, $kwIDs, $node_order, $exec_type, $importance); // BUGID 3801 $ret['id'] = $tcase_id; $ret['tcversion_id'] = $tcversion_id; $resultMap[] = array($name, $messages['already_exists_updated']); break; case 0: $doCreate = true; break; default: $doCreate = false; break; } } } if ($doCreate) { $createOptions = array('check_duplicate_name' => testcase::CHECK_DUPLICATE_NAME, 'action_on_duplicate_name' => $duplicatedLogic['actionOnHit']); if ($ret = $tcase_mgr->create($container_id, $name, $summary, $preconditions, $steps, $userID, $kwIDs, $node_order, testcase::AUTOMATIC_ID, $exec_type, $importance, $createOptions)) { $resultMap[] = array($name, $ret['msg']); } } // 20090106 - franciscom // Custom Fields Management // Check if CF with this name and that can be used on Test Cases is defined in current Test Project. // If Check fails => give message to user. // Else Import CF data // $hasCustomFieldsInfo = isset($tc['customfields']) && !is_null($tc['customfields']); if ($hasCustomFieldsInfo) { new dBug($ret); if ($tprojectHas['customFields']) { // BUGID 3431 - Custom Field values at Test Case VERSION Level $msg = processCustomFields($tcase_mgr, $name, $ret['id'], $ret['tcversion_id'], $tc['customfields'], $linkedCustomFields, $feedbackMsg); if (!is_null($msg)) { $resultMap = array_merge($resultMap, $msg); } } else { // Can not import Custom Fields Values, give feedback $msg[] = array($name, $messages['cf_warning']); $resultMap = array_merge($resultMap, $msg); } } // BUGID - 20090205 - franciscom // Requirements Management // Check if Requirement ... // If Check fails => give message to user. // Else Import // $hasRequirements = isset($tc['requirements']) && !is_null($tc['requirements']); if ($hasRequirements) { if ($tprojectHas['reqSpec']) { $msg = processRequirements($db, $req_mgr, $name, $ret['id'], $tc['requirements'], $reqSpecSet, $feedbackMsg); if (!is_null($msg)) { $resultMap = array_merge($resultMap, $msg); } } else { $msg[] = array($name, $messages['reqspec_warning']); $resultMap = array_merge($resultMap, $msg); } } } return $resultMap; }