Skip to content

Commit 8da45cb

Browse files
feat: optionally hide room-only schedule diffs (#9861)
* feat: optionally hide room-only schedule diffs * test: update test
1 parent 87c3a9d commit 8da45cb

File tree

2 files changed

+151
-56
lines changed

2 files changed

+151
-56
lines changed

ietf/meeting/tests_views.py

Lines changed: 138 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@
4949
from ietf.meeting.helpers import send_interim_minutes_reminder, populate_important_dates, update_important_dates
5050
from ietf.meeting.models import Session, TimeSlot, Meeting, SchedTimeSessAssignment, Schedule, SessionPresentation, SlideSubmission, SchedulingEvent, Room, Constraint, ConstraintName
5151
from ietf.meeting.test_data import make_meeting_test_data, make_interim_meeting, make_interim_test_data
52-
from ietf.meeting.utils import condition_slide_order, generate_proceedings_content
52+
from ietf.meeting.utils import (
53+
condition_slide_order,
54+
generate_proceedings_content,
55+
diff_meeting_schedules,
56+
)
5357
from ietf.meeting.utils import add_event_info_to_session_qs, participants_for_meeting
5458
from ietf.meeting.utils import create_recording, delete_recording, get_next_sequence, bluesheet_data
5559
from ietf.meeting.views import session_draft_list, parse_agenda_filter_params, sessions_post_save, agenda_extract_schedule
@@ -4765,73 +4769,151 @@ def test_list_schedules(self):
47654769
self.assertTrue(r.status_code, 200)
47664770

47674771
def test_diff_schedules(self):
4768-
meeting = make_meeting_test_data()
4769-
4770-
url = urlreverse('ietf.meeting.views.diff_schedules',kwargs={'num':meeting.number})
4771-
login_testing_unauthorized(self,"secretary", url)
4772-
r = self.client.get(url)
4773-
self.assertTrue(r.status_code, 200)
4774-
4775-
from_schedule = Schedule.objects.get(meeting=meeting, name="test-unofficial-schedule")
4776-
4777-
session1 = Session.objects.filter(meeting=meeting, group__acronym='mars').first()
4778-
session2 = Session.objects.filter(meeting=meeting, group__acronym='ames').first()
4779-
session3 = SessionFactory(meeting=meeting, group=Group.objects.get(acronym='mars'),
4780-
attendees=10, requested_duration=datetime.timedelta(minutes=70),
4781-
add_to_schedule=False)
4782-
SchedulingEvent.objects.create(session=session3, status_id='schedw', by=Person.objects.first())
4783-
4784-
slot2 = TimeSlot.objects.filter(meeting=meeting, type='regular').order_by('-time').first()
4785-
slot3 = TimeSlot.objects.create(
4786-
meeting=meeting, type_id='regular', location=slot2.location,
4787-
duration=datetime.timedelta(minutes=60),
4788-
time=slot2.time + datetime.timedelta(minutes=60),
4772+
# Create meeting and some time slots
4773+
meeting = MeetingFactory(type_id="ietf", populate_schedule=False)
4774+
rooms = RoomFactory.create_batch(2, meeting=meeting)
4775+
# first index is room, second is time
4776+
timeslots = [
4777+
[
4778+
TimeSlotFactory(
4779+
location=room,
4780+
meeting=meeting,
4781+
time=datetime.datetime.combine(
4782+
meeting.date, datetime.time(9, 0, tzinfo=datetime.UTC)
4783+
)
4784+
),
4785+
TimeSlotFactory(
4786+
location=room,
4787+
meeting=meeting,
4788+
time=datetime.datetime.combine(
4789+
meeting.date, datetime.time(10, 0, tzinfo=datetime.UTC)
4790+
)
4791+
),
4792+
TimeSlotFactory(
4793+
location=room,
4794+
meeting=meeting,
4795+
time=datetime.datetime.combine(
4796+
meeting.date, datetime.time(11, 0, tzinfo=datetime.UTC)
4797+
)
4798+
),
4799+
]
4800+
for room in rooms
4801+
]
4802+
sessions = SessionFactory.create_batch(
4803+
5, meeting=meeting, add_to_schedule=False
47894804
)
47904805

4791-
# copy
4792-
new_url = urlreverse("ietf.meeting.views.new_meeting_schedule", kwargs=dict(num=meeting.number, owner=from_schedule.owner_email(), name=from_schedule.name))
4793-
r = self.client.post(new_url, {
4794-
'name': "newtest",
4795-
'public': "on",
4796-
})
4797-
self.assertNoFormPostErrors(r)
4806+
from_schedule = ScheduleFactory(meeting=meeting)
4807+
to_schedule = ScheduleFactory(meeting=meeting)
47984808

4799-
to_schedule = Schedule.objects.get(meeting=meeting, name='newtest')
4809+
# sessions[0]: not scheduled in from_schedule, scheduled in to_schedule
4810+
SchedTimeSessAssignment.objects.create(
4811+
schedule=to_schedule,
4812+
session=sessions[0],
4813+
timeslot=timeslots[0][0],
4814+
)
4815+
# sessions[1]: scheduled in from_schedule, not scheduled in to_schedule
4816+
SchedTimeSessAssignment.objects.create(
4817+
schedule=from_schedule,
4818+
session=sessions[1],
4819+
timeslot=timeslots[0][0],
4820+
)
4821+
# sessions[2]: moves rooms, not time
4822+
SchedTimeSessAssignment.objects.create(
4823+
schedule=from_schedule,
4824+
session=sessions[2],
4825+
timeslot=timeslots[0][1],
4826+
)
4827+
SchedTimeSessAssignment.objects.create(
4828+
schedule=to_schedule,
4829+
session=sessions[2],
4830+
timeslot=timeslots[1][1],
4831+
)
4832+
# sessions[3]: moves time, not room
4833+
SchedTimeSessAssignment.objects.create(
4834+
schedule=from_schedule,
4835+
session=sessions[3],
4836+
timeslot=timeslots[1][1],
4837+
)
4838+
SchedTimeSessAssignment.objects.create(
4839+
schedule=to_schedule,
4840+
session=sessions[3],
4841+
timeslot=timeslots[1][2],
4842+
)
4843+
# sessions[4]: moves room and time
4844+
SchedTimeSessAssignment.objects.create(
4845+
schedule=from_schedule,
4846+
session=sessions[4],
4847+
timeslot=timeslots[1][0],
4848+
)
4849+
SchedTimeSessAssignment.objects.create(
4850+
schedule=to_schedule,
4851+
session=sessions[4],
4852+
timeslot=timeslots[0][2],
4853+
)
48004854

4801-
# make some changes
4855+
# Check the raw diffs
4856+
raw_diffs = diff_meeting_schedules(from_schedule, to_schedule)
4857+
self.assertCountEqual(
4858+
raw_diffs,
4859+
[
4860+
{
4861+
"change": "schedule",
4862+
"session": sessions[0].pk,
4863+
"to": timeslots[0][0].pk,
4864+
},
4865+
{
4866+
"change": "unschedule",
4867+
"session": sessions[1].pk,
4868+
"from": timeslots[0][0].pk,
4869+
},
4870+
{
4871+
"change": "move",
4872+
"session": sessions[2].pk,
4873+
"from": timeslots[0][1].pk,
4874+
"to": timeslots[1][1].pk,
4875+
},
4876+
{
4877+
"change": "move",
4878+
"session": sessions[3].pk,
4879+
"from": timeslots[1][1].pk,
4880+
"to": timeslots[1][2].pk,
4881+
},
4882+
{
4883+
"change": "move",
4884+
"session": sessions[4].pk,
4885+
"from": timeslots[1][0].pk,
4886+
"to": timeslots[0][2].pk,
4887+
},
4888+
]
4889+
)
48024890

4803-
edit_url = urlreverse("ietf.meeting.views.edit_meeting_schedule", kwargs=dict(num=meeting.number, owner=to_schedule.owner_email(), name=to_schedule.name))
4891+
# Check the view
4892+
url = urlreverse("ietf.meeting.views.diff_schedules",
4893+
kwargs={"num": meeting.number})
4894+
login_testing_unauthorized(self, "secretary", url)
4895+
r = self.client.get(url)
4896+
self.assertTrue(r.status_code, 200)
48044897

4805-
# schedule session
4806-
r = self.client.post(edit_url, {
4807-
'action': 'assign',
4808-
'timeslot': slot3.pk,
4809-
'session': session3.pk,
4810-
})
4811-
self.assertEqual(json.loads(r.content)['success'], True)
4812-
# unschedule session
4813-
r = self.client.post(edit_url, {
4814-
'action': 'unassign',
4815-
'session': session1.pk,
4816-
})
4817-
self.assertEqual(json.loads(r.content)['success'], True)
4818-
# move session
4819-
r = self.client.post(edit_url, {
4820-
'action': 'assign',
4821-
'timeslot': slot2.pk,
4822-
'session': session2.pk,
4898+
# with show room changes disabled - does not show sessions[2] because it did
4899+
# not change time
4900+
r = self.client.get(url, {
4901+
"from_schedule": from_schedule.name,
4902+
"to_schedule": to_schedule.name,
48234903
})
4824-
self.assertEqual(json.loads(r.content)['success'], True)
4904+
self.assertTrue(r.status_code, 200)
4905+
q = PyQuery(r.content)
4906+
self.assertEqual(len(q(".schedule-diffs tr")), 4 + 1)
48254907

4826-
# now get differences
4908+
# with show room changes enabled - shows all changes
48274909
r = self.client.get(url, {
4828-
'from_schedule': from_schedule.name,
4829-
'to_schedule': to_schedule.name,
4910+
"from_schedule": from_schedule.name,
4911+
"to_schedule": to_schedule.name,
4912+
"show_room_changes": "on",
48304913
})
48314914
self.assertTrue(r.status_code, 200)
4832-
48334915
q = PyQuery(r.content)
4834-
self.assertEqual(len(q(".schedule-diffs tr")), 3+1)
4916+
self.assertEqual(len(q(".schedule-diffs tr")), 5 + 1)
48354917

48364918
def test_delete_schedule(self):
48374919
url = urlreverse('ietf.meeting.views.delete_schedule',

ietf/meeting/views.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,6 +1675,11 @@ def list_schedules(request, num):
16751675
class DiffSchedulesForm(forms.Form):
16761676
from_schedule = forms.ChoiceField()
16771677
to_schedule = forms.ChoiceField()
1678+
show_room_changes = forms.BooleanField(
1679+
initial=False,
1680+
required=False,
1681+
help_text="Include changes to room without a date or time change",
1682+
)
16781683

16791684
def __init__(self, meeting, user, *args, **kwargs):
16801685
super().__init__(*args, **kwargs)
@@ -1707,6 +1712,14 @@ def diff_schedules(request, num):
17071712
raw_diffs = diff_meeting_schedules(from_schedule, to_schedule)
17081713

17091714
diffs = prefetch_schedule_diff_objects(raw_diffs)
1715+
if not form.cleaned_data["show_room_changes"]:
1716+
# filter out room-only changes
1717+
diffs = [
1718+
d
1719+
for d in diffs
1720+
if (d["change"] != "move") or (d["from"].time != d["to"].time)
1721+
]
1722+
17101723
for d in diffs:
17111724
s = d['session']
17121725
s.session_label = s.short_name

0 commit comments

Comments
 (0)