feat: show expired WG/RG drafts at WG/RG Documents page (#4252)

* Show expired WG/RG drafts.

* Update 0009_add_group_exp_rule_to_groups.py

fix dependency on migration file name

* Update forms.py

Simplify condition statements

* Update views.py

Fix - remove erroneous check (never happen)

* Added tests for expired WG drafts filtering rule
This commit is contained in:
Valery Smyslov 2022-07-26 20:02:09 +03:00 committed by GitHub
parent b1aecf9525
commit a5f27b0a5b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 97 additions and 8 deletions

View file

@ -38,9 +38,12 @@ class SearchRuleForm(forms.ModelForm):
f.initial = f.queryset[0].pk
f.widget = forms.HiddenInput()
if rule_type in ['group', 'group_rfc', 'area', 'area_rfc']:
restrict_state("draft", "rfc" if rule_type.endswith("rfc") else "active")
if rule_type in ["group", "group_rfc", "area", "area_rfc", "group_exp"]:
if rule_type == "group_exp":
restrict_state("draft", "expired")
else:
restrict_state("draft", "rfc" if rule_type.endswith("rfc") else "active")
if rule_type.startswith("area"):
self.fields["group"].label = "Area"
self.fields["group"].queryset = self.fields["group"].queryset.filter(Q(type="area") | Q(acronym="irtf")).order_by("acronym")

View file

@ -0,0 +1,18 @@
# Generated by Django 2.2.28 on 2022-06-30 05:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('community', '0007_remove_docs2_m2m'),
]
operations = [
migrations.AlterField(
model_name='searchrule',
name='rule_type',
field=models.CharField(choices=[('group', 'All I-Ds associated with a particular group'), ('area', 'All I-Ds associated with all groups in a particular Area'), ('group_rfc', 'All RFCs associated with a particular group'), ('area_rfc', 'All RFCs associated with all groups in a particular Area'), ('group_exp', 'All expired I-Ds of a particular group'), ('state_iab', 'All I-Ds that are in a particular IAB state'), ('state_iana', 'All I-Ds that are in a particular IANA state'), ('state_iesg', 'All I-Ds that are in a particular IESG state'), ('state_irtf', 'All I-Ds that are in a particular IRTF state'), ('state_ise', 'All I-Ds that are in a particular ISE state'), ('state_rfceditor', 'All I-Ds that are in a particular RFC Editor state'), ('state_ietf', 'All I-Ds that are in a particular Working Group state'), ('author', 'All I-Ds with a particular author'), ('author_rfc', 'All RFCs with a particular author'), ('ad', 'All I-Ds with a particular responsible AD'), ('shepherd', 'All I-Ds with a particular document shepherd'), ('name_contains', 'All I-Ds with particular text/regular expression in the name')], max_length=30),
),
]

View file

@ -0,0 +1,29 @@
# Generated by Django 2.2.28 on 2022-06-30 23:15
from django.db import migrations
def forward(apps, schema_editor):
SearchRule = apps.get_model('community', 'SearchRule')
Group = apps.get_model('group', 'Group')
State = apps.get_model('doc', 'State')
for group in Group.objects.filter(type_id__in=['wg','rg'], state_id='active'):
Rule = SearchRule.objects.filter(group = group)
if Rule.exists():
SearchRule.objects.create(community_list=Rule[0].community_list, rule_type="group_exp", group=group, state=State.objects.get(slug="expired", type="draft"),)
def reverse(apps, schema_editor):
SearchRule = apps.get_model('community', 'SearchRule')
SearchRule.objects.filter(rule_type='group_exp').delete()
class Migration(migrations.Migration):
dependencies = [
('community', '0008_add_group_exp_rule'),
]
operations = [
migrations.RunPython(forward, reverse),
]

View file

@ -45,6 +45,7 @@ class SearchRule(models.Model):
('area', 'All I-Ds associated with all groups in a particular Area'),
('group_rfc', 'All RFCs associated with a particular group'),
('area_rfc', 'All RFCs associated with all groups in a particular Area'),
('group_exp', 'All expired I-Ds of a particular group'),
('state_iab', 'All I-Ds that are in a particular IAB state'),
('state_iana', 'All I-Ds that are in a particular IANA state'),

View file

@ -52,6 +52,8 @@ class CommunityListTests(WebTest):
rule_shepherd = SearchRule.objects.create(rule_type="shepherd", state=State.objects.get(type="draft", slug="active"), person=draft.shepherd.person, community_list=clist)
rule_group_exp = SearchRule.objects.create(rule_type="group_exp", group=draft.group, state=State.objects.get(type="draft", slug="expired"), community_list=clist)
rule_name_contains = SearchRule.objects.create(rule_type="name_contains", state=State.objects.get(type="draft", slug="active"), text="draft-.*" + "-".join(draft.name.split("-")[2:]), community_list=clist)
reset_name_contains_index_for_rule(rule_name_contains)
@ -65,6 +67,7 @@ class CommunityListTests(WebTest):
self.assertTrue(rule_ad in matching_rules)
self.assertTrue(rule_shepherd in matching_rules)
self.assertTrue(rule_name_contains in matching_rules)
self.assertTrue(rule_group_exp not in matching_rules)
# rule -> docs
self.assertTrue(draft in list(docs_matching_community_list_rule(rule_group)))
@ -75,6 +78,16 @@ class CommunityListTests(WebTest):
self.assertTrue(draft in list(docs_matching_community_list_rule(rule_ad)))
self.assertTrue(draft in list(docs_matching_community_list_rule(rule_shepherd)))
self.assertTrue(draft in list(docs_matching_community_list_rule(rule_name_contains)))
self.assertTrue(draft not in list(docs_matching_community_list_rule(rule_group_exp)))
draft.set_state(State.objects.get(type='draft', slug='expired'))
# doc -> rules
matching_rules = list(community_list_rules_matching_doc(draft))
self.assertTrue(rule_group_exp in matching_rules)
# rule -> docs
self.assertTrue(draft in list(docs_matching_community_list_rule(rule_group_exp)))
def test_view_list(self):
PersonFactory(user__username='plain')

