Skip to content

Commit eab14ea

Browse files
author
Sasha Romijn
committed
Early work to extract reviewer policy from review/utils.py.
- Legacy-Id: 16950
1 parent 2caf18d commit eab14ea

8 files changed

Lines changed: 419 additions & 354 deletions

File tree

ietf/doc/tests_review.py

Lines changed: 3 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,9 @@
3333
from ietf.review.factories import ReviewRequestFactory, ReviewAssignmentFactory
3434
from ietf.review.models import (ReviewRequest, ReviewerSettings,
3535
ReviewWish, UnavailablePeriod, NextReviewerInTeam)
36-
from ietf.review.utils import reviewer_rotation_list, possibly_advance_next_reviewer_for_team
36+
from ietf.review.policies import policy_for_team
3737

3838
from ietf.utils.test_utils import TestCase
39-
from ietf.utils.test_data import create_person
4039
from ietf.utils.test_utils import login_testing_unauthorized, reload_db_objects
4140
from ietf.utils.mail import outbox, empty_outbox, parseaddr, on_behalf_of
4241
from ietf.person.factories import PersonFactory
@@ -232,95 +231,8 @@ def test_close_request(self):
232231
self.assertIn("closed", mail_content)
233232
self.assertIn("review_request_close_comment", mail_content)
234233

