/** * Generate data for Test Specification * * @param string $spec_view_type can get one of the following values: * 'testproject','testplan','uncoveredtestcases' * * This setting change the processing done * to get the keywords. * And indicates the type of id (testproject/testplan) * contained in the argument tobj_id. * when using uncoveredtestcases tobj_id = testproject id * @param integer $tobj_id can be a testproject id, or testplan id. * @param integer $id node id, that we are using as root for the view we want to build * @param string $name * @param array $linked_items map where key=testcase_id * value map with following keys: * [testsuite_id] => 2732 * [tc_id] => 2733 * [z] => 100 ---> nodes_hierarchy.order * [name] => TC1 * [tcversion_id] => 2734 * [feature_id] => 9 --->> testplan_tcversions.ID * [execution_order] => 10 * [version] => 1 * [active] => 1 * [external_id] => 1 * [exec_id] => 1 * [tcversion_number] => 1 * [executed] => 2734 * [exec_on_tplan] => 2735 * [user_id] => * [type] => * [status] => * [assigner_id] => * [urgency] => 2 IMPORTANT: exists ONLY FOR LINKED TEST CASES * [exec_status] => b * [priority] => 4 // urgency*importance IMPORTANT: exists ONLY FOR LINKED TEST CASES * * @param array $map_node_tccount * @TODO probably this argument ($map_node_tccount) is not needed, but it will depend * of how this feature (gen_spec_view) will be used on other TL areas. * * @param map $filters keys * [keyword_id] default 0 * [tcase_id] default null, can be an array * * @param map $options keys * [write_button_only_if_linked] default 0 * [prune_unlinked_tcversions]: default 0. * Useful when working on spec_view_type='testplan'. * 1 -> will return only linked tcversion * 0 -> returns all test cases specs. * [add_custom_fields]: default=0 * useful when working on spec_view_type='testproject' * when doing test case assign to test plans. * 1 -> for every test case cfields of area 'testplan_design' * will be fetched and displayed. * 0 -> do nothing * * [$tproject_id]: default = null * useful to improve performance in custom field method calls * when add_custom_fields=1. * * * @return array every element is an associative array with the following * structure: (to get last updated info add debug code and print_r returned value) * [testsuite] => Array( [id] => 28 * [name] => TS1 ) * [testcases] => Array( [2736] => Array * ( * [id] => 2736 * [name] => TC2 * [tcversions] => Array * ( * [2738] => 2 // key=tcversion id,value=version * [2737] => 1 * ) * [tcversions_active_status] => Array * ( * [2738] => 1 // key=tcversion id,value=active status * [2737] => 1 * ) * [tcversions_execution_type] => Array * ( * [2738] => 1 * [2737] => 2 * ) * [tcversions_qty] => 2 * [linked_version_id] => 2737 * [executed] => no * [user_id] => 0 ---> !=0 if execution has been assigned * [feature_id] => 12 ---> testplan_tcversions.id * [execution_order] => 20 * [external_id] => 2 * [linked_ts] => 2009-06-10 23:00 * [linked_by] => 2 * [priority] => HIGH, MEDIUM or LOW * ) * [81] => Array( [id] => 81 * [name] => TC88) * ... * ) * [level] = * [write_buttons] => yes or no * level and write_buttons are used to generate the user interface * * Warning: * if the root element of the spec_view, has 0 test => then the default * structure is returned ( $result = array('spec_view'=>array(), 'num_tc' => 0)) * * @internal Revisions: * * 20100721 - asimon - BUGID 3406 - added user_assignments_per_build to options * * 20090808 - franciscom - changed interface to reduce number of arguments * * 20070707 - franciscom - BUGID 921 - problems with display order in execution screen * 20070630 - franciscom - added new logic to include in for inactive test cases, testcase version id. * This is needed to show testcases linked to testplans, but after be linked to * test plan, has been set to inactive on test project. * 20061105 - franciscom - added new data on output: [tcversions_qty] * used in the logic to filter out inactive tcversions, * and inactive test cases. * Counts the quantity of active versions of a test case. * If 0 => test case is considered INACTIVE * 20090625 - Eloff - added priority output */ function gen_spec_view(&$db, $spec_view_type = 'testproject', $tobj_id, $id, $name, &$linked_items, $map_node_tccount, $filters = null, $options = null, $tproject_id = null) { $out = array(); $result = array('spec_view' => array(), 'num_tc' => 0, 'has_linked_items' => 0); $my = array(); $my['options'] = array('write_button_only_if_linked' => 0, 'prune_unlinked_tcversions' => 0, 'add_custom_fields' => 0) + (array) $options; // BUGID 2797 - filter by test case execution type $my['filters'] = array('keywords' => 0, 'testcases' => null, 'exec_type' => null, 'importance' => null); foreach ($my as $key => $settings) { if (!is_null(${$key}) && is_array(${$key})) { $my[$key] = array_merge($my[$key], ${$key}); } } $write_status = $my['options']['write_button_only_if_linked'] ? 'no' : 'yes'; $is_tplan_view_type = $spec_view_type == 'testplan' ? 1 : 0; $is_uncovered_view_type = $spec_view_type == 'uncoveredtestcases' ? 1 : 0; if (!$is_tplan_view_type && is_null($tproject_id)) { $tproject_id = $tobj_id; } $testplan_id = $is_tplan_view_type ? $tobj_id : null; $tcase_mgr = new testcase($db); $hash_descr_id = $tcase_mgr->tree_manager->get_available_node_types(); $hash_id_descr = array_flip($hash_descr_id); // BUGID 2797 - filter by test case execution type $pfFilters = array('keyword_id' => $my['filters']['keywords'], 'tcase_id' => $my['filters']['testcases'], 'tcase_node_type_id' => $hash_descr_id['testcase'], 'execution_type' => $my['filters']['exec_type'], 'importance' => $my['filters']['importance']); // $test_spec = getTestSpecFromNode($db,$tcase_mgr,$linked_items,$tobj_id,$id,$spec_view_type,$filters); $test_spec = getTestSpecFromNode($db, $tcase_mgr, $linked_items, $tobj_id, $id, $spec_view_type, $pfFilters); $platforms = getPlatforms($db, $tproject_id, $testplan_id); $idx = 0; $a_tcid = array(); $a_tsuite_idx = array(); if (count($test_spec)) { $cfg = array('node_types' => $hash_id_descr, 'write_status' => $write_status, 'is_uncovered_view_type' => $is_uncovered_view_type); list($a_tcid, $a_tsuite_idx, $tsuite_tcqty, $out) = buildSkeleton($id, $name, $cfg, $test_spec, $platforms); } // This code has been replace (see below on Remove empty branches) // Once we have created array with testsuite and children testsuites // we are trying to remove nodes that has 0 test case count. // May be this can be done (as noted by schlundus during performance // analisys done on october 2008) in a better way, or better can be absolutely avoided. // // This process is needed to prune whole branches that are empty // Need to look for every call in TL and understand if this can be removed // if (!is_null($map_node_tccount)) { foreach ($out as $key => $elem) { if (isset($map_node_tccount[$elem['testsuite']['id']]) && $map_node_tccount[$elem['testsuite']['id']]['testcount'] == 0) { // why not unset ? $out[$key] = null; } } } // Collect information related to linked testcase versions if (!is_null($out) && count($out) > 0 && !is_null($out[0]) && count($a_tcid)) { $tcaseSet = $tcase_mgr->get_by_id($a_tcid, testcase::ALL_VERSIONS); $result = addLinkedVersionsInfo($tcaseSet, $a_tsuite_idx, $out, $linked_items); } // Try to prune empty test suites, to reduce memory usage and to remove elements // that do not need to be displayed on user interface. if (count($result['spec_view']) > 0) { removeEmptyTestSuites($result['spec_view'], $tcase_mgr->tree_manager, $my['options']['prune_unlinked_tcversions'] && $is_tplan_view_type, $hash_descr_id); } // Remove empty branches // Loop to compute test case qty ($tsuite_tcqty) on every level and prune test suite branchs that are empty if (count($result['spec_view']) > 0) { removeEmptyBranches($result['spec_view'], $tsuite_tcqty); } /** @TODO: maybe we can integrate this into already present loops above? */ // This is not right condition for identifing an empty test suite for the porpouse // of gen_spec_view(), because for following structure // TS1 // \--- TS2 // \--TC1 // \--TC2 // // \--- TS3 // \-- TXX // // When we are displaying a Test Specification we want to see previous structure // But if we apply this criteria for empty test suite, TS1 results empty and will // be removed -> WRONG // // Need to understand when this feature will be needed and then reimplement // // if ($prune_empty_tsuites) // { // foreach($result['spec_view'] as $key => $value) // { // if(is_null($value) || !isset($value['testcases']) || !count($value['testcases'])) // unset($result['spec_view'][$key]); // } // } // #1650 We want to manage custom fields when user is doing test case execution assigment if (count($result['spec_view']) > 0 && $my['options']['add_custom_fields']) { addCustomFieldsToView($result['spec_view'], $tproject_id, $tcase_mgr); } // -------------------------------------------------------------------------------------------- unset($tcase_mgr); // with array_values() we reindex array to avoid "holes" $result['spec_view'] = array_values($result['spec_view']); return $result; }
/** * */ function genSpecViewFlat(&$db, $spec_view_type = 'testproject', $tobj_id, $id, $name, &$linked_items, $map_node_tccount, $filters = null, $options = null, $tproject_id = null) { $out = array(); $result = array('spec_view' => array(), 'num_tc' => 0, 'has_linked_items' => 0); $my = array(); $my['options'] = array('write_button_only_if_linked' => 0, 'prune_unlinked_tcversions' => 0, 'add_custom_fields' => 0) + (array) $options; $my['filters'] = array('keywords' => 0, 'testcases' => null, 'exec_type' => null, 'importance' => null, 'cfields' => null); foreach ($my as $key => $settings) { if (!is_null(${$key}) && is_array(${$key})) { $my[$key] = array_merge($my[$key], ${$key}); } } $write_status = $my['options']['write_button_only_if_linked'] ? 'no' : 'yes'; $is_tplan_view_type = $spec_view_type == 'testplan' ? 1 : 0; $is_uncovered_view_type = $spec_view_type == 'uncoveredtestcases' ? 1 : 0; if (!$is_tplan_view_type && is_null($tproject_id)) { $tproject_id = $tobj_id; } $testplan_id = $is_tplan_view_type ? $tobj_id : null; $tcase_mgr = new testcase($db); $hash_descr_id = $tcase_mgr->tree_manager->get_available_node_types(); $hash_id_descr = array_flip($hash_descr_id); $key2map = array('keyword_id' => 'keywords', 'tcase_id' => 'testcases', 'execution_type' => 'exec_type', 'importance' => 'importance', 'cfields' => 'cfields', 'tcase_name' => 'tcase_name', 'status' => 'workflow_status'); $pfFilters = array('tcase_node_type_id' => $hash_descr_id['testcase']); foreach ($key2map as $tk => $fk) { $pfFilters[$tk] = isset($my['filters'][$fk]) ? $my['filters'][$fk] : null; } $test_spec = getTestSpecFromNode($db, $tcase_mgr, $linked_items, $tobj_id, $id, $spec_view_type, $pfFilters); $platforms = getPlatforms($db, $tproject_id, $testplan_id); $idx = 0; $a_tcid = array(); $a_tsuite_idx = array(); if (count($test_spec)) { $cfg = array('node_types' => $hash_id_descr, 'write_status' => $write_status, 'is_uncovered_view_type' => $is_uncovered_view_type); // $a_tsuite_idx // key: test case version id // value: index inside $out, where parent test suite of test case version id is located. // list($a_tcid, $a_tsuite_idx, $tsuite_tcqty, $out) = buildSkeletonFlat($id, $name, $cfg, $test_spec, $platforms); } // Collect information related to linked testcase versions // DAMMED 0!!!! $firtsElemIDX = key($out); if (!is_null($out) && count($out) > 0 && !is_null($out[$firtsElemIDX]) && count($a_tcid)) { $optGBI = array('output' => 'full_without_users', 'order_by' => " ORDER BY NHTC.node_order, NHTC.name, TCV.version DESC "); $tcaseVersionSet = $tcase_mgr->get_by_id($a_tcid, testcase::ALL_VERSIONS, null, $optGBI); $result = addLinkedVersionsInfo($tcaseVersionSet, $a_tsuite_idx, $out, $linked_items, $options); } if (count($result['spec_view']) > 0 && $my['options']['add_custom_fields']) { addCustomFieldsToView($result['spec_view'], $tproject_id, $tcase_mgr); } // -------------------------------------------------------------------------------------------- unset($tcase_mgr); // with array_values() we reindex array to avoid "holes" $result['spec_view'] = array_values($result['spec_view']); return $result; }