View file

@ -75,6 +75,8 @@ def docs_matching_community_list_rule(rule):
docs = Document.objects.all()
if rule.rule_type in ['group', 'area', 'group_rfc', 'area_rfc']:
return docs.filter(Q(group=rule.group_id) | Q(group__parent=rule.group_id), states=rule.state)
elif rule.rule_type in ['group_exp']:
return docs.filter(group=rule.group_id, states=rule.state)
elif rule.rule_type.startswith("state_"):
return docs.filter(states=rule.state)
elif rule.rule_type in ["author", "author_rfc"]:
@ -98,7 +100,7 @@ def community_list_rules_matching_doc(doc):
if doc.group.parent_id:
groups.append(doc.group.parent_id)
rules |= SearchRule.objects.filter(
rule_type__in=['group', 'area', 'group_rfc', 'area_rfc'],
rule_type__in=['group', 'area', 'group_rfc', 'area_rfc', 'group_exp'],
state__in=states,
group__in=groups
)

View file

@ -26,7 +26,7 @@ from django.utils.html import escape
from ietf.community.models import CommunityList
from ietf.community.utils import reset_name_contains_index_for_rule
from ietf.doc.factories import WgDraftFactory, CharterFactory, BallotDocEventFactory
from ietf.doc.factories import WgDraftFactory, IndividualDraftFactory, CharterFactory, BallotDocEventFactory
from ietf.doc.models import Document, DocAlias, DocEvent, State
from ietf.doc.utils_charter import charter_name_for_group
from ietf.group.admin import GroupForm as AdminGroupForm
@ -212,6 +212,17 @@ class GroupPagesTests(TestCase):
old_dah.time_added -= datetime.timedelta(days=173) # make an "old" action holder
old_dah.save()
draft4 = WgDraftFactory(group=group)
draft4.set_state(State.objects.get(type='draft', slug='expired')) # Expired WG draft
draft5 = IndividualDraftFactory()
draft5.set_state(State.objects.get(type='draft', slug='expired')) # Expired non-WG draft
draft6 = WgDraftFactory(group=group)
draft6.set_state(State.objects.get(type='draft', slug='expired'))
draft6.set_state(State.objects.get(type='draft-iesg', slug='dead')) # Expired WG draft, marked as dead
draft7 = WgDraftFactory(group=group)
draft7.set_state(State.objects.get(type='draft', slug='expired'))
draft7.set_state(State.objects.get(type='draft-stream-%s' % draft7.stream_id, slug='dead')) # Expired WG draft, marked as dead
clist = CommunityList.objects.get(group=group)
related_docs_rule = clist.searchrule_set.get(rule_type='name_contains')
reset_name_contains_index_for_rule(related_docs_rule)
@ -229,6 +240,10 @@ class GroupPagesTests(TestCase):
for ah in draft3.action_holders.all():
self.assertContains(r, escape(ah.name))
self.assertContains(r, 'for 173 days', count=1) # the old_dah should be tagged
self.assertContains(r, draft4.name)
self.assertNotContains(r, draft5.name)
self.assertNotContains(r, draft6.name)
self.assertNotContains(r, draft7.name)
# Make sure that a logged in user is presented with an opportunity to add results to their community list
self.client.login(username="secretary", password="secretary+password")

View file

@ -193,6 +193,12 @@ def setup_default_community_list_for_group(group):
group=group,
state=State.objects.get(slug="rfc", type="draft"),
)
SearchRule.objects.create(
community_list=clist,
rule_type="group_exp",
group=group,
state=State.objects.get(slug="expired", type="draft"),
)
related_docs_rule = SearchRule.objects.create(
community_list=clist,
rule_type="name_contains",

View file

@ -452,10 +452,12 @@ def prepare_group_documents(request, group, clist):
# non-WG drafts and call for WG adoption are considered related
if (d.group != group
or (d.stream_id and d.get_state_slug("draft-stream-%s" % d.stream_id) in ("c-adopt", "wg-cand"))):
d.search_heading = "Related Internet-Draft"
docs_related.append(d)
if d.get_state_slug() != "expired":
d.search_heading = "Related Internet-Draft"
docs_related.append(d)
else:
docs.append(d)
if not (d.get_state_slug('draft-iesg') == "dead" or (d.stream_id and d.get_state_slug("draft-stream-%s" % d.stream_id) == "dead")):
docs.append(d)
meta_related = meta.copy()