Skip to content

Commit 07d60de

Browse files
committed
Merged in /branch/iola/meeting-improvement-r17835@18048. This provides a new snapshot of the new schedule editor work, with improved edit page layout and details.
- Legacy-Id: 18358
2 parents dd09b70 + 15de8ef commit 07d60de

14 files changed

Lines changed: 15546 additions & 15225 deletions

File tree

ietf/meeting/tests_js.py

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,24 @@ def test_edit_meeting_schedule(self):
8888
type_id='regular',
8989
location=room2,
9090
duration=datetime.timedelta(hours=2),
91-
time=slot1.time - datetime.timedelta(seconds=10 * 60),
91+
time=slot1.time - datetime.timedelta(minutes=10),
9292
)
9393

94+
slot3 = TimeSlot.objects.create(
95+
meeting=meeting,
96+
type_id='regular',
97+
location=room2,
98+
duration=datetime.timedelta(hours=2),
99+
time=max(slot1.end_time(), slot2.end_time()) + datetime.timedelta(minutes=10),
100+
)
101+
94102
s1, s2 = Session.objects.filter(meeting=meeting, type='regular')
95103
s2.requested_duration = slot2.duration + datetime.timedelta(minutes=10)
96104
s2.save()
97105
SchedTimeSessAssignment.objects.filter(session=s1).delete()
98106

107+
s2b = Session.objects.create(meeting=meeting, group=s2.group, attendees=10, requested_duration=datetime.timedelta(minutes=60), type_id='regular')
108+
99109
Constraint.objects.create(
100110
meeting=meeting,
101111
source=s1.group,
@@ -108,19 +118,20 @@ def test_edit_meeting_schedule(self):
108118
self.driver.get(url)
109119

110120
q = PyQuery(self.driver.page_source)
111-
self.assertEqual(len(q('.session')), 2)
121+
self.assertEqual(len(q('.session')), 3)
112122

113123
# select - show session info
114124
s2_element = self.driver.find_element_by_css_selector('#session{}'.format(s2.pk))
115125
s2_element.click()
116126

117-
session_info_element = self.driver.find_element_by_css_selector('.session-info-container label')
118-
self.assertIn(s2.group.acronym, session_info_element.text)
127+
session_info_container = self.driver.find_element_by_css_selector('.session-info-container')
128+
self.assertIn(s2.group.acronym, session_info_container.find_element_by_css_selector(".title").text)
129+
self.assertEqual(session_info_container.find_element_by_css_selector(".other-session .time").text, "not yet scheduled")
119130

120131
# deselect
121-
self.driver.find_element_by_css_selector('.session-info-container').click()
132+
self.driver.find_element_by_css_selector('.scheduling-panel').click()
122133

123-
self.assertEqual(self.driver.find_elements_by_css_selector('.session-info-container label'), [])
134+
self.assertEqual(session_info_container.find_elements_by_css_selector(".title"), [])
124135

125136
# unschedule
126137

@@ -139,39 +150,48 @@ def test_edit_meeting_schedule(self):
139150

140151
self.driver.execute_script('!function(s){s.fn.simulateDragDrop=function(t){return this.each(function(){new s.simulateDragDrop(this,t)})},s.simulateDragDrop=function(t,a){this.options=a,this.simulateEvent(t,a)},s.extend(s.simulateDragDrop.prototype,{simulateEvent:function(t,a){var e="dragstart",n=this.createEvent(e);this.dispatchEvent(t,e,n),e="drop";var r=this.createEvent(e,{});r.dataTransfer=n.dataTransfer,this.dispatchEvent(s(a.dropTarget)[0],e,r),e="dragend";var i=this.createEvent(e,{});i.dataTransfer=n.dataTransfer,this.dispatchEvent(t,e,i)},createEvent:function(t){var a=document.createEvent("CustomEvent");return a.initCustomEvent(t,!0,!0,null),a.dataTransfer={data:{},setData:function(t,a){this.data[t]=a},getData:function(t){return this.data[t]}},a},dispatchEvent:function(t,a,e){t.dispatchEvent?t.dispatchEvent(e):t.fireEvent&&t.fireEvent("on"+a,e)}})}(jQuery);')
141152

142-
self.driver.execute_script("jQuery('#session{}').simulateDragDrop({{dropTarget: '.unassigned-sessions'}});".format(s2.pk))
153+
self.driver.execute_script("jQuery('#session{}').simulateDragDrop({{dropTarget: '.unassigned-sessions .drop-target'}});".format(s2.pk))
143154

144155
WebDriverWait(self.driver, 2).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, '.unassigned-sessions #session{}'.format(s2.pk))))
145156

146157
self.assertEqual(list(SchedTimeSessAssignment.objects.filter(session=s2, schedule=schedule)), [])
147158

