website/events/tests/test_views.py
import datetime
from django.conf import settings
from django.contrib.auth.models import Permission
from django.core import mail
from django.test import Client, TestCase, override_settings
from django.urls import reverse
from django.utils import timezone
from activemembers.models import Committee, MemberGroupMembership
from events.models import (
BooleanRegistrationInformation,
Event,
EventRegistration,
IntegerRegistrationInformation,
RegistrationInformationField,
TextRegistrationInformation,
)
from mailinglists.models import MailingList
from members.models import Member
@override_settings(SUSPEND_SIGNALS=True)
class AdminTest(TestCase):
"""Tests for admin views."""
fixtures = ["members.json", "member_groups.json"]
@classmethod
def setUpTestData(cls):
cls.committee = Committee.objects.get(pk=1)
cls.event = Event.objects.create(
pk=1,
title="testevent",
description="desc",
published=True,
start=(timezone.now() + datetime.timedelta(hours=1)),
end=(timezone.now() + datetime.timedelta(hours=2)),
location="test location",
map_location="test map location",
price=0.00,
fine=0.00,
)
cls.event.organisers.add(cls.committee)
cls.member = Member.objects.filter(last_name="Wiggers").first()
cls.permission_change_event = Permission.objects.get(
content_type__model="event", codename="change_event"
)
cls.permission_delete_event = Permission.objects.get(
content_type__model="event", codename="delete_event"
)
cls.permission_override_orga = Permission.objects.get(
content_type__model="event", codename="override_organiser"
)
cls.member.user_permissions.add(cls.permission_change_event)
cls.member.user_permissions.add(cls.permission_delete_event)
cls.member.is_superuser = False
cls.member.save()
def setUp(self):
self.client.force_login(self.member)
def _remove_event_permission(self):
self.member.user_permissions.remove(self.permission_change_event)
self.member.user_permissions.remove(self.permission_delete_event)
def _add_override_organiser_permission(self):
self.member.user_permissions.add(self.permission_override_orga)
def test_admin_details_need_change_event_access(self):
"""I need the event.change_event permission to do stuff."""
self._remove_event_permission()
response = self.client.get("/admin/events/event/1/details/")
self.assertEqual(403, response.status_code)
def test_admin_details_organiser_denied(self):
response = self.client.get("/admin/events/event/1/details/")
self.assertEqual(403, response.status_code)
def test_admin_details_organiser_allowed(self):
MemberGroupMembership.objects.create(member=self.member, group=self.committee)
response = self.client.get("/admin/events/event/1/details/")
self.assertEqual(200, response.status_code)
def test_admin_details_override_organiser_allowed(self):
self._add_override_organiser_permission()
response = self.client.get("/admin/events/event/1/details/")
self.assertEqual(200, response.status_code)
def test_modeladmin_change_organiser_allowed(self):
"""Change event as an organiser.
If I'm an organiser I should be allowed access.
"""
MemberGroupMembership.objects.create(member=self.member, group=self.committee)
response = self.client.get("/admin/events/event/1/change/")
self.assertEqual(200, response.status_code)
def test_modeladmin_change_override_organiser_allowed(self):
"""Test the override organiser permission for changing events.
If I'm allowed to override organiser restrictions.
"""
self._add_override_organiser_permission()
response = self.client.get("/admin/events/event/1/change/")
self.assertEqual(200, response.status_code)
def test_modeladmin_change_organiser_no_permissions_denied(self):
"""Committee members without change permissions are banned.
If I'm an organiser, but don't have perms I should not
be allowed access.
"""
self._remove_event_permission()
MemberGroupMembership.objects.create(member=self.member, group=self.committee)
response = self.client.get("/admin/events/event/1/change/")
self.assertEqual(403, response.status_code)
def test_modeladmin_change_superuser_allowed(self):
"""Superuser should be allowed access always."""
self.member.is_superuser = True
self.member.save()
response = self.client.get("/admin/events/event/1/change/")
self.assertEqual(200, response.status_code)
self.assertIn("Change event", str(response.content))
def test_modeladmin_change_organiser_denied(self):
"""If I'm not an organiser I should not be allowed edit access."""
response = self.client.get("/admin/events/event/1/change/")
self.assertEqual(200, response.status_code)
self.assertIn("View event", str(response.content))
def test_modeladmin_delete_organiser_denied(self):
"""If I'm not an organiser I should not be allowed delete access."""
response = self.client.get("/admin/events/event/1/delete/")
self.assertEqual(403, response.status_code)
def test_mark_present_qr_organiser_denied(self):
response = self.client.get("/admin/events/event/1/mark-present-qr/")
self.assertEqual(403, response.status_code)
def test_mark_present_qr_organiser_allowed(self):
MemberGroupMembership.objects.create(member=self.member, group=self.committee)
response = self.client.get("/admin/events/event/1/mark-present-qr/")
self.assertEqual(200, response.status_code)
def test_mark_present_qr_override_organiser_allowed(self):
self._add_override_organiser_permission()
response = self.client.get("/admin/events/event/1/mark-present-qr/")
self.assertEqual(200, response.status_code)
@override_settings(SUSPEND_SIGNALS=True)
class RegistrationTest(TestCase):
"""Tests for registration view."""
fixtures = ["members.json", "member_groups.json"]
@classmethod
def setUpTestData(cls):
cls.mailinglist = MailingList.objects.create(name="testmail")
cls.committee = Committee.objects.create(
name="committee",
contact_mailinglist=cls.mailinglist,
)
cls.event = Event.objects.create(
pk=1,
title="testevent",
description="desc",
published=True,
start=(timezone.now() + datetime.timedelta(hours=1)),
end=(timezone.now() + datetime.timedelta(hours=2)),
location="test location",
map_location="test map location",
price=0.00,
fine=0.00,
)
cls.event.organisers.add(cls.committee)
cls.member = Member.objects.filter(last_name="Wiggers").first()
cls.mark_present_url = reverse(
"events:mark-present",
kwargs={
"pk": cls.event.pk,
"token": cls.event.mark_present_url_token,
},
)
def setUp(self):
self.client = Client()
self.client.force_login(self.member)
def test_registration_register_not_required(self):
response = self.client.post("/events/1/registration/register/", follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(self.event.participant_count, 1)
def test_registration_register(self):
self.event.registration_start = timezone.now() - datetime.timedelta(hours=1)
self.event.registration_end = timezone.now() + datetime.timedelta(hours=1)
self.event.cancel_deadline = timezone.now() + datetime.timedelta(hours=1)
self.event.save()
response = self.client.post("/events/1/registration/register/", follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(self.event.participant_count, 1)
self.assertEqual(self.event.eventregistration_set.first().member, self.member)
def test_registration_register_twice(self):
self.event.registration_start = timezone.now() - datetime.timedelta(hours=1)
self.event.registration_end = timezone.now() + datetime.timedelta(hours=1)
self.event.cancel_deadline = timezone.now() + datetime.timedelta(hours=1)
self.event.save()
response = self.client.post("/events/1/registration/register/", follow=True)
self.assertEqual(response.status_code, 200)
response = self.client.post("/events/1/registration/register/", follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(self.event.participant_count, 1)
def test_registration_register_closed(self):
self.event.registration_start = timezone.now() - datetime.timedelta(hours=2)
self.event.registration_end = timezone.now() - datetime.timedelta(hours=1)
self.event.cancel_deadline = timezone.now() + datetime.timedelta(hours=1)
self.event.save()
response = self.client.post("/events/1/registration/register/", follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(self.event.participant_count, 0)
def test_registration_cancel(self):
self.event.registration_start = timezone.now() - datetime.timedelta(hours=1)
self.event.registration_end = timezone.now() + datetime.timedelta(hours=1)
self.event.cancel_deadline = timezone.now() + datetime.timedelta(hours=1)
self.event.save()
EventRegistration.objects.create(event=self.event, member=self.member)
response = self.client.post("/events/1/registration/cancel/", follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(self.event.participant_count, 0)
def test_registration_register_no_fields(self):
self.event.registration_start = timezone.now() - datetime.timedelta(hours=1)
self.event.registration_end = timezone.now() + datetime.timedelta(hours=1)
self.event.cancel_deadline = timezone.now() + datetime.timedelta(hours=1)
self.event.save()
field1 = RegistrationInformationField.objects.create(
pk=1,
event=self.event,
type=RegistrationInformationField.BOOLEAN_FIELD,
name="test bool",
required=False,
)
field2 = RegistrationInformationField.objects.create(
pk=2,
event=self.event,
type=RegistrationInformationField.INTEGER_FIELD,
name="test int",
required=False,
)
field3 = RegistrationInformationField.objects.create(
pk=3,
event=self.event,
type=RegistrationInformationField.TEXT_FIELD,
name="test text",
required=False,
)
response = self.client.post(
"/events/1/registration/register/",
{"info_field_1": True, "info_field_2": 42, "info_field_3": "text"},
follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertEqual(self.event.participant_count, 1)
registration = self.event.eventregistration_set.first()
self.assertEqual(field1.get_value_for(registration), None)
self.assertEqual(field2.get_value_for(registration), None)
self.assertEqual(field3.get_value_for(registration), None)
def test_registration_missing_fields(self):
self.event.registration_start = timezone.now() - datetime.timedelta(hours=1)
self.event.registration_end = timezone.now() + datetime.timedelta(hours=1)
self.event.cancel_deadline = timezone.now() + datetime.timedelta(hours=1)
self.event.save()
RegistrationInformationField.objects.create(
pk=1,
event=self.event,
type=RegistrationInformationField.BOOLEAN_FIELD,
name="test bool",
required=False,
)
RegistrationInformationField.objects.create(
pk=2,
event=self.event,
type=RegistrationInformationField.INTEGER_FIELD,
name="test int",
required=False,
)
RegistrationInformationField.objects.create(
pk=3,
event=self.event,
type=RegistrationInformationField.TEXT_FIELD,
name="test text",
required=False,
)
response = self.client.post("/events/1/registration/register/", follow=True)
self.assertEqual(response.status_code, 200)
template_names = [template.name for template in response.templates]
self.assertIn("events/registration.html", template_names)
self.assertEqual(self.event.participant_count, 1)
def test_registration_register_fields_required(self):
self.event.registration_start = timezone.now() - datetime.timedelta(hours=1)
self.event.registration_end = timezone.now() + datetime.timedelta(hours=1)
self.event.cancel_deadline = timezone.now() + datetime.timedelta(hours=1)
self.event.save()
RegistrationInformationField.objects.create(
event=self.event,
type=RegistrationInformationField.TEXT_FIELD,
name="test",
required=True,
)
response = self.client.post("/events/1/registration/register/", follow=True)
self.assertEqual(response.status_code, 200)
template_names = [template.name for template in response.templates]
self.assertIn("events/registration.html", template_names)
self.assertEqual(self.event.participant_count, 1)
def test_registration_update_form_load_not_changes_fields(self):
self.event.registration_start = timezone.now() - datetime.timedelta(hours=1)
self.event.registration_end = timezone.now() + datetime.timedelta(hours=1)
self.event.cancel_deadline = timezone.now() + datetime.timedelta(hours=1)
self.event.save()
field1 = RegistrationInformationField.objects.create(
pk=1,
event=self.event,
type=RegistrationInformationField.BOOLEAN_FIELD,
name="test bool",
required=False,
)
field2 = RegistrationInformationField.objects.create(
pk=2,
event=self.event,
type=RegistrationInformationField.INTEGER_FIELD,
name="test int",
required=False,
)
field3 = RegistrationInformationField.objects.create(
pk=3,
event=self.event,
type=RegistrationInformationField.TEXT_FIELD,
name="test text",
required=False,
)
registration = EventRegistration.objects.create(
event=self.event, member=self.member
)
BooleanRegistrationInformation.objects.create(
registration=registration, field=field1, value=True
)
IntegerRegistrationInformation.objects.create(
registration=registration, field=field2, value=42
)
TextRegistrationInformation.objects.create(
registration=registration, field=field3, value="text"
)
# as if there is a csrf token
response = self.client.get("/events/1/registration/", follow=True)
self.assertEqual(response.status_code, 200)
registration = self.event.eventregistration_set.first()
self.assertEqual(field1.get_value_for(registration), True)
self.assertEqual(field2.get_value_for(registration), 42)
self.assertEqual(field3.get_value_for(registration), "text")
def test_registration_update_form_post_changes_fields(self):
self.event.registration_start = timezone.now() - datetime.timedelta(hours=1)
self.event.registration_end = timezone.now() + datetime.timedelta(hours=1)
self.event.cancel_deadline = timezone.now() + datetime.timedelta(hours=1)
self.event.save()
field1 = RegistrationInformationField.objects.create(
pk=1,
event=self.event,
type=RegistrationInformationField.BOOLEAN_FIELD,
name="test bool",
required=False,
)
field2 = RegistrationInformationField.objects.create(
pk=2,
event=self.event,
type=RegistrationInformationField.INTEGER_FIELD,
name="test int",
required=False,
)
field3 = RegistrationInformationField.objects.create(
pk=3,
event=self.event,
type=RegistrationInformationField.TEXT_FIELD,
name="test text",
required=False,
)
response = self.client.post(
"/events/1/registration/register/",
{
"info_field_1": True,
"info_field_2": 42,
"info_field_3": "text",
"csrf": "random",
},
follow=True,
)
self.assertEqual(response.status_code, 200)
response = self.client.post(
"/events/1/registration/",
{
"info_field_1": False,
"info_field_2": 1337,
"info_field_3": "no text",
"csrf": "random",
},
follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertEqual(self.event.participant_count, 1)
registration = self.event.eventregistration_set.first()
self.assertEqual(field1.get_value_for(registration), False)
self.assertEqual(field2.get_value_for(registration), 1337)
self.assertEqual(field3.get_value_for(registration), "no text")
def test_registration_cancel_after_deadline_notification(self):
self.event.registration_start = timezone.now() - datetime.timedelta(hours=2)
self.event.registration_end = timezone.now() - datetime.timedelta(hours=1)
self.event.cancel_deadline = timezone.now() - datetime.timedelta(hours=1)
self.event.send_cancel_email = True
self.event.save()
EventRegistration.objects.create(event=self.event, member=self.member)
response = self.client.post("/events/1/registration/cancel/", follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(self.event.participant_count, 0)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(
mail.outbox[0].to,
[
self.event.organisers.first().contact_mailinglist.name
+ "@"
+ settings.SITE_DOMAIN
],
)
def test_registration_cancel_after_deadline_warning(self):
self.event.registration_start = timezone.now() - datetime.timedelta(hours=2)
self.event.registration_end = timezone.now() - datetime.timedelta(hours=1)
self.event.cancel_deadline = timezone.now() - datetime.timedelta(hours=1)
self.event.save()
EventRegistration.objects.create(event=self.event, member=self.member)
response = self.client.get("/events/1/")
self.assertContains(
response,
"Cancellation is not allowed anymore without having to pay the full costs of",
)
def test_registration_cancel_after_deadline_waitinglist_no_warning(self):
self.event.registration_start = timezone.now() - datetime.timedelta(hours=2)
self.event.registration_end = timezone.now() - datetime.timedelta(hours=1)
self.event.cancel_deadline = timezone.now() - datetime.timedelta(hours=1)
self.event.max_participants = 1
self.event.save()
EventRegistration.objects.create(
event=self.event,
member=Member.objects.get(pk=2),
date=timezone.now() - datetime.timedelta(hours=1),
)
queue_register = EventRegistration.objects.create(
event=self.event, member=self.member
)
response = self.client.get("/events/1/")
self.assertTrue(queue_register in self.event.queue)
self.assertNotContains(
response,
"Cancellation isn't possible anymore without having to pay the full costs of",
)
def test_mark_present_url_registered(self):
registration = EventRegistration.objects.create(
event=self.event,
member=self.member,
date=timezone.now() - datetime.timedelta(hours=1),
)
response = self.client.get(self.mark_present_url, follow=True)
self.assertContains(response, "You have been marked as present.")
registration.refresh_from_db()
self.assertTrue(registration.present)
def test_mark_present_url_already_present(self):
registration = EventRegistration.objects.create(
event=self.event,
member=self.member,
date=timezone.now() - datetime.timedelta(hours=1),
present=True,
)
response = self.client.get(self.mark_present_url, follow=True)
self.assertContains(response, "You were already marked as present.")
registration.refresh_from_db()
self.assertTrue(registration.present)
def test_mark_present_url_not_registered(self):
response = self.client.get(self.mark_present_url, follow=True)
self.assertContains(response, "You are not registered for this event.")
def test_mark_present_url_wrong_token(self):
registration = EventRegistration.objects.create(
event=self.event,
member=self.member,
date=timezone.now() - datetime.timedelta(hours=3),
)
response = self.client.get(
reverse(
"events:mark-present",
kwargs={
"pk": self.event.pk,
"token": "11111111-2222-3333-4444-555555555555",
},
),
follow=True,
)
self.assertContains(response, "Invalid url.")
self.assertFalse(registration.present)
def test_mark_present_url_past_event(self):
registration = EventRegistration.objects.create(
event=self.event,
member=self.member,
date=timezone.now() - datetime.timedelta(hours=3),
)
self.event.start = timezone.now() - datetime.timedelta(hours=2)
self.event.end = timezone.now() - datetime.timedelta(hours=1)
self.event.save()
response = self.client.get(self.mark_present_url, follow=True)
self.assertContains(response, "This event has already ended.")
self.assertFalse(registration.present)
@override_settings(SUSPEND_SIGNALS=True)
class EventPageTest(TestCase):
"""Tests for event list page."""
fixtures = ["members.json", "member_groups.json"]
@classmethod
def setUpTestData(cls):
cls.mailinglist = MailingList.objects.create(name="testmail")
cls.committee = Committee.objects.create(
name="committee",
contact_mailinglist=cls.mailinglist,
)
cls.event = Event.objects.create(
pk=1,
title="testevent",
description="desc",
published=True,
start=(timezone.now() + datetime.timedelta(hours=1)),
end=(timezone.now() + datetime.timedelta(hours=2)),
location="test location",
map_location="test map location",
price=0.00,
fine=0.00,
)
cls.event.organisers.add(cls.committee)
cls.member = Member.objects.filter(last_name="Wiggers").first()
cls.mark_present_url = reverse(
"events:mark-present",
kwargs={
"pk": cls.event.pk,
"token": cls.event.mark_present_url_token,
},
)
def setUp(self):
self.client = Client()
self.client.force_login(self.member)
def test_list_page(self):
# note: this does not test the calendar itself!
# but we test the API so it should work
response = self.client.get("/events/")
self.assertEqual(response.status_code, 200)
def test_event_page(self):
response = self.client.get("/events/1/")
self.assertEqual(response.status_code, 200)
self.assertContains(response, "testevent")