Update migrations and fix a few failing tests. Branch ready for merge.

- Legacy-Id: 19571
This commit is contained in:
Jennifer Richards 2021-11-09 02:40:54 +00:00
parent bcd37edfcd
commit 0706f8519f
11 changed files with 212 additions and 12 deletions

View file

@ -694,21 +694,21 @@ def is_special_agenda_item(assignment):
def should_show_agenda_session_buttons(assignment):
"""Should this agenda item show the session buttons (jabber link, etc)?
In IETF-111 and earlier, office hours sessions were designated by a name ending
In IETF-112 and earlier, office hours sessions were designated by a name ending
with ' office hours' and belonged to the IESG or some other group. This led to
incorrect session buttons being displayed. Suppress session buttons for
when name ends with 'office hours' in the pre-111 meetings.
when name ends with 'office hours' in the pre-112 meetings.
>>> from collections import namedtuple # use to build mock objects
>>> mock_meeting = namedtuple('t3', ['number'])
>>> mock_session = namedtuple('t2', ['name'])
>>> mock_assignment = namedtuple('t1', ['meeting', 'session']) # meeting must be a callable
>>> factory = lambda num, name: mock_assignment(session=mock_session(name), meeting=lambda: mock_meeting(num))
>>> test_cases = [('105', 'acme office hours'), ('111', 'acme office hours')]
>>> test_cases = [('105', 'acme office hours'), ('112', 'acme office hours')]
>>> any(should_show_agenda_session_buttons(factory(*tc)) for tc in test_cases)
False
>>> test_cases = [('interim-2020-acme-112', 'acme'), ('112', 'acme'), ('150', 'acme'), ('105', 'acme'),]
>>> test_cases.extend([('111', 'acme'), ('interim-2020-acme-112', 'acme office hours')])
>>> test_cases.extend([('112', 'acme office hours'), ('150', 'acme office hours')])
>>> test_cases = [('interim-2020-acme-113', 'acme'), ('113', 'acme'), ('150', 'acme'), ('105', 'acme'),]
>>> test_cases.extend([('112', 'acme'), ('interim-2020-acme-113', 'acme office hours')])
>>> test_cases.extend([('113', 'acme office hours'), ('150', 'acme office hours')])
>>> all(should_show_agenda_session_buttons(factory(*tc)) for tc in test_cases)
True
"""

View file

@ -0,0 +1,20 @@
# Copyright The IETF Trust 2021 All Rights Reserved
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('name', '0033_populate_agendafiltertypename'),
('group', '0049_auto_20211019_1136'),
]
operations = [
migrations.AddField(
model_name='groupfeatures',
name='agenda_filter_type',
field=models.ForeignKey(default='none', on_delete=django.db.models.deletion.PROTECT, to='name.AgendaFilterTypeName'),
),
]

View file

@ -0,0 +1,35 @@
# Copyright The IETF Trust 2021 All Rights Reserved
from django.db import migrations
def forward(apps, schema_editor):
GroupFeatures = apps.get_model('group', 'GroupFeatures')
# map AgendaFilterTypeName slug to group types - unlisted get 'none'
filter_types = dict(
# list previously hard coded in agenda view, plus 'review'
normal={'wg', 'ag', 'rg', 'rag', 'iab', 'program', 'review'},
heading={'area', 'ietf', 'irtf'},
special={'team', 'adhoc'},
)
for ft, group_types in filter_types.items():
for gf in GroupFeatures.objects.filter(type__slug__in=group_types):
gf.agenda_filter_type_id = ft
gf.save()
def reverse(apps, schema_editor):
pass # nothing to do, model will be deleted anyway
class Migration(migrations.Migration):
dependencies = [
('group', '0050_groupfeatures_agenda_filter_type'),
]
operations = [
migrations.RunPython(forward, reverse),
]

View file

@ -0,0 +1,24 @@
# Copyright The IETF Trust 2021 All Rights Reserved
# Generated by Django 2.2.24 on 2021-09-26 11:29
from django.db import migrations
import ietf.group.models
import ietf.name.models
import jsonfield.fields
class Migration(migrations.Migration):
dependencies = [
('group', '0051_populate_groupfeatures_agenda_filter_type'),
('name', '0034_sessionpurposename'),
]
operations = [
migrations.AddField(
model_name='groupfeatures',
name='session_purposes',
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)]),
),
]

View file

@ -0,0 +1,64 @@
# Copyright The IETF Trust 2021 All Rights Reserved
# Generated by Django 2.2.24 on 2021-09-26 11:29
from django.db import migrations
default_purposes = dict(
adhoc=['presentation'],
adm=['closed_meeting', 'officehours'],
ag=['regular'],
area=['regular'],
dir=['open_meeting', 'presentation', 'regular', 'social', 'tutorial'],
iab=['closed_meeting', 'regular'],
iabasg=['closed_meeting', 'officehours', 'open_meeting'],
iana=['officehours'],
iesg=['closed_meeting', 'open_meeting'],
ietf=['admin', 'plenary', 'presentation', 'social'],
irtf=[],
ise=['officehours'],
isoc=['officehours', 'open_meeting', 'presentation'],
nomcom=['closed_meeting', 'officehours'],
program=['regular', 'tutorial'],
rag=['regular'],
review=['open_meeting', 'social'],
rfcedtyp=['officehours'],
rg=['regular'],
team=['coding', 'presentation', 'social', 'tutorial'],
wg=['regular'],
)
def forward(apps, schema_editor):
GroupFeatures = apps.get_model('group', 'GroupFeatures')
SessionPurposeName = apps.get_model('name', 'SessionPurposeName')
# verify that we're not about to use an invalid purpose
for purposes in default_purposes.values():
for purpose in purposes:
SessionPurposeName.objects.get(pk=purpose) # throws an exception unless exists
for type_, purposes in default_purposes.items():
GroupFeatures.objects.filter(
type=type_
).update(
session_purposes=purposes
)
def reverse(apps, schema_editor):
GroupFeatures = apps.get_model('group', 'GroupFeatures')
GroupFeatures.objects.update(session_purposes=[]) # clear back out to default
class Migration(migrations.Migration):
dependencies = [
('group', '0052_groupfeatures_session_purposes'),
('name', '0035_populate_sessionpurposename'),
]
operations = [
migrations.RunPython(forward, reverse),
]

