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;
 }
Example #3
0
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;
}