Skip to content

Commit 1656b00

Browse files
committed
Merged in [16819] from sasha@dashcare.nl:
Fix ietf-tools#2186 - Return review req to 'requested' status if no review assignments are open. If a review assignment is rejected, withdrawn, marked no response, etc., and this leaves a review request without any assigned/accepted/completed review assignments, return the request state to 'requested', which means it will be shown as an unassigned review in all interfaces. - Legacy-Id: 16881 Note: SVN reference [16819] has been migrated to Git commit fdb4c2a
2 parents 45465f1 + fdb4c2a commit 1656b00

3 files changed

Lines changed: 49 additions & 2 deletions

File tree

ietf/group/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1290,7 +1290,7 @@ def get_open_review_requests_for_team(team, assignment_status=None):
12901290
Q(state_id='requested') | Q(state_id='assigned',reviewassignment__state__in=('assigned','accepted'))
12911291
).prefetch_related(
12921292
"type", "state", "doc", "doc__states",
1293-
).order_by("-time", "-id")
1293+
).order_by("-time", "-id").distinct()
12941294

12951295
if assignment_status == "unassigned":
12961296
open_review_requests = suggested_review_requests_for_team(team) + list(open_review_requests.filter(state_id='requested'))

ietf/review/models.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,19 @@ class ReviewAssignment(models.Model):
158158
def __str__(self):
159159
return "Assignment for %s (%s) : %s %s of %s" % (self.reviewer.person, self.state, self.review_request.team.acronym, self.review_request.type, self.review_request.doc)
160160

161+
def save(self, *args, **kwargs):
162+
"""
163+
Save the assignment, and check whether the review request status needs to be updated.
164+
If the review request has no other active or completed reviews, the review request
165+
needs to be treated as an unassigned request, as it will need a new reviewer.
166+
"""
167+
super(ReviewAssignment, self).save(*args, **kwargs)
168+
active_states = ['assigned', 'accepted', 'completed']
169+
review_req_has_active_assignments = self.review_request.reviewassignment_set.filter(state__in=active_states)
170+
if self.review_request.state_id == 'assigned' and not review_req_has_active_assignments:
171+
self.review_request.state_id = 'requested'
172+
self.review_request.save()
173+
161174

162175
def get_default_review_types():
163176
return ReviewTypeName.objects.filter(slug__in=['early','lc','telechat'])

ietf/review/tests.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
from __future__ import absolute_import, print_function, unicode_literals
66

7-
from ietf.utils.test_utils import TestCase
7+
from ietf.review.factories import ReviewAssignmentFactory, ReviewRequestFactory
8+
from ietf.utils.test_utils import TestCase, reload_db_objects
89
from .mailarch import hash_list_message_id
910

1011
class HashTest(TestCase):
@@ -23,3 +24,36 @@ def test_hash_list_message_id(self):
2324
):
2425
self.assertEqual(hash, hash_list_message_id(list, msgid))
2526

27+
28+
class ReviewAssignmentTest(TestCase):
29+
def test_update_review_req_status(self):
30+
review_req = ReviewRequestFactory(state_id='assigned')
31+
ReviewAssignmentFactory(review_request=review_req, state_id='part-completed')
32+
assignment = ReviewAssignmentFactory(review_request=review_req)
33+
34+
assignment.state_id = 'no-response'
35+
assignment.save()
36+
review_req = reload_db_objects(review_req)
37+
self.assertEqual(review_req.state_id, 'requested')
38+
39+
def test_no_update_review_req_status_when_other_active_assignment(self):
40+
# If there is another still active assignment, do not update review_req state
41+
review_req = ReviewRequestFactory(state_id='assigned')
42+
ReviewAssignmentFactory(review_request=review_req, state_id='assigned')
43+
assignment = ReviewAssignmentFactory(review_request=review_req)
44+
45+
assignment.state_id = 'no-response'
46+
assignment.save()
47+
review_req = reload_db_objects(review_req)
48+
self.assertEqual(review_req.state_id, 'assigned')
49+
50+
def test_no_update_review_req_status_when_review_req_withdrawn(self):
51+
# review_req state must only be changed to "requested", if old state was "assigned",
52+
# to prevent reviving dead review requests
53+
review_req = ReviewRequestFactory(state_id='withdrawn')
54+
assignment = ReviewAssignmentFactory(review_request=review_req)
55+
56+
assignment.state_id = 'no-response'
57+
assignment.save()
58+
review_req = reload_db_objects(review_req)
59+
self.assertEqual(review_req.state_id, 'withdrawn')

0 commit comments

Comments
 (0)