From 15fc82d5fc91f729fb0e0b88fd0b7b752f3a9306 Mon Sep 17 00:00:00 2001 From: Rosen Sasov Date: Tue, 24 Mar 2020 19:31:48 +0200 Subject: [PATCH] Refactor updateAssignee to use JSON-RPC. Refs #1063 Remove unused imports Refactor update of assignee rpc call Remove override of assignee form field Remove trimming Fix tests for changeAssignee Revert change in test case for updateAssignee with invalid id Add tests for updateAssignee --- tcms/rpc/api/forms/testrun.py | 1 - tcms/rpc/tests/test_testexecution.py | 30 ++++++++++++++++++++++++-- tcms/static/js/testrun_actions.js | 22 ++++++------------- tcms/testruns/urls.py | 1 - tcms/testruns/views.py | 32 +--------------------------- 5 files changed, 35 insertions(+), 51 deletions(-) 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'})