plateforme-tfjm2/registration/tests.py

431 lines
20 KiB
Python

# Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later
import os
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
from django.urls import reverse
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from participation.models import Team
from tfjm.tokens import email_validation_token
from .models import CoachRegistration, StudentRegistration, VolunteerRegistration
class TestIndexPage(TestCase):
def test_index(self) -> None:
"""
Display the index page, without any right.
"""
response = self.client.get(reverse("index"))
self.assertEqual(response.status_code, 200)
def test_not_authenticated(self):
"""
Try to load some pages without being authenticated.
"""
response = self.client.get(reverse("registration:reset_admin"))
self.assertRedirects(response, reverse("login") + "?next=" + reverse("registration:reset_admin"), 302, 200)
User.objects.create()
response = self.client.get(reverse("registration:user_detail", args=(1,)))
self.assertRedirects(response, reverse("login") + "?next=" + reverse("registration:user_detail", args=(1,)))
Team.objects.create()
response = self.client.get(reverse("participation:team_detail", args=(1,)))
self.assertRedirects(response, reverse("login") + "?next=" + reverse("participation:team_detail", args=(1,)))
response = self.client.get(reverse("participation:update_team", args=(1,)))
self.assertRedirects(response, reverse("login") + "?next=" + reverse("participation:update_team", args=(1,)))
response = self.client.get(reverse("participation:create_team"))
self.assertRedirects(response, reverse("login") + "?next=" + reverse("participation:create_team"))
response = self.client.get(reverse("participation:join_team"))
self.assertRedirects(response, reverse("login") + "?next=" + reverse("participation:join_team"))
response = self.client.get(reverse("participation:team_authorizations", args=(1,)))
self.assertRedirects(response, reverse("login") + "?next="
+ reverse("participation:team_authorizations", args=(1,)))
response = self.client.get(reverse("participation:participation_detail", args=(1,)))
self.assertRedirects(response, reverse("login") + "?next="
+ reverse("participation:participation_detail", args=(1,)))
class TestRegistration(TestCase):
def setUp(self) -> None:
self.user = User.objects.create_superuser(
username="admin",
password="admin",
email="admin@example.com",
)
self.client.force_login(self.user)
self.student = User.objects.create(email="student@example.com")
StudentRegistration.objects.create(
user=self.student,
student_class=11,
school="Earth",
address="1 Rue de Rivoli",
zip_code=75001,
city="Paris",
)
self.coach = User.objects.create(email="coach@example.com")
CoachRegistration.objects.create(
user=self.coach,
address="1 Rue de Rivoli",
zip_code=75001,
city="Paris",
professional_activity="Teacher",
)
def test_admin_pages(self):
"""
Check that admin pages are rendering successfully.
"""
response = self.client.get(reverse("admin:index") + "registration/registration/")
self.assertEqual(response.status_code, 200)
response = self.client.get(reverse("admin:index")
+ f"registration/registration/{self.user.registration.pk}/change/")
self.assertEqual(response.status_code, 200)
response = self.client.get(reverse("admin:index") +
f"r/{ContentType.objects.get_for_model(VolunteerRegistration).id}/"
f"{self.user.registration.pk}/")
self.assertRedirects(response, "http://" + Site.objects.get().domain +
str(self.user.registration.get_absolute_url()), 302, 200)
response = self.client.get(reverse("admin:index")
+ f"registration/registration/{self.student.registration.pk}/change/")
self.assertEqual(response.status_code, 200)
response = self.client.get(reverse("admin:index") +
f"r/{ContentType.objects.get_for_model(StudentRegistration).id}/"
f"{self.student.registration.pk}/")
self.assertRedirects(response, "http://" + Site.objects.get().domain +
str(self.student.registration.get_absolute_url()), 302, 200)
response = self.client.get(reverse("admin:index")
+ f"registration/registration/{self.coach.registration.pk}/change/")
self.assertEqual(response.status_code, 200)
response = self.client.get(reverse("admin:index") +
f"r/{ContentType.objects.get_for_model(CoachRegistration).id}/"
f"{self.coach.registration.pk}/")
self.assertRedirects(response, "http://" + Site.objects.get().domain +
str(self.coach.registration.get_absolute_url()), 302, 200)
def test_registration(self):
"""
Ensure that the signup form is working successfully.
"""
response = self.client.get(reverse("registration:signup"))
self.assertEqual(response.status_code, 200)
# Incomplete form
response = self.client.post(reverse("registration:signup"), data=dict(
last_name="Toto",
first_name="Toto",
email="toto@example.com",
password1="azertyuiopazertyuiop",
password2="azertyuiopazertyuiop",
role="participant",
))
self.assertEqual(response.status_code, 200)
response = self.client.post(reverse("registration:signup"), data=dict(
last_name="Toto",
first_name="Toto",
email="toto@example.com",
password1="azertyuiopazertyuiop",
password2="azertyuiopazertyuiop",
role="participant",
student_class=12,
school="God",
birth_date="2000-01-01",
gender="other",
address="1 Rue de Rivoli",
zip_code=75001,
city="Paris",
phone_number="0123456789",
responsible_name="Toto",
responsible_phone="0123456789",
responsible_email="toto@example.com",
give_contact_to_animath=False,
))
self.assertRedirects(response, reverse("registration:email_validation_sent"), 302, 200)
self.assertTrue(User.objects.filter(
email="toto@example.com",
registration__participantregistration__studentregistration__responsible_name="Toto").exists())
# Email is already used
response = self.client.post(reverse("registration:signup"), data=dict(
last_name="Toto",
first_name="Toto",
email="toto@example.com",
password1="azertyuiopazertyuiop",
password2="azertyuiopazertyuiop",
role="participant",
student_class=12,
school="God",
birth_date="2000-01-01",
gender="other",
address="1 Rue de Rivoli",
zip_code=75001,
city="Paris",
phone_number="0123456789",
responsible_name="Toto",
responsible_phone="0123456789",
responsible_email="toto@example.com",
give_contact_to_animath=False,
))
self.assertEqual(response.status_code, 200)
response = self.client.get(reverse("registration:email_validation_sent"))
self.assertEqual(response.status_code, 200)
response = self.client.post(reverse("registration:signup"), data=dict(
last_name="Toto",
first_name="Coach",
email="coachtoto@example.com",
password1="azertyuiopazertyuiop",
password2="azertyuiopazertyuiop",
role="coach",
gender="other",
address="1 Rue de Rivoli",
zip_code=75001,
city="Paris",
phone_number="0123456789",
professional_activity="God",
last_degree="Master",
give_contact_to_animath=True,
))
self.assertRedirects(response, reverse("registration:email_validation_sent"), 302, 200)
self.assertTrue(User.objects.filter(email="coachtoto@example.com").exists())
user = User.objects.get(email="coachtoto@example.com")
token = email_validation_token.make_token(user)
uid = urlsafe_base64_encode(force_bytes(user.pk))
response = self.client.get(reverse("registration:email_validation", kwargs=dict(uidb64=uid, token=token)))
self.assertEqual(response.status_code, 200)
user.registration.refresh_from_db()
self.assertTrue(user.registration.email_confirmed)
# Token has expired
response = self.client.get(reverse("registration:email_validation", kwargs=dict(uidb64=uid, token=token)))
self.assertEqual(response.status_code, 400)
# Uid does not exist
response = self.client.get(reverse("registration:email_validation", kwargs=dict(uidb64=0, token="toto")))
self.assertEqual(response.status_code, 400)
response = self.client.get(reverse("registration:email_validation_resend", args=(user.pk,)))
self.assertRedirects(response, reverse("registration:email_validation_sent"), 302, 200)
def test_login(self):
"""
With a registered user, try to log in
"""
response = self.client.get(reverse("login"))
self.assertEqual(response.status_code, 200)
self.client.logout()
response = self.client.post(reverse("login"), data=dict(
username="admin",
password="toto",
))
self.assertEqual(response.status_code, 200)
response = self.client.post(reverse("login"), data=dict(
username="admin@example.com",
password="admin",
))
self.assertRedirects(response, reverse("index"), 302, 200)
def test_user_detail(self):
"""
Load a user detail page.
"""
response = self.client.get(reverse("registration:my_account_detail"))
self.assertRedirects(response, reverse("registration:user_detail", args=(self.user.pk,)))
response = self.client.get(reverse("registration:user_detail", args=(self.user.pk,)))
self.assertEqual(response.status_code, 200)
def test_user_list(self):
"""
Display the list of all users.
"""
response = self.client.get(reverse("registration:user_list"))
self.assertEqual(response.status_code, 200)
def test_update_user(self):
"""
Update the user information, for each type of user.
"""
# To test the modification of mailing lists
from participation.models import Team
self.student.registration.team = Team.objects.create(
name="toto",
trigram="TOT",
)
self.student.registration.save()
for user, data in [(self.user, dict(professional_activity="Bot", admin=True)),
(self.student, dict(student_class=11, school="Sky", birth_date="2001-01-01",
gender="female", address="1 Rue de Rivoli", zip_code=75001,
city="Paris", responsible_name="Toto",
responsible_phone="0123456789",
responsible_email="toto@example.com")),
(self.coach, dict(professional_activity="God", last_degree="Médaille Fields", gender="male",
address="1 Rue de Rivoli", zip_code=75001, city="Paris"))]:
response = self.client.get(reverse("registration:update_user", args=(user.pk,)))
self.assertEqual(response.status_code, 200)
response = self.client.post(reverse("registration:update_user", args=(user.pk,)), data=dict(
first_name="Changed",
last_name="Name",
email="new_" + user.email,
give_contact_to_animath=True,
email_confirmed=True,
team_id="",
))
self.assertEqual(response.status_code, 200)
data.update(
first_name="Changed",
last_name="Name",
email="new_" + user.email,
give_contact_to_animath=True,
email_confirmed=True,
team_id="",
)
response = self.client.post(reverse("registration:update_user", args=(user.pk,)), data=data)
self.assertRedirects(response, reverse("registration:user_detail", args=(user.pk,)), 302, 200)
user.refresh_from_db()
self.assertEqual(user.email, user.username)
self.assertFalse(user.registration.email_confirmed)
self.assertEqual(user.first_name, "Changed")
def test_upload_photo_authorization(self):
"""
Try to upload a photo authorization.
"""
for auth_type in ["photo_authorization", "health_sheet", "parental_authorization"]:
response = self.client.get(reverse("registration:upload_user_photo_authorization",
args=(self.student.registration.pk,)))
self.assertEqual(response.status_code, 200)
# README is not a valid PDF file
response = self.client.post(reverse(f"registration:upload_user_{auth_type}",
args=(self.student.registration.pk,)), data={
auth_type: open("README.md", "rb"),
})
self.assertEqual(response.status_code, 200)
# Don't send too large files
response = self.client.post(reverse(f"registration:upload_user_{auth_type}",
args=(self.student.registration.pk,)), data={
auth_type: SimpleUploadedFile("file.pdf", content=int(0).to_bytes(2000001, "big"),
content_type="application/pdf"),
})
self.assertEqual(response.status_code, 200)
response = self.client.post(reverse(f"registration:upload_user_{auth_type}",
args=(self.student.registration.pk,)), data={
auth_type: open("tfjm/static/Fiche_sanitaire.pdf", "rb"),
})
self.assertRedirects(response, reverse("registration:user_detail", args=(self.student.pk,)), 302, 200)
self.student.registration.refresh_from_db()
self.assertTrue(getattr(self.student.registration, auth_type))
response = self.client.get(reverse(
auth_type, args=(getattr(self.student.registration, auth_type).name.split('/')[-1],)))
self.assertEqual(response.status_code, 200)
from participation.models import Team
team = Team.objects.create(name="Test", trigram="TES")
self.student.registration.team = team
self.student.registration.save()
response = self.client.get(reverse("participation:team_authorizations", args=(team.pk,)))
self.assertEqual(response.status_code, 200)
self.assertEqual(response["content-type"], "application/zip")
# Do it twice, ensure that the previous authorization got deleted
old_authoratization = self.student.registration.photo_authorization.path
response = self.client.post(reverse("registration:upload_user_photo_authorization",
args=(self.student.registration.pk,)), data=dict(
photo_authorization=open("tfjm/static/Fiche_sanitaire.pdf", "rb"),
))
self.assertRedirects(response, reverse("registration:user_detail", args=(self.student.pk,)), 302, 200)
self.assertFalse(os.path.isfile(old_authoratization))
self.student.registration.refresh_from_db()
self.student.registration.photo_authorization.delete()
self.student.registration.save()
def test_user_detail_forbidden(self):
"""
Create a new user and ensure that it can't see the detail of another user.
"""
self.client.force_login(self.coach)
response = self.client.get(reverse("registration:user_detail", args=(self.user.pk,)))
self.assertEqual(response.status_code, 403)
response = self.client.get(reverse("registration:update_user", args=(self.user.pk,)))
self.assertEqual(response.status_code, 403)
response = self.client.get(reverse("registration:upload_user_photo_authorization",
args=(self.student.registration.pk,)))
self.assertEqual(response.status_code, 403)
response = self.client.get(reverse("photo_authorization", args=("inexisting-authorization",)))
self.assertEqual(response.status_code, 404)
with open("media/authorization/photo/example", "w") as f:
f.write("I lost the game.")
self.student.registration.photo_authorization = "authorization/photo/example"
self.student.registration.save()
response = self.client.get(reverse("photo_authorization", args=("example",)))
self.assertEqual(response.status_code, 403)
os.remove("media/authorization/photo/example")
def test_impersonate(self):
"""
Admin can impersonate other people to act as them.
"""
response = self.client.get(reverse("registration:user_impersonate", args=(0x7ffff42ff,)))
self.assertEqual(response.status_code, 404)
# Impersonate student account
response = self.client.get(reverse("registration:user_impersonate", args=(self.student.pk,)))
self.assertRedirects(response, reverse("registration:user_detail", args=(self.student.pk,)), 302, 200)
self.assertEqual(self.client.session["_fake_user_id"], self.student.id)
# Reset admin view
response = self.client.get(reverse("registration:reset_admin"))
self.assertRedirects(response, reverse("index"), 302, 200)
self.assertFalse("_fake_user_id" in self.client.session)
def test_research(self):
"""
Try to search some things.
"""
response = self.client.get(reverse("haystack_search") + "?q=" + self.user.email + "&models=auth.user")
self.assertEqual(response.status_code, 200)
self.assertTrue(response.context["object_list"])
response = self.client.get(reverse("haystack_search") + "?q=" +
str(self.coach.registration.professional_activity)
+ "&models=registration.CoachRegistration")
self.assertEqual(response.status_code, 200)
self.assertTrue(response.context["object_list"])
response = self.client.get(reverse("haystack_search") + "?q=" +
self.student.registration.school + "&models=registration.StudentRegistration")
self.assertEqual(response.status_code, 200)
self.assertTrue(response.context["object_list"])