diff --git a/lib/api/xmlrpc/v1/APIErrors.php b/lib/api/xmlrpc/v1/APIErrors.php index 324e1f4fd3..02c703a441 100644 --- a/lib/api/xmlrpc/v1/APIErrors.php +++ b/lib/api/xmlrpc/v1/APIErrors.php @@ -76,6 +76,9 @@ define('PARAMETER_NOT_INT',210); define('PARAMETER_NOT_INT_STR', lang_get('API_PARAMETER_NOT_INT',null,1)); +define('ILLEGAL_PARAMETER_VALUE',211); +define('ILLEGAL_PARAMETER_VALUE_STR', lang_get('API_ILLEGAL_PARAMETER_VALUE',null,1)); + define('NO_TESTSUITENAME', 220); define('NO_TESTSUITENAME_STR', lang_get('API_NO_TESTSUITENAME',null,1)); @@ -363,3 +366,4 @@ */ define('ITS_NOT_FOUND',13000); define('ITS_NOT_FOUND_STR', lang_get('API_ITS_NOT_FOUND',null,1)); + diff --git a/lib/api/xmlrpc/v1/xmlrpc.class.php b/lib/api/xmlrpc/v1/xmlrpc.class.php index 157d98f9b4..a1f4456cec 100644 --- a/lib/api/xmlrpc/v1/xmlrpc.class.php +++ b/lib/api/xmlrpc/v1/xmlrpc.class.php @@ -3348,6 +3348,249 @@ public function addTestCaseToTestPlan($args) { return($status_ok ? $op_result : $this->errors); } + /** + * Return test plan item params "executionorder" (positive integer as specifed in test plan) and "urgency" (1:low, 2:med, 3:high) + * + * @param + * args['testprojectid'] + * @param + * args['testplanid'] + * @param + * args['testcaseexternalid'] + * @param + * args['version'] + * @param + * args['platformid'] - OPTIONAL Only if test plan has no platforms + */ + public function getTestPlanItemParams($args) { + $operation = __FUNCTION__; + $msg_prefix = "({$operation}) - "; + $this->_setArgs( $args ); + + $op_result = null; + $hasPlatforms = false; + $hasPlatformIDArgs = false; + $platform_id = 0; + $checkFunctions = array( + 'authenticate', + 'checkTestProjectID', + 'checkTestCaseVersionNumber', + 'checkTestCaseIdentity', + 'checkTestPlanID' + ); + + $status_ok = $this->_runChecks( $checkFunctions, $messagePrefix ); + + // Test Plan belongs to test project ? + if($status_ok) { + $tproject_id = $this->args[self::$testProjectIDParamName]; + $tplan_id = $this->args[self::$testPlanIDParamName]; + $tplan_info = $this->tplanMgr->get_by_id( $tplan_id ); + + $sql = " SELECT id FROM {$this->tables['testplans']}" . " WHERE testproject_id={$tproject_id} AND id = {$tplan_id}"; + + $rs = $this->dbObj->get_recordset( $sql ); + + if(count( $rs ) != 1) { + $status_ok = false; + $tproject_info = $this->tprojectMgr->get_by_id( $tproject_id ); + $msg = sprintf( TPLAN_TPROJECT_KO_STR, $tplan_info['name'], $tplan_id, $tproject_info['name'], $tproject_id ); + $this->errors[] = new IXR_Error( TPLAN_TPROJECT_KO, $msg_prefix . $msg ); + } + } + + // Test Case belongs to test project ? + if($status_ok) { + $ret = $this->checkTestCaseAncestry(); + $status_ok = $ret['status_ok']; + + if(! $ret['status_ok']) { + $this->errors[] = new IXR_Error( $ret['error_code'], $msg_prefix . $ret['error_msg'] ); + } + } + + // Does this Version number exist for this test case ? + if($status_ok) { + $tcase_id = $this->args[self::$testCaseIDParamName]; + $version_number = $this->args[self::$versionNumberParamName]; + $sql = " SELECT TCV.version,TCV.id " . " FROM {$this->tables['nodes_hierarchy']} NH, {$this->tables['tcversions']} TCV " . " WHERE NH.parent_id = {$tcase_id} " . " AND TCV.version = {$version_number} " . " AND TCV.id = NH.id "; + $target_tcversion = $this->dbObj->fetchRowsIntoMap( $sql, 'version' ); + + if(is_null( $target_tcversion ) || count( $target_tcversion ) != 1) { + $status_ok = false; + $tcase_info = $this->tcaseMgr->get_by_id( $tcase_id ); + $msg = sprintf( TCASE_VERSION_NUMBER_KO_STR, $version_number, $tcase_external_id, $tcase_info[0]['name'] ); + $this->errors[] = new IXR_Error( TCASE_VERSION_NUMBER_KO, $msg_prefix . $msg ); + } + } + + if( $status_ok ) { + $opt = array( + 'outputFormat' => 'mapAccessByID' + ); + $platformSet = $this->tplanMgr->getPlatforms( $tplan_id, $opt ); + $hasPlatforms = ! is_null( $platformSet ); + $hasPlatformIDArgs = $this->_isParamPresent( self::$platformIDParamName ); + if($hasPlatforms) { + if($hasPlatformIDArgs) { + // Check if platform id belongs to test plan + $platform_id = $this->args[self::$platformIDParamName]; + $status_ok = isset( $platformSet[$platform_id] ); + if(! $status_ok) { + $msg = sprintf( PLATFORM_ID_NOT_LINKED_TO_TESTPLAN_STR, $platform_id, $tplan_info['name'] ); + $this->errors[] = new IXR_Error( PLATFORM_ID_NOT_LINKED_TO_TESTPLAN, $msg ); + } + } else { + $msg = sprintf( MISSING_PLATFORMID_BUT_NEEDED_STR, $tplan_info['name'], $tplan_id ); + $this->errors[] = new IXR_Error( MISSING_PLATFORMID_BUT_NEEDED, $msg_prefix . $msg ); + $status_ok = false; + } + } else { + if($hasPlatformIDArgs) { + // test plan has no platforms, but platform specified + $platform_id = $this->args[self::$platformIDParamName]; + $msg = sprintf( PLATFORM_ID_NOT_LINKED_TO_TESTPLAN_STR, $platform_id, $tplan_info['name'] ); + $this->errors[] = new IXR_Error( PLATFORM_ID_NOT_LINKED_TO_TESTPLAN, $msg ); + $status_ok = false; + } + } + } + + if( $status_ok) { + $sql = "SELECT TPV.id, TPV.node_order, TPV.urgency FROM {$this->tables['nodes_hierarchy']} NH, {$this->tables['tcversions']} TCV, {$this->tables['testplan_tcversions']} TPV WHERE NH.parent_id = {$tcase_id} AND TCV.version = {$version_number} AND TPV.tcversion_id = TCV.id AND testplan_id = {$tplan_id} AND TCV.id = NH.id"; + if( $hasPlatforms ) { + $sql .= " AND platform_id=" . intval( $platform_id ); + } + + $res = $this->dbObj->get_recordset( $sql ); + + if( is_null( $res ) || count( $res ) != 1) { + $status_ok = false; + $tcase_id = $this->args[self::$testCaseIDParamName]; + $version_number = $this->args[self::$versionNumberParamName]; + $tcase_external_id = $this->tcaseMgr->getExternalID( $tcase_id )[0]; + $msg = sprintf( TCVERSIONID_NOT_IN_TPLANID_STR, $tcase_id, $tcase_external_id, $tplan_info['name'], $tplan_id ); + $this->errors[] = new IXR_Error( TCVERSIONID_NOT_IN_TPLANID, $msg_prefix . $msg ); + } else { + $data = array( + "executionorder" => $res[0]['node_order'], + "urgency" => $res[0]['urgency'], + "id" => $res[0]['id'] + ); + } + } + + return($status_ok ? $data : $this->errors); + } + + /** + * Set test plan item params + * + * @param + * args['testprojectid'] + * @param + * args['testplanid'] + * @param + * args['testcaseexternalid'] + * @param + * args['version'] + * @param + * args['platformid'] - OPTIONAL Only if test plan has no platforms + * @param + * args['executionorder'] positive integer - OPTIONAL only if urgency is given + * @param + * args['urgency'] 1:low, 2:med, 3:high - OPTIONAL only if executionorder is given + */ + public function setTestPlanItemParams($args) { + $operation = __FUNCTION__; + $msg_prefix = "({$operation}) - "; + $this->_setArgs( $args ); + + $checkFunctions = array( + 'authenticate', + 'checkTestProjectID', + 'checkTestCaseVersionNumber', + 'checkTestCaseIdentity', + 'checkTestPlanID' + ); + + $status_ok = $this->_runChecks( $checkFunctions, $messagePrefix ); + + $urgency = $this->args[self::$urgencyParamName]; + $executionOrder = $this->args[self::$executionOrderParamName]; + + $updateOrder = ! is_null($executionOrder); + $updateUrgency = ! is_null($urgency); + + if( ! $updateOrder && ! $updateUrgency){ + $status_ok = false; + $msg = sprintf( MISSING_REQUIRED_PARAMETER_STR, '"urgency" AND/OR "executionOrder"' ); + $this->errors[] = new IXR_Error( MISSING_REQUIRED_PARAMETER, $msg_prefix . $msg ); + } + + if( $updateOrder && (! is_int($executionOrder) || $executionOrder < 0 )) { + $status_ok = false; + $msg = sprintf( PARAMETER_NOT_INT_STR, '"executionOrder"', $executionOrder ); + $this->errors[] = new IXR_Error( PARAMETER_NOT_INT, $msg_prefix . $msg ); + } + + if( $updateUrgency && (! in_array($urgency, array(1,2,3)))) { + $status_ok = false; + $msg = sprintf( ILLEGAL_PARAMETER_VALUE_STR, '"urgency"', '[1, 2, 3]', $urgency ); + $this->errors[] = new IXR_Error( ILLEGAL_PARAMETER_VALUE, $msg_prefix . $msg ); + } + + if( $status_ok ) { + $act = self::getTestPlanItemParams($args); + if( count($this->errors) ) { + $status_ok = false; + } + } + + if( $status_ok ) { + if(! $this->userHasRight( "testplan_planning", self::CHECK_PUBLIC_PRIVATE_ATTR )) { + $status_ok = false; + $msg = sprintf( INSUFFICIENT_RIGHTS_STR ); + $this->errors[] = new IXR_Error( INSUFFICIENT_RIGHTS, $msg_prefix . $msg ); + } + } + + if( $status_ok ){ + $tp_tcvers_id = $act['id']; + $act_executionorder = $act['executionorder']; + $act_urgency = $act['urgency']; + + $sql = "UPDATE {$this->tables['testplan_tcversions']} TPV SET"; + + $update = false; + if( $updateOrder && $act_executionorder != $executionOrder){ + $sql .= " node_order = {intval($executionOrder)}"; + $update = true; + } + if( $updateUrgency && $act_urgency != $urgency){ + if( $update ){ + $sql .= " ,"; + } + $sql .= " urgency = {intval($urgency)}"; + $update = true; + } + + if( $update ) { + $sql .= " WHERE TPV.id = {$tp_tcvers_id}"; + $this->dbObj->exec_query( $sql ); + $op_result['operation'] = $operation; + $op_result['status'] = true; + $op_result['message'] = 'Update done.'; + } else { + $op_result['operation'] = $operation; + $op_result['status'] = true; + $op_result['message'] = 'Already matching.'; + } + } + + return($status_ok ? $op_result : $this->errors); + } + /** * get set of test suites AT TOP LEVEL of tree on a Test Project * @@ -8312,6 +8555,8 @@ function initMethodYellowPages() { 'tl.uploadAttachment' => 'this:uploadAttachment', 'tl.assignRequirements' => 'this:assignRequirements', 'tl.addTestCaseToTestPlan' => 'this:addTestCaseToTestPlan', + 'tl.getTestPlanItemParams' => 'this:getTestPlanItemParams', + 'tl.setTestPlanItemParams' => 'this:setTestPlanItemParams', 'tl.addPlatformToTestPlan' => 'this:addPlatformToTestPlan', 'tl.removePlatformFromTestPlan' => 'this:removePlatformFromTestPlan', 'tl.getExecCountersByBuild' => 'this:getExecCountersByBuild', @@ -8378,3 +8623,4 @@ function initMethodYellowPages() { ); } } // class end + diff --git a/locale/de_DE/strings.txt b/locale/de_DE/strings.txt index 973f54869e..86fd55e6c6 100644 --- a/locale/de_DE/strings.txt +++ b/locale/de_DE/strings.txt @@ -3146,6 +3146,7 @@ $TLS_API_MISSING_REQUIRED_PARAMETER = "Parameter %s ist angefordert, aber nicht $TLS_API_INVALID_TESTCASE_VERSION_NUMBER="Die Angeforderte Versionsnummer existiert nicht für Testfall"; $TLS_API_PARAMETER_NOT_INT = "Parameter (%s) sollte ein Integer sein (current value: %s)."; +$TLS_API_ILLEGAL_PARAMETER_VALUE = "Parameter (%s) muss enthalten sein in (%s) (aktueller Wert: %s)."; $TLS_API_TPLAN_TPROJECT_KO="Test Plan (name=%s / id=%s) gehört nicht zu dem Test Projekt (name=%s / id=%s)"; $TLS_API_TCASE_TPROJECT_KO="Testfall (%s:%s) gehört nicht zu dem Test Projekt (name=%s / id=%s)"; @@ -3663,3 +3664,4 @@ $TLS_confirm_uninstall_header = "undefined"; $TLS_confirm_uninstall_text = "undefined"; // ----- END ------------------------------------------------------------------ ?> + diff --git a/locale/en_GB/strings.txt b/locale/en_GB/strings.txt index 5e0eb4bf70..35d04470d3 100644 --- a/locale/en_GB/strings.txt +++ b/locale/en_GB/strings.txt @@ -3196,6 +3196,7 @@ $TLS_API_MISSING_REQUIRED_PARAMETER = "Parameter %s is required, but has not bee $TLS_API_INVALID_TESTCASE_VERSION_NUMBER = "The required version number does not exist for test case"; $TLS_API_PARAMETER_NOT_INT = "Parameter (%s) must be an integer (current value: %s)."; +$TLS_API_ILLEGAL_PARAMETER_VALUE = "Parameter (%s) must be in (%s) (current value: %s)."; $TLS_API_TPLAN_TPROJECT_KO = "Test Plan (name=%s / id=%s) does not belong to Test Project (name=%s / id=%s)"; $TLS_API_TCASE_TPROJECT_KO = "Test Case (%s:%s) does not belong to Test Project (name=%s / id=%s)"; @@ -4047,3 +4048,4 @@ $TLS_after_title = "After Title"; $TLS_after_summary = "After summary"; $TLS_after_preconditions = "After Preconditions"; // ----- END ----------------------------------------------------- + diff --git a/locale/en_US/strings.txt b/locale/en_US/strings.txt index db58daff31..ceb77a5e0d 100644 --- a/locale/en_US/strings.txt +++ b/locale/en_US/strings.txt @@ -3128,6 +3128,7 @@ $TLS_API_MISSING_REQUIRED_PARAMETER = "Parameter %s is required, but has not bee $TLS_API_INVALID_TESTCASE_VERSION_NUMBER="The required version number does not exist for test case"; $TLS_API_PARAMETER_NOT_INT = "Parameter (%s) must be an integer (current value: %s)."; +$TLS_API_ILLEGAL_PARAMETER_VALUE = "Parameter (%s) must be in (%s) (current value: %s)."; $TLS_API_TPLAN_TPROJECT_KO="Test Plan (name=%s / id=%s) does not belong to Test Project (name=%s / id=%s)"; $TLS_API_TCASE_TPROJECT_KO="Test Case (%s:%s) does not belong to Test Project (name=%s / id=%s)"; @@ -3773,3 +3774,4 @@ $TLS_no_access_to_feature = 'You do not have enough rights to access the feature $TLS_applyExecTypeChangeToAllSteps = "Apply To All Steps"; // ----- END ------------------------------------------------------------------ +