Allow anyone to see the pending and awaiting announcement tabs on the upcoming meeting view. Fixes #2929. Partially addresses #3016. Commit ready for merge.

- Legacy-Id: 18589
This commit is contained in:
Robert Sparks 2020-10-09 20:19:16 +00:00
parent 1a7aa2129d
commit b0eeaecca0
3 changed files with 22 additions and 108 deletions

View file

@ -12,6 +12,7 @@ from tempfile import mkstemp
from django.http import HttpRequest, Http404 from django.http import HttpRequest, Http404
from django.db.models import F, Max, Q, Prefetch from django.db.models import F, Max, Q, Prefetch
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from django.core.cache import cache from django.core.cache import cache
from django.urls import reverse from django.urls import reverse
from django.utils.cache import get_cache_key from django.utils.cache import get_cache_key
@ -341,6 +342,8 @@ def session_constraint_expire(request,session):
def can_approve_interim_request(meeting, user): def can_approve_interim_request(meeting, user):
'''Returns True if the user has permissions to approve an interim meeting request''' '''Returns True if the user has permissions to approve an interim meeting request'''
if not user or isinstance(user,AnonymousUser):
return False
if meeting.type.slug != 'interim': if meeting.type.slug != 'interim':
return False return False
if has_role(user, 'Secretariat'): if has_role(user, 'Secretariat'):

View file

