Merged in [13615] and [13627]from rcross@amsl.com:
Changed views that use GET requests to delete objects to use POST. Fixes #1796. - Legacy-Id: 13654 Note: SVN reference [13615] has been migrated to Git commit3ccb550888
Note: SVN reference [13627] has been migrated to Git commitb908caf95c
This commit is contained in:
commit
7ecf7dfa44
|
@ -1,5 +1,6 @@
|
|||
# -*- conf-mode -*-
|
||||
|
||||
/personal/rcross/6.54.2.dev0@13632 # resolved differently in [13653]
|
||||
/personal/lars/6.48.2.dev0@13124 # fails drag-and-drop test
|
||||
/branch/proceedings/6.29.1.dev0@11850 # Merged into /branch/proceedings/6.30.1.dev0, will be merged from there
|
||||
/branch/proceedings/6.29.1.dev0@11856 # Merged into /branch/proceedings/6.30.1.dev0, will be merged from there
|
||||
|
|
|
@ -154,3 +154,16 @@ class SecrDraftsTestCase(TestCase):
|
|||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_author_delete(self):
|
||||
draft = make_test_data()
|
||||
author = draft.documentauthor_set.first()
|
||||
id = author.id
|
||||
url = urlreverse('ietf.secr.drafts.views.author_delete', kwargs={'id':draft.name, 'oid':id})
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
redirect_url = urlreverse('ietf.secr.drafts.views.authors', kwargs={'id':draft.name})
|
||||
response = self.client.post(url, {'post':'yes'})
|
||||
self.assertRedirects(response, redirect_url)
|
||||
self.assertFalse(draft.documentauthor_set.filter(id=id))
|
||||
|
||||
|
|
|
@ -542,9 +542,14 @@ def author_delete(request, id, oid):
|
|||
'''
|
||||
This view deletes the specified author from the draft
|
||||
'''
|
||||
DocumentAuthor.objects.get(id=oid).delete()
|
||||
messages.success(request, 'The author was deleted successfully')
|
||||
return redirect('ietf.secr.drafts.views.authors', id=id)
|
||||
author = DocumentAuthor.objects.get(id=oid)
|
||||
|
||||
if request.method == 'POST' and request.POST['post'] == 'yes':
|
||||
author.delete()
|
||||
messages.success(request, 'The author was deleted successfully')
|
||||
return redirect('ietf.secr.drafts.views.authors', id=id)
|
||||
|
||||
return render(request, 'confirm_delete.html', {'object': author})
|
||||
|
||||
@role_required('Secretariat')
|
||||
def authors(request, id):
|
||||
|
|
|
@ -140,12 +140,15 @@ class GroupsTest(TestCase):
|
|||
make_test_data()
|
||||
group = Group.objects.filter(acronym='mars')[0]
|
||||
role = group.role_set.all()[0]
|
||||
id = role.id
|
||||
url = reverse('ietf.secr.groups.views.delete_role', kwargs={'acronym':group.acronym,'id':role.id})
|
||||
target = reverse('ietf.secr.groups.views.people', kwargs={'acronym':group.acronym})
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url,follow=True)
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.post(url, {'post':'yes'})
|
||||
self.assertRedirects(response, target)
|
||||
self.assertTrue('deleted successfully' in response.content)
|
||||
self.assertFalse(group.role_set.filter(id=id))
|
||||
|
||||
def test_people_add(self):
|
||||
make_test_data()
|
||||
|
|
|
@ -190,14 +190,17 @@ def delete_role(request, acronym, id):
|
|||
"""
|
||||
group = get_object_or_404(Group, acronym=acronym)
|
||||
role = get_object_or_404(Role, id=id)
|
||||
|
||||
if request.method == 'POST' and request.POST['post'] == 'yes':
|
||||
# save group
|
||||
save_group_in_history(group)
|
||||
|
||||
# save group
|
||||
save_group_in_history(group)
|
||||
role.delete()
|
||||
messages.success(request, 'The entry was deleted successfully')
|
||||
return redirect('ietf.secr.groups.views.people', acronym=acronym)
|
||||
|
||||
role.delete()
|
||||
return render(request, 'confirm_delete.html', {'object': role})
|
||||
|
||||
messages.success(request, 'The entry was deleted successfully')
|
||||
return redirect('ietf.secr.groups.views.people', acronym=acronym)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def edit(request, acronym):
|
||||
|
|
|
@ -236,13 +236,19 @@ class SecrMeetingTestCase(TestCase):
|
|||
before = qs.count()
|
||||
expected_deletion_count = qs.filter(time=qs.first().time).count()
|
||||
url = reverse('ietf.secr.meetings.views.times_delete',kwargs={
|
||||
'meeting_id':42,
|
||||
'schedule_name':'test-agenda',
|
||||
'meeting_id':meeting.number,
|
||||
'schedule_name':meeting.agenda.name,
|
||||
'time':qs.first().time.strftime("%Y:%m:%d:%H:%M")
|
||||
})
|
||||
redirect_url = reverse('ietf.secr.meetings.views.times',kwargs={
|
||||
'meeting_id':meeting.number,
|
||||
'schedule_name':meeting.agenda.name
|
||||
})
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.post(url, {'post':'yes'})
|
||||
self.assertRedirects(response, redirect_url)
|
||||
after = TimeSlot.objects.filter(meeting=meeting,type='session').count()
|
||||
self.assertEqual(after,before - expected_deletion_count)
|
||||
|
||||
|
@ -312,6 +318,18 @@ class SecrMeetingTestCase(TestCase):
|
|||
timeslot = session.official_timeslotassignment().timeslot
|
||||
self.assertEqual(timeslot.time,new_time)
|
||||
|
||||
def test_meetings_non_session_delete(self):
|
||||
meeting = make_meeting_test_data()
|
||||
slot = meeting.agenda.assignments.filter(timeslot__type='reg').first().timeslot
|
||||
url = reverse('ietf.secr.meetings.views.non_session_delete', kwargs={'meeting_id':meeting.number,'schedule_name':meeting.agenda.name,'slot_id':slot.id})
|
||||
target = reverse('ietf.secr.meetings.views.non_session', kwargs={'meeting_id':meeting.number,'schedule_name':meeting.agenda.name})
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.post(url, {'post':'yes'})
|
||||
self.assertRedirects(response, target)
|
||||
self.assertFalse(meeting.agenda.assignments.filter(timeslot=slot))
|
||||
|
||||
def test_meetings_select_group(self):
|
||||
make_meeting_test_data()
|
||||
url = reverse('ietf.secr.meetings.views.select_group',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
|
||||
|
@ -321,6 +339,17 @@ class SecrMeetingTestCase(TestCase):
|
|||
q = PyQuery(response.content)
|
||||
self.assertEqual(len(q("#id_scheduled_sessions")),1)
|
||||
|
||||
def test_meetings_schedule(self):
|
||||
meeting = make_meeting_test_data()
|
||||
url = reverse('ietf.secr.meetings.views.schedule',kwargs={
|
||||
'meeting_id':meeting.number,
|
||||
'schedule_name':meeting.agenda.name,
|
||||
'acronym':'mars'
|
||||
})
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# ----------------------
|
||||
# Unit Tests
|
||||
# -----------------------
|
||||
|
|
|
@ -18,6 +18,7 @@ from ietf.utils.mail import send_mail
|
|||
from ietf.meeting.forms import duration_string
|
||||
from ietf.meeting.helpers import get_meeting, make_materials_directories
|
||||
from ietf.meeting.models import Meeting, Session, Room, TimeSlot, SchedTimeSessAssignment, Schedule
|
||||
from ietf.name.models import SessionStatusName
|
||||
from ietf.group.models import Group, GroupEvent
|
||||
from ietf.person.models import Person
|
||||
from ietf.secr.meetings.blue_sheets import create_blue_sheets
|
||||
|
@ -517,26 +518,30 @@ def non_session(request, meeting_id, schedule_name):
|
|||
@role_required('Secretariat')
|
||||
def non_session_delete(request, meeting_id, schedule_name, slot_id):
|
||||
'''
|
||||
This function deletes the non-session TimeSlot. For "other" and "plenary" timeslot
|
||||
types we need to delete the corresponding Session object as well. Check for uploaded
|
||||
This function deletes the non-session TimeSlot. Check for uploaded
|
||||
material first. SchedTimeSessAssignment objects get deleted as well.
|
||||
'''
|
||||
meeting = get_object_or_404(Meeting, number=meeting_id)
|
||||
# schedule = get_object_or_404(Schedule, meeting=meeting, name=schedule_name)
|
||||
slot = get_object_or_404(TimeSlot, id=slot_id)
|
||||
if slot.type_id in ('other','plenary','lead'):
|
||||
assignments = slot.sessionassignments.filter(schedule__meeting=meeting)
|
||||
assert slot.type_id in ('other','plenary','lead', 'reg')
|
||||
|
||||
if request.method == 'POST' and request.POST['post'] == 'yes':
|
||||
assignments = slot.sessionassignments.all()
|
||||
session_objects = [ x.session for x in assignments ]
|
||||
|
||||
for session in session_objects:
|
||||
if session.materials.exclude(states__slug='deleted'):
|
||||
messages.error(request, 'Materials have already been uploaded for "%s". You must delete those before deleting the timeslot.' % slot.name)
|
||||
return redirect('ietf.secr.meetings.views.non_session', meeting_id=meeting_id, schedule_name=schedule_name)
|
||||
else:
|
||||
Session.objects.filter(pk__in=[ x.pk for x in session_objects ]).delete()
|
||||
slot.delete()
|
||||
|
||||
# delete high order assignments, then sessions and slots
|
||||
assignments.delete()
|
||||
Session.objects.filter(pk__in=[ x.pk for x in session_objects ]).delete()
|
||||
slot.delete()
|
||||
|
||||
messages.success(request, 'Non-Session timeslot deleted successfully')
|
||||
return redirect('ietf.secr.meetings.views.non_session', meeting_id=meeting_id, schedule_name=schedule_name)
|
||||
messages.success(request, 'The entry was deleted successfully')
|
||||
return redirect('ietf.secr.meetings.views.non_session', meeting_id=meeting_id, schedule_name=schedule_name)
|
||||
|
||||
return render(request, 'confirm_delete.html', {'object': slot})
|
||||
|
||||
@role_required('Secretariat')
|
||||
def non_session_edit(request, meeting_id, schedule_name, slot_id):
|
||||
|
@ -1004,11 +1009,24 @@ def times_delete(request, meeting_id, schedule_name, time):
|
|||
|
||||
parts = [ int(x) for x in time.split(':') ]
|
||||
dtime = datetime.datetime(*parts)
|
||||
status = SessionStatusName.objects.get(slug='schedw')
|
||||
|
||||
TimeSlot.objects.filter(meeting=meeting,time=dtime).delete()
|
||||
if request.method == 'POST' and request.POST['post'] == 'yes':
|
||||
for slot in TimeSlot.objects.filter(meeting=meeting,time=dtime):
|
||||
for assignment in slot.sessionassignments.all():
|
||||
if assignment.session:
|
||||
session = assignment.session
|
||||
session.status = status
|
||||
session.save()
|
||||
assignment.delete()
|
||||
slot.delete()
|
||||
messages.success(request, 'The entry was deleted successfully')
|
||||
return redirect('ietf.secr.meetings.views.times', meeting_id=meeting_id,schedule_name=schedule_name)
|
||||
|
||||
messages.success(request, 'Timeslot deleted')
|
||||
return redirect('ietf.secr.meetings.views.times', meeting_id=meeting_id,schedule_name=schedule_name)
|
||||
return render(request, 'confirm_delete.html', {
|
||||
'object': '%s timeslots' % dtime.strftime("%A %H:%M"),
|
||||
'extra': 'Any sessions assigned to this timeslot will be unscheduled'
|
||||
})
|
||||
|
||||
@role_required('Secretariat')
|
||||
def unschedule(request, meeting_id, schedule_name, session_id):
|
||||
|
|
|
@ -28,13 +28,16 @@ class SecrRolesMainTestCase(TestCase):
|
|||
augment_data()
|
||||
group = Group.objects.filter(acronym='mars')[0]
|
||||
role = group.role_set.all()[0]
|
||||
id = role.id
|
||||
url = reverse('ietf.secr.roles.views.delete_role', kwargs={'acronym':group.acronym,'id':role.id})
|
||||
target = reverse('ietf.secr.roles.views.main') + '?group=%s' % group.acronym
|
||||
target = reverse('ietf.secr.roles.views.main')
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url,follow=True)
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.post(url, {'post':'yes'})
|
||||
self.assertRedirects(response, target)
|
||||
self.assertTrue('deleted successfully' in response.content)
|
||||
|
||||
self.assertFalse(group.role_set.filter(id=id))
|
||||
|
||||
def test_roles_add(self):
|
||||
make_test_data()
|
||||
augment_data()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from django.contrib import messages
|
||||
from django.urls import reverse
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
|
||||
from ietf.group.models import Group, Role
|
||||
from ietf.group.utils import save_group_in_history
|
||||
|
@ -53,14 +53,15 @@ def delete_role(request, acronym, id):
|
|||
role = get_object_or_404(Role, id=id)
|
||||
group = get_object_or_404(Group, acronym=acronym)
|
||||
|
||||
# save group
|
||||
save_group_in_history(role.group)
|
||||
|
||||
role.delete()
|
||||
|
||||
messages.success(request, 'The entry was deleted successfully')
|
||||
url = reverse('ietf.secr.roles.views.main') + '?group=%s' % group.acronym
|
||||
return HttpResponseRedirect(url)
|
||||
if request.method == 'POST' and request.POST['post'] == 'yes':
|
||||
# save group
|
||||
save_group_in_history(group)
|
||||
|
||||
role.delete()
|
||||
messages.success(request, 'The entry was deleted successfully')
|
||||
return redirect('ietf.secr.roles.views.main')
|
||||
|
||||
return render(request, 'confirm_delete.html', {'object': role})
|
||||
|
||||
@role_required('Secretariat')
|
||||
def main(request):
|
||||
|
|
26
ietf/secr/templates/confirm_delete.html
Normal file
26
ietf/secr/templates/confirm_delete.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
{% extends "base_site.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block title %}Confirm Delete{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="module draft-container">
|
||||
<h2>Confirm Delete</h2>
|
||||
<h3>Are you sure?</h3>
|
||||
<p>You are about to delete: {{ object }}</p>
|
||||
{% if extra %}<p>{{ extra }}</p>{% endif %}
|
||||
|
||||
<form action="" method="post">{% csrf_token %}
|
||||
<div>
|
||||
<p>
|
||||
<input type="hidden" name="post" value="yes">
|
||||
<input type="submit" value="Yes, I'm sure">
|
||||
<a href="#" onclick="history.go(-1);return false;" class="button cancel-link">Take me back</a>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div> <!-- module -->
|
||||
|
||||
{% endblock %}
|
|
@ -23,7 +23,7 @@
|
|||
<td>{{ item.time|date:"H:i" }} - {{ item.end_time|date:"H:i" }}</td>
|
||||
<td>{{ item.name }}</td>
|
||||
<td><a href="{% url "ietf.secr.meetings.views.times_edit" meeting_id=meeting.number schedule_name=schedule.name time=item.time|date:"Y:m:d:H:i" %}">Edit</a></td>
|
||||
<td><a href="{% url "ietf.secr.meetings.views.times_delete" meeting_id=meeting.number schedule_name=schedule.name time=item.time|date:"Y:m:d:H:i" %}" onclick="return window.confirm('Are you sure you want to delete this timeslot? Any sessions assigned to this timeslot will be unscheduled.');">Delete</a></td>
|
||||
<td><a href="{% url "ietf.secr.meetings.views.times_delete" meeting_id=meeting.number schedule_name=schedule.name time=item.time|date:"Y:m:d:H:i" %}">Delete</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
Loading…
Reference in a new issue