diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py
index 0f91986f77..a93a26b981 100644
--- a/ietf/meeting/tests_views.py
+++ b/ietf/meeting/tests_views.py
@@ -6541,110 +6541,130 @@ def test_upload_bluesheets_interim_chair_access(self):
self.assertIn('Upload', str(q("title")))
- def test_upload_minutes_agenda(self):
- for doctype in ('minutes','agenda'):
- session = SessionFactory(meeting__type_id='ietf')
- if doctype == 'minutes':
- url = urlreverse('ietf.meeting.views.upload_session_minutes',kwargs={'num':session.meeting.number,'session_id':session.id})
- else:
- url = urlreverse('ietf.meeting.views.upload_session_agenda',kwargs={'num':session.meeting.number,'session_id':session.id})
- self.client.logout()
- login_testing_unauthorized(self,"secretary",url)
- r = self.client.get(url)
- self.assertEqual(r.status_code, 200)
- q = PyQuery(r.content)
- self.assertIn('Upload', str(q("Title")))
- self.assertFalse(session.presentations.exists())
- self.assertFalse(q('form input[type="checkbox"]'))
-
- session2 = SessionFactory(meeting=session.meeting,group=session.group)
- r = self.client.get(url)
- self.assertEqual(r.status_code, 200)
- q = PyQuery(r.content)
- self.assertTrue(q('form input[type="checkbox"]'))
-
- # test not submitting a file
- r = self.client.post(url, dict(submission_method="upload"))
- self.assertEqual(r.status_code, 200)
- q = PyQuery(r.content)
- self.assertTrue(q("form .is-invalid"))
-
- test_file = BytesIO(b'this is some text for a test')
- test_file.name = "not_really.json"
- r = self.client.post(url,dict(submission_method="upload",file=test_file))
- self.assertEqual(r.status_code, 200)
- q = PyQuery(r.content)
- self.assertTrue(q('form .is-invalid'))
-
- test_file = BytesIO(b'this is some text for a test'*1510000)
- test_file.name = "not_really.pdf"
- r = self.client.post(url,dict(submission_method="upload",file=test_file))
- self.assertEqual(r.status_code, 200)
- q = PyQuery(r.content)
- self.assertTrue(q('form .is-invalid'))
-
- test_file = BytesIO(b'
')
- test_file.name = "not_really.html"
- r = self.client.post(url,dict(submission_method="upload",file=test_file))
- self.assertEqual(r.status_code, 200)
- q = PyQuery(r.content)
- self.assertTrue(q('form .is-invalid'))
-
- # Test html sanitization
- test_file = BytesIO(b'TitleTitle
')
- test_file.name = "some.html"
- r = self.client.post(url,dict(submission_method="upload",file=test_file))
- self.assertEqual(r.status_code, 302)
- doc = session.presentations.filter(document__type_id=doctype).first().document
- self.assertEqual(doc.rev,'00')
- text = doc.text()
- self.assertIn('Some text', text)
- self.assertNotIn('', text)
- text = retrieve_str(doctype, f"{doc.name}-{doc.rev}.html")
- self.assertIn('Some text', text)
- self.assertNotIn('', text)
-
- # txt upload
- test_bytes = b'This is some text for a test, with the word\nvirtual at the beginning of a line.'
- test_file = BytesIO(test_bytes)
- test_file.name = "some.txt"
- r = self.client.post(url,dict(submission_method="upload",file=test_file,apply_to_all=False))
- self.assertEqual(r.status_code, 302)
- doc = session.presentations.filter(document__type_id=doctype).first().document
- self.assertEqual(doc.rev,'01')
- self.assertFalse(session2.presentations.filter(document__type_id=doctype))
- retrieved_bytes = retrieve_bytes(doctype, f"{doc.name}-{doc.rev}.txt")
- self.assertEqual(retrieved_bytes, test_bytes)
-
+ def test_label_future_sessions(self):
+ self.client.login(username='secretary', password='secretary+password')
+ for future in (True, False):
+ mtg_date = date_today()+datetime.timedelta(days=180 if future else -180)
+ session = SessionFactory(meeting__type_id='ietf', meeting__date=mtg_date)
+ # Verify future warning shows on the session details panel
+ url = urlreverse('ietf.meeting.views.session_details', kwargs={'num':session.meeting.number, 'acronym': session.group.acronym})
r = self.client.get(url)
- self.assertEqual(r.status_code, 200)
- q = PyQuery(r.content)
- self.assertIn('Revise', str(q("Title")))
- test_bytes = b'this is some different text for a test'
- test_file = BytesIO(test_bytes)
- test_file.name = "also_some.txt"
- r = self.client.post(url,dict(submission_method="upload",file=test_file,apply_to_all=True))
- self.assertEqual(r.status_code, 302)
- doc = Document.objects.get(pk=doc.pk)
- self.assertEqual(doc.rev,'02')
- self.assertTrue(session2.presentations.filter(document__type_id=doctype))
- retrieved_bytes = retrieve_bytes(doctype, f"{doc.name}-{doc.rev}.txt")
- self.assertEqual(retrieved_bytes, test_bytes)
-
- # Test bad encoding
- test_file = BytesIO('Title
'.encode('latin1'))
- test_file.name = "some.html"
- r = self.client.post(url,dict(submission_method="upload",file=test_file))
- self.assertContains(r, 'Could not identify the file encoding')
- doc = Document.objects.get(pk=doc.pk)
- self.assertEqual(doc.rev,'02')
+ self.assertTrue(r.status_code==200)
+ if future:
+ self.assertContains(r, "Session has not ended yet")
+ else:
+ self.assertNotContains(r, "Session has not ended yet")
- # Verify that we don't have dead links
- url = urlreverse('ietf.meeting.views.session_details', kwargs={'num':session.meeting.number, 'acronym': session.group.acronym})
- top = '/meeting/%s/' % session.meeting.number
- self.requests_mock.get(f'{session.notes_url()}/download', text='markdown notes')
- self.requests_mock.get(f'{session.notes_url()}/info', text=json.dumps({'title': 'title', 'updatetime': '2021-12-01T17:11:00z'}))
- self.crawl_materials(url=url, top=top)
+ def test_upload_minutes_agenda(self):
+ for doctype in ('minutes','agenda'):
+ for future in (True, False):
+ mtg_date = date_today()+datetime.timedelta(days=180 if future else -180)
+ session = SessionFactory(meeting__type_id='ietf', meeting__date=mtg_date)
+ if doctype == 'minutes':
+ url = urlreverse('ietf.meeting.views.upload_session_minutes',kwargs={'num':session.meeting.number,'session_id':session.id})
+ else:
+ url = urlreverse('ietf.meeting.views.upload_session_agenda',kwargs={'num':session.meeting.number,'session_id':session.id})
+ self.client.logout()
+ login_testing_unauthorized(self,"secretary",url)
+ r = self.client.get(url)
+ self.assertEqual(r.status_code, 200)
+ q = PyQuery(r.content)
+ self.assertIn('Upload', str(q("Title")))
+ self.assertFalse(session.presentations.exists())
+ self.assertFalse(q('form input[type="checkbox"]'))
+ if future and doctype == "minutes":
+ self.assertContains(r, "Session has not ended yet")
+ else:
+ self.assertNotContains(r, "Session has not ended yet")
+
+ session2 = SessionFactory(meeting=session.meeting,group=session.group)
+ r = self.client.get(url)
+ self.assertEqual(r.status_code, 200)
+ q = PyQuery(r.content)
+ self.assertTrue(q('form input[type="checkbox"]'))
+
+ # test not submitting a file
+ r = self.client.post(url, dict(submission_method="upload"))
+ self.assertEqual(r.status_code, 200)
+ q = PyQuery(r.content)
+ self.assertTrue(q("form .is-invalid"))
+
+ test_file = BytesIO(b'this is some text for a test')
+ test_file.name = "not_really.json"
+ r = self.client.post(url,dict(submission_method="upload",file=test_file))
+ self.assertEqual(r.status_code, 200)
+ q = PyQuery(r.content)
+ self.assertTrue(q('form .is-invalid'))
+
+ test_file = BytesIO(b'this is some text for a test'*1510000)
+ test_file.name = "not_really.pdf"
+ r = self.client.post(url,dict(submission_method="upload",file=test_file))
+ self.assertEqual(r.status_code, 200)
+ q = PyQuery(r.content)
+ self.assertTrue(q('form .is-invalid'))
+
+ test_file = BytesIO(b'')
+ test_file.name = "not_really.html"
+ r = self.client.post(url,dict(submission_method="upload",file=test_file))
+ self.assertEqual(r.status_code, 200)
+ q = PyQuery(r.content)
+ self.assertTrue(q('form .is-invalid'))
+
+ # Test html sanitization
+ test_file = BytesIO(b'TitleTitle
')
+ test_file.name = "some.html"
+ r = self.client.post(url,dict(submission_method="upload",file=test_file))
+ self.assertEqual(r.status_code, 302)
+ doc = session.presentations.filter(document__type_id=doctype).first().document
+ self.assertEqual(doc.rev,'00')
+ text = doc.text()
+ self.assertIn('Some text', text)
+ self.assertNotIn('', text)
+ text = retrieve_str(doctype, f"{doc.name}-{doc.rev}.html")
+ self.assertIn('Some text', text)
+ self.assertNotIn('', text)
+
+ # txt upload
+ test_bytes = b'This is some text for a test, with the word\nvirtual at the beginning of a line.'
+ test_file = BytesIO(test_bytes)
+ test_file.name = "some.txt"
+ r = self.client.post(url,dict(submission_method="upload",file=test_file,apply_to_all=False))
+ self.assertEqual(r.status_code, 302)
+ doc = session.presentations.filter(document__type_id=doctype).first().document
+ self.assertEqual(doc.rev,'01')
+ self.assertFalse(session2.presentations.filter(document__type_id=doctype))
+ retrieved_bytes = retrieve_bytes(doctype, f"{doc.name}-{doc.rev}.txt")
+ self.assertEqual(retrieved_bytes, test_bytes)
+
+ r = self.client.get(url)
+ self.assertEqual(r.status_code, 200)
+ q = PyQuery(r.content)
+ self.assertIn('Revise', str(q("Title")))
+ test_bytes = b'this is some different text for a test'
+ test_file = BytesIO(test_bytes)
+ test_file.name = "also_some.txt"
+ r = self.client.post(url,dict(submission_method="upload",file=test_file,apply_to_all=True))
+ self.assertEqual(r.status_code, 302)
+ doc = Document.objects.get(pk=doc.pk)
+ self.assertEqual(doc.rev,'02')
+ self.assertTrue(session2.presentations.filter(document__type_id=doctype))
+ retrieved_bytes = retrieve_bytes(doctype, f"{doc.name}-{doc.rev}.txt")
+ self.assertEqual(retrieved_bytes, test_bytes)
+
+ # Test bad encoding
+ test_file = BytesIO('Title
'.encode('latin1'))
+ test_file.name = "some.html"
+ r = self.client.post(url,dict(submission_method="upload",file=test_file))
+ self.assertContains(r, 'Could not identify the file encoding')
+ doc = Document.objects.get(pk=doc.pk)
+ self.assertEqual(doc.rev,'02')
+
+ # Verify that we don't have dead links
+ url = urlreverse('ietf.meeting.views.session_details', kwargs={'num':session.meeting.number, 'acronym': session.group.acronym})
+ top = '/meeting/%s/' % session.meeting.number
+ self.requests_mock.get(f'{session.notes_url()}/download', text='markdown notes')
+ self.requests_mock.get(f'{session.notes_url()}/info', text=json.dumps({'title': 'title', 'updatetime': '2021-12-01T17:11:00z'}))
+ self.crawl_materials(url=url, top=top)
def test_upload_minutes_agenda_unscheduled(self):
for doctype in ('minutes','agenda'):
@@ -6661,6 +6681,7 @@ def test_upload_minutes_agenda_unscheduled(self):
self.assertIn('Upload', str(q("Title")))
self.assertFalse(session.presentations.exists())
self.assertFalse(q('form input[type="checkbox"]'))
+ self.assertNotContains(r, "Session has not ended yet")
test_file = BytesIO(b'this is some text for a test')
test_file.name = "not_really.txt"
@@ -6669,35 +6690,40 @@ def test_upload_minutes_agenda_unscheduled(self):
@override_settings(MEETING_MATERIALS_SERVE_LOCALLY=True)
def test_upload_minutes_agenda_interim(self):
- session=SessionFactory(meeting__type_id='interim')
for doctype in ('minutes','agenda'):
- if doctype=='minutes':
- url = urlreverse('ietf.meeting.views.upload_session_minutes',kwargs={'num':session.meeting.number,'session_id':session.id})
- else:
- url = urlreverse('ietf.meeting.views.upload_session_agenda',kwargs={'num':session.meeting.number,'session_id':session.id})
- self.client.logout()
- login_testing_unauthorized(self,"secretary",url)
- r = self.client.get(url)
- self.assertEqual(r.status_code, 200)
- q = PyQuery(r.content)
- self.assertIn('Upload', str(q("title")))
- self.assertFalse(session.presentations.filter(document__type_id=doctype))
- test_bytes = b'this is some text for a test'
- test_file = BytesIO(test_bytes)
- test_file.name = "not_really.txt"
- r = self.client.post(url,dict(submission_method="upload",file=test_file))
- self.assertEqual(r.status_code, 302)
- doc = session.presentations.filter(document__type_id=doctype).first().document
- self.assertEqual(doc.rev,'00')
- retrieved_bytes = retrieve_bytes(doctype, f"{doc.name}-{doc.rev}.txt")
- self.assertEqual(retrieved_bytes, test_bytes)
-
- # Verify that we don't have dead links
- url = urlreverse('ietf.meeting.views.session_details', kwargs={'num':session.meeting.number, 'acronym': session.group.acronym})
- top = '/meeting/%s/' % session.meeting.number
- self.requests_mock.get(f'{session.notes_url()}/download', text='markdown notes')
- self.requests_mock.get(f'{session.notes_url()}/info', text=json.dumps({'title': 'title', 'updatetime': '2021-12-01T17:11:00z'}))
- self.crawl_materials(url=url, top=top)
+ for future in (True, False):
+ session=SessionFactory(meeting__type_id='interim', meeting__date = date_today()+datetime.timedelta(days=180 if future else -180))
+ if doctype=='minutes':
+ url = urlreverse('ietf.meeting.views.upload_session_minutes',kwargs={'num':session.meeting.number,'session_id':session.id})
+ else:
+ url = urlreverse('ietf.meeting.views.upload_session_agenda',kwargs={'num':session.meeting.number,'session_id':session.id})
+ self.client.logout()
+ login_testing_unauthorized(self,"secretary",url)
+ r = self.client.get(url)
+ self.assertEqual(r.status_code, 200)
+ q = PyQuery(r.content)
+ self.assertIn('Upload', str(q("title")))
+ self.assertFalse(session.presentations.filter(document__type_id=doctype))
+ if future and doctype == "minutes":
+ self.assertContains(r, "Session has not ended yet")
+ else:
+ self.assertNotContains(r, "Session has not ended yet")
+ test_bytes = b'this is some text for a test'
+ test_file = BytesIO(test_bytes)
+ test_file.name = "not_really.txt"
+ r = self.client.post(url,dict(submission_method="upload",file=test_file))
+ self.assertEqual(r.status_code, 302)
+ doc = session.presentations.filter(document__type_id=doctype).first().document
+ self.assertEqual(doc.rev,'00')
+ retrieved_bytes = retrieve_bytes(doctype, f"{doc.name}-{doc.rev}.txt")
+ self.assertEqual(retrieved_bytes, test_bytes)
+
+ # Verify that we don't have dead links
+ url = urlreverse('ietf.meeting.views.session_details', kwargs={'num':session.meeting.number, 'acronym': session.group.acronym})
+ top = '/meeting/%s/' % session.meeting.number
+ self.requests_mock.get(f'{session.notes_url()}/download', text='markdown notes')
+ self.requests_mock.get(f'{session.notes_url()}/info', text=json.dumps({'title': 'title', 'updatetime': '2021-12-01T17:11:00z'}))
+ self.crawl_materials(url=url, top=top)
@override_settings(MEETING_MATERIALS_SERVE_LOCALLY=True)
def test_upload_narrativeminutes(self):
diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py
index 6a73059d92..722bf829e1 100644
--- a/ietf/meeting/views.py
+++ b/ietf/meeting/views.py
@@ -2522,6 +2522,8 @@ def session_details(request, num, acronym):
else:
pending_suggestions = SlideSubmission.objects.none()
+ tsa = session.official_timeslotassignment()
+ future = tsa is not None and timezone.now() < tsa.timeslot.end_time()
return render(request, "meeting/session_details.html",
{ 'scheduled_sessions':scheduled_sessions ,
'unscheduled_sessions':unscheduled_sessions ,
@@ -2532,6 +2534,7 @@ def session_details(request, num, acronym):
'can_manage_materials' : can_manage,
'can_view_request': can_view_request,
'thisweek': datetime_today()-datetime.timedelta(days=7),
+ 'future': future,
})
class SessionDraftsForm(forms.Form):
@@ -2823,11 +2826,14 @@ def upload_session_minutes(request, session_id, num):
else:
form = UploadMinutesForm(show_apply_to_all_checkbox)
+ tsa = session.official_timeslotassignment()
+ future = tsa is not None and timezone.now() < tsa.timeslot.end_time()
return render(request, "meeting/upload_session_minutes.html",
{'session': session,
'session_number': session_number,
'minutes_sp' : minutes_sp,
'form': form,
+ 'future': future,
})
@role_required("Secretariat")
diff --git a/ietf/templates/meeting/session_details_panel.html b/ietf/templates/meeting/session_details_panel.html
index 87d9e3d672..7c52ac0b4a 100644
--- a/ietf/templates/meeting/session_details_panel.html
+++ b/ietf/templates/meeting/session_details_panel.html
@@ -109,7 +109,7 @@ Agenda, Minutes, and Bluesheets
{% endif %}
{% if not session.type_counter.minutes %}
- Import minutes from notes.ietf.org
+ Import minutes from notes.ietf.org
Upload minutes
diff --git a/ietf/templates/meeting/upload_session_minutes.html b/ietf/templates/meeting/upload_session_minutes.html
index 30eadda277..324440681f 100644
--- a/ietf/templates/meeting/upload_session_minutes.html
+++ b/ietf/templates/meeting/upload_session_minutes.html
@@ -26,6 +26,11 @@
{% if session_number %}
Session {{ session_number }} : {{ session.official_timeslotassignment.timeslot.time|timezone:session.meeting.time_zone|date:"D M-d-Y Hi" }}
{% endif %}
+ {% if future %}
+
+ Caution: Session has not ended yet
+
+ {% endif %}