148159
# sorting unassigned
149-
sorted_pks = [s.pk for s in sorted([s1, s2], key=lambda s: s.group.acronym)]
160+
sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (s.group.acronym, s.requested_duration, s.pk))]
150161
self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=name]').click()
151-
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions #session{} + #session{}'.format(*sorted_pks)))
162+
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{} + #session{}'.format(*sorted_pks)))
152163

153-
sorted_pks = [s.pk for s in sorted([s1, s2], key=lambda s: (s.group.parent.acronym, s.group.acronym))]
164+
sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (s.group.parent.acronym, s.group.acronym, s.requested_duration, s.pk))]
154165
self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=parent]').click()
155-
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions #session{} + #session{}'.format(*sorted_pks)))
166+
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks)))
156167

157-
sorted_pks = [s.pk for s in sorted([s1, s2], key=lambda s: (s.requested_duration, s.group.parent.acronym, s.group.acronym))]
168+
sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (s.requested_duration, s.group.parent.acronym, s.group.acronym, s.pk))]
158169
self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=duration]').click()
159-
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions #session{} + #session{}'.format(*sorted_pks)))
170+
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks)))
160171

161-
sorted_pks = [s.pk for s in sorted([s1, s2], key=lambda s: (bool(s.comments), s.group.parent.acronym, s.group.acronym))]
172+
sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (int(bool(s.comments)), s.group.parent.acronym, s.group.acronym, s.requested_duration, s.pk))]
162173
self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=comments]').click()
163-
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions #session{} + #session{}'.format(*sorted_pks)))
174+
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks)))
164175

165176
# schedule
166-
self.driver.execute_script("jQuery('#session{}').simulateDragDrop({{dropTarget: '#timeslot{}'}});".format(s2.pk, slot1.pk))
177+
self.driver.execute_script("jQuery('#session{}').simulateDragDrop({{dropTarget: '#timeslot{} .drop-target'}});".format(s2.pk, slot1.pk))
167178

168179
WebDriverWait(self.driver, 2).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, '#timeslot{} #session{}'.format(slot1.pk, s2.pk))))
169180

170181
assignment = SchedTimeSessAssignment.objects.get(session=s2, schedule=schedule)
171182
self.assertEqual(assignment.timeslot, slot1)
172183

184+
# timeslot constraint hints when selected
185+
s1_element = self.driver.find_element_by_css_selector('#session{}'.format(s1.pk))
186+
s1_element.click()
187+
188+
# violated due to constraints
189+
self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.would-violate-hint'.format(slot1.pk)))
190+
# violated due to missing capacity
191+
self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.would-violate-hint'.format(slot3.pk)))
192+
173193
# reschedule
174-
self.driver.execute_script("jQuery('#session{}').simulateDragDrop({{dropTarget: '#timeslot{}'}});".format(s2.pk, slot2.pk))
194+
self.driver.execute_script("jQuery('#session{}').simulateDragDrop({{dropTarget: '#timeslot{} .drop-target'}});".format(s2.pk, slot2.pk))
175195

176196
WebDriverWait(self.driver, 2).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, '#timeslot{} #session{}'.format(slot2.pk, s2.pk))))
177197

@@ -185,14 +205,12 @@ def test_edit_meeting_schedule(self):
185205
self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.overfull'.format(slot2.pk)))
186206

187207
# constraint hints
188-
s1_element = self.driver.find_element_by_css_selector('#session{}'.format(s1.pk))
189208
s1_element.click()
190-
191-
constraint_element = s2_element.find_element_by_css_selector(".constraints span[data-sessions=\"{}\"].selected-hint".format(s1.pk))
209+
constraint_element = s2_element.find_element_by_css_selector(".constraints span[data-sessions=\"{}\"].would-violate-hint".format(s1.pk))
192210
self.assertTrue(constraint_element.is_displayed())
193211

194212
# current constraint violations
195-
self.driver.execute_script("jQuery('#session{}').simulateDragDrop({{dropTarget: '#timeslot{}'}});".format(s1.pk, slot1.pk))
213+
self.driver.execute_script("jQuery('#session{}').simulateDragDrop({{dropTarget: '#timeslot{} .drop-target'}});".format(s1.pk, slot1.pk))
196214

197215
WebDriverWait(self.driver, 2).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, '#timeslot{} #session{}'.format(slot1.pk, s1.pk))))
198216

