Skip to content

Commit

Permalink
Refactor updateAssignee to use JSON-RPC. Refs kiwitcms#1063
Browse files Browse the repository at this point in the history
  • Loading branch information
rsasov authored Apr 28, 2020
1 parent 8708ef0 commit 8c9f6e7
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 83 deletions.
1 change: 0 additions & 1 deletion tcms/rpc/api/forms/testrun.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
103 changes: 69 additions & 34 deletions tcms/rpc/tests/test_testexecution.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,20 @@ def test_create_with_no_required_fields(self):
self.rpc_client.TestExecution.create(value)

def test_create_with_required_fields(self):
tcr = self.rpc_client.TestExecution.create({
execution = self.rpc_client.TestExecution.create({
"run": self.test_run.pk,
"build": self.build.pk,
"case": self.case.pk,
"case_text_version": 15,
})
self.assertIsNotNone(tcr)
self.assertIsNotNone(tcr['id'])
self.assertEqual(tcr['build_id'], self.build.pk)
self.assertEqual(tcr['case_id'], self.case.pk)
self.assertEqual(tcr['run_id'], self.test_run.pk)
self.assertIsNotNone(execution)
self.assertIsNotNone(execution['id'])
self.assertEqual(execution['build_id'], self.build.pk)
self.assertEqual(execution['case_id'], self.case.pk)
self.assertEqual(execution['run_id'], self.test_run.pk)

def test_create_with_all_fields(self):
tcr = self.rpc_client.TestExecution.create({
execution = self.rpc_client.TestExecution.create({
"run": self.test_run.pk,
"build": self.build.pk,
"case": self.case.pk,
Expand All @@ -80,14 +80,14 @@ def test_create_with_all_fields(self):
"status": self.status.pk,
"case_text_version": 3,
})
self.assertIsNotNone(tcr)
self.assertIsNotNone(tcr['id'])
self.assertEqual(tcr['build_id'], self.build.pk)
self.assertEqual(tcr['case_id'], self.case.pk)
self.assertEqual(tcr['assignee_id'], self.api_user.pk)
self.assertEqual(tcr['sortkey'], 90)
self.assertEqual(tcr['status'], self.status.name)
self.assertEqual(tcr['case_text_version'], 3)
self.assertIsNotNone(execution)
self.assertIsNotNone(execution['id'])
self.assertEqual(execution['build_id'], self.build.pk)
self.assertEqual(execution['case_id'], self.case.pk)
self.assertEqual(execution['assignee_id'], self.api_user.pk)
self.assertEqual(execution['sortkey'], 90)
self.assertEqual(execution['status'], self.status.name)
self.assertEqual(execution['case_text_version'], 3)

def test_create_with_non_exist_fields(self):
values = [
Expand Down Expand Up @@ -224,15 +224,15 @@ def test_with_non_exist_id(self):
self.assertEqual(0, len(found))

def test_filter_by_id(self):
tcr = self.rpc_client.TestExecution.filter({'pk': self.case_run.pk})[0]
self.assertIsNotNone(tcr)
self.assertEqual(tcr['build_id'], self.case_run.build.pk)
self.assertEqual(tcr['case_id'], self.case_run.case.pk)
self.assertEqual(tcr['assignee_id'], self.tester.pk)
self.assertEqual(tcr['tested_by_id'], None)
self.assertEqual(tcr['sortkey'], 10)
self.assertEqual(tcr['status'], self.status_idle.name)
self.assertEqual(tcr['status_id'], self.status_idle.pk)
execution = self.rpc_client.TestExecution.filter({'pk': self.case_run.pk})[0]
self.assertIsNotNone(execution)
self.assertEqual(execution['build_id'], self.case_run.build.pk)
self.assertEqual(execution['case_id'], self.case_run.case.pk)
self.assertEqual(execution['assignee_id'], self.tester.pk)
self.assertEqual(execution['tested_by_id'], None)
self.assertEqual(execution['sortkey'], 10)
self.assertEqual(execution['status'], self.status_idle.name)
self.assertEqual(execution['status_id'], self.status_idle.pk)


class TestExecutionGetLinks(APITestCase):
Expand All @@ -258,11 +258,11 @@ def test_get_empty_logs(self):
self.assertEqual(len(logs), 0)

def test_get_links(self):
tcr_log = LinkReference.objects.get(execution=self.case_run_1.pk)
execution_log = LinkReference.objects.get(execution=self.case_run_1.pk)
logs = self.rpc_client.TestExecution.get_links({'execution': self.case_run_1.pk})
self.assertIsInstance(logs, list)
self.assertEqual(len(logs), 1)
self.assertEqual(logs[0]['id'], tcr_log.pk)
self.assertEqual(logs[0]['id'], execution_log.pk)
self.assertEqual(logs[0]['name'], "Test logs")
self.assertEqual(logs[0]['url'], 'http://kiwitcms.org')

Expand All @@ -280,24 +280,59 @@ def _fixture_setup(self):
self.status_positive = TestExecutionStatus.objects.filter(weight__gt=0).last()

def test_update_with_single_caserun(self):
tcr = self.rpc_client.TestExecution.update(self.case_run_1.pk, {
execution = self.rpc_client.TestExecution.update(self.case_run_1.pk, {
"build": self.build.pk,
"assignee": self.user.pk,
"status": self.status_positive.pk,
"sortkey": 90
})
self.assertEqual(tcr['build'], self.build.name)
self.assertEqual(tcr['assignee'], self.user.username)
self.assertEqual(tcr['status'], self.status_positive.name)
self.assertEqual(tcr['sortkey'], 90)
self.assertEqual(execution['build'], self.build.name)
self.assertEqual(execution['assignee'], self.user.username)
self.assertEqual(execution['status'], self.status_positive.name)
self.assertEqual(execution['sortkey'], 90)

def test_update_with_assignee_id(self):
self.assertNotEqual(self.case_run_1.assignee, self.user.pk)
execution = self.rpc_client.TestExecution.update(self.case_run_1.pk, {
"assignee": self.user.pk
})
self.assertEqual(execution['assignee'], self.user.username)

def test_update_with_assignee_email(self):
self.assertNotEqual(self.case_run_1.assignee, self.user.email)
execution = self.rpc_client.TestExecution.update(self.case_run_1.pk, {
"assignee": self.user.email
})
self.assertEqual(execution['assignee'], self.user.username)

def test_update_with_assignee_username(self):
self.assertNotEqual(self.case_run_1.assignee, self.user.username)
execution = self.rpc_client.TestExecution.update(self.case_run_1.pk, {
"assignee": self.user.username
})
self.assertEqual(execution['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'):
self.rpc_client.TestExecution.update(self.case_run_1.pk, {"assignee": 1111111})
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": '[email protected]'
})

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'):
Expand Down
22 changes: 6 additions & 16 deletions tcms/static/js/testrun_actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
1 change: 0 additions & 1 deletion tcms/testruns/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
url(r'^(?P<pk>\d+)/cc/$', views.ManageTestRunCC.as_view(), name='testruns-cc'),
url(r'^(?P<pk>\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'),
]
32 changes: 1 addition & 31 deletions tcms/testruns/views.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
# -*- 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
from django.contrib.auth.decorators import permission_required
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
Expand Down Expand Up @@ -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'})

0 comments on commit 8c9f6e7

Please sign in to comment.