Example #1
0
/**
 * 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;
}