Skip to content

Commit 77a5647

Browse files
committed
Merged in [16933] from sasha@dashcare.nl:
Fix ietf-tools#2119 - Allow specifying review type for suggested reviews in LC and telechat If a review is suggested on the 'manage unassigned reviews' page, and the document is in both last call and telechat, the assign form now asks for the type of review that should be assigned. This commit also fixes two bugs in this process: - Comparisons in some cases between strings and integers (group/views.py:1485/1487) - Rejections when assigning suggested reviews, as they could be considered a newly opened request due to not having a pk (group/views.py:1508) - Legacy-Id: 16951 Note: SVN reference [16933] has been migrated to Git commit ee4bc0c
2 parents 0f12d47 + ee4bc0c commit 77a5647

5 files changed

Lines changed: 125 additions & 18 deletions

File tree

ietf/group/forms.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
# IETF imports
1818
from ietf.group.models import Group, GroupHistory, GroupStateName
19+
from ietf.name.models import ReviewTypeName
1920
from ietf.person.fields import SearchableEmailsField, PersonEmailChoiceField
2021
from ietf.person.models import Person
2122
from ietf.review.models import ReviewerSettings, UnavailablePeriod, ReviewSecretarySettings
@@ -229,6 +230,7 @@ class ManageReviewRequestForm(forms.Form):
229230
close = forms.ModelChoiceField(queryset=close_review_request_states(), required=False)
230231
close_comment = forms.CharField(max_length=255, required=False)
231232
reviewer = PersonEmailChoiceField(empty_label="(None)", required=False, label_with="person")
233+
review_type = forms.ModelChoiceField(queryset=ReviewTypeName.objects.filter(slug__in=['telechat', 'lc']), required=True)
232234
add_skip = forms.BooleanField(required=False)
233235

234236
def __init__(self, review_req, *args, **kwargs):
@@ -257,6 +259,9 @@ def __init__(self, review_req, *args, **kwargs):
257259
setup_reviewer_field(self.fields["reviewer"], review_req)
258260
self.fields["reviewer"].widget.attrs["class"] = "form-control input-sm"
259261

262+
if not getattr(review_req, 'in_lc_and_telechat', False):
263+
del self.fields["review_type"]
264+
260265
if self.is_bound:
261266
if self.data.get("action") == "close":
262267
self.fields["close"].required = True

ietf/group/tests_review.py

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from django.urls import reverse as urlreverse
1414

1515
from ietf.utils.test_utils import login_testing_unauthorized, TestCase, reload_db_objects
16-
from ietf.doc.models import TelechatDocEvent
16+
from ietf.doc.models import TelechatDocEvent, LastCallDocEvent, State
1717
from ietf.group.models import Role
1818
from ietf.iesg.models import TelechatDate
1919
from ietf.person.models import Person
@@ -26,7 +26,8 @@
2626
reviewer_rotation_list,
2727
send_unavaibility_period_ending_reminder, send_reminder_all_open_reviews,
2828
send_review_reminder_overdue_assignment, send_reminder_unconfirmed_assignments)
29-
from ietf.name.models import ReviewResultName, ReviewRequestStateName, ReviewAssignmentStateName
29+
from ietf.name.models import ReviewResultName, ReviewRequestStateName, ReviewAssignmentStateName, \
30+
ReviewTypeName
3031
import ietf.group.views
3132
from ietf.utils.mail import outbox, empty_outbox
3233
from ietf.dbtemplate.factories import DBTemplateFactory
@@ -91,6 +92,7 @@ def test_suggested_review_requests(self):
9192
self.assertEqual(len(suggestions), 1)
9293
self.assertEqual(suggestions[0].doc, doc)
9394
self.assertEqual(suggestions[0].team, team)
95+
self.assertFalse(getattr(suggestions[0], 'in_lc_and_telechat', None))
9496

9597
# blocked by non-versioned refusal
9698
review_req.requested_rev = ""
@@ -120,6 +122,35 @@ def test_suggested_review_requests(self):
120122

121123
self.assertEqual(len(suggested_review_requests_for_team(team)), 1)
122124

