def validate(self, value): super(DurationField, self).validate(value) try: from tcms.xmlrpc.utils import pre_process_estimated_time pre_process_estimated_time(value) except ValueError: raise forms.ValidationError(self.error_messages['invalid'])
def test_pre_process_estimated_time_with_upper_string(self): try: U.pre_process_estimated_time("1D13H22M54S") except ValueError as e: self.assertEqual(str(e), 'Invaild estimated_time format.') except Exception: self.fail("Unexcept error occurs.") else: self.fail("Missing validations.")
def test_pre_process_estimated_time_with_upper_string(self): try: U.pre_process_estimated_time("1D13H22M54S") except ValueError as e: self.assertEqual(str(e), 'Invaild estimated_time format.') except Exception: self.fail("Unexcept error occurs.") else: self.fail("Missing validations.")
def test_pre_process_estimated_time_with_symbols(self): try: U.pre_process_estimated_time("aa@bb@cc") except ValueError as e: self.assertEqual(str(e), 'Invaild estimated_time format.') except Exception: self.fail("Unexcept error occurs.") else: self.fail("Missing validations.")
def test_pre_process_estimated_time_with_symbols(self): try: U.pre_process_estimated_time("aa@bb@cc") except ValueError as e: self.assertEqual(str(e), 'Invaild estimated_time format.') except Exception: self.fail("Unexcept error occurs.") else: self.fail("Missing validations.")
def test_pre_process_estimated_time(self): bad_args = ([], (), {}, True, False, 0, 1, -1) for arg in bad_args: try: U.pre_process_estimated_time(arg) except ValueError as e: self.assertEqual(str(e), 'Invaild estimated_time format.') except Exception: self.fail("Unexcept error occurs.") else: self.fail("Missing validations.")
def test_pre_process_estimated_time(self): bad_args = ([], (), {}, True, False, 0, 1, -1) for arg in bad_args: try: U.pre_process_estimated_time(arg) except ValueError as e: self.assertEqual(str(e), 'Invaild estimated_time format.') except Exception: self.fail("Unexcept error occurs.") else: self.fail("Missing validations.")
def test_pre_process_estimated_time_with_time_string(self): try: time = U.pre_process_estimated_time("13:22:54") except Exception: self.fail("Unexcept error occurs.") else: self.assertEqual(time, "13h22m54s") try: time = U.pre_process_estimated_time("1d13h22m54s") except Exception: self.fail("Unexcept error occurs.") else: self.assertEqual(time, "1d13h22m54s")
def test_pre_process_estimated_time_with_time_string(self): try: time = U.pre_process_estimated_time("13:22:54") except Exception: self.fail("Unexcept error occurs.") else: self.assertEqual(time, "13h22m54s") try: time = U.pre_process_estimated_time("1d13h22m54s") except Exception: self.fail("Unexcept error occurs.") else: self.assertEqual(time, "1d13h22m54s")
def update(case_id, values, **kwargs): """ .. function:: XML-RPC TestCase.update(case_id, values) Update the fields of the selected test case. :param case_id: PK of TestCase to be modified :type case_id: int :param values: Field values for :class:`tcms.testcases.models.TestCase`. The special keys ``setup``, ``breakdown``, ``action`` and ``effect`` are recognized and will cause update of the underlying :class:`tcms.testcases.models.TestCaseText` object! :type values: dict :return: Serialized :class:`tcms.testcases.models.TestCase` object :rtype: dict :raises: TestCase.DoesNotExist if object specified by PK doesn't exist :raises: PermissionDenied if missing *testcases.change_testcase* permission """ if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time( values.get('estimated_time')) form = UpdateCaseForm(values) if values.get('category') and not values.get('product'): raise ValueError('Product ID is required for category') if values.get('product'): form.populate(product_id=values['product']) if form.is_valid(): tc = TestCase.objects.get(pk=case_id) for key in values.keys(): # only modify attributes that were passed via parameters # skip attributes which are Many-to-Many relations if key not in ['component', 'tag'] and hasattr(tc, key): setattr(tc, key, form.cleaned_data[key]) tc.save() # if we're updating the text if any one of these parameters was # specified if any(x in ['setup', 'action', 'effect', 'breakdown'] for x in values.keys()): action = form.cleaned_data.get('action', '').strip() effect = form.cleaned_data.get('effect', '').strip() setup = form.cleaned_data.get('setup', '').strip() breakdown = form.cleaned_data.get('breakdown', '').strip() author = kwargs.get(REQUEST_KEY).user tc.add_text( author=author, action=action, effect=effect, setup=setup, breakdown=breakdown, ) else: raise ValueError(form_errors_to_list(form)) return tc.serialize()
def filter(query): """ .. function:: XML-RPC TestCase.filter(query) Perform a search and return the resulting list of test cases augmented with their latest ``text``. :param query: Field lookups for :class:`tcms.testcases.models.TestCase` :type query: dict :return: Serialized list of :class:`tcms.testcases.models.TestCase` objects. The key ``text`` holds a the latest version of a serialized :class:`tcms.testcases.models.TestCaseText` object! :rtype: list(dict) """ if query.get('estimated_time'): query['estimated_time'] = timedelta2int( pre_process_estimated_time(query.get('estimated_time'))) results = [] for case in TestCase.objects.filter(**query): serialized_case = case.serialize() serialized_case['text'] = case.latest_text().serialize() results.append(serialized_case) return results
def update(request, case_ids, values): """Updates the fields of the selected case or cases. $values - Hash of keys matching TestCase fields and the new values to set each field to. :param case_ids: give one or more case IDs. It could be an integer, a string containing comma separated IDs, or a list of int each of them is a case ID. :type case_ids: int, str or list :param dict values: a mapping containing these case data to update. * case_status: (ini) optional * product: (ini) optional (Required if changes category) * category: (ini) optional * priority: (ini) optional * default_tester: (str or int) optional (str - user_name, int - user_id) * estimated_time: (str) optional (2h30m30s(recommend) or HH:MM:SS * is_automated: (ini) optional (0 - Manual, 1 - Auto, 2 - Both) * is_automated_proposed: (bool) optional * script: (str) optional * arguments: (str) optional * summary: (str) optional * requirement: (str) optional * alias: (str) optional * notes: (str) optional * extra_link: (str) optional (reference link) :return: a list of mappings of updated :class:`TestCase`. :rtype: list(dict) Example:: # Update alias to 'tcms' for case 1 and 2 TestCase.update([1, 2], {'alias': 'tcms'}) """ from tcms.core import forms from tcms.xmlrpc.forms import UpdateCaseForm if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time(values.get('estimated_time')) form = UpdateCaseForm(values) if values.get('category') and not values.get('product'): raise ValueError('Product ID is required for category') if values.get('product'): form.populate(product_id=values['product']) if form.is_valid(): tcs = TestCase.update( case_ids=pre_process_ids(value=case_ids), values=form.cleaned_data, ) else: raise ValueError(forms.errors_to_list(form)) query = {'pk__in': tcs.values_list('pk', flat=True)} return TestCase.to_xmlrpc(query)
def update(request, case_ids, values): """Updates the fields of the selected case or cases. $values - Hash of keys matching TestCase fields and the new values to set each field to. :param case_ids: give one or more case IDs. It could be an integer, a string containing comma separated IDs, or a list of int each of them is a case ID. :type case_ids: int, str or list :param dict values: a mapping containing these case data to update. * case_status: (ini) optional * product: (ini) optional (Required if changes category) * category: (ini) optional * priority: (ini) optional * default_tester: (str or int) optional (str - user_name, int - user_id) * estimated_time: (str) optional (2h30m30s(recommend) or HH:MM:SS * is_automated: (ini) optional (0 - Manual, 1 - Auto, 2 - Both) * is_automated_proposed: (bool) optional * script: (str) optional * arguments: (str) optional * summary: (str) optional * requirement: (str) optional * alias: (str) optional * notes: (str) optional * extra_link: (str) optional (reference link) :return: a list of mappings of updated :class:`TestCase`. :rtype: list(dict) Example:: # Update alias to 'tcms' for case 1 and 2 >>> TestCase.update([1, 2], {'alias': 'tcms'}) """ from tcms.core import forms from tcms.xmlrpc.forms import UpdateCaseForm if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time(values.get('estimated_time')) form = UpdateCaseForm(values) if values.get('category') and not values.get('product'): raise ValueError('Product ID is required for category') if values.get('product'): form.populate(product_id=values['product']) if form.is_valid(): tcs = TestCase.update( case_ids=pre_process_ids(value=case_ids), values=form.cleaned_data, ) else: raise ValueError(forms.errors_to_list(form)) query = {'pk__in': tcs.values_list('pk', flat=True)} return TestCase.to_xmlrpc(query)
def create(values, **kwargs): """ .. function:: XML-RPC TestCase.create(values) Create a new TestCase object and store it in the database. :param values: Field values for :class:`tcms.testcases.models.TestCase` :type values: dict :return: Serialized :class:`tcms.testcases.models.TestCase` object :rtype: dict :raises: PermissionDenied if missing *testcases.add_testcase* permission Minimal test case parameters:: >>> values = { 'category': 135, 'product': 61, 'summary': 'Testing XML-RPC', 'priority': 1, } >>> TestCase.create(values) """ request = kwargs.get(REQUEST_KEY) if not (values.get('category') or values.get('summary')): raise ValueError() if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time( values.get('estimated_time')) form = NewCaseForm(values) form.populate(values.get('product')) if form.is_valid(): # Create the case tc = TestCase.create(author=request.user, values=form.cleaned_data) # Add case text to the case tc.add_text( action=form.cleaned_data['action'] or '', effect=form.cleaned_data['effect'] or '', setup=form.cleaned_data['setup'] or '', breakdown=form.cleaned_data['breakdown'] or '', ) # Add tag to the case for tag in string_to_list(values.get('tag', [])): t, c = TestTag.objects.get_or_create(name=tag) tc.add_tag(tag=t) else: # Print the errors if the form is not passed validation. raise ValueError(form_errors_to_list(form)) result = tc.serialize() result['text'] = tc.latest_text().serialize() return result
def filter(request, query): """ Description: Performs a search and returns the resulting list of test cases. Params: $query - Hash: keys must match valid search fields. +------------------------------------------------------------------+ | Case Search Parameters | +------------------------------------------------------------------+ | Key | Valid Values | | author | A bugzilla login (email address) | | attachment | ForeignKey: Attchment | | alias | String | | case_id | Integer | | case_status | ForeignKey: Case Stat | | category | ForeignKey: Category | | component | ForeignKey: Component | | default_tester | ForeignKey: Auth.User | | estimated_time | String: 2h30m30s(recommend) or HH:MM:SS | | plan | ForeignKey: Test Plan | | priority | ForeignKey: Priority | | category__product | ForeignKey: Product | | summary | String | | tags | ForeignKey: Tags | | create_date | Datetime | | is_automated | 1: Only show current 0: show not current | | script | Text | +------------------------------------------------------------------+ Returns: Array: Matching test cases are retuned in a list of hashes. Example: # Get all of cases contain 'TCMS' in summary >>> TestCase.filter({'summary__icontain': 'TCMS'}) # Get all of cases create by xkuang >>> TestCase.filter({'author__username': '******'}) # Get all of cases the author name starts with x >>> TestCase.filter({'author__username__startswith': 'x'}) # Get all of cases belong to the plan 137 >>> TestCase.filter({'plan__plan_id': 137}) # Get all of cases belong to the plan create by xkuang >>> TestCase.filter({'plan__author__username': '******'}) # Get cases with ID 12345, 23456, 34567 - Here is only support array so far. >>> TestCase.filter({'case_id__in': [12345, 23456, 34567]}) """ if query.get('estimated_time'): query['estimated_time'] = timedelta2int( pre_process_estimated_time(query.get('estimated_time')) ) return TestCase.to_xmlrpc(query)
def filter_count(request, values={}): """Performs a search and returns the resulting count of cases. :param dict values: a mapping containing same criteria with :meth:`TestCase.filter <tcms.xmlrpc.api.testcase.filter>`. :return: the number of matching cases. :rtype: int .. seealso:: Examples of :meth:`TestCase.filter <tcms.xmlrpc.api.testcase.filter>`. """ if values.get('estimated_time'): values['estimated_time'] = timedelta2int( pre_process_estimated_time(values.get('estimated_time'))) return distinct_count(TestCase, values)
def filter(request, query): """Performs a search and returns the resulting list of test cases. :param dict query: a mapping containing these criteria. * author: A Bugzilla login (email address) * attachments: ForeignKey: Attachment * alias: (str) * case_id: (int) * case_status: ForeignKey: Case Stat * category: ForeignKey: :class:`Category` * component: ForeignKey: :class:`Component` * default_tester: ForeignKey: ``Auth.User`` * estimated_time: String: 2h30m30s(recommend) or HH:MM:SS * plan: ForeignKey: :class:`TestPlan` * priority: ForeignKey: :class:`Priority` * category__product: ForeignKey: :class:`Product` * summary: (str) * tags: ForeignKey: :class:`Tags` * create_date: Datetime * is_automated: 1: Only show current 0: show not current * script: (str) :return: list of mappings of found :class:`TestCase`. :rtype: list Example:: # Get all of cases contain 'TCMS' in summary TestCase.filter({'summary__icontain': 'TCMS'}) # Get all of cases create by xkuang TestCase.filter({'author__username': '******'}) # Get all of cases the author name starts with x TestCase.filter({'author__username__startswith': 'x'}) # Get all of cases belong to the plan 1 TestCase.filter({'plan__plan_id': 1}) # Get all of cases belong to the plan create by xkuang TestCase.filter({'plan__author__username': '******'}) # Get cases with ID 12345, 23456, 34567 - Here is only support array so far. TestCase.filter({'case_id__in': [12345, 23456, 34567]}) """ if query.get('estimated_time'): query['estimated_time'] = timedelta2int( pre_process_estimated_time(query.get('estimated_time')) ) deprecate_critetion_attachment(query) return TestCase.to_xmlrpc(query)
def filter(request, query): """Performs a search and returns the resulting list of test cases. :param dict query: a mapping containing these criteria. * author: A Bugzilla login (email address) * attachment: ForeignKey: Attachment * alias: (str) * case_id: (int) * case_status: ForeignKey: Case Stat * category: ForeignKey: :class:`Category` * component: ForeignKey: :class:`Component` * default_tester: ForeignKey: ``Auth.User`` * estimated_time: String: 2h30m30s(recommend) or HH:MM:SS * plan: ForeignKey: :class:`TestPlan` * priority: ForeignKey: :class:`Priority` * category__product: ForeignKey: :class:`Product` * summary: (str) * tags: ForeignKey: :class:`Tags` * create_date: Datetime * is_automated: 1: Only show current 0: show not current * script: (str) :return: list of mappings of found :class:`TestCase`. :rtype: list Example:: # Get all of cases contain 'TCMS' in summary >>> TestCase.filter({'summary__icontain': 'TCMS'}) # Get all of cases create by xkuang >>> TestCase.filter({'author__username': '******'}) # Get all of cases the author name starts with x >>> TestCase.filter({'author__username__startswith': 'x'}) # Get all of cases belong to the plan 1 >>> TestCase.filter({'plan__plan_id': 1}) # Get all of cases belong to the plan create by xkuang >>> TestCase.filter({'plan__author__username': '******'}) # Get cases with ID 12345, 23456, 34567 - Here is only support array so far. >>> TestCase.filter({'case_id__in': [12345, 23456, 34567]}) """ if query.get('estimated_time'): query['estimated_time'] = timedelta2int( pre_process_estimated_time(query.get('estimated_time')) ) return TestCase.to_xmlrpc(query)
def filter_count(request, values={}): """Performs a search and returns the resulting count of cases. :param dict values: a mapping containing same criteria with :meth:`TestCase.filter <tcms.xmlrpc.api.testcase.filter>`. :return: the number of matching cases. :rtype: int .. seealso:: Examples of :meth:`TestCase.filter <tcms.xmlrpc.api.testcase.filter>`. """ if values.get('estimated_time'): values['estimated_time'] = timedelta2int( pre_process_estimated_time(values.get('estimated_time')) ) return distinct_count(TestCase, values)
def filter_count(values={}): """ Description: Performs a search and returns the resulting count of cases. Params: $values - Hash: keys must match valid search fields (see filter). Returns: Integer - total matching cases. Example: # See TestCase.filter() """ if values.get('estimated_time'): values['estimated_time'] = timedelta2int( pre_process_estimated_time(values.get('estimated_time'))) return distinct_count(TestCase, values)
def filter_count(request, values={}): """ Description: Performs a search and returns the resulting count of cases. Params: $values - Hash: keys must match valid search fields (see filter). Returns: Integer - total matching cases. Example: # See TestCase.filter() """ if values.get('estimated_time'): values['estimated_time'] = timedelta2int( pre_process_estimated_time(values.get('estimated_time')) ) return distinct_count(TestCase, values)
def update(request, run_ids, values): """Updates the fields of the selected test run. :param run_ids: give one or more run IDs. It could be an integer, a string containing comma separated IDs, or a list of int each of them is a run ID. :type run_ids: int, str or list :param dict values: a mapping containing these data to update specified runs. * plan: (int) TestPlan.plan_id * product: (int) Product.id * build: (int) Build.id * manager: (int) Auth.User.id * default_tester: Intege Auth.User.id * summary: (str) * estimated_time: (TimeDelta) in format ``2h30m30s`` which is recommended or ``HH:MM:SS``. * product_version: (int) * plan_text_version: (int) * notes: (str) * status: (int) 0:RUNNING 1:FINISHED :return: list of mappings of the updated test runs. :rtype: list[dict] .. versionchanged:: 4.5 Argument ``errata_id`` is removed. Example:: # Update status to finished for run 1 and 2 TestRun.update([1, 2], {'status': 1}) """ from datetime import datetime from tcms.core import forms from tcms.testruns.forms import XMLRPCUpdateRunForm if (values.get('product_version') and not values.get('product')): raise ValueError('Field "product" is required by product_version') if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time( values.get('estimated_time')) form = XMLRPCUpdateRunForm(values) if values.get('product_version'): form.populate(product_id=values['product']) if form.is_valid(): trs = TestRun.objects.filter(pk__in=pre_process_ids(value=run_ids)) _values = dict() if form.cleaned_data['plan']: _values['plan'] = form.cleaned_data['plan'] if form.cleaned_data['build']: _values['build'] = form.cleaned_data['build'] if form.cleaned_data['manager']: _values['manager'] = form.cleaned_data['manager'] if 'default_tester' in values: default_tester = form.cleaned_data['default_tester'] if values.get('default_tester') and default_tester: _values['default_tester'] = default_tester else: _values['default_tester'] = None if form.cleaned_data['summary']: _values['summary'] = form.cleaned_data['summary'] if values.get('estimated_time') is not None: _values['estimated_time'] = form.cleaned_data['estimated_time'] if form.cleaned_data['product_version']: _values['product_version'] = form.cleaned_data['product_version'] if 'notes' in values: if values['notes'] in (None, ''): _values['notes'] = values['notes'] if form.cleaned_data['notes']: _values['notes'] = form.cleaned_data['notes'] if form.cleaned_data['plan_text_version']: _values['plan_text_version'] = form.cleaned_data[ 'plan_text_version'] if isinstance(form.cleaned_data['status'], int): if form.cleaned_data['status']: _values['stop_date'] = datetime.now() else: _values['stop_date'] = None trs.update(**_values) else: raise ValueError(forms.errors_to_list(form)) query = {'pk__in': trs.values_list('pk', flat=True)} return TestRun.to_xmlrpc(query)
def test_pre_process_estimated_time_with_time_string(self): time = U.pre_process_estimated_time("13:22:54") self.assertEqual(time, "13h22m54s") time = U.pre_process_estimated_time("1d13h22m54s") self.assertEqual(time, "1d13h22m54s")
def create(request, values): """Creates a new Test Run object and stores it in the database. :param dict values: a mapping containing these data to create a test run. * plan: (int) **Required** ID of test plan * build: (int)/(str) **Required** ID of Build * manager: (int) **Required** ID of run manager * summary: (str) **Required** * product: (int) **Required** ID of product * product_version: (int) **Required** ID of product version * default_tester: (int) optional ID of run default tester * plan_text_version: (int) optional * estimated_time: (str) optional, could be in format ``2h30m30s``, which is recommended or ``HH:MM:SS``. * notes: (str) optional * status: (int) optional 0:RUNNING 1:STOPPED (default 0) * case: list or (str) optional list of case ids to add to the run * tag: list or (str) optional list of tag to add to the run :return: a mapping representing newly created :class:`TestRun`. :rtype: dict .. versionchanged:: 4.5 Argument ``errata_id`` is removed. Example:: values = { 'build': 2, 'manager': 1, 'plan': 1, 'product': 1, 'product_version': 2, 'summary': 'Testing XML-RPC for TCMS', } TestRun.create(values) """ from datetime import datetime from tcms.core import forms from tcms.testruns.forms import XMLRPCNewRunForm if not values.get('product'): raise ValueError('Value of product is required') # TODO: XMLRPC only accept HH:MM:SS rather than DdHhMm if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time( values.get('estimated_time')) if values.get('case'): values['case'] = pre_process_ids(value=values['case']) form = XMLRPCNewRunForm(values) form.populate(product_id=values['product']) if form.is_valid(): tr = TestRun.objects.create( product_version=form.cleaned_data['product_version'], plan_text_version=form.cleaned_data['plan_text_version'], stop_date=form.cleaned_data['status'] and datetime.now() or None, summary=form.cleaned_data['summary'], notes=form.cleaned_data['notes'], estimated_time=form.cleaned_data['estimated_time'], plan=form.cleaned_data['plan'], build=form.cleaned_data['build'], manager=form.cleaned_data['manager'], default_tester=form.cleaned_data['default_tester'], ) if form.cleaned_data['case']: for c in form.cleaned_data['case']: tr.add_case_run(case=c) del c if form.cleaned_data['tag']: tags = form.cleaned_data['tag'] if isinstance(tags, str): tags = [c.strip() for c in tags.split(',') if c] for tag in tags: t, c = TestTag.objects.get_or_create(name=tag) tr.add_tag(tag=t) del tag, t, c else: raise ValueError(forms.errors_to_list(form)) return tr.serialize()
def create(request, values): """Creates a new Test Run object and stores it in the database. :param dict values: a mapping containing these data to create a test run. * plan: (int) **Required** ID of test plan * build: (int)/(str) **Required** ID of Build * errata_id: (int) optional ID of Errata * manager: (int) **Required** ID of run manager * summary: (str) **Required** * product: (int) **Required** ID of product * product_version: (int) **Required** ID of product version * default_tester: (int) optional ID of run default tester * plan_text_version: (int) optional * estimated_time: (str) optional, could be in format ``2h30m30s``, which is recommended or ``HH:MM:SS``. * notes: (str) optional * status: (int) optional 0:RUNNING 1:STOPPED (default 0) * case: list or (str) optional list of case ids to add to the run * tag: list or (str) optional list of tag to add to the run :return: a mapping representing newly created :class:`TestRun`. :rtype: dict Example:: >>> values = { 'build': 2, 'manager': 1, 'plan': 1, 'errata_id': 2, 'product': 1, 'product_version': 2, 'summary': 'Testing XML-RPC for TCMS', } >>> TestRun.create(values) """ from datetime import datetime from tcms.core import forms from tcms.testruns.forms import XMLRPCNewRunForm if not values.get('product'): raise ValueError('Value of product is required') # TODO: XMLRPC only accept HH:MM:SS rather than DdHhMm if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time( values.get('estimated_time')) if values.get('case'): values['case'] = pre_process_ids(value=values['case']) form = XMLRPCNewRunForm(values) form.populate(product_id=values['product']) if form.is_valid(): tr = TestRun.objects.create( product_version=form.cleaned_data['product_version'], plan_text_version=form.cleaned_data['plan_text_version'], stop_date=form.cleaned_data['status'] and datetime.now() or None, summary=form.cleaned_data['summary'], notes=form.cleaned_data['notes'], estimated_time=form.cleaned_data['estimated_time'], plan=form.cleaned_data['plan'], build=form.cleaned_data['build'], errata_id=form.cleaned_data['errata_id'], manager=form.cleaned_data['manager'], default_tester=form.cleaned_data['default_tester'], ) if form.cleaned_data['case']: for c in form.cleaned_data['case']: tr.add_case_run(case=c) del c if form.cleaned_data['tag']: tags = form.cleaned_data['tag'] if isinstance(tags, str): tags = [c.strip() for c in tags.split(',') if c] for tag in tags: t, c = TestTag.objects.get_or_create(name=tag) tr.add_tag(tag=t) del tag, t, c else: raise ValueError(forms.errors_to_list(form)) return tr.serialize()
def create(request, values): """Creates a new Test Case object and stores it in the database. :param values: a mapping or list of mappings containing these case information for creation. * product: (int) **Required** ID of Product * category: (int) **Required** ID of Category * priority: (int) **Required** ID of Priority * summary: (str) **Required** * case_status: (int) optional ID of case status * plan Array/Str/Int optional ID or List of plan_ids * component: (int)/str optional ID of Priority * default_tester: (str) optional Login of tester * estimated_time: (str) optional 2h30m30s(recommend) or HH:MM:SS Format| * is_automated: (int) optional 0: Manual, 1: Auto, 2: Both * is_automated_proposed: (bool) optional Default 0 * script: (str) optional * arguments: (str) optional * requirement: (str) optional * alias: (str) optional Must be unique * action: (str) optional * effect: (str) optional Expected Result * setup: (str) optional * breakdown: (str) optional * tag Array/str optional String Comma separated * bug Array/str optional String Comma separated * extra_link: (str) optional reference link :return: a mapping of newly created test case if a single case was created, or a list of mappings of created cases if more than one are created. :rtype: dict of list[dict] Example:: # Minimal test case parameters values = { 'category': 1, 'product': 1, 'summary': 'Testing XML-RPC', 'priority': 1, } TestCase.create(values) """ from tcms.core import forms from tcms.xmlrpc.forms import NewCaseForm if not (values.get('category') or values.get('summary')): raise ValueError() values['component'] = pre_process_ids(values.get('component', [])) values['plan'] = pre_process_ids(values.get('plan', [])) values['bug'] = pre_process_ids(values.get('bug', [])) if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time(values.get('estimated_time')) form = NewCaseForm(values) form.populate(values.get('product')) if form.is_valid(): # Create the case tc = TestCase.create(author=request.user, values=form.cleaned_data) # Add case text to the case tc.add_text( action=form.cleaned_data['action'] or '', effect=form.cleaned_data['effect'] or '', setup=form.cleaned_data['setup'] or '', breakdown=form.cleaned_data['breakdown'] or '', ) # Add the case to specific plans for p in form.cleaned_data['plan']: tc.add_to_plan(plan=p) del p # Add components to the case for c in form.cleaned_data['component']: tc.add_component(component=c) del c # Add tag to the case for tag in TestTag.string_to_list(values.get('tag', [])): t, c = TestTag.objects.get_or_create(name=tag) tc.add_tag(tag=t) else: # Print the errors if the form is not passed validation. raise ValueError(forms.errors_to_list(form)) return get(request, tc.case_id)
def update(run_id, values): """ .. function:: XML-RPC TestRun.update(run_id, values) Update the selected TestRun :param run_id: PK of TestRun to modify :type run_id: int :param values: Field values for :class:`tcms.testruns.models.TestRun` :type values: dict :return: Serialized :class:`tcms.testruns.models.TestRun` object :raises: PermissionDenied if missing *testruns.change_testrun* permission :raises: ValueError if data validations fail """ if (values.get('product_version') and not values.get('product')): raise ValueError('Field "product" is required by product_version') if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time( values.get('estimated_time')) form = XMLRPCUpdateRunForm(values) if values.get('product_version'): form.populate(product_id=values['product']) if form.is_valid(): tr = TestRun.objects.get(pk=run_id) if form.cleaned_data['plan']: tr.plan = form.cleaned_data['plan'] if form.cleaned_data['build']: tr.build = form.cleaned_data['build'] if form.cleaned_data['manager']: tr.manager = form.cleaned_data['manager'] if 'default_tester' in values: if values.get('default_tester') and \ form.cleaned_data['default_tester']: tr.default_tester = form.cleaned_data['default_tester'] else: tr.default_tester = None if form.cleaned_data['summary']: tr.summary = form.cleaned_data['summary'] if values.get('estimated_time') is not None: tr.estimated_time = form.cleaned_data['estimated_time'] if form.cleaned_data['product_version']: tr.product_version = form.cleaned_data['product_version'] if 'notes' in values: if values['notes'] in (None, ''): tr.notes = values['notes'] if form.cleaned_data['notes']: tr.notes = form.cleaned_data['notes'] if form.cleaned_data['plan_text_version']: tr.plan_text_version = form.cleaned_data['plan_text_version'] if isinstance(form.cleaned_data['status'], int): if form.cleaned_data['status']: tr.stop_date = datetime.now() else: tr.stop_date = None tr.save() else: raise ValueError(form_errors_to_list(form)) return tr.serialize()
def create(values): """ .. function:: XML-RPC TestRun.create(values) Create new TestRun object and store it in the database. :param values: Field values for :class:`tcms.testruns.models.TestRun` :type values: dict :return: Serialized :class:`tcms.testruns.models.TestRun` object :raises: PermissionDenied if missing *testruns.add_testrun* permission :raises: ValueError if data validations fail Example:: >>> values = {'build': 384, 'manager': 137, 'plan': 137, 'product': 61, 'product_version': 93, 'summary': 'Testing XML-RPC for TCMS', } >>> TestRun.create(values) """ if not values.get('product'): raise ValueError('Value of product is required') # TODO: XMLRPC only accept HH:MM:SS rather than DdHhMm if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time( values.get('estimated_time')) form = XMLRPCNewRunForm(values) form.populate(product_id=values['product']) if form.is_valid(): tr = TestRun.objects.create( product_version=form.cleaned_data['product_version'], plan_text_version=form.cleaned_data['plan_text_version'], stop_date=form.cleaned_data['status'] and datetime.now() or None, summary=form.cleaned_data['summary'], notes=form.cleaned_data['notes'], estimated_time=form.cleaned_data['estimated_time'], plan=form.cleaned_data['plan'], build=form.cleaned_data['build'], manager=form.cleaned_data['manager'], default_tester=form.cleaned_data['default_tester'], ) if form.cleaned_data['tag']: tags = form.cleaned_data['tag'] if isinstance(tags, str): tags = [c.strip() for c in tags.split(',') if c] for tag in tags: t, c = TestTag.objects.get_or_create(name=tag) tr.add_tag(tag=t) del tag, t, c else: raise ValueError(form_errors_to_list(form)) return tr.serialize()
def create(request, values): """ Description: Creates a new Test Run object and stores it in the database. Params: $values - Hash: A reference to a hash with keys and values matching the fields of the test run to be created. +-------------------+----------------+-----------+---------------------------------------+ | Field | Type | Null | Description | +-------------------+----------------+-----------+---------------------------------------+ | plan | Integer | Required | ID of test plan | | build | Integer/String | Required | ID of Build | | errata_id | Integer | Optional | ID of Errata | | manager | Integer | Required | ID of run manager | | summary | String | Required | | | product | Integer | Required | ID of product | | product_version | Integer | Required | ID of product version | | default_tester | Integer | Optional | ID of run default tester | | plan_text_version | Integer | Optional | | | estimated_time | String | Optional | 2h30m30s(recommend) or HH:MM:SS Format| | notes | String | Optional | | | status | Integer | Optional | 0:RUNNING 1:STOPPED (default 0) | | case | Array/String | Optional | list of case ids to add to the run | | tag | Array/String | Optional | list of tag to add to the run | +-------------------+----------------+-----------+---------------------------------------+ Returns: The newly created object hash. Example: >>> values = {'build': 384, 'manager': 137, 'plan': 137, 'errata_id': 124, 'product': 61, 'product_version': 93, 'summary': 'Testing XML-RPC for TCMS', } >>> TestRun.create(values) """ from datetime import datetime from tcms.core import forms from tcms.testruns.forms import XMLRPCNewRunForm if not values.get('product'): raise ValueError('Value of product is required') # TODO: XMLRPC only accept HH:MM:SS rather than DdHhMm if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time( values.get('estimated_time')) if values.get('case'): values['case'] = pre_process_ids(value=values['case']) form = XMLRPCNewRunForm(values) form.populate(product_id=values['product']) if form.is_valid(): tr = TestRun.objects.create( product_version=form.cleaned_data['product_version'], plan_text_version=form.cleaned_data['plan_text_version'], stop_date=form.cleaned_data['status'] and datetime.now() or None, summary=form.cleaned_data['summary'], notes=form.cleaned_data['notes'], estimated_time=form.cleaned_data['estimated_time'], plan=form.cleaned_data['plan'], build=form.cleaned_data['build'], errata_id=form.cleaned_data['errata_id'], manager=form.cleaned_data['manager'], default_tester=form.cleaned_data['default_tester'], ) if form.cleaned_data['case']: for c in form.cleaned_data['case']: tr.add_case_run(case=c) del c if form.cleaned_data['tag']: tags = form.cleaned_data['tag'] if isinstance(tags, str): tags = [c.strip() for c in tags.split(',') if c] for tag in tags: t, c = TestTag.objects.get_or_create(name=tag) tr.add_tag(tag=t) del tag, t, c else: raise ValueError(forms.errors_to_list(form)) return tr.serialize()
def update(request, run_ids, values): """Updates the fields of the selected test run. :param run_ids: give one or more run IDs. It could be an integer, a string containing comma separated IDs, or a list of int each of them is a run ID. :type run_ids: int, str or list :param dict values: a mapping containing these data to update specified runs. * plan: (int) TestPlan.plan_id * product: (int) Product.id * build: (int) Build.id * errata_id: (int) Errata.id * manager: (int) Auth.User.id * default_tester: Intege Auth.User.id * summary: (str) * estimated_time: (TimeDelta) in format ``2h30m30s`` which is recommended or ``HH:MM:SS``. * product_version: (int) * plan_text_version: (int) * notes: (str) * status: (int) 0:RUNNING 1:FINISHED :return: list of mappings of the updated test runs. :rtype: list[dict] Example:: # Update status to finished for run 1 and 2 >>> TestRun.update([1, 2], {'status': 1}) """ from datetime import datetime from tcms.core import forms from tcms.testruns.forms import XMLRPCUpdateRunForm if (values.get('product_version') and not values.get('product')): raise ValueError('Field "product" is required by product_version') if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time( values.get('estimated_time')) form = XMLRPCUpdateRunForm(values) if values.get('product_version'): form.populate(product_id=values['product']) if form.is_valid(): trs = TestRun.objects.filter(pk__in=pre_process_ids(value=run_ids)) _values = dict() if form.cleaned_data['plan']: _values['plan'] = form.cleaned_data['plan'] if form.cleaned_data['build']: _values['build'] = form.cleaned_data['build'] if form.cleaned_data['errata_id']: _values['errata_id'] = form.cleaned_data['errata_id'] if form.cleaned_data['manager']: _values['manager'] = form.cleaned_data['manager'] if 'default_tester' in values: if values.get('default_tester') and \ form.cleaned_data['default_tester']: _values['default_tester'] = form.cleaned_data['default_tester'] else: _values['default_tester'] = None if form.cleaned_data['summary']: _values['summary'] = form.cleaned_data['summary'] if values.get('estimated_time') is not None: _values['estimated_time'] = form.cleaned_data['estimated_time'] if form.cleaned_data['product_version']: _values['product_version'] = form.cleaned_data['product_version'] if 'notes' in values: if values['notes'] in (None, ''): _values['notes'] = values['notes'] if form.cleaned_data['notes']: _values['notes'] = form.cleaned_data['notes'] if form.cleaned_data['plan_text_version']: _values['plan_text_version'] = form.cleaned_data[ 'plan_text_version'] if isinstance(form.cleaned_data['status'], int): if form.cleaned_data['status']: _values['stop_date'] = datetime.now() else: _values['stop_date'] = None trs.update(**_values) else: raise ValueError(forms.errors_to_list(form)) query = {'pk__in': trs.values_list('pk', flat=True)} return TestRun.to_xmlrpc(query)
def test_pre_process_estimated_time_with_symbols(self): with self.assertRaisesRegex(ValueError, 'Invalid estimated_time format.'): U.pre_process_estimated_time("aa@bb@cc")
def update(request, run_ids, values): """ Description: Updates the fields of the selected test run. Params: $run_ids - Integer/Array/String: An integer or alias representing the ID in the database, an array of run_ids, or a string of comma separated run_ids. $values - Hash of keys matching TestRun fields and the new values to set each field to. See params of TestRun.create for description +-------------------+----------------+--------------------------------+ | Field | Type | Description | +-------------------+----------------+--------------------------------+ | plan | Integer | TestPlan.plan_id | | product | Integer | Product.id | | build | Integer | Build.id | | errata_id | Integer | Errata.id | | manager | Integer | Auth.User.id | | default_tester | Intege | Auth.User.id | | summary | String | | | estimated_time | TimeDelta | 2h30m30s(recommend) or HH:MM:SS| | product_version | Integer | | | plan_text_version | Integer | | | notes | String | | | status | Integer | 0:RUNNING 1:FINISHED | +-------------------+----------------+ -------------------------------+ Returns: Hash: The updated test run object. Example: # Update status to finished for run 1193 and 1194 >>> TestRun.update([1193, 1194], {'status': 1}) """ from datetime import datetime from tcms.core import forms from tcms.testruns.forms import XMLRPCUpdateRunForm if (values.get('product_version') and not values.get('product')): raise ValueError('Field "product" is required by product_version') if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time( values.get('estimated_time')) form = XMLRPCUpdateRunForm(values) if values.get('product_version'): form.populate(product_id=values['product']) if form.is_valid(): trs = TestRun.objects.filter(pk__in=pre_process_ids(value=run_ids)) _values = dict() if form.cleaned_data['plan']: _values['plan'] = form.cleaned_data['plan'] if form.cleaned_data['build']: _values['build'] = form.cleaned_data['build'] if form.cleaned_data['errata_id']: _values['errata_id'] = form.cleaned_data['errata_id'] if form.cleaned_data['manager']: _values['manager'] = form.cleaned_data['manager'] if 'default_tester' in values: if values.get('default_tester') and \ form.cleaned_data['default_tester']: _values['default_tester'] = form.cleaned_data['default_tester'] else: _values['default_tester'] = None if form.cleaned_data['summary']: _values['summary'] = form.cleaned_data['summary'] if values.get('estimated_time') is not None: _values['estimated_time'] = form.cleaned_data['estimated_time'] if form.cleaned_data['product_version']: _values['product_version'] = form.cleaned_data['product_version'] if 'notes' in values: if values['notes'] in (None, ''): _values['notes'] = values['notes'] if form.cleaned_data['notes']: _values['notes'] = form.cleaned_data['notes'] if form.cleaned_data['plan_text_version']: _values['plan_text_version'] = form.cleaned_data[ 'plan_text_version'] if isinstance(form.cleaned_data['status'], int): if form.cleaned_data['status']: _values['stop_date'] = datetime.now() else: _values['stop_date'] = None trs.update(**_values) else: raise ValueError(forms.errors_to_list(form)) query = {'pk__in': trs.values_list('pk', flat=True)} return TestRun.to_xmlrpc(query)
def test_pre_process_estimated_time(self): bad_args = ([], (), {}) for arg in bad_args: with self.assertRaisesRegex(ValueError, 'Invalid estimated_time format.'): U.pre_process_estimated_time(arg)
def test_pre_process_estimated_time_with_empty(self): time = U.pre_process_estimated_time("") self.assertEqual('', time)
def test_pre_process_estimated_time_with_string(self): with self.assertRaisesRegex(ValueError, 'Invalid estimated_time format.'): U.pre_process_estimated_time("aa:bb:cc")
def test_pre_process_estimated_time_with_empty(self): time = U.pre_process_estimated_time("") self.assertEqual('', time)
def create(request, values): """ Description: Creates a new Test Run object and stores it in the database. Params: $values - Hash: A reference to a hash with keys and values matching the fields of the test run to be created. +-------------------+----------------+-----------+---------------------------------------+ | Field | Type | Null | Description | +-------------------+----------------+-----------+---------------------------------------+ | plan | Integer | Required | ID of test plan | | build | Integer/String | Required | ID of Build | | manager | Integer | Required | ID of run manager | | summary | String | Required | | | product | Integer | Required | ID of product | | product_version | Integer | Required | ID of product version | | default_tester | Integer | Optional | ID of run default tester | | plan_text_version | Integer | Optional | | | estimated_time | String | Optional | 2h30m30s(recommend) or HH:MM:SS Format| | notes | String | Optional | | | status | Integer | Optional | 0:RUNNING 1:STOPPED (default 0) | | case | Array/String | Optional | list of case ids to add to the run | | tag | Array/String | Optional | list of tag to add to the run | +-------------------+----------------+-----------+---------------------------------------+ Returns: The newly created object hash. Example: >>> values = {'build': 384, 'manager': 137, 'plan': 137, 'product': 61, 'product_version': 93, 'summary': 'Testing XML-RPC for TCMS', } >>> TestRun.create(values) """ from datetime import datetime from tcms.core import forms from tcms.testruns.forms import XMLRPCNewRunForm if not values.get('product'): raise ValueError('Value of product is required') # TODO: XMLRPC only accept HH:MM:SS rather than DdHhMm if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time( values.get('estimated_time')) if values.get('case'): values['case'] = pre_process_ids(value=values['case']) form = XMLRPCNewRunForm(values) form.populate(product_id=values['product']) if form.is_valid(): tr = TestRun.objects.create( product_version=form.cleaned_data['product_version'], plan_text_version=form.cleaned_data['plan_text_version'], stop_date=form.cleaned_data['status'] and datetime.now() or None, summary=form.cleaned_data['summary'], notes=form.cleaned_data['notes'], estimated_time=form.cleaned_data['estimated_time'], plan=form.cleaned_data['plan'], build=form.cleaned_data['build'], manager=form.cleaned_data['manager'], default_tester=form.cleaned_data['default_tester'], ) if form.cleaned_data['case']: for c in form.cleaned_data['case']: tr.add_case_run(case=c) del c if form.cleaned_data['tag']: tags = form.cleaned_data['tag'] if isinstance(tags, str): tags = [c.strip() for c in tags.split(',') if c] for tag in tags: t, c = TestTag.objects.get_or_create(name=tag) tr.add_tag(tag=t) del tag, t, c else: raise ValueError(forms.errors_to_list(form)) return tr.serialize()
def create(request, values): """Creates a new Test Case object and stores it in the database. :param values: a mapping or list of mappings containing these case information for creation. * product: (int) **Required** ID of Product * category: (int) **Required** ID of Category * priority: (int) **Required** ID of Priority * summary: (str) **Required** * case_status: (int) optional ID of case status * plan Array/Str/Int optional ID or List of plan_ids * component: (int)/str optional ID of Priority * default_tester: (str) optional Login of tester * estimated_time: (str) optional 2h30m30s(recommend) or HH:MM:SS Format| * is_automated: (int) optional 0: Manual, 1: Auto, 2: Both * is_automated_proposed: (bool) optional Default 0 * script: (str) optional * arguments: (str) optional * requirement: (str) optional * alias: (str) optional Must be unique * action: (str) optional * effect: (str) optional Expected Result * setup: (str) optional * breakdown: (str) optional * tag Array/str optional String Comma separated * bug Array/str optional String Comma separated * extra_link: (str) optional reference link :return: a mapping of newly created test case if a single case was created, or a list of mappings of created cases if more than one are created. :rtype: dict of list[dict] Example:: # Minimal test case parameters >>> values = { 'category': 1, 'product': 1, 'summary': 'Testing XML-RPC', 'priority': 1, } >>> TestCase.create(values) """ from tcms.core import forms from tcms.xmlrpc.forms import NewCaseForm if not (values.get('category') or values.get('summary')): raise ValueError() values['component'] = pre_process_ids(values.get('component', [])) values['plan'] = pre_process_ids(values.get('plan', [])) values['bug'] = pre_process_ids(values.get('bug', [])) if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time(values.get('estimated_time')) form = NewCaseForm(values) form.populate(values.get('product')) if form.is_valid(): # Create the case tc = TestCase.create(author=request.user, values=form.cleaned_data) # Add case text to the case tc.add_text( action=form.cleaned_data['action'] or '', effect=form.cleaned_data['effect'] or '', setup=form.cleaned_data['setup'] or '', breakdown=form.cleaned_data['breakdown'] or '', ) # Add the case to specific plans for p in form.cleaned_data['plan']: tc.add_to_plan(plan=p) del p # Add components to the case for c in form.cleaned_data['component']: tc.add_component(component=c) del c # Add tag to the case for tag in TestTag.string_to_list(values.get('tag', [])): t, c = TestTag.objects.get_or_create(name=tag) tc.add_tag(tag=t) else: # Print the errors if the form is not passed validation. raise ValueError(forms.errors_to_list(form)) return get(request, tc.case_id)
def update(request, run_ids, values): """ Description: Updates the fields of the selected test run. Params: $run_ids - Integer/Array/String: An integer or alias representing the ID in the database, an array of run_ids, or a string of comma separated run_ids. $values - Hash of keys matching TestRun fields and the new values to set each field to. See params of TestRun.create for description +-------------------+----------------+--------------------------------+ | Field | Type | Description | +-------------------+----------------+--------------------------------+ | plan | Integer | TestPlan.plan_id | | product | Integer | Product.id | | build | Integer | Build.id | | manager | Integer | Auth.User.id | | default_tester | Intege | Auth.User.id | | summary | String | | | estimated_time | TimeDelta | 2h30m30s(recommend) or HH:MM:SS| | product_version | Integer | | | plan_text_version | Integer | | | notes | String | | | status | Integer | 0:RUNNING 1:FINISHED | +-------------------+----------------+ -------------------------------+ Returns: Hash: The updated test run object. Example: # Update status to finished for run 1193 and 1194 >>> TestRun.update([1193, 1194], {'status': 1}) """ from datetime import datetime from tcms.core import forms from tcms.testruns.forms import XMLRPCUpdateRunForm if (values.get('product_version') and not values.get('product')): raise ValueError('Field "product" is required by product_version') if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time( values.get('estimated_time')) form = XMLRPCUpdateRunForm(values) if values.get('product_version'): form.populate(product_id=values['product']) if form.is_valid(): trs = TestRun.objects.filter(pk__in=pre_process_ids(value=run_ids)) _values = dict() if form.cleaned_data['plan']: _values['plan'] = form.cleaned_data['plan'] if form.cleaned_data['build']: _values['build'] = form.cleaned_data['build'] if form.cleaned_data['manager']: _values['manager'] = form.cleaned_data['manager'] if 'default_tester' in values: if values.get('default_tester') and \ form.cleaned_data['default_tester']: _values['default_tester'] = form.cleaned_data['default_tester'] else: _values['default_tester'] = None if form.cleaned_data['summary']: _values['summary'] = form.cleaned_data['summary'] if values.get('estimated_time') is not None: _values['estimated_time'] = form.cleaned_data['estimated_time'] if form.cleaned_data['product_version']: _values['product_version'] = form.cleaned_data['product_version'] if 'notes' in values: if values['notes'] in (None, ''): _values['notes'] = values['notes'] if form.cleaned_data['notes']: _values['notes'] = form.cleaned_data['notes'] if form.cleaned_data['plan_text_version']: _values['plan_text_version'] = form.cleaned_data[ 'plan_text_version'] if isinstance(form.cleaned_data['status'], int): if form.cleaned_data['status']: _values['stop_date'] = datetime.now() else: _values['stop_date'] = None trs.update(**_values) else: raise ValueError(forms.errors_to_list(form)) query = {'pk__in': trs.values_list('pk', flat=True)} return TestRun.to_xmlrpc(query)
def test_pre_process_estimated_time_with_bad_form(self): with self.assertRaisesRegex(ValueError, 'Invalid estimated_time format.'): U.pre_process_estimated_time("aaaaaa")
def update(request, case_ids, values): """ Description: Updates the fields of the selected case or cases. Params: $case_ids - Integer/String/Array Integer: A single TestCase ID. String: A comma separates string of TestCase IDs for batch processing. Array: An array of case IDs for batch mode processing $values - Hash of keys matching TestCase fields and the new values to set each field to. Returns: Array: an array of case hashes. If the update on any particular case failed, the has will contain a ERROR key and the message as to why it failed. +-----------------------+----------------+-----------------------------------------+ | Field | Type | Null | +-----------------------+----------------+-----------------------------------------+ | case_status | Integer | Optional | | product | Integer | Optional(Required if changes category) | | category | Integer | Optional | | priority | Integer | Optional | | default_tester | String/Integer | Optional(str - user_name, int - user_id)| | estimated_time | String | Optional(2h30m30s(recommend) or HH:MM:SS| | is_automated | Integer | Optional(0 - Manual, 1 - Auto, 2 - Both)| | is_automated_proposed | Boolean | Optional | | script | String | Optional | | arguments | String | Optional | | summary | String | Optional | | requirement | String | Optional | | alias | String | Optional | | notes | String | Optional | | extra_link | String | Optional(reference link) +-----------------------+----------------+-----------------------------------------+ Example: # Update alias to 'tcms' for case 12345 and 23456 >>> TestCase.update([12345, 23456], {'alias': 'tcms'}) """ from tcms.core import forms from tcms.xmlrpc.forms import UpdateCaseForm if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time(values.get('estimated_time')) form = UpdateCaseForm(values) if values.get('category') and not values.get('product'): raise ValueError('Product ID is required for category') if values.get('product'): form.populate(product_id=values['product']) if form.is_valid(): tcs = TestCase.update( case_ids=pre_process_ids(value=case_ids), values=form.cleaned_data, ) else: raise ValueError(forms.errors_to_list(form)) query = {'pk__in': tcs.values_list('pk', flat=True)} return TestCase.to_xmlrpc(query)
def create(request, values): """ Description: Creates a new Test Case object and stores it in the database. Params: $values - Array/Hash: A reference to a hash or array of hashes with keys and values matching the fields of the test case to be created. +----------------------------+----------------+-----------+---------------------------------------+ | Field | Type | Null | Description | +----------------------------+----------------+-----------+---------------------------------------+ | product | Integer | Required | ID of Product | | category | Integer | Required | ID of Category | | priority | Integer | Required | ID of Priority | | summary | String | Required | | | case_status | Integer | Optional | ID of case status | | plan | Array/Str/Int | Optional | ID or List of plan_ids | | component | Integer/String | Optional | ID of Priority | | default_tester | String | Optional | Login of tester | | estimated_time | String | Optional | 2h30m30s(recommend) or HH:MM:SS Format| | is_automated | Integer | Optional | 0: Manual, 1: Auto, 2: Both | | is_automated_proposed | Boolean | Optional | Default 0 | | script | String | Optional | | | arguments | String | Optional | | | requirement | String | Optional | | | alias | String | Optional | Must be unique | | action | String | Optional | | | effect | String | Optional | Expected Result | | setup | String | Optional | | | breakdown | String | Optional | | | tag | Array/String | Optional | String Comma separated | | bug | Array/String | Optional | String Comma separated | | extra_link | String | Optional | reference link | +----------------------------+----------------+-----------+---------------------------------------+ Returns: Array/Hash: The newly created object hash if a single case was created, or an array of objects if more than one was created. If any single case threw an error during creation, a hash with an ERROR key will be set in its place. Example: # Minimal test case parameters >>> values = { 'category': 135, 'product': 61, 'summary': 'Testing XML-RPC', 'priority': 1, } >>> TestCase.create(values) """ from tcms.core import forms from tcms.xmlrpc.forms import NewCaseForm if not (values.get('category') or values.get('summary')): raise ValueError() values['component'] = pre_process_ids(values.get('component', [])) values['plan'] = pre_process_ids(values.get('plan', [])) values['bug'] = pre_process_ids(values.get('bug', [])) if values.get('estimated_time'): values['estimated_time'] = pre_process_estimated_time(values.get('estimated_time')) form = NewCaseForm(values) form.populate(values.get('product')) if form.is_valid(): # Create the case tc = TestCase.create(author=request.user, values=form.cleaned_data) # Add case text to the case tc.add_text( action=form.cleaned_data['action'] or '', effect=form.cleaned_data['effect'] or '', setup=form.cleaned_data['setup'] or '', breakdown=form.cleaned_data['breakdown'] or '', ) # Add the case to specific plans for p in form.cleaned_data['plan']: tc.add_to_plan(plan=p) del p # Add components to the case for c in form.cleaned_data['component']: tc.add_component(component=c) del c # Add tag to the case for tag in TestTag.string_to_list(values.get('tag', [])): t, c = TestTag.objects.get_or_create(name=tag) tc.add_tag(tag=t) else: # Print the errors if the form is not passed validation. raise ValueError(forms.errors_to_list(form)) return get(request, tc.case_id)
def test_pre_process_estimated_time_with_time_string(self): time = U.pre_process_estimated_time("13:22:54") self.assertEqual(time, "13h22m54s") time = U.pre_process_estimated_time("1d13h22m54s") self.assertEqual(time, "1d13h22m54s")
def test_pre_process_estimated_time_with_upper_string(self): with self.assertRaisesRegex(ValueError, 'Invalid estimated_time format.'): U.pre_process_estimated_time("1D13H22M54S")
def test_pre_process_estimated_time_with_mhs(self): with self.assertRaisesRegex(ValueError, 'Invaild estimated_time format.'): U.pre_process_estimated_time("ambhcs")