members/tests: add tests for views

pull/104/head
Christian Merten 11 months ago
parent d4a8c4a515
commit 7d74e5d908
Signed by: christian.merten
GPG Key ID: D953D69721B948B3

@ -1,7 +1,11 @@
from http import HTTPStatus
from django.core.files.uploadedfile import SimpleUploadedFile
from django.contrib.auth import models as authmodels from django.contrib.auth import models as authmodels
from django.contrib.admin.sites import AdminSite from django.contrib.admin.sites import AdminSite
from django.contrib.messages import get_messages from django.contrib.messages import get_messages
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _
from django.test import TestCase, Client, RequestFactory from django.test import TestCase, Client, RequestFactory
from django.utils import timezone, translation from django.utils import timezone, translation
from django.conf import settings from django.conf import settings
@ -9,8 +13,10 @@ from django.urls import reverse
from unittest import skip, mock from unittest import skip, mock
from .models import Member, Group, PermissionMember, PermissionGroup, Freizeit, GEMEINSCHAFTS_TOUR, MUSKELKRAFT_ANREISE,\ from .models import Member, Group, PermissionMember, PermissionGroup, Freizeit, GEMEINSCHAFTS_TOUR, MUSKELKRAFT_ANREISE,\
MemberNoteList, NewMemberOnList, confirm_mail_by_key, EmergencyContact, MemberWaitingList,\ MemberNoteList, NewMemberOnList, confirm_mail_by_key, EmergencyContact, MemberWaitingList,\
DIVERSE, MALE, FEMALE RegistrationPassword, MemberUnconfirmedProxy, InvitationToGroup, DIVERSE, MALE, FEMALE
from .admin import MemberWaitingListAdmin, MemberAdmin, FreizeitAdmin from .admin import MemberWaitingListAdmin, MemberAdmin, FreizeitAdmin
from mailer.models import EmailAddress
from django.db import connection from django.db import connection
from django.db.migrations.executor import MigrationExecutor from django.db.migrations.executor import MigrationExecutor
import random import random
@ -19,6 +25,41 @@ from dateutil.relativedelta import relativedelta
import math import math
REGISTRATION_DATA = {
'prename': 'Peter',
'lastname': 'Wulter',
'street': 'Street 123',
'plz': '12345 EJ',
'town': 'Town 1',
'phone_number': '+49 123456',
'birth_date': '2010-05-17',
'gender': '2',
'email': settings.TEST_MAIL,
'alternative_email': settings.TEST_MAIL,
}
WAITER_DATA = {
'prename': 'Peter',
'lastname': 'Wulter',
'birth_date': '1999-02-16',
'gender': '0',
'email': settings.TEST_MAIL,
'application_text': 'hoho',
}
EMERGENCY_CONTACT_DATA = {
'emergencycontact_set-TOTAL_FORMS': '1',
'emergencycontact_set-INITIAL_FORMS': '0',
'emergencycontact_set-MIN_NUM_FORMS': '1',
'emergencycontact_set-MAX_NUM_FORMS': '1000',
'emergencycontact_set-0-prename': 'Papa',
'emergencycontact_set-0-lastname': 'Wulter',
'emergencycontact_set-0-email': settings.TEST_MAIL,
'emergencycontact_set-0-phone_number': '-49 124125',
'emergencycontact_set-0-id': '',
'emergencycontact_set-0-DELETE': '',
'emergencycontact_set-0-member': '',
}
def create_custom_user(username, groups, prename, lastname): def create_custom_user(username, groups, prename, lastname):
user = User.objects.create_user( user = User.objects.create_user(
username=username, password='secret' username=username, password='secret'
@ -47,6 +88,10 @@ class BasicMemberTestCase(TestCase):
self.fritz.group.add(self.alp) self.fritz.group.add(self.alp)
self.fritz.save() self.fritz.save()
em = EmailAddress.objects.create(name='foobar')
self.alp.contact_email = em
self.alp.save()
self.peter = Member.objects.create(prename="Peter", lastname="Wulter", self.peter = Member.objects.create(prename="Peter", lastname="Wulter",
birth_date=timezone.now().date(), birth_date=timezone.now().date(),
email=settings.TEST_MAIL, gender=MALE) email=settings.TEST_MAIL, gender=MALE)
@ -625,3 +670,420 @@ class MailConfirmationTestCase(BasicMemberTestCase):
for em in self.fritz.emergencycontact_set.all(): for em in self.fritz.emergencycontact_set.all():
self.assertTrue(em.confirmed_mail, self.assertTrue(em.confirmed_mail,
msg='Mail of every emergency contact should be confirmed after manually confirming.') msg='Mail of every emergency contact should be confirmed after manually confirming.')
class RegisterWaitingListViewTestCase(BasicMemberTestCase):
def test_register_waiting_list_get(self):
url = reverse('members:register_waiting_list')
response = self.client.get(url)
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_register_waiting_list_post(self):
url = reverse('members:register_waiting_list')
response = self.client.post(url, data=dict(WAITER_DATA, save=''))
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _("Your registration for the waiting list was successful."))
def test_register_waiting_list_post_invalid(self):
url = reverse('members:register_waiting_list')
response = self.client.post(url, data={
'save': '',
})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _("This field is required."))
# this is required to bump the test coverage, but this is probably dead code
response = self.client.post(url, data={})
self.assertEqual(response.status_code, HTTPStatus.OK)
class RegisterViewTestCase(BasicMemberTestCase):
REGISTRATION_PASSWORD = "foobar"
def setUp(self):
super().setUp()
RegistrationPassword.objects.create(group=self.alp,
password=RegisterViewTestCase.REGISTRATION_PASSWORD)
def test_register_password_get(self):
url = reverse('members:register')
response = self.client.get(url)
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_register_password_post(self):
url = reverse('members:register')
response = self.client.post(url, data={
'password': RegisterViewTestCase.REGISTRATION_PASSWORD,
})
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_register_password_post_save(self):
url = reverse('members:register')
response = self.client.post(url, data=dict(
REGISTRATION_DATA,
**EMERGENCY_CONTACT_DATA,
password=RegisterViewTestCase.REGISTRATION_PASSWORD,
save='',
))
self.assertEqual(response.status_code, HTTPStatus.FOUND)
reg = MemberUnconfirmedProxy.objects.get(prename='Peter', lastname='Wulter', town='Town 1')
self.assertEqual(reg.street, 'Street 123')
def test_register_password_post_incomplete(self):
url = reverse('members:register')
response = self.client.post(url, data={
'password': RegisterViewTestCase.REGISTRATION_PASSWORD,
'save': '',
})
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_register_password_post_missing_emergency_contact(self):
url = reverse('members:register')
response = self.client.post(url, data=dict(
REGISTRATION_DATA,
password=RegisterViewTestCase.REGISTRATION_PASSWORD,
save='',
))
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_register_password_post_invalid(self):
url = reverse('members:register')
response = self.client.post(url, data={
'password': RegisterViewTestCase.REGISTRATION_PASSWORD + "_",
})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _("The entered password is wrong."))
class UploadRegistrationFormViewTestCase(BasicMemberTestCase):
def setUp(self):
super().setUp()
self.reg = MemberUnconfirmedProxy.objects.create(**REGISTRATION_DATA)
self.reg.create_from_registration(None, self.alp)
def test_upload_registration_form_get(self):
url = self.reg.get_upload_registration_form_link()
response = self.client.get(url)
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('If you are not an adult yet, please let someone responsible for you sign the agreement.'))
def test_upload_registration_form_get_invalid(self):
url = reverse('members:upload_registration_form')
response = self.client.get(url)
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('The supplied key for uploading a registration form is invalid.'))
url = reverse('members:upload_registration_form') + '?key=foobar'
response = self.client.get(url)
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('The supplied key for uploading a registration form is invalid.'))
def test_upload_registration_form_post_no_key(self):
url = reverse('members:upload_registration_form')
# no key
response = self.client.post(url, data={})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('The supplied key for uploading a registration form is invalid.'))
# invalid key
response = self.client.post(url, data={'key': 'foobar'})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('The supplied key for uploading a registration form is invalid.'))
def test_upload_registration_form_post_incomplete(self):
url = reverse('members:upload_registration_form')
response = self.client.post(url, data={
'key': self.reg.upload_registration_form_key,
})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _("This field is required."))
def test_upload_registration_form_post(self):
url = reverse('members:upload_registration_form')
file = SimpleUploadedFile("form.pdf", b"file_content", content_type="application/pdf")
response = self.client.post(url, data={
'key': self.reg.upload_registration_form_key,
'registration_form': file,
})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response,
_("Thank you for uploading the registration form. Our team will process your registration shortly."))
class DownloadRegistrationFormViewTestCase(BasicMemberTestCase):
def setUp(self):
super().setUp()
self.reg = MemberUnconfirmedProxy.objects.create(**REGISTRATION_DATA)
self.reg.create_from_registration(None, self.alp)
def test_download_registration_form_get_invalid(self):
url = reverse('members:download_registration_form')
response = self.client.get(url)
self.assertEqual(response.status_code, HTTPStatus.OK)
# this is how it is implemented, but it is questionable if this is the correct behaviour
self.assertContains(response, _('The supplied key for uploading a registration form is invalid.'))
response = self.client.get(url, data={'key': 'foobar'})
self.assertEqual(response.status_code, HTTPStatus.OK)
# this is how it is implemented, but it is questionable if this is the correct behaviour
self.assertContains(response, _('The supplied key for uploading a registration form is invalid.'))
def test_download_registration_form_get(self):
url = reverse('members:download_registration_form')
response = self.client.get(url, data={'key': self.reg.upload_registration_form_key})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertEqual(response.headers['Content-Type'], 'application/pdf')
class RegistrationFromWaiterViewTestCase(BasicMemberTestCase):
def setUp(self):
super().setUp()
self.waiter = MemberWaitingList.objects.create(**WAITER_DATA)
self.waiter.invite_to_group(self.alp)
self.invitation = InvitationToGroup.objects.get(group=self.alp, waiter=self.waiter)
def test_register_post_waiter_key_invalid(self):
url = reverse('members:register')
response = self.client.post(url, data={
'waiter_key': 'foobar',
})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('Something went wrong while processing your registration.'))
def test_register_post(self):
url = reverse('members:register')
response = self.client.post(url, data=dict(
REGISTRATION_DATA,
**EMERGENCY_CONTACT_DATA,
waiter_key=self.invitation.key,
save='',
))
self.assertEqual(response.status_code, HTTPStatus.FOUND)
def test_register_post_invalid(self):
url = reverse('members:register')
response = self.client.post(url, data=dict(
REGISTRATION_DATA,
waiter_key=self.invitation.key,
save='',
))
self.assertEqual(response.status_code, HTTPStatus.OK)
@skip("This currently throws an 'AttributeError'.")
def test_register_post_no_save(self):
url = reverse('members:register')
response = self.client.post(url, data=dict(
waiter_key=self.invitation.key,
))
self.assertEqual(response.status_code, HTTPStatus.OK)
class InvitationToGroupViewTestCase(BasicMemberTestCase):
def setUp(self):
super().setUp()
self.waiter = MemberWaitingList.objects.create(**WAITER_DATA)
self.waiter.invite_to_group(self.alp)
self.invitation = InvitationToGroup.objects.get(group=self.alp, waiter=self.waiter)
def _assert_reject_invalid(self, response):
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('This invitation is invalid or expired.'))
def test_accept_get_no_key(self):
url = reverse('members:registration')
response = self.client.get(url)
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_accept_get_invalid(self):
url = reverse('members:registration')
response = self.client.get(url, data={'key': 'foobar'})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('invalid'))
url = reverse('members:registration')
self.invitation.rejected = True
self.invitation.save()
response = self.client.get(url, data={'key': self.invitation.key})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('expired'))
def test_accept_get(self):
url = reverse('members:registration')
response = self.client.get(url, data={'key': self.invitation.key})
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_reject_get(self):
url = reverse('members:reject_invitation')
response = self.client.get(url, data={'key': self.invitation.key})
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_reject_get_invalid(self):
url = reverse('members:reject_invitation')
response = self.client.get(url, data={'key': 'foobar'})
self._assert_reject_invalid(response)
self.invitation.rejected = True
self.invitation.save()
response = self.client.get(url, data={'key': self.invitation.key})
self._assert_reject_invalid(response)
def test_reject_post_invalid(self):
url = reverse('members:reject_invitation')
response = self.client.post(url)
self._assert_reject_invalid(response)
response = self.client.post(url, data={'key': 'foobar'})
self._assert_reject_invalid(response)
response = self.client.post(url, data={'key': self.invitation.key})
self._assert_reject_invalid(response)
def test_reject_post_reject(self):
url = reverse('members:reject_invitation')
response = self.client.post(url, data={
'key': self.invitation.key,
'reject_invitation': '',
})
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_reject_post_leave(self):
url = reverse('members:reject_invitation')
response = self.client.post(url, data={
'key': self.invitation.key,
'leave_waitinglist': '',
})
self.assertEqual(response.status_code, HTTPStatus.OK)
class ConfirmWaitingViewTestCase(BasicMemberTestCase):
def setUp(self):
super().setUp()
self.waiter = MemberWaitingList.objects.create(**WAITER_DATA)
self.waiter.ask_for_wait_confirmation()
self.key = self.waiter.generate_wait_confirmation_key()
def test_get_no_key(self):
url = reverse('members:confirm_waiting')
response = self.client.get(url)
self.assertEqual(response.status_code, HTTPStatus.FOUND)
url = reverse('members:confirm_waiting')
response = self.client.get(url, data={'key': 'foobar'})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('The supplied link is invalid.'))
def test_get(self):
url = reverse('members:confirm_waiting')
response = self.client.get(url, data={'key': self.key})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('Waiting confirmed'))
# modify the POST data, otherwise the request is cached
response = self.client.get(url, data={'key': self.key, 'foo': 'bar'})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('Waiting confirmed'))
@skip("This currently fails, because `last_wait_confirmation` has `auto_now=True`, which is wrong.")
def test_get_expired(self):
self.waiter.last_wait_confirmation = datetime.date(1900, 1, 1)
self.waiter.save()
# after setting the last wait confirmation to an old date, the waiting status
# should be unconfirmed
self.assertFalse(self.waiter.waiting_confirmed())
url = reverse('members:confirm_waiting')
self.waiter.wait_confirmation_key_expire = timezone.now() - timezone.timedelta(days=10)
self.waiter.save()
response = self.client.get(url, data={'key': self.key})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('rejoin the waiting list'))
class MailConfirmationViewTestCase(BasicMemberTestCase):
def setUp(self):
super().setUp()
self.waiter = MemberWaitingList.objects.create(**WAITER_DATA)
self.waiter.request_mail_confirmation()
def test_get_invalid(self):
url = reverse('members:confirm_mail')
response = self.client.get(url)
self.assertEqual(response.status_code, HTTPStatus.FOUND)
url = reverse('members:confirm_mail')
response = self.client.get(url, data={'key': 'foobar'})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _("Mail confirmation failed"))
def test_get(self):
url = reverse('members:confirm_mail')
response = self.client.get(url, {'key': self.waiter.confirm_mail_key})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _("Mail confirmed"))
class EchoViewTestCase(BasicMemberTestCase):
def setUp(self):
super().setUp()
self.key = self.fritz.generate_echo_key()
def _assert_failed(self, response):
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('Echo failed'))
def test_get_invalid(self):
url = reverse('members:echo')
response = self.client.get(url)
self.assertEqual(response.status_code, HTTPStatus.FOUND)
url = reverse('members:echo')
response = self.client.get(url, data={'key': 'foobar'})
self._assert_failed(response)
def test_get(self):
url = reverse('members:echo')
response = self.client.get(url, data={'key': self.key})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('Thanks for echoing back. Please enter the password, which you can find in the email we sent you.\n'))
def test_post_invalid(self):
url = reverse('members:echo')
# no key
response = self.client.post(url)
self._assert_failed(response)
# wrong key
response = self.client.post(url, data={'key': 'foobar', 'password': self.fritz.echo_password})
self._assert_failed(response)
# wrong password
response = self.client.post(url, data={'key': self.key, 'password': 'foobar'})
self.assertContains(response, _('The entered password is wrong.'))
# expired key
self.fritz.echo_expire = timezone.now() - timezone.timedelta(days=settings.ECHO_GRACE_PERIOD)
self.fritz.save()
response = self.client.post(url, data={'key': self.key, 'password': self.fritz.echo_password})
self._assert_failed(response)
def test_post(self):
url = reverse('members:echo')
response = self.client.post(url, data={'key': self.key, 'password': self.fritz.echo_password})
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('Thanks for echoing back. Here is your current data:'))
def test_post_save(self):
url = reverse('members:echo')
# provide data, but no emergency contacts
response = self.client.post(url, data=dict(
REGISTRATION_DATA,
key=self.key,
password=self.fritz.echo_password,
save='',
))
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('Thanks for echoing back. Here is your current data:'))
# provide everything correctly
url = reverse('members:echo')
response = self.client.post(url, data=dict(
REGISTRATION_DATA,
**EMERGENCY_CONTACT_DATA,
key=self.key,
password=self.fritz.echo_password,
save='',
))
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(response, _('Your data was successfully updated.'))

Loading…
Cancel
Save