125+
def test_suggested_review_requests_on_lc_and_telechat(self):
126+
review_req = ReviewRequestFactory(state_id='assigned')
127+
doc = review_req.doc
128+
team = review_req.team
129+
130+
# put on telechat
131+
TelechatDocEvent.objects.create(
132+
type="scheduled_for_telechat",
133+
by=Person.objects.get(name="(System)"),
134+
doc=doc,
135+
rev=doc.rev,
136+
telechat_date=TelechatDate.objects.all().first().date,
137+
)
138+
139+
# Put on last call as well
140+
doc.states.add(State.objects.get(type="draft-iesg", slug="lc", used=True))
141+
LastCallDocEvent.objects.create(
142+
doc=doc,
143+
expires=datetime.datetime.now() + datetime.timedelta(days=365),
144+
by=Person.objects.get(name="(System)"),
145+
rev=doc.rev
146+
)
147+
148+
suggestions = suggested_review_requests_for_team(team)
149+
self.assertEqual(len(suggestions), 1)
150+
self.assertEqual(suggestions[0].doc, doc)
151+
self.assertEqual(suggestions[0].team, team)
152+
self.assertTrue(suggestions[0].in_lc_and_telechat)
153+
123154
def test_reviewer_overview(self):
124155
team = ReviewTeamFactory()
125156
reviewer = RoleFactory(name_id='reviewer',group=team,person__user__username='reviewer').person
@@ -228,7 +259,9 @@ def test_manage_review_requests(self):
228259
"r{}-action".format(review_req3.pk): "assign",
229260
"r{}-reviewer".format(review_req3.pk): another_reviewer.email_set.first().pk,
230261
"r{}-add_skip".format(review_req3.pk): 1,
231-
262+
# Should be ignored, setting review_type only applies to suggested reviews
263+
"r{}-review_type".format(review_req3.pk): ReviewTypeName.objects.get(slug='telechat').pk,
264+
232265
"action": "save",
233266
})
234267
self.assertEqual(r.status_code, 302)
@@ -237,7 +270,67 @@ def test_manage_review_requests(self):
237270
settings = ReviewerSettings.objects.filter(team=review_req3.team, person=another_reviewer).first()
238271
self.assertEqual(settings.skip_next,1)
239272
self.assertEqual(review_req3.state_id, "assigned")
273+
self.assertEqual(review_req3.type_id, "lc")
274+
275+
def test_manage_review_requests_assign_suggested_reviews(self):
276+
doc = DocumentFactory()
277+
team = ReviewTeamFactory()
240278

279+
# put on telechat
280+
TelechatDocEvent.objects.create(
281+
type="scheduled_for_telechat",
282+
by=Person.objects.get(name="(System)"),
283+
doc=doc,
284+
rev=doc.rev,
285+
telechat_date=TelechatDate.objects.all().first().date,
286+
)
287+
288+
# Put on last call as well
289+
doc.states.add(State.objects.get(type="draft-iesg", slug="lc", used=True))
290+
LastCallDocEvent.objects.create(
291+
doc=doc,
292+
expires=datetime.datetime.now() + datetime.timedelta(days=365),
293+
by=Person.objects.get(name="(System)"),
294+
rev=doc.rev
295+
)
296+
297+
reviewer = RoleFactory(name_id='reviewer', group=team, person__user__username='reviewer')
298+
unassigned_url = urlreverse(ietf.group.views.manage_review_requests, kwargs={ 'acronym': team.acronym, 'group_type': team.type_id, "assignment_status": "unassigned" })
299+
300+
login_testing_unauthorized(self, "secretary", unassigned_url)
301+
302+
# get
303+
r = self.client.get(unassigned_url)
304+
self.assertEqual(r.status_code, 200)
305+
self.assertContains(r, doc.name)
306+
307+
# Submit as lc review
308+
r = self.client.post(unassigned_url, {
309+
"rlc-{}-action".format(doc.name): "assign",
310+
"rlc-{}-review_type".format(doc.name): ReviewTypeName.objects.get(slug='lc').pk,
311+
"rlc-{}-reviewer".format(doc.name): reviewer.person.email_set.first().pk,
312+
313+
"action": "save",
314+
})
315+
self.assertEqual(r.status_code, 302)
316+
review_request = doc.reviewrequest_set.get()
317+
self.assertEqual(review_request.type_id, 'lc')
318+
319+
# Clean up and try again as telechat
320+
review_request.reviewassignment_set.all().delete()
321+
review_request.delete()
322+
323+
r = self.client.post(unassigned_url, {
324+
"rlc-{}-action".format(doc.name): "assign",
325+
"rlc-{}-review_type".format(doc.name): ReviewTypeName.objects.get(slug='telechat').pk,
326+
"rlc-{}-reviewer".format(doc.name): reviewer.person.email_set.first().pk,
327+
328+
"action": "save",
329+
})
330+
self.assertEqual(r.status_code, 302)
331+
review_request = doc.reviewrequest_set.get()
332+
self.assertEqual(review_request.type_id, 'telechat')
333+
241334
def test_email_open_review_assignments(self):
242335
review_req1 = ReviewRequestFactory()
243336
review_assignment_completed = ReviewAssignmentFactory(review_request=review_req1,reviewer=EmailFactory(person__user__username='marschairman'), state_id='completed', reviewed_rev=0)

