diff --git a/tcms/rpc/api/forms/testrun.py b/tcms/rpc/api/forms/testrun.py index f6d18ebc06..96e2f9a3da 100644 --- a/tcms/rpc/api/forms/testrun.py +++ b/tcms/rpc/api/forms/testrun.py @@ -69,6 +69,5 @@ def clean_status(self): class UpdateExecutionForm(BaseCaseRunForm): - assignee = forms.ModelChoiceField(queryset=User.objects.all(), required=False) tested_by = forms.ModelChoiceField(queryset=User.objects.all(), required=False) build = forms.ModelChoiceField(queryset=Build.objects.all(), required=False) diff --git a/tcms/rpc/tests/test_testexecution.py b/tcms/rpc/tests/test_testexecution.py index 22c59bbfcf..03bc436ef1 100644 --- a/tcms/rpc/tests/test_testexecution.py +++ b/tcms/rpc/tests/test_testexecution.py @@ -291,14 +291,40 @@ def test_update_with_single_caserun(self): self.assertEqual(tcr['status'], self.status_positive.name) self.assertEqual(tcr['sortkey'], 90) + def test_update_with_assignee_id(self): + tcr = self.rpc_client.TestExecution.update(self.case_run_1.pk, { + "assignee": self.user.pk + }) + self.assertEqual(tcr['assignee'], self.user.username) + + def test_update_with_assignee_email(self): + tcr = self.rpc_client.TestExecution.update(self.case_run_1.pk, { + "assignee": self.user.email + }) + self.assertEqual(tcr['assignee'], self.user.username) + + def test_update_with_assignee_username(self): + tcr = self.rpc_client.TestExecution.update(self.case_run_1.pk, { + "assignee": self.user.username + }) + self.assertEqual(tcr['assignee'], self.user.username) + def test_update_with_non_existing_build(self): with self.assertRaisesRegex(XmlRPCFault, 'Select a valid choice'): self.rpc_client.TestExecution.update(self.case_run_1.pk, {"build": 1111111}) - def test_update_with_non_existing_assignee(self): - with self.assertRaisesRegex(XmlRPCFault, 'Select a valid choice'): + def test_update_with_non_existing_assignee_id(self): + with self.assertRaisesRegex(XmlRPCFault, 'Unknown user_id'): self.rpc_client.TestExecution.update(self.case_run_1.pk, {"assignee": 1111111}) + def test_update_with_non_existing_assignee_email(self): + with self.assertRaisesRegex(XmlRPCFault, 'Unknown user'): + self.rpc_client.TestExecution.update(self.case_run_1.pk, {"assignee": 'nonExistentEmail@gmail.com'}) + + def test_update_with_non_existing_assignee_username(self): + with self.assertRaisesRegex(XmlRPCFault, 'Unknown user:'): + self.rpc_client.TestExecution.update(self.case_run_1.pk, {"assignee": 'nonExistentUsername'}) + def test_update_with_non_existing_status(self): with self.assertRaisesRegex(XmlRPCFault, 'Select a valid choice'): self.rpc_client.TestExecution.update(self.case_run_1.pk, diff --git a/tcms/static/js/testrun_actions.js b/tcms/static/js/testrun_actions.js index 5b2e451d7d..5272e394f2 100644 --- a/tcms/static/js/testrun_actions.js +++ b/tcms/static/js/testrun_actions.js @@ -527,28 +527,18 @@ function removeRunCC(run_id, user, container) { } function changeCaseRunAssignee() { - var runs = serializeCaseRunFromInputList(jQ('#id_table_cases')[0]); - if (!runs.length) { + var executions = serializeCaseRunFromInputList(jQ('#id_table_cases')[0]); + if (!executions.length) { window.alert(default_messages.alert.no_case_selected); return false; } - var p = window.prompt('Please type new email or username for assignee'); - if (!p) { + var assignee = window.prompt('Please type new email or username for assignee'); + if (!assignee) { return false; } - - jQ.ajax({ - 'url': '/runs/update-assignee/', - 'type': 'POST', - 'data': { ids: runs, assignee: p }, - 'success': function (data, textStatus, jqXHR) { - window.location.reload(); - }, - 'error': function (jqXHR, textStatus, errorThrown) { - json_failure(jqXHR); - } - }); + executions.forEach(execution_id => jsonRPC('TestExecution.update', [execution_id, {'assignee': assignee}], () => { }, sync=true)); + window.location.reload(); } function serializeCaseRunFromInputList(table, name) { diff --git a/tcms/testruns/urls.py b/tcms/testruns/urls.py index 9766cc264e..c1dd2b47f5 100644 --- a/tcms/testruns/urls.py +++ b/tcms/testruns/urls.py @@ -20,7 +20,6 @@ url(r'^(?P\d+)/cc/$', views.ManageTestRunCC.as_view(), name='testruns-cc'), url(r'^(?P\d+)/update/$', views.UpdateCaseRunTextView.as_view(), name='testruns-update_case_run_text'), - url(r'^update-assignee/$', views.UpdateAssigneeView.as_view()), url(r'^search/$', views.SearchTestRunView.as_view(), name='testruns-search'), ] diff --git a/tcms/testruns/views.py b/tcms/testruns/views.py index 1b81e06717..2f15fe2e46 100755 --- a/tcms/testruns/views.py +++ b/tcms/testruns/views.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from http import HTTPStatus - from django.conf import settings from django.contrib import messages from django.contrib.auth import get_user_model @@ -9,7 +7,7 @@ from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist from django.db.models import Count, Q -from django.http import Http404, HttpResponseRedirect, JsonResponse +from django.http import Http404, HttpResponseRedirect from django.shortcuts import get_object_or_404, render from django.urls import reverse from django.utils.decorators import method_decorator @@ -584,31 +582,3 @@ def get_caseruns_of_runs(runs, kwargs=None): if status: caseruns = caseruns.filter(status__name__iexact=status) return caseruns - - -@method_decorator(permission_required('testruns.change_testexecution'), name='dispatch') -class UpdateAssigneeView(View): - """Updates TestExecution.assignee. Called from the front-end.""" - - http_method_names = ['post'] - - def post(self, request): - assignee = request.POST.get('assignee') - try: - user = User.objects.get(username=assignee) - except User.DoesNotExist: - try: - user = User.objects.get(email=assignee) - except User.DoesNotExist: - return JsonResponse({'rc': 1, - 'response': _('User %s not found!') % assignee}, - status=HTTPStatus.NOT_FOUND) - - object_ids = request.POST.getlist('ids[]') - - for caserun_pk in object_ids: - execution = get_object_or_404(TestExecution, pk=int(caserun_pk)) - execution.assignee = user - execution.save() - - return JsonResponse({'rc': 0, 'response': 'ok'})