Skip to content

Commit b5d8644

Browse files
committed
Added two new configuration settings for the review team secretary,
one to set how many days to include in the reviewers list, and another one to limit the number of completed items in the list for each person. This version replaces the one I did earlier, and includes much more test cases to test different limits on the reviewers page. Commit ready for merge. - Legacy-Id: 17034
1 parent 996fcf8 commit b5d8644

6 files changed

Lines changed: 209 additions & 7 deletions

File tree

ietf/group/forms.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ def clean_end_date(self):
334334
class ReviewSecretarySettingsForm(forms.ModelForm):
335335
class Meta:
336336
model = ReviewSecretarySettings
337-
fields = ['remind_days_before_deadline']
337+
fields = ['remind_days_before_deadline', 'max_items_to_show_in_reviewer_list',
338+
'days_to_show_in_reviewer_list']
338339

339340

ietf/group/tests_review.py

Lines changed: 156 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ def test_reviewer_overview(self):
156156
reviewer = RoleFactory(name_id='reviewer',group=team,person__user__username='reviewer').person
157157
ReviewerSettingsFactory(person=reviewer,team=team)
158158
review_req1 = ReviewRequestFactory(state_id='completed',team=team)
159+
secretary = Person.objects.get(user__username="secretary")
159160
ReviewAssignmentFactory(review_request = review_req1, reviewer=reviewer.email())
160161
PersonFactory(user__username='plain')
161162

@@ -212,6 +213,156 @@ def test_reviewer_overview(self):
212213
# secretariat can see reason for being unavailable
213214
self.assertContains(r, "Availability")
214215