View file

@ -17,7 +17,7 @@ from django.dispatch import receiver
import debug # pyflakes:ignore
from ietf.group.colors import fg_group_colors, bg_group_colors
from ietf.name.models import (GroupStateName, GroupTypeName, DocTagName, GroupMilestoneStateName, RoleName,
from ietf.name.models import (GroupStateName, GroupTypeName, DocTagName, GroupMilestoneStateName, RoleName,
AgendaTypeName, AgendaFilterTypeName, ExtResourceName, SessionPurposeName)
from ietf.person.models import Email, Person
from ietf.utils.db import IETFJSONField
@ -264,8 +264,8 @@ class GroupFeatures(models.Model):
groupman_authroles = IETFJSONField(max_length=128, accepted_empty_values=[[], {}], blank=False, default=["Secretariat",])
matman_roles = IETFJSONField(max_length=128, accepted_empty_values=[[], {}], blank=False, default=["ad","chair","delegate","secr"])
role_order = IETFJSONField(max_length=128, accepted_empty_values=[[], {}], blank=False, default=["chair","secr","member"],
help_text="The order in which roles are shown, for instance on photo pages. Enter valid JSON.")
session_purposes = jsonfield.JSONField(max_length=256, blank=False, default=[],
help_text="The order in which roles are shown, for instance on photo pages. Enter valid JSON.")
session_purposes = IETFJSONField(max_length=256, accepted_empty_values=[[], {}], blank=False, default=[],
help_text="Allowed session purposes for this group type",
validators=[JSONForeignKeyListValidator(SessionPurposeName)])

View file

@ -0,0 +1,18 @@
# Generated by Django 2.2.24 on 2021-10-22 06:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('meeting', '0049_session_purpose'),
]
operations = [
migrations.AddField(
model_name='session',
name='on_agenda',
field=models.BooleanField(default=True, help_text='Is this session visible on the meeting agenda?'),
),
]

View file

@ -0,0 +1,39 @@
# Generated by Django 2.2.24 on 2021-10-22 06:58
from django.db import migrations, models
def forward(apps, schema_editor):
Session = apps.get_model('meeting', 'Session')
SchedTimeSessAssignment = apps.get_model('meeting', 'SchedTimeSessAssignment')
# find official assignments that are to private timeslots and fill in session.on_agenda
private_assignments = SchedTimeSessAssignment.objects.filter(
models.Q(
schedule=models.F('session__meeting__schedule')
) | models.Q(
schedule=models.F('session__meeting__schedule__base')
),
timeslot__type__private=True,
)
for pa in private_assignments:
pa.session.on_agenda = False
pa.session.save()
# Also update any sessions to match their purpose's default setting (this intentionally
# overrides the timeslot settings above, but that is unlikely to matter because the
# purposes will roll out at the same time as the on_agenda field)
Session.objects.filter(purpose__on_agenda=False).update(on_agenda=False)
Session.objects.filter(purpose__on_agenda=True).update(on_agenda=True)
def reverse(apps, schema_editor):
Session = apps.get_model('meeting', 'Session')
Session.objects.update(on_agenda=True) # restore all to default on_agenda=True state
class Migration(migrations.Migration):
dependencies = [
('meeting', '0050_session_on_agenda'),
]
operations = [
migrations.RunPython(forward, reverse),
]

View file

@ -766,7 +766,7 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
all of the events needed by the editor.
"""
# Set up a meeting and a schedule a plain user can edit
schedule = ScheduleFactory(owner__user__username="plain")
schedule = ScheduleFactory(meeting__type_id='ietf', owner__user__username="plain")
meeting = schedule.meeting
# Open the editor

View file

@ -3714,7 +3714,7 @@ class EditTests(TestCase):
self.assertEqual(meeting.schedule_set.count(), orig_schedule_count, 'Schedule should not be created')
def test_edit_session(self):
session = SessionFactory(group__type_id='team') # type determines allowed session purposes
session = SessionFactory(meeting__type_id='ietf', group__type_id='team') # type determines allowed session purposes
self.client.login(username='secretary', password='secretary+password')
url = urlreverse('ietf.meeting.views.edit_session', kwargs={'session_id': session.pk})
r = self.client.get(url)

View file

@ -23,7 +23,7 @@ class Migration(migrations.Migration):
dependencies = [
('name', '0035_populate_sessionpurposename'),
('meeting', '0050_populate_session_on_agenda'),
('meeting', '0051_populate_session_on_agenda'),
]
operations = [