235-
def test_possibly_advance_next_reviewer_for_team(self):
236-
237-
team = ReviewTeamFactory(acronym="rotationteam", name="Review Team", list_email="rotationteam@ietf.org", parent=Group.objects.get(acronym="farfut"))
238-
doc = WgDraftFactory()
239-
240-
# make a bunch of reviewers
241-
reviewers = [
242-
create_person(team, "reviewer", name="Test Reviewer{}".format(i), username="testreviewer{}".format(i))
243-
for i in range(5)
244-
]
245-
246-
self.assertEqual(reviewers, reviewer_rotation_list(team))
247-
248-
def get_skip_next(person):
249-
settings = (ReviewerSettings.objects.filter(team=team, person=person).first()
250-
or ReviewerSettings(team=team))
251-
return settings.skip_next
252-
253-
possibly_advance_next_reviewer_for_team(team, assigned_review_to_person_id=reviewers[0].pk, add_skip=False)
254-
self.assertEqual(NextReviewerInTeam.objects.get(team=team).next_reviewer, reviewers[1])
255-
self.assertEqual(get_skip_next(reviewers[0]), 0)
256-
self.assertEqual(get_skip_next(reviewers[1]), 0)
257-
258-
possibly_advance_next_reviewer_for_team(team, assigned_review_to_person_id=reviewers[1].pk, add_skip=True)
259-
self.assertEqual(NextReviewerInTeam.objects.get(team=team).next_reviewer, reviewers[2])
260-
self.assertEqual(get_skip_next(reviewers[1]), 1)
261-
self.assertEqual(get_skip_next(reviewers[2]), 0)
262-
263-
# skip reviewer 2
264-
possibly_advance_next_reviewer_for_team(team, assigned_review_to_person_id=reviewers[3].pk, add_skip=True)
265-
self.assertEqual(NextReviewerInTeam.objects.get(team=team).next_reviewer, reviewers[2])
266-
self.assertEqual(get_skip_next(reviewers[0]), 0)
267-
self.assertEqual(get_skip_next(reviewers[1]), 1)
268-
self.assertEqual(get_skip_next(reviewers[2]), 0)
269-
self.assertEqual(get_skip_next(reviewers[3]), 1)
270-
271-
# pick reviewer 2, use up reviewer 3's skip_next
272-
possibly_advance_next_reviewer_for_team(team, assigned_review_to_person_id=reviewers[2].pk, add_skip=False)
273-
self.assertEqual(NextReviewerInTeam.objects.get(team=team).next_reviewer, reviewers[4])
274-
self.assertEqual(get_skip_next(reviewers[0]), 0)
275-
self.assertEqual(get_skip_next(reviewers[1]), 1)
276-
self.assertEqual(get_skip_next(reviewers[2]), 0)
277-
self.assertEqual(get_skip_next(reviewers[3]), 0)
278-
self.assertEqual(get_skip_next(reviewers[4]), 0)
279-
280-
# check wrap-around
281-
possibly_advance_next_reviewer_for_team(team, assigned_review_to_person_id=reviewers[4].pk)
282-
self.assertEqual(NextReviewerInTeam.objects.get(team=team).next_reviewer, reviewers[0])
283-
self.assertEqual(get_skip_next(reviewers[0]), 0)
284-
self.assertEqual(get_skip_next(reviewers[1]), 1)
285-
self.assertEqual(get_skip_next(reviewers[2]), 0)
286-
self.assertEqual(get_skip_next(reviewers[3]), 0)
287-
self.assertEqual(get_skip_next(reviewers[4]), 0)
288-
289-
# unavailable
290-
today = datetime.date.today()
291-
UnavailablePeriod.objects.create(team=team, person=reviewers[1], start_date=today, end_date=today, availability="unavailable")
292-
possibly_advance_next_reviewer_for_team(team, assigned_review_to_person_id=reviewers[0].pk)
293-
self.assertEqual(NextReviewerInTeam.objects.get(team=team).next_reviewer, reviewers[2])
294-
self.assertEqual(get_skip_next(reviewers[0]), 0)
295-
self.assertEqual(get_skip_next(reviewers[1]), 1) # don't consume that skip while the reviewer is unavailable
296-
self.assertEqual(get_skip_next(reviewers[2]), 0)
297-
self.assertEqual(get_skip_next(reviewers[3]), 0)
298-
self.assertEqual(get_skip_next(reviewers[4]), 0)
299-
300-
# pick unavailable anyway
301-
possibly_advance_next_reviewer_for_team(team, assigned_review_to_person_id=reviewers[1].pk, add_skip=False)
302-
self.assertEqual(NextReviewerInTeam.objects.get(team=team).next_reviewer, reviewers[2])
303-
self.assertEqual(get_skip_next(reviewers[0]), 0)
304-
self.assertEqual(get_skip_next(reviewers[1]), 1)
305-
self.assertEqual(get_skip_next(reviewers[2]), 0)
306-
self.assertEqual(get_skip_next(reviewers[3]), 0)
307-
self.assertEqual(get_skip_next(reviewers[4]), 0)
308-
309-
# not through min_interval so advance past reviewer[2]
310-
settings, _ = ReviewerSettings.objects.get_or_create(team=team, person=reviewers[2])
311-
settings.min_interval = 30
312-
settings.save()
313-
req = ReviewRequest.objects.create(team=team, doc=doc, type_id="early", state_id="assigned", deadline=today, requested_by=reviewers[0])
314-
ReviewAssignmentFactory(review_request=req, state_id="accepted", reviewer = reviewers[2].email_set.first(),assigned_on = req.time)
315-
possibly_advance_next_reviewer_for_team(team, assigned_review_to_person_id=reviewers[3].pk)
316-
self.assertEqual(NextReviewerInTeam.objects.get(team=team).next_reviewer, reviewers[4])
317-
self.assertEqual(get_skip_next(reviewers[0]), 0)
318-
self.assertEqual(get_skip_next(reviewers[1]), 1)
319-
self.assertEqual(get_skip_next(reviewers[2]), 0)
320-
self.assertEqual(get_skip_next(reviewers[3]), 0)
321-
self.assertEqual(get_skip_next(reviewers[4]), 0)
322-
323234
def test_assign_reviewer(self):
235+
# TODO: this test overlaps way too much with the reviewer policy
324236
doc = WgDraftFactory(pages=2)
325237
review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut"))
326238
rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',person__name='Some Reviewer',name_id='reviewer')
@@ -413,7 +325,7 @@ def test_assign_reviewer(self):
413325