@ -2095,49 +2095,7 @@ class InterimTests(TestCase):
settings.AGENDA_PATH = self.saved_agenda_path settings.AGENDA_PATH = self.saved_agenda_path
shutil.rmtree(self.materials_dir) shutil.rmtree(self.materials_dir)
def check_interim_tabs(self, url): # test_interim_announce subsumed by test_appears_on_announce
'''Helper function to check interim meeting list tabs'''
# no logged in - no tabs
r = self.client.get(url)
q = PyQuery(r.content)
self.assertEqual(len(q("ul.nav-tabs")), 0)
# plain user - no tabs
username = "plain"
self.client.login(username=username, password=username + "+password")
r = self.client.get(url)
q = PyQuery(r.content)
self.assertEqual(len(q("ul.nav-tabs")), 0)
self.client.logout()
# privileged user
username = "ad"
self.client.login(username=username, password=username + "+password")
r = self.client.get(url)
q = PyQuery(r.content)
self.assertEqual(len(q("a:contains('Pending')")), 1)
self.assertEqual(len(q("a:contains('Announce')")), 0)
self.client.logout()
# secretariat
username = "secretary"
self.client.login(username=username, password=username + "+password")
r = self.client.get(url)
q = PyQuery(r.content)
self.assertEqual(len(q("a:contains('Pending')")), 1)
self.assertEqual(len(q("a:contains('Announce')")), 1)
self.client.logout()
def test_interim_announce(self):
make_interim_test_data()
url = urlreverse("ietf.meeting.views.interim_announce")
meeting = Meeting.objects.filter(type='interim', session__group__acronym='mars').first()
session = meeting.session_set.first()
SchedulingEvent.objects.create(
session=session,
status=SessionStatusName.objects.get(slug='scheda'),
by=Person.objects.get(name='(System)')
)
login_testing_unauthorized(self, "secretary", url)
r = self.client.get(url)
self.assertContains(r, meeting.number)
def test_interim_skip_announcement(self): def test_interim_skip_announcement(self):
make_meeting_test_data() make_meeting_test_data()
@ -2226,7 +2184,6 @@ class InterimTests(TestCase):
mars=add_event_info_to_session_qs(Session.objects.filter(meeting__type='interim', meeting__date__gt=today, group__acronym='mars')).filter(current_status='sched').first().meeting, mars=add_event_info_to_session_qs(Session.objects.filter(meeting__type='interim', meeting__date__gt=today, group__acronym='mars')).filter(current_status='sched').first().meeting,
ames=add_event_info_to_session_qs(Session.objects.filter(meeting__type='interim', meeting__date__gt=today, group__acronym='ames')).filter(current_status='canceled').first().meeting, ames=add_event_info_to_session_qs(Session.objects.filter(meeting__type='interim', meeting__date__gt=today, group__acronym='ames')).filter(current_status='canceled').first().meeting,
) )
self.check_interim_tabs(url)
return self.client.get(url), interims return self.client.get(url), interims
def test_upcoming(self): def test_upcoming(self):
@ -2238,22 +2195,7 @@ class InterimTests(TestCase):
q = PyQuery(r.content) q = PyQuery(r.content)
self.assertIn('CANCELLED', q('tr>td.text-right>span').text()) self.assertIn('CANCELLED', q('tr>td.text-right>span').text())
def test_upcoming_filters_ignored(self): # test_upcoming_filters_ignored removed - we _don't_ want to ignore filters now, and the test passed because it wasn't testing the filtering anyhow (which requires testing the js).
"""The upcoming view should ignore filter querystrings"""
r, interims = self.do_upcoming_test()
self.assertContains(r, interims['mars'].number)
self.assertContains(r, interims['ames'].number)
self.assertContains(r, 'IETF 72')
r, interims = self.do_upcoming_test('show=ames', create_meeting=False)
self.assertContains(r, interims['mars'].number)
self.assertContains(r, interims['ames'].number)
self.assertContains(r, 'IETF 72')
r, interims = self.do_upcoming_test('show=ames&hide=ames,mars', create_meeting=False)
self.assertContains(r, interims['mars'].number)
self.assertContains(r, interims['ames'].number)
self.assertContains(r, 'IETF 72')
def do_upcoming_ical_test(self, querystring=None, create_meeting=True): def do_upcoming_ical_test(self, querystring=None, create_meeting=True):
if create_meeting: if create_meeting:
@ -2806,23 +2748,7 @@ class InterimTests(TestCase):
self.assertEqual(session.agenda_note,agenda_note) self.assertEqual(session.agenda_note,agenda_note)
def test_interim_pending(self): # test_interim_pending subsumed by test_appears_on_pending
make_interim_test_data()
url = urlreverse('ietf.meeting.views.interim_pending')
count = len(set(s.meeting_id for s in add_event_info_to_session_qs(Session.objects.filter(meeting__type='interim')).filter(current_status='apprw')))
# unpriviledged user
login_testing_unauthorized(self,"plain",url)
r = self.client.get(url)
self.assertEqual(r.status_code, 403)
# secretariat
login_testing_unauthorized(self,"secretary",url)
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
self.assertEqual(len(q("#pending-interim-meetings-table tr"))-1, count)
self.client.logout()
def test_can_approve_interim_request(self): def test_can_approve_interim_request(self):
@ -3885,6 +3811,7 @@ class HasMeetingsTests(TestCase):
def test_appears_on_upcoming(self): def test_appears_on_upcoming(self):
url = urlreverse('ietf.meeting.views.upcoming') url = urlreverse('ietf.meeting.views.upcoming')
sessions=[]
for gf in GroupFeatures.objects.filter(has_meetings=True): for gf in GroupFeatures.objects.filter(has_meetings=True):
session = SessionFactory( session = SessionFactory(
group__type_id = gf.type_id, group__type_id = gf.type_id,
@ -3892,14 +3819,17 @@ class HasMeetingsTests(TestCase):
meeting__date = datetime.datetime.today()+datetime.timedelta(days=30), meeting__date = datetime.datetime.today()+datetime.timedelta(days=30),
status_id='sched', status_id='sched',
) )
r = self.client.get(url) sessions.append(session)
self.assertEqual(r.status_code, 200) r = self.client.get(url)
q = PyQuery(r.content) self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
for session in sessions:
self.assertIn(session.meeting.number, q('.interim-meeting-link').text()) self.assertIn(session.meeting.number, q('.interim-meeting-link').text())
def test_appears_on_pending(self): def test_appears_on_pending(self):
url = urlreverse('ietf.meeting.views.interim_pending') url = urlreverse('ietf.meeting.views.interim_pending')
sessions=[]
for gf in GroupFeatures.objects.filter(has_meetings=True): for gf in GroupFeatures.objects.filter(has_meetings=True):
group = GroupFactory(type_id=gf.type_id) group = GroupFactory(type_id=gf.type_id)
meeting_date = datetime.datetime.today() + datetime.timedelta(days=30) meeting_date = datetime.datetime.today() + datetime.timedelta(days=30)
@ -3910,27 +3840,16 @@ class HasMeetingsTests(TestCase):
meeting__number = 'interim-%d-%s-00'%(meeting_date.year,group.acronym), meeting__number = 'interim-%d-%s-00'%(meeting_date.year,group.acronym),
status_id='apprw', status_id='apprw',
) )
for role_name in gf.groupman_roles: sessions.append(session)
role = RoleFactory(group=group, name_id=role_name) r = self.client.get(url)
self.client.login(username=role.person.user.username, password=role.person.user.username+'+password') self.assertEqual(r.status_code, 200)
r = self.client.get(url) q = PyQuery(r.content)
self.assertEqual(r.status_code, 200) for session in sessions:
q = PyQuery(r.content) self.assertIn(session.meeting.number, q('.interim-meeting-link').text())
self.assertIn(session.meeting.number, q('.interim-meeting-link').text())
self.client.logout()
for authrole in gf.groupman_authroles:
role = self.create_role_for_authrole(authrole)
self.client.login(username=role.person.user.username, password=role.person.user.username+'+password')
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
self.assertIn(session.meeting.number, q('.interim-meeting-link').text())
self.client.logout()
def test_appears_on_announce(self): def test_appears_on_announce(self):
url = urlreverse('ietf.meeting.views.interim_announce') url = urlreverse('ietf.meeting.views.interim_announce')
login_testing_unauthorized(self,"secretary",url)
sessions=[] sessions=[]
for gf in GroupFeatures.objects.filter(has_meetings=True): for gf in GroupFeatures.objects.filter(has_meetings=True):
group = GroupFactory(type_id=gf.type_id) group = GroupFactory(type_id=gf.type_id)

