# 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.core.management import call_command 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", 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", 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.last_name) 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)) self.assertEqual(response.status_code, 200) self.assertTrue(response.context["object_list"]) response = self.client.get(reverse("haystack_search") + "?q=" + self.student.registration.school) self.assertEqual(response.status_code, 200) self.assertTrue(response.context["object_list"])