/** * Creates data for tree menu used on : * - Execution of Test Cases * - Remove Test cases from test plan * * @internal Revisions: * * 20101003 - franciscom - added option remove_empty_nodes_of_type on get_subtree() call * 20100820 - asimon - refactoring for less redundant checks and better readibility * 20100719 - asimon - BUGID 3406 - user assignments per build: * filter assigned test cases by setting_build * 20080617 - franciscom - return type changed to use extjs tree component * 20080305 - franciscom - interface refactoring * 20080224 - franciscom - added include_unassigned * 20071002 - jbarchibald - BUGID 1051 - added cf element to parameter list * 20070204 - franciscom - changed $bForPrinting -> $bHideTCs */ function generateExecTree(&$db, &$menuUrl, $tproject_id, $tproject_name, $tplan_id, $tplan_name, $filters, $additionalInfo) { $treeMenu = new stdClass(); $treeMenu->rootnode = null; $treeMenu->menustring = ''; $resultsCfg = config_get('results'); $showTestCaseID = config_get('treemenu_show_testcase_id'); $glueChar = config_get('testcase_cfg')->glue_character; $menustring = null; $any_exec_status = null; $tplan_tcases = null; $tck_map = null; $idx = 0; $testCaseQty = 0; $testCaseSet = null; $keyword_id = 0; $keywordsFilterType = 'Or'; if (property_exists($filters, 'filter_keywords') && !is_null($filters->{'filter_keywords'})) { $keyword_id = $filters->{'filter_keywords'}; $keywordsFilterType = $filters->{'filter_keywords_filter_type'}; } // BUGID 3406 - user assignments per build // can't use $build_id here because we need the build ID from settings panel $build2filter_assignments = isset($filters->{'setting_build'}) ? $filters->{'setting_build'} : 0; $tc_id = isset($filters->filter_tc_id) ? $filters->filter_tc_id : null; $build_id = isset($filters->filter_result_build) ? $filters->filter_result_build : null; $bHideTCs = isset($filters->hide_testcases) ? $filters->hide_testcases : false; $assignedTo = isset($filters->filter_assigned_user) ? $filters->filter_assigned_user : null; $include_unassigned = isset($filters->filter_assigned_user_include_unassigned) ? $filters->filter_assigned_user_include_unassigned : false; $setting_platform = isset($filters->setting_platform) ? $filters->setting_platform : null; $execution_type = isset($filters->filter_execution_type) ? $filters->filter_execution_type : null; $status = isset($filters->filter_result_result) ? $filters->filter_result_result : null; $cf_hash = isset($filters->filter_custom_fields) ? $filters->filter_custom_fields : null; $show_testsuite_contents = isset($filters->show_testsuite_contents) ? $filters->show_testsuite_contents : true; $urgencyImportance = isset($filters->filter_priority) ? $filters->filter_priority : null; $useCounters = isset($additionalInfo->useCounters) ? $additionalInfo->useCounters : null; $useColors = isset($additionalInfo->useColours) ? $additionalInfo->useColours : null; $colorBySelectedBuild = isset($additionalInfo->testcases_colouring_by_selected_build) ? $additionalInfo->testcases_colouring_by_selected_build : null; $tplan_mgr = new testplan($db); $tproject_mgr = new testproject($db); $tcase_mgr = new testcase($db); $tree_manager = $tplan_mgr->tree_manager; $tcase_node_type = $tree_manager->node_descr_id['testcase']; $hash_descr_id = $tree_manager->get_available_node_types(); $hash_id_descr = array_flip($hash_descr_id); $decoding_hash = array('node_id_descr' => $hash_id_descr, 'status_descr_code' => $resultsCfg['status_code'], 'status_code_descr' => $resultsCfg['code_status']); $tcase_prefix = $tproject_mgr->getTestCasePrefix($tproject_id) . $glueChar; $nt2exclude = array('testplan' => 'exclude_me', 'requirement_spec' => 'exclude_me', 'requirement' => 'exclude_me'); $nt2exclude_children = array('testcase' => 'exclude_my_children', 'requirement_spec' => 'exclude_my_children'); // 20101003 - franciscom // remove test spec, test suites (or branches) that have ZERO test cases linked to test plan // // IMPORTANT: // using 'order_cfg' => array("type" =>'exec_order',"tplan_id" => $tplan_id)) // makes the magic of ignoring test cases not linked to test plan. // This unexpected bonus can be useful on export test plan as XML. // $my['options'] = array('recursive' => true, 'remove_empty_nodes_of_type' => $tree_manager->node_descr_id['testsuite'], 'order_cfg' => array("type" => 'exec_order', "tplan_id" => $tplan_id)); $my['filters'] = array('exclude_node_types' => $nt2exclude, 'exclude_children_of' => $nt2exclude_children); // BUGID 3301 - added for filtering by toplevel testsuite if (isset($filters->{'filter_toplevel_testsuite'}) && is_array($filters->{'filter_toplevel_testsuite'})) { $my['filters']['exclude_branches'] = $filters->{'filter_toplevel_testsuite'}; } $test_spec = $tree_manager->get_subtree($tproject_id, $my['filters'], $my['options']); $test_spec['name'] = $tproject_name . " / " . $tplan_name; // To be discussed $test_spec['id'] = $tproject_id; $test_spec['node_type_id'] = $hash_descr_id['testproject']; $map_node_tccount = array(); $tplan_tcases = null; $apply_other_filters = true; if ($test_spec) { if (is_null($tc_id) || $tc_id >= 0) { $doFilterByKeyword = !is_null($keyword_id) && $keyword_id > 0; if ($doFilterByKeyword) { $tck_map = $tproject_mgr->get_keywords_tcases($tproject_id, $keyword_id, $keywordsFilterType); } // Multiple step algoritm to apply keyword filter on type=AND // get_linked_tcversions filters by keyword ALWAYS in OR mode. // BUGID 3406: user assignments per build $opt = array('include_unassigned' => $include_unassigned, 'steps_info' => false, 'user_assignments_per_build' => $build2filter_assignments); // 20100417 - BUGID 3380 - execution type $linkedFilters = array('tcase_id' => $tc_id, 'keyword_id' => $keyword_id, 'assigned_to' => $assignedTo, 'cf_hash' => $cf_hash, 'platform_id' => $setting_platform, 'urgencyImportance' => $urgencyImportance, 'exec_type' => $execution_type); $tplan_tcases = $tplan_mgr->get_linked_tcversions($tplan_id, $linkedFilters, $opt); // BUGID 3814: fixed keyword filtering with "and" selected as type if ($tplan_tcases && $doFilterByKeyword && $keywordsFilterType == 'And') { $filteredSet = $tcase_mgr->filterByKeyword(array_keys($tplan_tcases), $keyword_id, $keywordsFilterType); // CAUTION: if $filteredSet is null, // then get_linked_tcversions() thinks there are just no filters set, // but really there are no testcases which match the wanted keyword criteria, // so we have to set $tplan_tcases to null because there is no more filtering necessary if ($filteredSet != null) { $linkedFilters = array('tcase_id' => array_keys($filteredSet)); $tplan_tcases = $tplan_mgr->get_linked_tcversions($tplan_id, $linkedFilters); } else { $tplan_tcases = null; } } } if (is_null($tplan_tcases)) { $tplan_tcases = array(); $apply_other_filters = false; } $filter_methods = config_get('execution_filter_methods'); // 20100820 - asimon - refactoring for less redundant checks and better readibility $ffn = array($filter_methods['status_code']['any_build'] => 'filter_by_status_for_any_build', $filter_methods['status_code']['all_builds'] => 'filter_by_same_status_for_all_builds', $filter_methods['status_code']['specific_build'] => 'filter_by_status_for_build', $filter_methods['status_code']['current_build'] => 'filter_by_status_for_build', $filter_methods['status_code']['latest_execution'] => 'filter_by_status_for_last_execution'); $requested_filter_method = isset($filters->filter_result_method) ? $filters->filter_result_method : null; $requested_filter_result = isset($filters->filter_result_result) ? $filters->filter_result_result : null; // if "any" was selected as filtering status, don't filter by status $requested_filter_result = (array) $requested_filter_result; if (in_array($resultsCfg['status_code']['all'], $requested_filter_result)) { $requested_filter_result = null; } if ($apply_other_filters && !is_null($requested_filter_method) && isset($ffn[$requested_filter_method])) { // special case 1: when filtering by "not run" status in any build, // we need another filter function if (in_array($resultsCfg['status_code']['not_run'], $requested_filter_result)) { $ffn[$filter_methods['status_code']['any_build']] = 'filter_not_run_for_any_build'; } // special case 2: when filtering by "current build", we set the build to filter with // to the build chosen in settings instead of the one in filters if ($requested_filter_method == $filter_methods['status_code']['current_build']) { $filters->filter_result_build = $filters->setting_build; } // call the filter function and do the filtering $tplan_tcases = $ffn[$requested_filter_method]($tplan_mgr, $tplan_tcases, $tplan_id, $filters); if (is_null($tplan_tcases)) { $tplan_tcases = array(); $apply_other_filters = false; } } // end 20100820 refactoring // BUGID 3450 - Change colors/counters in exec tree. // Means: replace exec status in filtered array $tplan_tcases // by the one of last execution of selected build. // Since this changes exec status, replacing is done after filtering by status. // It has to be done before call to prepareNode() though, // because that one sets the counters according to status. if ($useColors && $colorBySelectedBuild) { $tables = tlObject::getDBTables('executions'); foreach ($tplan_tcases as $id => $info) { // get last execution result for selected build $sql = " SELECT status FROM {$tables['executions']} E " . " WHERE tcversion_id = {$info['tcversion_id']} " . " AND testplan_id = {$tplan_id} " . " AND platform_id = {$info['platform_id']} " . " AND build_id = {$filters->setting_build} " . " ORDER BY execution_ts DESC "; // BUGID 3772: MS SQL - LIMIT CLAUSE can not be used // get_recordset($sql,$fetch_mode = null,$limit = -1) $result = null; $rs = $db->get_recordset($sql, null, 1); if (!is_null($rs)) { $result = $rs[0]['status']; } if (is_null($result)) { // if no value can be loaded it has to be set to not run $result = $resultsCfg['status_code']['not_run']; } if ($result != $info['exec_status']) { $tplan_tcases[$id]['exec_status'] = $result; } } } // 20080224 - franciscom - // After reviewing code, seems that assignedTo has no sense because tp_tcs // has been filtered. // Then to avoid changes to prepareNode() due to include_unassigned, // seems enough to set assignedTo to 0, if include_unassigned==true $assignedTo = $include_unassigned ? null : $assignedTo; $pnFilters = array('assignedTo' => $assignedTo); $keys2init = array('filter_testcase_name', 'filter_execution_type', 'filter_priority'); foreach ($keys2init as $keyname) { $pnFilters[$keyname] = isset($filters->{$keyname}) ? $filters->{$keyname} : null; } // 20100412 - franciscom $pnOptions = array('hideTestCases' => $bHideTCs, 'viewType' => 'executionTree'); $testcase_counters = prepareNode($db, $test_spec, $decoding_hash, $map_node_tccount, $tck_map, $tplan_tcases, $pnFilters, $pnOptions); foreach ($testcase_counters as $key => $value) { $test_spec[$key] = $testcase_counters[$key]; } // BUGID 3516 // can now be left in form of array, will not be sent by URL anymore //$keys = implode(array_keys($tplan_tcases), ","); $keys = array_keys($tplan_tcases); $menustring = renderExecTreeNode(1, $test_spec, $tplan_tcases, $hash_id_descr, 1, $menuUrl, $bHideTCs, $useCounters, $useColors, $showTestCaseID, $tcase_prefix, $show_testsuite_contents); } // if($test_spec) $treeMenu->rootnode = new stdClass(); $treeMenu->rootnode->name = $test_spec['text']; $treeMenu->rootnode->id = $test_spec['id']; $treeMenu->rootnode->leaf = $test_spec['leaf']; $treeMenu->rootnode->text = $test_spec['text']; $treeMenu->rootnode->position = $test_spec['position']; $treeMenu->rootnode->href = $test_spec['href']; if (!is_null($menustring)) { // Change key ('childNodes') to the one required by Ext JS tree. $menustring = str_ireplace('childNodes', 'children', json_encode($test_spec['childNodes'])); // Remove null elements (Ext JS tree do not like it ). // :null happens on -> "children":null,"text" that must become "children":[],"text" // $menustring = str_ireplace(array(':null',',null','null,'),array(':[]','',''), $menustring); $menustring = str_ireplace(array(':null', ',null', 'null,', 'null'), array(':[]', '', '', ''), $menustring); } $treeMenu->menustring = $menustring; return array($treeMenu, $keys); }
/** * * * * */ function getTPlanTCases4ExecTree(&$dbHandler, &$tprojectMgr, &$tplanMgr, $enviro, $filters) { $tcaseMgr = new testcase($dbHandler); $tplan_tcases = null; $tck_map = null; if ($doFilterByKeyword = !is_null($filters->filter_keywords) && $filters->filter_keywords > 0) { $tck_map = $tprojectMgr->get_keywords_tcases($enviro['tproject_id'], $filters->filter_keywords, $filters->filter_keywords_filter_type); } // Multiple step algoritm to apply keyword filter on type=AND // get_linked_tcversions filters by keyword ALWAYS in OR mode. // // TICKET 4790: Setting & Filters panel - Wrong use of BUILD on settings area $opt = array('steps_info' => false, 'include_unassigned' => $filters->filter_assigned_user_include_unassigned, 'user_assignments_per_build' => $filters->user_assignments_per_build); $linkedFilters = array('tcase_id' => $filters->filter_tc_id, 'keyword_id' => $filters->filter_keywords, 'assigned_to' => $filters->filter_assigned_user, 'cf_hash' => $filters->filter_custom_fields, 'platform_id' => $filters->setting_platform, 'urgencyImportance' => $filters->filter_priority, 'exec_type' => $filters->filter_execution_type); $tplan_tcases = $tplanMgr->get_linked_tcversions($enviro['tplan_id'], $linkedFilters, $opt); // BUGID 3814: fixed keyword filtering with "and" selected as type if ($tplan_tcases && $doFilterByKeyword && $filters->filter_keywords_filter_type == 'And') { $filteredSet = $tcaseMgr->filterByKeyword(array_keys($tplan_tcases), $filters->filter_keywords, $filters->filter_keywords_filter_type); // CAUTION: // if $filteredSet is null, then get_linked_tcversions() thinks there are just no filters set, // but really there are no testcases which match the wanted keyword criteria, // so we have to set $tplan_tcases to null because there is no more filtering necessary $tplan_tcases = null; if ($filteredSet != null) { $tplan_tcases = $tplanMgr->get_linked_tcversions($enviro['tplan_id'], array('tcase_id' => array_keys($filteredSet))); } } return array($tplan_tcases, $tck_map); }