import os from django.contrib.sites.models import Site from corres2math.tokens import email_validation_token from django.contrib.contenttypes.models import ContentType from django.contrib.auth.models import User 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 .models import AdminRegistration, CoachRegistration, Registration, StudentRegistration 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) 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") self.coach = User.objects.create(email="coach@example.com") CoachRegistration.objects.create(user=self.coach, 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(AdminRegistration).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", give_contact_to_animath=False, )) self.assertRedirects(response, reverse("registration:email_validation_sent"), 302, 200) self.assertTrue(User.objects.filter(email="toto@example.com").exists()) 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", 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_update_user(self): """ Update the user information, for each type of user. """ for user, data in [(self.user, dict(role="Bot")), (self.student, dict(student_class=11, school="Sky")), (self.coach, dict(professional_activity="God"))]: 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, )) self.assertEqual(response.status_code, 200) data.update( first_name="Changed", last_name="Name", email="new_" + user.email, give_contact_to_animath=True, ) 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. """ 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("registration:upload_user_photo_authorization", args=(self.student.registration.pk,)), data=dict( photo_authorization=open("README.md", "rb"), )) self.assertEqual(response.status_code, 200) response = self.client.post(reverse("registration:upload_user_photo_authorization", args=(self.student.registration.pk,)), data=dict( photo_authorization=open("corres2math/static/Autorisation de droit à l'image - majeur.pdf", "rb"), )) self.assertRedirects(response, reverse("registration:user_detail", args=(self.student.pk,)), 302, 200) self.student.registration.refresh_from_db() self.assertTrue(self.student.registration.photo_authorization) response = self.client.get(reverse("photo_authorization", args=(self.student.registration.photo_authorization.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("corres2math/static/Autorisation de droit à l'image - majeur.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() 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.user.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. """ call_command("rebuild_index", "--noinput", "-v", 0) response = self.client.get(reverse("haystack_search") + "?q=" + self.user.email) 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.get_student_class_display()) self.assertEqual(response.status_code, 200) self.assertTrue(response.context["object_list"]) def test_not_implemented_error(self): # Only for coverage self.assertRaises(NotImplementedError, lambda: Registration().type) self.assertRaises(NotImplementedError, lambda: Registration().form_class)