Skip to content

Commit 45caa77

Browse files
committed
Merged in [19385] from jennifer@painless-security.com:
Correctly highlight session constraints in the meeting schedule editor. Fixes ietf-tools#3327. - Legacy-Id: 19389 Note: SVN reference [19385] has been migrated to Git commit 6719818
2 parents dd33e91 + 6719818 commit 45caa77

2 files changed

Lines changed: 67 additions & 15 deletions

File tree

ietf/meeting/tests_js.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from ietf.group.models import Group
2727
from ietf.group.factories import GroupFactory
2828
from ietf.meeting.factories import ( MeetingFactory, RoomFactory, SessionFactory, TimeSlotFactory,
29-
ProceedingsMaterialFactory )
29+
ProceedingsMaterialFactory, ScheduleFactory, ConstraintFactory )
3030
from ietf.meeting.test_data import make_meeting_test_data, make_interim_meeting
3131
from ietf.meeting.models import (Schedule, SchedTimeSessAssignment, Session,
3232
Room, TimeSlot, Constraint, ConstraintName,
@@ -794,6 +794,56 @@ def test_unassigned_sessions_drop_target_visible_when_empty(self):
794794
self.assertGreater(drop_target.size['width'], 0,
795795
'Drop target for unassigned sessions collapsed to 0 width')
796796

797+
def test_session_constraint_hints(self):
798+
"""Selecting a session should mark conflicting sessions
799+
800+
To test for recurrence of https://trac.ietf.org/trac/ietfdb/ticket/3327 need to have some constraints that
801+
do not conflict. Testing with only violated constraints does not exercise the code adequately.
802+
"""
803+
meeting = MeetingFactory(type_id='ietf', date=datetime.date.today(), populate_schedule=False)
804+
TimeSlotFactory.create_batch(5, meeting=meeting)
805+
schedule = ScheduleFactory(meeting=meeting)
806+
sessions = SessionFactory.create_batch(5, meeting=meeting, add_to_schedule=False)
807+
groups = [s.group for s in sessions]
808+
809+
# Now set up constraints
810+
# Get an arbitrary enabled group conflict ConstraintName
811+
constraint_names = meeting.enabled_constraint_names().filter(is_group_conflict=True)
812+
self.assertGreaterEqual(len(constraint_names), 2, 'Not enough constraint names enabled to perform test')
813+
814+
# one-way conflict from group 0 to 1
815+
ConstraintFactory(meeting=meeting, name=constraint_names[0], source=groups[0], target=groups[1], person=None)
816+
817+
# one-way conflict from group 2 to 0
818+
ConstraintFactory(meeting=meeting, name=constraint_names[0], source=groups[2], target=groups[0], person=None)
819+
820+
# two-way conflict between groups 0 and 3
821+
ConstraintFactory(meeting=meeting, name=constraint_names[0], source=groups[0], target=groups[3], person=None)
822+
ConstraintFactory(meeting=meeting, name=constraint_names[0], source=groups[3], target=groups[0], person=None)
823+
824+
# constraints that are not active when selecting sessions[0]
825+
ConstraintFactory(meeting=meeting, name=constraint_names[1], source=groups[1], target=groups[2], person=None)
826+
ConstraintFactory(meeting=meeting, name=constraint_names[1], source=groups[3], target=groups[4], person=None)
827+
828+
url = self.absreverse('ietf.meeting.views.edit_meeting_schedule',
829+
kwargs=dict(num=meeting.number, owner=schedule.owner.email(), name=schedule.name))
830+
self.login(schedule.owner.user.username)
831+
self.driver.get(url)
832+
session_elements = [self.driver.find_element_by_css_selector(f'#session{sess.pk}') for sess in sessions]
833+
session_elements[0].click()
834+
835+
# All conflicting sessions should be flagged with the would-violate-hint class.
836+
self.assertIn('would-violate-hint', session_elements[1].get_attribute('class'),
837+
'Constraint violation should be indicated on conflicting session')
838+
self.assertIn('would-violate-hint', session_elements[2].get_attribute('class'),
839+
'Constraint violation should be indicated on conflicting session')
840+
self.assertIn('would-violate-hint', session_elements[3].get_attribute('class'),
841+
'Constraint violation should be indicated on conflicting session')
842+
843+
# And the non-conflicting session should not be flagged
844+
self.assertNotIn('would-violate-hint', session_elements[4].get_attribute('class'),
845+
'Constraint violation should not be indicated on non-conflicting session')
846+
797847
@ifSeleniumEnabled
798848
@skipIf(django.VERSION[0]==2, "Skipping test with race conditions under Django 2")
799849
class ScheduleEditTests(IetfSeleniumTestCase):

ietf/static/ietf/js/edit-meeting-schedule.js

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jQuery(document).ready(function () {
2626
}
2727

2828
let sessions = content.find(".session").not(".readonly");
29+
let sessionConstraints = sessions.find('.constraints > span');
2930
let timeslots = content.find(".timeslot");
3031
let timeslotLabels = content.find(".time-label");
3132
let swapDaysButtons = content.find('.swap-days');
@@ -154,25 +155,26 @@ jQuery(document).ready(function () {
154155
timeslotLabels.removeClass("would-violate-hint");
155156
}
156157

158+
/**
159+
* Remove all would-violate-hint classes on sessions and their formatted constraints
160+
*/
161+
function resetSessionsWouldViolate() {
162+
sessions.removeClass("would-violate-hint");
163+
sessionConstraints.removeClass("would-violate-hint");
164+
}
165+
157166
function showConstraintHints(selectedSession) {
158167
let sessionId = selectedSession ? selectedSession.id.slice("session".length) : null;
159168
// hints on the sessions
160-
sessions.find(".constraints > span").each(function () {
161-
let wouldViolate = false;
162-
let applyChange = true;
163-
if (sessionId) {
169+
resetSessionsWouldViolate();
170+
if (sessionId) {
171+
sessionConstraints.each(function () {
164172
let sessionIds = this.dataset.sessions;
165-
if (!sessionIds) {
166-
applyChange = false;
167-
} else {
168-
wouldViolate = sessionIds.split(",").indexOf(sessionId) !== -1;
173+
if (sessionIds && (sessionIds.split(",").indexOf(sessionId) !== -1)) {
174+
setSessionWouldViolate(this, true);
169175
}
170-
}
171-
172-
if (applyChange) {
173-
setSessionWouldViolate(this, wouldViolate);
174-
}
175-
});
176+
});
177+
}
176178

177179
// hints on timeslots
178180
resetTimeslotsWouldViolate();

0 commit comments

Comments
 (0)