414326
# assign
415327
empty_outbox()
416-
rotation_list = reviewer_rotation_list(review_req.team)
328+
rotation_list = policy_for_team(review_req.team).reviewer_rotation_list(review_req.team)
417329
reviewer = Email.objects.filter(role__name="reviewer", role__group=review_req.team, person=rotation_list[0]).first()
418330
r = self.client.post(assign_url, { "action": "assign", "reviewer": reviewer.pk })
419331
self.assertEqual(r.status_code, 302)

ietf/doc/views_review.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@
3333
from ietf.message.models import Message
3434
from ietf.message.utils import infer_message
3535
from ietf.person.fields import PersonEmailChoiceField, SearchablePersonField
36+
from ietf.review.policies import policy_for_team
3637
from ietf.review.utils import (active_review_teams, assign_review_request_to_reviewer,
3738
can_request_review_of_doc, can_manage_review_requests_for_team,
3839
email_review_assignment_change, email_review_request_change,
3940
close_review_request_states,
40-
close_review_request, setup_reviewer_field)
41+
close_review_request)
4142
from ietf.review import mailarch
4243
from ietf.utils.fields import DatepickerDateField
4344
from ietf.utils.text import strip_prefix, xslugify
@@ -293,7 +294,7 @@ class AssignReviewerForm(forms.Form):
293294

294295
def __init__(self, review_req, *args, **kwargs):
295296
super(AssignReviewerForm, self).__init__(*args, **kwargs)
296-
setup_reviewer_field(self.fields["reviewer"], review_req)
297+
policy_for_team(review_req.team).setup_reviewer_field(self.fields["reviewer"], review_req)
297298

298299

299300
@login_required

ietf/group/forms.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
from ietf.person.fields import SearchableEmailsField, PersonEmailChoiceField
2020
from ietf.person.models import Person
2121
from ietf.review.models import ReviewerSettings, UnavailablePeriod, ReviewSecretarySettings
22-
from ietf.review.utils import close_review_request_states, setup_reviewer_field
22+
from ietf.review.policies import policy_for_team
23+
from ietf.review.utils import close_review_request_states
2324
from ietf.utils.textupload import get_cleaned_text_file_content
2425
from ietf.utils.text import strip_suffix
2526
#from ietf.utils.ordereddict import insert_after_in_ordered_dict
@@ -254,7 +255,7 @@ def __init__(self, review_req, *args, **kwargs):
254255

255256
self.fields["close"].widget.attrs["class"] = "form-control input-sm"
256257

257-
setup_reviewer_field(self.fields["reviewer"], review_req)
258+
policy_for_team(review_req.team).setup_reviewer_field(self.fields["reviewer"], review_req)
258259
self.fields["reviewer"].widget.attrs["class"] = "form-control input-sm"
259260

260261
if self.is_bound:

ietf/group/tests_review.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from django.urls import reverse as urlreverse
1414

15+
from ietf.review.policies import policy_for_team
1516
from ietf.utils.test_utils import login_testing_unauthorized, TestCase, reload_db_objects
1617
from ietf.doc.models import TelechatDocEvent
1718
from ietf.group.models import Role
@@ -23,7 +24,6 @@
2324
suggested_review_requests_for_team,
2425
review_assignments_needing_reviewer_reminder, email_reviewer_reminder,
2526
review_assignments_needing_secretary_reminder, email_secretary_reminder,
26-
reviewer_rotation_list,
2727
send_unavaibility_period_ending_reminder, send_reminder_all_open_reviews,
2828
send_review_reminder_overdue_assignment, send_reminder_unconfirmed_assignments)
2929
from ietf.name.models import ReviewResultName, ReviewRequestStateName, ReviewAssignmentStateName
@@ -655,7 +655,8 @@ def test_rotation_queue_update(self):
655655
secretary = RoleFactory.create(group=group,name_id='secr')
656656
docs = [DocumentFactory.create(type_id='draft',group=None) for i in range(4)]
657657
requests = [ReviewRequestFactory(team=group,doc=docs[i]) for i in range(4)]
658-
rot_list = reviewer_rotation_list(group)
658+
policy = policy_for_team(group)
659+
rot_list = policy.reviewer_rotation_list(group)
659660