View file

@ -107,11 +107,9 @@ from .forms import (InterimMeetingModelForm, InterimAnnounceForm, InterimSession
def get_interim_menu_entries(request): def get_interim_menu_entries(request):
'''Setup menu entries for interim meeting view tabs''' '''Setup menu entries for interim meeting view tabs'''
entries = [] entries = []
if can_manage_some_groups(request.user): entries.append(("Upcoming", reverse("ietf.meeting.views.upcoming")))
entries.append(("Upcoming", reverse("ietf.meeting.views.upcoming"))) entries.append(("Pending", reverse("ietf.meeting.views.interim_pending")))
entries.append(("Pending", reverse("ietf.meeting.views.interim_pending"))) entries.append(("Announce", reverse("ietf.meeting.views.interim_announce")))
if has_role(request.user, "Secretariat"):
entries.append(("Announce", reverse("ietf.meeting.views.interim_announce")))
return entries return entries
def send_interim_change_notice(request, meeting): def send_interim_change_notice(request, meeting):
@ -2905,7 +2903,6 @@ def ajax_get_utc(request):
content_type='application/json') content_type='application/json')
@role_required('Secretariat',)
def interim_announce(request): def interim_announce(request):
'''View which shows interim meeting requests awaiting announcement''' '''View which shows interim meeting requests awaiting announcement'''
meetings = data_for_meetings_overview(Meeting.objects.filter(type='interim').order_by('date'), interim_status='scheda') meetings = data_for_meetings_overview(Meeting.objects.filter(type='interim').order_by('date'), interim_status='scheda')
@ -2968,19 +2965,14 @@ def interim_skip_announcement(request, number):
'meeting': meeting}) 'meeting': meeting})
@login_required
def interim_pending(request): def interim_pending(request):
if not can_manage_some_groups(request.user):
permission_denied(request, "You are not authorized to access this view")
'''View which shows interim meeting requests pending approval''' '''View which shows interim meeting requests pending approval'''
meetings = data_for_meetings_overview(Meeting.objects.filter(type='interim').order_by('date'), interim_status='apprw') meetings = data_for_meetings_overview(Meeting.objects.filter(type='interim').order_by('date'), interim_status='apprw')
menu_entries = get_interim_menu_entries(request) menu_entries = get_interim_menu_entries(request)
selected_menu_entry = 'pending' selected_menu_entry = 'pending'
meetings = [m for m in meetings if can_view_interim_request(m, request.user)]
for meeting in meetings: for meeting in meetings:
if can_approve_interim_request(meeting, request.user): if can_approve_interim_request(meeting, request.user):
meeting.can_approve = True meeting.can_approve = True