216+
# add one closed review with no response and see it is visible
217+
review_req2 = ReviewRequestFactory(state_id='completed',team=team)
218+
ReviewAssignmentFactory(
219+
review_request__doc=review_req2.doc,
220+
review_request__team=review_req2.team,
221+
review_request__type_id="lc",
222+
review_request__deadline=datetime.date.today() - datetime.timedelta(days=30),
223+
review_request__state_id="assigned",
224+
review_request__requested_by=Person.objects.get(user__username="reviewer"),
225+
state_id = "no-response",
226+
reviewer=reviewer.email_set.first(),
227+
)
228+
self.client.login(username="secretary", password="secretary+password")
229+
r = self.client.get(url)
230+
self.assertEqual(r.status_code, 200)
231+
# We should see the new document with status of no response
232+
self.assertContains(r, "No Response")
233+
self.assertContains(r, review_req1.doc.name)
234+
self.assertContains(r, review_req2.doc.name)
235+
# None of the reviews should be completed this time,
236+
# note that "Days Since Completed has soft hypens in it, so it
237+
# will not match
238+
self.assertNotContains(r, "Completed")
239+
# add multiple completed reviews
240+
review_req3 = ReviewRequestFactory(state_id='completed', team=team)
241+
ReviewAssignmentFactory(
242+
review_request__doc=review_req3.doc,
243+
review_request__time=datetime.date.today() - datetime.timedelta(days=30),
244+
review_request__team=review_req3.team,
245+
review_request__type_id="telechat",
246+
review_request__deadline=datetime.date.today() - datetime.timedelta(days=25),
247+
review_request__state_id="completed",
248+
review_request__requested_by=Person.objects.get(user__username="reviewer"),
249+
state_id = "completed",
250+
reviewer=reviewer.email_set.first(),
251+
assigned_on=datetime.date.today() - datetime.timedelta(days=30)
252+
)
253+
r = self.client.get(url)
254+
self.assertEqual(r.status_code, 200)
255+
self.assertContains(r, "Completed")
256+
self.assertContains(r, review_req1.doc.name)
257+
self.assertContains(r, review_req2.doc.name)
258+
self.assertContains(r, review_req3.doc.name)
259+
# Few more to make sure we hit the limit
260+
reqs = [ReviewRequestFactory(state_id='completed', team=team) for i in range(10)]
261+
for i in range(10):
262+
ReviewAssignmentFactory(
263+
review_request__doc=reqs[i].doc,
264+
review_request__time=datetime.date.today() - datetime.timedelta(days=i*30),
265+
review_request__team=reqs[i].team,
266+
review_request__type_id="telechat",
267+
review_request__deadline=datetime.date.today() - datetime.timedelta(days=i*20),
268+
review_request__state_id="completed",
269+
review_request__requested_by=Person.objects.get(user__username="reviewer"),
270+
state_id = "completed",
271+
reviewer=reviewer.email_set.first(),
272+
assigned_on=datetime.date.today() - datetime.timedelta(days=i*30)
273+
)
274+
r = self.client.get(url)
275+
self.assertEqual(r.status_code, 200)
276+
self.assertContains(r, "Completed")
277+
self.assertContains(r, review_req1.doc.name)
278+
self.assertContains(r, review_req2.doc.name)
279+
self.assertContains(r, review_req3.doc.name)
280+
# The default is 10 completed entries, we had one before + one No response
281+
# so we should have 8 more here
282+
for i in range(10):
283+
if i < 8:
284+
self.assertContains(r, reqs[i].doc.name)
285+
else:
286+
self.assertNotContains(r, reqs[i].doc.name)
287+
# Change the limit to be 15 instead of 10, so we should get all
288+
secretary_settings = ReviewSecretarySettings(team=team, person=secretary)
289+
secretary_settings.max_items_to_show_in_reviewer_list = 15
290+
secretary_settings.save()
291+
r = self.client.get(url)
292+
self.assertEqual(r.status_code, 200)
293+
self.assertContains(r, review_req1.doc.name)
294+
self.assertContains(r, review_req2.doc.name)
295+
self.assertContains(r, review_req3.doc.name)
296+
for i in range(10):
297+
self.assertContains(r, reqs[i].doc.name)
298+
# Change the time limit to 100 days, so we should only get 3 completed
299+
secretary_settings.days_to_show_in_reviewer_list = 100
300+
secretary_settings.save()
301+
r = self.client.get(url)
302+
self.assertEqual(r.status_code, 200)
303+
self.assertContains(r, review_req1.doc.name)
304+
self.assertContains(r, review_req2.doc.name)
305+
self.assertContains(r, review_req3.doc.name)
306+
for i in range(10):
307+
if i < 4:
308+
self.assertContains(r, reqs[i].doc.name)
309+
else:
310+
self.assertNotContains(r, reqs[i].doc.name)
311+
# Add assigned items, they should be visible as long as they
312+
# are withing time period
313+
review_req4 = ReviewRequestFactory(state_id='completed', team=team)
314+
ReviewAssignmentFactory(
315+
review_request__doc=review_req4.doc,
316+
review_request__time=datetime.date.today() - datetime.timedelta(days=80),
317+
review_request__team=review_req4.team,
318+
review_request__type_id="lc",
319+
review_request__deadline=datetime.date.today() - datetime.timedelta(days=60),
320+
review_request__state_id="assigned",
321+
review_request__requested_by=Person.objects.get(user__username="reviewer"),
322+
state_id = "accepted",
323+
reviewer=reviewer.email_set.first(),
324+
assigned_on=datetime.date.today() - datetime.timedelta(days=80)
325+
)
326+
review_req5 = ReviewRequestFactory(state_id='completed', team=team)
327+
ReviewAssignmentFactory(
328+
review_request__doc=review_req5.doc,
329+
review_request__time=datetime.date.today() - datetime.timedelta(days=120),
330+
review_request__team=review_req5.team,
331+
review_request__type_id="lc",
332+
review_request__deadline=datetime.date.today() - datetime.timedelta(days=100),
333+
review_request__state_id="assigned",
334+
review_request__requested_by=Person.objects.get(user__username="reviewer"),
335+
state_id = "accepted",
336+
reviewer=reviewer.email_set.first(),
337+
assigned_on=datetime.date.today() - datetime.timedelta(days=120)
338+
)
339+
r = self.client.get(url)
340+
self.assertEqual(r.status_code, 200)
341+
self.assertContains(r, review_req1.doc.name)
342+
self.assertContains(r, review_req2.doc.name)
343+
self.assertContains(r, review_req3.doc.name)
344+
self.assertContains(r, review_req4.doc.name)
345+
self.assertNotContains(r, review_req5.doc.name)
346+
for i in range(10):
347+
if i < 4:
348+
self.assertContains(r, reqs[i].doc.name)
349+
else:
350+
self.assertNotContains(r, reqs[i].doc.name)
351+
# Change the limit to be 1 instead of 10, so we should only one entry
352+
secretary_settings.max_items_to_show_in_reviewer_list = 1
353+
secretary_settings.save()
354+
r = self.client.get(url)
355+
self.assertEqual(r.status_code, 200)
356+
self.assertContains(r, review_req1.doc.name)
357+
self.assertContains(r, review_req2.doc.name)
358+
self.assertNotContains(r, review_req3.doc.name)
359+
for i in range(10):
360+
self.assertNotContains(r, reqs[i].doc.name)
361+
self.assertContains(r, review_req4.doc.name)
362+
self.assertNotContains(r, review_req5.doc.name)
363+
364+
# print(r.content)
365+
215366
def test_manage_review_requests(self):
216367
group = ReviewTeamFactory()
217368
RoleFactory(name_id='reviewer',group=group,person__user__username='reviewer').person
@@ -539,11 +690,15 @@ def test_change_review_secretary_settings(self):
539690

540691
# set settings
541692
r = self.client.post(url, {
542-
"remind_days_before_deadline": "6"
693+
"remind_days_before_deadline": "6",
694+
"max_items_to_show_in_reviewer_list": 10,
695+
"days_to_show_in_reviewer_list": 365
543696
})
544697
self.assertEqual(r.status_code, 302)
545698
settings = ReviewSecretarySettings.objects.get(person=secretary, team=review_req.team)
546699
self.assertEqual(settings.remind_days_before_deadline, 6)
700+
self.assertEqual(settings.max_items_to_show_in_reviewer_list, 10)
701+
self.assertEqual(settings.days_to_show_in_reviewer_list, 365)
547702

548703
def test_review_reminders(self):
549704
review_req = ReviewRequestFactory(state_id='assigned')

