Skip to content

Commit 0706f85

Browse files
Update migrations and fix a few failing tests. Branch ready for merge.
- Legacy-Id: 19571
1 parent bcd37ed commit 0706f85

11 files changed

Lines changed: 212 additions & 12 deletions

ietf/doc/templatetags/ietf_filters.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -694,21 +694,21 @@ def is_special_agenda_item(assignment):
694694
def should_show_agenda_session_buttons(assignment):
695695
"""Should this agenda item show the session buttons (jabber link, etc)?
696696
697-
In IETF-111 and earlier, office hours sessions were designated by a name ending
697+
In IETF-112 and earlier, office hours sessions were designated by a name ending
698698
with ' office hours' and belonged to the IESG or some other group. This led to
699699
incorrect session buttons being displayed. Suppress session buttons for
700-
when name ends with 'office hours' in the pre-111 meetings.
700+
when name ends with 'office hours' in the pre-112 meetings.
701701
>>> from collections import namedtuple # use to build mock objects
702702
>>> mock_meeting = namedtuple('t3', ['number'])
703703
>>> mock_session = namedtuple('t2', ['name'])
704704
>>> mock_assignment = namedtuple('t1', ['meeting', 'session']) # meeting must be a callable
705705
>>> factory = lambda num, name: mock_assignment(session=mock_session(name), meeting=lambda: mock_meeting(num))
706-
>>> test_cases = [('105', 'acme office hours'), ('111', 'acme office hours')]
706+
>>> test_cases = [('105', 'acme office hours'), ('112', 'acme office hours')]
707707
>>> any(should_show_agenda_session_buttons(factory(*tc)) for tc in test_cases)
708708
False
709-
>>> test_cases = [('interim-2020-acme-112', 'acme'), ('112', 'acme'), ('150', 'acme'), ('105', 'acme'),]
710-
>>> test_cases.extend([('111', 'acme'), ('interim-2020-acme-112', 'acme office hours')])
711-
>>> test_cases.extend([('112', 'acme office hours'), ('150', 'acme office hours')])
709+
>>> test_cases = [('interim-2020-acme-113', 'acme'), ('113', 'acme'), ('150', 'acme'), ('105', 'acme'),]
710+
>>> test_cases.extend([('112', 'acme'), ('interim-2020-acme-113', 'acme office hours')])
711+
>>> test_cases.extend([('113', 'acme office hours'), ('150', 'acme office hours')])
712712
>>> all(should_show_agenda_session_buttons(factory(*tc)) for tc in test_cases)
713713
True
714714
"""
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Copyright The IETF Trust 2021 All Rights Reserved
2+
3+
from django.db import migrations, models
4+
import django.db.models.deletion
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('name', '0033_populate_agendafiltertypename'),
11+
('group', '0049_auto_20211019_1136'),
12+
]
13+
14+
operations = [
15+
migrations.AddField(
16+
model_name='groupfeatures',
17+
name='agenda_filter_type',
18+
field=models.ForeignKey(default='none', on_delete=django.db.models.deletion.PROTECT, to='name.AgendaFilterTypeName'),
19+
),
20+
]
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright The IETF Trust 2021 All Rights Reserved
2+
3+
from django.db import migrations
4+
5+
6+
def forward(apps, schema_editor):
7+
GroupFeatures = apps.get_model('group', 'GroupFeatures')
8+
9+
# map AgendaFilterTypeName slug to group types - unlisted get 'none'
10+
filter_types = dict(
11+
# list previously hard coded in agenda view, plus 'review'
12+
normal={'wg', 'ag', 'rg', 'rag', 'iab', 'program', 'review'},
13+
heading={'area', 'ietf', 'irtf'},
14+
special={'team', 'adhoc'},
15+
)
16+
17+
for ft, group_types in filter_types.items():
18+
for gf in GroupFeatures.objects.filter(type__slug__in=group_types):
19+
gf.agenda_filter_type_id = ft
20+
gf.save()
21+
22+
23+
def reverse(apps, schema_editor):
24+
pass # nothing to do, model will be deleted anyway
25+
26+
27+
class Migration(migrations.Migration):
28+
29+
dependencies = [
30+
('group', '0050_groupfeatures_agenda_filter_type'),
31+
]
32+
33+
operations = [
34+
migrations.RunPython(forward, reverse),
35+
]
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright The IETF Trust 2021 All Rights Reserved
2+
3+
# Generated by Django 2.2.24 on 2021-09-26 11:29
4+
5+
from django.db import migrations
6+
import ietf.group.models
7+
import ietf.name.models
8+
import jsonfield.fields
9+
10+
11+
class Migration(migrations.Migration):
12+
13+
dependencies = [
14+
('group', '0051_populate_groupfeatures_agenda_filter_type'),
15+
('name', '0034_sessionpurposename'),
16+
]
17+
18+
operations = [
19+
migrations.AddField(
20+
model_name='groupfeatures',
21+
name='session_purposes',
22+
field=jsonfield.fields.JSONField(default=[], help_text='Allowed session purposes for this group type', max_length=256, validators=[ietf.group.models.JSONForeignKeyListValidator(ietf.name.models.SessionPurposeName)]),
23+
),
24+
]
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Copyright The IETF Trust 2021 All Rights Reserved
2+
3+
# Generated by Django 2.2.24 on 2021-09-26 11:29
4+
5+
from django.db import migrations
6+
7+
8+
default_purposes = dict(
9+
adhoc=['presentation'],
10+
adm=['closed_meeting', 'officehours'],
11+
ag=['regular'],
12+
area=['regular'],
13+
dir=['open_meeting', 'presentation', 'regular', 'social', 'tutorial'],
14+
iab=['closed_meeting', 'regular'],
15+
iabasg=['closed_meeting', 'officehours', 'open_meeting'],
16+
iana=['officehours'],
17+
iesg=['closed_meeting', 'open_meeting'],
18+
ietf=['admin', 'plenary', 'presentation', 'social'],
19+
irtf=[],
20+
ise=['officehours'],
21+
isoc=['officehours', 'open_meeting', 'presentation'],
22+
nomcom=['closed_meeting', 'officehours'],
23+
program=['regular', 'tutorial'],
24+
rag=['regular'],
25+
review=['open_meeting', 'social'],
26+
rfcedtyp=['officehours'],
27+
rg=['regular'],
28+
team=['coding', 'presentation', 'social', 'tutorial'],
29+
wg=['regular'],
30+
)
31+
32+
33+
def forward(apps, schema_editor):
34+
GroupFeatures = apps.get_model('group', 'GroupFeatures')
35+
SessionPurposeName = apps.get_model('name', 'SessionPurposeName')
36+
37+
# verify that we're not about to use an invalid purpose
38+
for purposes in default_purposes.values():
39+
for purpose in purposes:
40+
SessionPurposeName.objects.get(pk=purpose) # throws an exception unless exists
41+
42+
for type_, purposes in default_purposes.items():
43+
GroupFeatures.objects.filter(
44+
type=type_
45+
).update(
46+
session_purposes=purposes
47+
)
48+
49+
def reverse(apps, schema_editor):
50+
GroupFeatures = apps.get_model('group', 'GroupFeatures')
51+
GroupFeatures.objects.update(session_purposes=[]) # clear back out to default
52+
53+
54+
class Migration(migrations.Migration):
55+
56+
dependencies = [
57+
('group', '0052_groupfeatures_session_purposes'),
58+
('name', '0035_populate_sessionpurposename'),
59+
60+
]
61+
62+
operations = [
63+
migrations.RunPython(forward, reverse),
64+
]