@@ -203,6 +221,16 @@ def test_edit_meeting_schedule(self):
203221
self.assertTrue(s1_element.is_displayed())
204222
self.driver.find_element_by_css_selector(".session-parent-toggles [value=\"{}\"]".format(s1.group.parent.acronym)).click()
205223
self.assertTrue(not s1_element.is_displayed())
224+
self.driver.find_element_by_css_selector(".session-parent-toggles [value=\"{}\"]".format(s1.group.parent.acronym)).click()
225+
self.assertTrue(s1_element.is_displayed())
226+
227+
# hide timeslots
228+
self.driver.find_element_by_css_selector(".timeslot-group-toggles button").click()
229+
self.assertTrue(self.driver.find_element_by_css_selector("#timeslot-group-toggles-modal").is_displayed())
230+
self.driver.find_element_by_css_selector("#timeslot-group-toggles-modal [value=\"{}\"]".format("ts-group-{}-{}".format(slot2.time.strftime("%Y%m%d-%H%M"), int(slot2.duration.total_seconds() / 60)))).click()
231+
self.driver.find_element_by_css_selector("#timeslot-group-toggles-modal [data-dismiss=\"modal\"]").click()
232+
self.assertTrue(not self.driver.find_element_by_css_selector("#timeslot-group-toggles-modal").is_displayed())
233+
206234

207235
@skipIf(skip_selenium, skip_message)
208236
@skipIf(django.VERSION[0]==2, "Skipping test with race conditions under Django 2")

ietf/meeting/tests_views.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ def test_edit_meeting_schedule(self):
10571057
name=ConstraintName.objects.get(slug="conflict"),
10581058
)
10591059

1060-
p = Person.objects.all().first()
1060+
p = Person.objects.order_by('pk')[1]
10611061

10621062
Constraint.objects.create(
10631063
meeting=meeting,
@@ -1090,16 +1090,26 @@ def test_edit_meeting_schedule(self):
10901090
for s in [s1, s2]:
10911091
e = q("#session{}".format(s.pk))
10921092

1093-
# info in the movable entity
1093+
# info in the item representing the session that can be moved around
10941094
self.assertIn(s.group.acronym, e.find(".session-label").text())
10951095
if s.comments:
10961096
self.assertTrue(e.find(".comments"))
10971097
if s.attendees is not None:
10981098
self.assertIn(str(s.attendees), e.find(".attendees").text())
10991099
self.assertTrue(e.hasClass("parent-{}".format(s.group.parent.acronym)))
11001100

1101+
constraints = e.find(".constraints > span")
1102+
s_other = s2 if s == s1 else s1
1103+
self.assertEqual(len(constraints), 3)
1104+
self.assertEqual(constraints.eq(0).attr("data-sessions"), str(s_other.pk))
1105+
self.assertEqual(constraints.eq(0).find(".fa-user-o").parent().text(), "1") # 1 person in the constraint
1106+
self.assertEqual(constraints.eq(1).attr("data-sessions"), str(s_other.pk))
1107+
self.assertEqual(constraints.eq(1).find(".encircled").text(), "1" if s_other == s2 else "-1")
1108+
self.assertEqual(constraints.eq(2).attr("data-sessions"), str(s_other.pk))
1109+
self.assertEqual(constraints.eq(2).find(".encircled").text(), "AD")
1110+
11011111
# session info for the panel
1102-
self.assertIn(str(s.requested_duration.total_seconds() / 60.0 / 60), e.find(".session-info label").text())
1112+
self.assertIn(str(round(s.requested_duration.total_seconds() / 60.0 / 60, 1)), e.find(".session-info .title").text())
11031113

11041114
event = SchedulingEvent.objects.filter(session=s).order_by("id").first()
11051115
if event:
@@ -1108,14 +1118,12 @@ def test_edit_meeting_schedule(self):
11081118
if s.comments:
11091119
self.assertIn(s.comments, e.find(".comments").text())
11101120

1111-
# constraints
1112-
constraints = e.find(".constraints > span")
1113-
s_other = s2 if s == s1 else s1
1114-
self.assertEqual(len(constraints), 2)
1115-
self.assertEqual(constraints.eq(0).attr("data-sessions"), str(s_other.pk))
1116-
self.assertEqual(constraints.eq(1).attr("data-sessions"), str(s_other.pk))
1117-
self.assertEqual(constraints.find(".encircled").text(), "1")
1118-
self.assertEqual(constraints.find(".fa-user-o").parent().text(), "1") # 1 person in the constraint
1121+
formatted_constraints = e.find(".session-info .formatted-constraints > *")
1122+
if s == s1:
1123+
self.assertIn(s_other.group.acronym, formatted_constraints.eq(0).html())
1124+
self.assertIn(p.name, formatted_constraints.eq(1).html())
1125+
elif s == s2:
1126+
self.assertIn(p.name, formatted_constraints.eq(0).html())
11191127

11201128
self.assertTrue(q("em:contains(\"You can't edit this schedule\")"))
11211129

0 commit comments

Comments
 (0)