ietf/group/views.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,24 @@ def reviewer_overview(request, acronym, group_type=None):
14021402

14031403
today = datetime.date.today()
14041404

1405-
req_data_for_reviewers = latest_review_assignments_for_reviewers(group)
1405+
max_closed_reqs = 10
1406+
days_back = 365
1407+
if can_manage:
1408+
secretary_settings = (ReviewSecretarySettings.objects.filter(person=
1409+
request.user.person,
1410+
team=group).first()
1411+
or ReviewSecretarySettings(person=request.user.person,
1412+
team=group))
1413+
if secretary_settings:
1414+
max_closed_reqs = secretary_settings.max_items_to_show_in_reviewer_list
1415+
days_back = secretary_settings.days_to_show_in_reviewer_list
1416+
1417+
if max_closed_reqs == None:
1418+
max_closed_reqs = 10
1419+
1420+
if days_back == None:
1421+
days_back = 365
1422+
req_data_for_reviewers = latest_review_assignments_for_reviewers(group, days_back)
14061423
assignment_state_by_slug = { n.slug: n for n in ReviewAssignmentStateName.objects.all() }
14071424

14081425
days_needed = days_needed_to_fulfill_min_interval_for_reviewers(group)
@@ -1424,13 +1441,14 @@ def reviewer_overview(request, acronym, group_type=None):
14241441
person.busy = person.id in days_needed
14251442

14261443

1427-
MAX_CLOSED_REQS = 10 # This keeps the overview page with being filled with too many closed requests, since the focus should be on open or recently closed per reviewer
14281444
days_since = 9999
14291445
req_data = req_data_for_reviewers.get(person.pk, [])
1430-
open_reqs = sum(1 for d in req_data if d.state in ["assigned", "accepted"])
1446+
closed_reqs = 0
14311447
latest_reqs = []
14321448
for d in req_data:
1433-
if d.state in ["assigned", "accepted"] or len(latest_reqs) < MAX_CLOSED_REQS + open_reqs:
1449+
if d.state in ["assigned", "accepted"] or closed_reqs < max_closed_reqs:
1450+
if not d.state in ["assigned", "accepted"]:
1451+
closed_reqs += 1
14341452
latest_reqs.append((d.assignment_pk, d.request_pk, d.doc_name, d.reviewed_rev, d.assigned_time, d.deadline,
14351453
assignment_state_by_slug.get(d.state),
14361454
int(math.ceil(d.assignment_to_closure_days)) if d.assignment_to_closure_days is not None else None))

ietf/review/admin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def acronym(self, obj):
2323
admin.site.register(ReviewerSettings, ReviewerSettingsAdmin)
2424

2525
class ReviewSecretarySettingsAdmin(admin.ModelAdmin):
26-
list_display = ['id', 'team', 'person', 'remind_days_before_deadline']
26+
list_display = ['id', 'team', 'person', 'remind_days_before_deadline', 'max_items_to_show_in_reviewer_list', 'days_to_show_in_reviewer_list']
2727
raw_id_fields = ['team', 'person']
2828
admin.site.register(ReviewSecretarySettings, ReviewSecretarySettingsAdmin)
2929

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Copyright The IETF Trust 2019, All Rights Reserved
2+
# -*- coding: utf-8 -*-
3+
# Generated by Django 1.11.26 on 2019-11-15 20:59
4+
from __future__ import unicode_literals
5+
6+
from django.db import migrations, models
7+
8+
9+
class Migration(migrations.Migration):
10+
11+
dependencies = [
12+
('review', '0019_auto_20191023_0829'),
13+
]
14+
15+
operations = [
16+
migrations.AddField(
17+
model_name='reviewsecretarysettings',
18+
name='days_to_show_in_reviewer_list',
19+
field=models.IntegerField(blank=True, help_text='Maximum number of days to show in reviewer list for completed items.', null=True),
20+
),
21+
migrations.AddField(
22+
model_name='reviewsecretarysettings',
23+
name='max_items_to_show_in_reviewer_list',
24+
field=models.IntegerField(blank=True, help_text='Maximum number of completed items to show for one reviewer in the reviewer list view, the list is also filtered by the days to show in reviews list setting.', null=True),
25+
),
26+
]

ietf/review/models.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ class ReviewSecretarySettings(models.Model):
5252
team = ForeignKey(Group, limit_choices_to=~models.Q(reviewteamsettings=None))
5353
person = ForeignKey(Person)
5454
remind_days_before_deadline = models.IntegerField(null=True, blank=True, help_text="To get an email reminder in case a reviewer forgets to do an assigned review, enter the number of days before review deadline you want to receive it. Clear the field if you don't want a reminder.")
55+
max_items_to_show_in_reviewer_list = models.IntegerField(null=True, blank=True, help_text="Maximum number of completed items to show for one reviewer in the reviewer list view, the list is also filtered by the days to show in reviews list setting.")
56+
days_to_show_in_reviewer_list = models.IntegerField(null=True, blank=True, help_text="Maximum number of days to show in reviewer list for completed items.")
5557

5658
def __str__(self):
5759
return "{} in {}".format(self.person, self.team)

0 commit comments

Comments
 (0)