ietf/group/models.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import debug # pyflakes:ignore
1818

1919
from ietf.group.colors import fg_group_colors, bg_group_colors
20-
from ietf.name.models import (GroupStateName, GroupTypeName, DocTagName, GroupMilestoneStateName, RoleName,
20+
from ietf.name.models import (GroupStateName, GroupTypeName, DocTagName, GroupMilestoneStateName, RoleName,
2121
AgendaTypeName, AgendaFilterTypeName, ExtResourceName, SessionPurposeName)
2222
from ietf.person.models import Email, Person
2323
from ietf.utils.db import IETFJSONField
@@ -264,8 +264,8 @@ class GroupFeatures(models.Model):
264264
groupman_authroles = IETFJSONField(max_length=128, accepted_empty_values=[[], {}], blank=False, default=["Secretariat",])
265265
matman_roles = IETFJSONField(max_length=128, accepted_empty_values=[[], {}], blank=False, default=["ad","chair","delegate","secr"])
266266
role_order = IETFJSONField(max_length=128, accepted_empty_values=[[], {}], blank=False, default=["chair","secr","member"],
267-
help_text="The order in which roles are shown, for instance on photo pages. Enter valid JSON.")
268-
session_purposes = jsonfield.JSONField(max_length=256, blank=False, default=[],
267+
help_text="The order in which roles are shown, for instance on photo pages. Enter valid JSON.")
268+
session_purposes = IETFJSONField(max_length=256, accepted_empty_values=[[], {}], blank=False, default=[],
269269
help_text="Allowed session purposes for this group type",
270270
validators=[JSONForeignKeyListValidator(SessionPurposeName)])
271271

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 2.2.24 on 2021-10-22 06:58
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('meeting', '0049_session_purpose'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='session',
15+
name='on_agenda',
16+
field=models.BooleanField(default=True, help_text='Is this session visible on the meeting agenda?'),
17+
),
18+
]
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Generated by Django 2.2.24 on 2021-10-22 06:58
2+
3+
from django.db import migrations, models
4+
5+
6+
def forward(apps, schema_editor):
7+
Session = apps.get_model('meeting', 'Session')
8+
SchedTimeSessAssignment = apps.get_model('meeting', 'SchedTimeSessAssignment')
9+
# find official assignments that are to private timeslots and fill in session.on_agenda
10+
private_assignments = SchedTimeSessAssignment.objects.filter(
11+
models.Q(
12+
schedule=models.F('session__meeting__schedule')
13+
) | models.Q(
14+
schedule=models.F('session__meeting__schedule__base')
15+
),
16+
timeslot__type__private=True,
17+
)
18+
for pa in private_assignments:
19+
pa.session.on_agenda = False
20+
pa.session.save()
21+
# Also update any sessions to match their purpose's default setting (this intentionally
22+
# overrides the timeslot settings above, but that is unlikely to matter because the
23+
# purposes will roll out at the same time as the on_agenda field)
24+
Session.objects.filter(purpose__on_agenda=False).update(on_agenda=False)
25+
Session.objects.filter(purpose__on_agenda=True).update(on_agenda=True)
26+
27+
def reverse(apps, schema_editor):
28+
Session = apps.get_model('meeting', 'Session')
29+
Session.objects.update(on_agenda=True) # restore all to default on_agenda=True state
30+
31+
class Migration(migrations.Migration):
32+
33+
dependencies = [
34+
('meeting', '0050_session_on_agenda'),
35+
]
36+
37+
operations = [
38+
migrations.RunPython(forward, reverse),
39+
]

ietf/meeting/tests_js.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ def test_unassigned_sessions_drop_target_visible_when_empty(self):
766766
all of the events needed by the editor.
767767
"""
768768
# Set up a meeting and a schedule a plain user can edit
769-
schedule = ScheduleFactory(owner__user__username="plain")
769+
schedule = ScheduleFactory(meeting__type_id='ietf', owner__user__username="plain")
770770
meeting = schedule.meeting
771771

772772
# Open the editor

ietf/meeting/tests_views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3714,7 +3714,7 @@ def test_new_meeting_schedule_rejects_invalid_names(self):
37143714
self.assertEqual(meeting.schedule_set.count(), orig_schedule_count, 'Schedule should not be created')
37153715

37163716
def test_edit_session(self):
3717-
session = SessionFactory(group__type_id='team') # type determines allowed session purposes
3717+
session = SessionFactory(meeting__type_id='ietf', group__type_id='team') # type determines allowed session purposes
37183718
self.client.login(username='secretary', password='secretary+password')
37193719
url = urlreverse('ietf.meeting.views.edit_session', kwargs={'session_id': session.pk})
37203720
r = self.client.get(url)

0 commit comments

Comments
 (0)