ietf/group/views.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,9 +1481,9 @@ def manage_review_requests(request, acronym, group_type=None, assignment_status=
14811481
for a in r.reviewassignment_set.all():
14821482
if l and rev:
14831483
if r.doc_id == l[0].doc_id and a.reviewed_rev:
1484-
if int(a.reviewed_rev) > rev:
1484+
if int(a.reviewed_rev) > int(rev):
14851485
l = [r]
1486-
elif int(a.reviewed_rev) == rev:
1486+
elif int(a.reviewed_rev) == int(rev):
14871487
l.append(r)
14881488
else:
14891489
l = [r]
@@ -1504,7 +1504,7 @@ def manage_review_requests(request, acronym, group_type=None, assignment_status=
15041504
saving = form_action.startswith("save")
15051505

15061506
# check for conflicts
1507-
review_requests_dict = { six.text_type(r.pk): r for r in review_requests }
1507+
review_requests_dict = { six.text_type(r.pk): r for r in review_requests if r.pk}
15081508
posted_reqs = set(request.POST.getlist("reviewrequest", []))
15091509
current_reqs = set(review_requests_dict.keys())
15101510

@@ -1529,6 +1529,8 @@ def manage_review_requests(request, acronym, group_type=None, assignment_status=
15291529
close_review_request(request, review_req, review_req.form.cleaned_data["close"],
15301530
review_req.form.cleaned_data["close_comment"])
15311531
elif action=="assign" and review_req.form.cleaned_data["reviewer"]:
1532+
if review_req.form.cleaned_data.get("review_type"):
1533+
review_req.type = review_req.form.cleaned_data.get("review_type")
15321534
reqs_to_assign.append(review_req)
15331535

15341536
assignments_by_person = dict()

ietf/review/utils.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,6 @@ def suggested_review_requests_for_team(team):
608608
requested_by=system_person,
609609
state=requested_state,
610610
)
611-
612611
seen_deadlines[doc.pk] = deadline
613612

614613

@@ -642,16 +641,20 @@ def suggested_review_requests_for_team(team):
642641

643642
if not deadline or deadline > seen_deadlines.get(doc_pk, datetime.date.max):
644643
continue
645-
646-
requests[doc_pk] = ReviewRequest(
647-
time=event_time,
648-
type=telechat_type,
649-
doc_id=doc_pk,
650-
team=team,
651-
deadline=deadline,
652-
requested_by=system_person,
653-
state=requested_state,
654-
)
644+
645+
if doc_pk in requests:
646+
# Document was already added in last call, i.e. it is both in last call and telechat
647+
requests[doc_pk].in_lc_and_telechat = True
648+
else:
649+
requests[doc_pk] = ReviewRequest(
650+
time=event_time,
651+
type=telechat_type,
652+
doc_id=doc_pk,
653+
team=team,
654+
deadline=deadline,
655+
requested_by=system_person,
656+
state=requested_state,
657+
)
655658

656659
seen_deadlines[doc_pk] = deadline
657660

ietf/templates/group/manage_review_requests.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ <h1>Manage {{ assignment_status }} open review requests for {{ group.acronym }}<
3737

3838
<h3 class="panel-title">
3939
<span class="pull-right">
40-
{{ r.type.name }}
40+
{% if r.in_lc_and_telechat %}Last Call and telechat{% else %}{{ r.type.name }}{% endif %}
4141
- deadline {{ r.deadline|date:"Y-m-d" }}
4242
{% if r.due %}<span class="label label-warning">{{ r.due }} day{{ r.due|pluralize }}</span>{% endif %}
4343
</span>
@@ -134,6 +134,10 @@ <h3 class="panel-title">
134134
{{ r.form.action }}
135135

136136
<span class="reviewer-controls form-inline">
137+
{% if r.form.review_type %}
138+
<label for="{{ r.form.review_type.id_for_label }}">Review Type:</label>
139+
{{ r.form.review_type }}
140+
{% endif %}
137141
<label for="{{ r.form.reviewer.id_for_label }}">Assign:</label>
138142
{{ r.form.reviewer }}
139143
{{ r.form.add_skip }} <label for="{{ r.form.add_skip.id_for_label }}">Skip next time</label>

0 commit comments

Comments
 (0)