660661
expected_ending_head_of_rotation = rot_list[3]
661662

@@ -676,6 +677,6 @@ def test_rotation_queue_update(self):
676677
self.client.login(username=secretary.person.user.username,password=secretary.person.user.username+'+password')
677678
r = self.client.post(unassigned_url, postdict)
678679
self.assertEqual(r.status_code,302)
679-
self.assertEqual(expected_ending_head_of_rotation,reviewer_rotation_list(group)[0])
680+
self.assertEqual(expected_ending_head_of_rotation, policy.reviewer_rotation_list(group)[0])
680681
self.assertMailboxContains(outbox, subject='Last Call assignment', text='Requested by', count=4)
681682

ietf/group/views.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
from ietf.name.models import GroupTypeName, StreamName
9393
from ietf.person.models import Email
9494
from ietf.review.models import ReviewRequest, ReviewAssignment, ReviewerSettings, ReviewSecretarySettings
95+
from ietf.review.policies import policy_for_team
9596
from ietf.review.utils import (can_manage_review_requests_for_team,
9697
can_access_review_stats_for_team,
9798

@@ -103,7 +104,6 @@
103104
unavailable_periods_to_list,
104105
current_unavailable_periods_for_reviewers,
105106
email_reviewer_availability_change,
106-
reviewer_rotation_list,
107107
latest_review_assignments_for_reviewers,
108108
augment_review_requests_with_events,
109109
get_default_filter_re,
@@ -1391,7 +1391,7 @@ def reviewer_overview(request, acronym, group_type=None):
13911391

13921392
can_manage = can_manage_review_requests_for_team(request.user, group)
13931393

1394-
reviewers = reviewer_rotation_list(group)
1394+
reviewers = policy_for_team(group).reviewer_rotation_list(group)
13951395

13961396
reviewer_settings = { s.person_id: s for s in ReviewerSettings.objects.filter(team=group) }
13971397
unavailable_periods = defaultdict(list)
@@ -1541,13 +1541,14 @@ def manage_review_requests(request, acronym, group_type=None, assignment_status=
15411541
# Make sure the any assignments to the person at the head
15421542
# of the rotation queue are processed first so that the queue
15431543
# rotates before any more assignments are processed
1544-
head_of_rotation = reviewer_rotation_list(group)[0]
1544+
reviewer_policy = policy_for_team(group)
1545+
head_of_rotation = reviewer_policy.reviewer_rotation_list(group)[0]
15451546
while head_of_rotation in assignments_by_person:
15461547
for review_req in assignments_by_person[head_of_rotation]:
15471548
assign_review_request_to_reviewer(request, review_req, review_req.form.cleaned_data["reviewer"],review_req.form.cleaned_data["add_skip"])
15481549
reqs_to_assign.remove(review_req)
15491550
del assignments_by_person[head_of_rotation]
1550-
head_of_rotation = reviewer_rotation_list(group)[0]
1551+
head_of_rotation = reviewer_policy.reviewer_rotation_list(group)[0]
15511552

15521553
for review_req in reqs_to_assign:
15531554
assign_review_request_to_reviewer(request, review_req, review_req.form.cleaned_data["reviewer"],review_req.form.cleaned_data["add_skip"])
@@ -1660,7 +1661,7 @@ def should_be_replicated_in_last_call_section(r):
16601661

16611662
partial_msg = render_to_string(template.path, {
16621663
"review_assignments": review_assignments,
1663-
"rotation_list": reviewer_rotation_list(group)[:10],
1664+
"rotation_list": policy_for_team(group).reviewer_rotation_list(group)[:10],
16641665
"group" : group,
16651666
})
16661667

0 commit comments

Comments
 (0)