from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import Site from django.test import TestCase from django.urls import reverse from registration.models import StudentRegistration from .models import Participation, Question, Team class TestStudentParticipation(TestCase): def setUp(self) -> None: self.superuser = User.objects.create_superuser( username="admin", email="admin@example.com", password="toto1234", ) self.user = User.objects.create( first_name="Toto", last_name="Toto", email="toto@example.com", password="toto", ) StudentRegistration.objects.create( user=self.user, student_class=12, school="Earth", give_contact_to_animath=True, email_confirmed=True, ) self.team = Team.objects.create( name="Super team", trigram="AAA", access_code="azerty", grant_animath_access_videos=True, ) self.question = Question.objects.create(participation=self.team.participation, question="Pourquoi l'existence précède l'essence ?") self.client.force_login(self.user) self.second_user = User.objects.create( first_name="Lalala", last_name="Lalala", email="lalala@example.com", password="lalala", ) StudentRegistration.objects.create( user=self.second_user, student_class=11, school="Moon", give_contact_to_animath=True, email_confirmed=True, ) self.second_team = Team.objects.create( name="Poor team", trigram="FFF", access_code="qwerty", grant_animath_access_videos=True, ) def test_admin_pages(self): """ Load Django-admin pages. """ self.client.force_login(self.superuser) # Test team pages response = self.client.get(reverse("admin:index") + "participation/team/") self.assertEqual(response.status_code, 200) response = self.client.get(reverse("admin:index") + f"participation/team/{self.team.pk}/change/") self.assertEqual(response.status_code, 200) response = self.client.get(reverse("admin:index") + f"r/{ContentType.objects.get_for_model(Team).id}/" f"{self.team.pk}/") self.assertRedirects(response, "http://" + Site.objects.get().domain + str(self.team.get_absolute_url()), 302, 200) # Test participation pages self.team.participation.valid = True self.team.participation.save() response = self.client.get(reverse("admin:index") + "participation/participation/") self.assertEqual(response.status_code, 200) response = self.client.get(reverse("admin:index") + f"participation/participation/{self.team.participation.pk}/change/") self.assertEqual(response.status_code, 200) response = self.client.get(reverse("admin:index") + f"r/{ContentType.objects.get_for_model(Participation).id}/" f"{self.team.participation.pk}/") self.assertRedirects(response, "http://" + Site.objects.get().domain + str(self.team.participation.get_absolute_url()), 302, 200) # Test video pages response = self.client.get(reverse("admin:index") + "participation/video/") self.assertEqual(response.status_code, 200) response = self.client.get(reverse("admin:index") + f"participation/video/{self.team.participation.solution.pk}/change/") self.assertEqual(response.status_code, 200) # Test question pages response = self.client.get(reverse("admin:index") + "participation/question/") self.assertEqual(response.status_code, 200) response = self.client.get(reverse("admin:index") + f"participation/question/{self.question.pk}/change/") self.assertEqual(response.status_code, 200) # Test phase pages response = self.client.get(reverse("admin:index") + "participation/phase/") self.assertEqual(response.status_code, 200) response = self.client.get(reverse("admin:index") + "participation/phase/1/change/") self.assertEqual(response.status_code, 200) def test_create_team(self): """ Try to create a team. """ response = self.client.get(reverse("participation:create_team")) self.assertEqual(response.status_code, 200) response = self.client.post(reverse("participation:create_team"), data=dict( name="Test team", trigram="123", grant_animath_access_videos=False, )) self.assertEqual(response.status_code, 200) response = self.client.post(reverse("participation:create_team"), data=dict( name="Test team", trigram="TES", grant_animath_access_videos=False, )) self.assertTrue(Team.objects.filter(trigram="TES").exists()) team = Team.objects.get(trigram="TES") self.assertRedirects(response, reverse("participation:team_detail", args=(team.pk,)), 302, 200) # Already in a team response = self.client.post(reverse("participation:create_team"), data=dict( name="Test team 2", trigram="TET", grant_animath_access_videos=False, )) self.assertEqual(response.status_code, 403) def test_join_team(self): """ Try to join an existing team. """ response = self.client.get(reverse("participation:join_team")) self.assertEqual(response.status_code, 200) team = Team.objects.create(name="Test", trigram="TES") response = self.client.post(reverse("participation:join_team"), data=dict( access_code="éééééé", )) self.assertEqual(response.status_code, 200) response = self.client.post(reverse("participation:join_team"), data=dict( access_code=team.access_code, )) self.assertRedirects(response, reverse("participation:team_detail", args=(team.pk,)), 302, 200) self.assertTrue(Team.objects.filter(trigram="TES").exists()) # Already joined response = self.client.post(reverse("participation:join_team"), data=dict( access_code=team.access_code, )) self.assertEqual(response.status_code, 403) def test_no_myteam_redirect_noteam(self): """ Test redirection. """ response = self.client.get(reverse("participation:my_team_detail")) self.assertTrue(response.status_code, 200) def test_team_detail(self): """ Try to display the information of a team. """ self.user.registration.team = self.team self.user.registration.save() response = self.client.get(reverse("participation:my_team_detail")) self.assertRedirects(response, reverse("participation:team_detail", args=(self.team.pk,)), 302, 200) response = self.client.get(reverse("participation:team_detail", args=(self.team.pk,))) self.assertEqual(response.status_code, 200) # Can't see other teams self.second_user.registration.team = self.second_team self.second_user.registration.save() self.client.force_login(self.second_user) response = self.client.get(reverse("participation:team_detail", args=(self.team.participation.pk,))) self.assertEqual(response.status_code, 403) def test_request_validate_team(self): """ The team ask for validation. """ self.user.registration.team = self.team self.user.registration.save() second_user = User.objects.create( first_name="Blublu", last_name="Blublu", email="blublu@example.com", password="blublu", ) StudentRegistration.objects.create( user=second_user, student_class=12, school="Jupiter", give_contact_to_animath=True, email_confirmed=True, team=self.team, photo_authorization="authorization/photo/mai-linh", ) third_user = User.objects.create( first_name="Zupzup", last_name="Zupzup", email="zupzup@example.com", password="zupzup", ) StudentRegistration.objects.create( user=third_user, student_class=10, school="Sun", give_contact_to_animath=False, email_confirmed=True, team=self.team, photo_authorization="authorization/photo/yohann", ) self.client.force_login(self.superuser) # Admin users can't ask for validation resp = self.client.post(reverse("participation:team_detail", args=(self.team.pk,)), data=dict( _form_type="RequestValidationForm", engagement=True, )) self.assertEqual(resp.status_code, 200) self.client.force_login(self.user) self.assertIsNone(self.team.participation.valid) resp = self.client.get(reverse("participation:team_detail", args=(self.team.pk,))) self.assertEqual(resp.status_code, 200) self.assertFalse(resp.context["can_validate"]) # Can't validate resp = self.client.post(reverse("participation:team_detail", args=(self.team.pk,)), data=dict( _form_type="RequestValidationForm", engagement=True, )) self.assertEqual(resp.status_code, 200) self.user.registration.photo_authorization = "authorization/photo/ananas" self.user.registration.save() resp = self.client.get(reverse("participation:team_detail", args=(self.team.pk,))) self.assertEqual(resp.status_code, 200) self.assertFalse(resp.context["can_validate"]) self.team.participation.problem = 2 self.team.participation.save() resp = self.client.get(reverse("participation:team_detail", args=(self.team.pk,))) self.assertEqual(resp.status_code, 200) self.assertTrue(resp.context["can_validate"]) resp = self.client.post(reverse("participation:team_detail", args=(self.team.pk,)), data=dict( _form_type="RequestValidationForm", engagement=True, )) self.assertRedirects(resp, reverse("participation:team_detail", args=(self.team.pk,)), 302, 200) self.team.participation.refresh_from_db() self.assertFalse(self.team.participation.valid) self.assertIsNotNone(self.team.participation.valid) # Team already asked for validation resp = self.client.post(reverse("participation:team_detail", args=(self.team.pk,)), data=dict( _form_type="RequestValidationForm", engagement=True, )) self.assertEqual(resp.status_code, 200) def test_validate_team(self): """ A team asked for validation. Try to validate it. """ self.team.participation.valid = False self.team.participation.save() # No right to do that resp = self.client.post(reverse("participation:team_detail", args=(self.team.pk,)), data=dict( _form_type="ValidateParticipationForm", message="J'ai 4 ans", validate=True, )) self.assertEqual(resp.status_code, 200) self.client.force_login(self.superuser) resp = self.client.get(reverse("participation:team_detail", args=(self.team.pk,))) self.assertEqual(resp.status_code, 200) resp = self.client.post(reverse("participation:team_detail", args=(self.team.pk,)), data=dict( _form_type="ValidateParticipationForm", message="Woops I didn't said anything", )) self.assertEqual(resp.status_code, 200) # Test invalidate team resp = self.client.post(reverse("participation:team_detail", args=(self.team.pk,)), data=dict( _form_type="ValidateParticipationForm", message="Wsh nope", invalidate=True, )) self.assertRedirects(resp, reverse("participation:team_detail", args=(self.team.pk,)), 302, 200) self.team.participation.refresh_from_db() self.assertIsNone(self.team.participation.valid) # Team did not ask validation resp = self.client.post(reverse("participation:team_detail", args=(self.team.pk,)), data=dict( _form_type="ValidateParticipationForm", message="Bienvenue ça va être trop cool", validate=True, )) self.assertEqual(resp.status_code, 200) self.team.participation.valid = False self.team.participation.save() # Test validate team resp = self.client.post(reverse("participation:team_detail", args=(self.team.pk,)), data=dict( _form_type="ValidateParticipationForm", message="Bienvenue ça va être trop cool", validate=True, )) self.assertRedirects(resp, reverse("participation:team_detail", args=(self.team.pk,)), 302, 200) self.team.participation.refresh_from_db() self.assertTrue(self.team.participation.valid) def test_update_team(self): """ Try to update team information. """ self.user.registration.team = self.team self.user.registration.save() response = self.client.get(reverse("participation:update_team", args=(self.team.pk,))) self.assertEqual(response.status_code, 200) # Form is invalid response = self.client.post(reverse("participation:update_team", args=(self.team.pk,)), data=dict( name="Updated team name", trigram="BBB", grant_animath_access_videos=True, problem=42, )) self.assertEqual(response.status_code, 200) response = self.client.post(reverse("participation:update_team", args=(self.team.pk,)), data=dict( name="Updated team name", trigram="BBB", grant_animath_access_videos=True, problem=3, )) self.assertRedirects(response, reverse("participation:team_detail", args=(self.team.pk,)), 302, 200) self.assertTrue(Team.objects.filter(trigram="BBB", participation__problem=3).exists()) def test_leave_team(self): """ A user is in a team, and leaves it. """ # User is not in a team response = self.client.post(reverse("participation:team_leave")) self.assertEqual(response.status_code, 403) self.user.registration.team = self.team self.user.registration.save() # Team is pending validation self.team.participation.valid = False self.team.participation.save() response = self.client.post(reverse("participation:team_leave")) self.assertEqual(response.status_code, 403) # Team is valid self.team.participation.valid = True self.team.participation.save() response = self.client.post(reverse("participation:team_leave")) self.assertEqual(response.status_code, 403) # Unauthenticated users are redirected to login page self.client.logout() response = self.client.get(reverse("participation:team_leave")) self.assertRedirects(response, reverse("login") + "?next=" + reverse("participation:team_leave"), 302, 200) self.client.force_login(self.user) self.team.participation.valid = None self.team.participation.save() response = self.client.post(reverse("participation:team_leave")) self.assertRedirects(response, reverse("index"), 302, 200) self.user.registration.refresh_from_db() self.assertIsNone(self.user.registration.team) self.assertFalse(Team.objects.filter(pk=self.team.pk).exists()) def test_no_myparticipation_redirect_nomyparticipation(self): """ Ensure a permission denied when we search my team participation when we are in no team. """ response = self.client.get(reverse("participation:my_participation_detail")) self.assertEqual(response.status_code, 403) def test_participation_detail(self): """ Try to display the detail of a team participation. """ self.user.registration.team = self.team self.user.registration.save() # Can't see the participation if it is not valid response = self.client.get(reverse("participation:my_participation_detail")) self.assertRedirects(response, reverse("participation:participation_detail", args=(self.team.participation.pk,)), 302, 403) self.team.participation.valid = True self.team.participation.save() response = self.client.get(reverse("participation:my_participation_detail")) self.assertRedirects(response, reverse("participation:participation_detail", args=(self.team.participation.pk,)), 302, 200) response = self.client.get(reverse("participation:participation_detail", args=(self.team.participation.pk,))) self.assertEqual(response.status_code, 200) # Can't see other participations self.second_user.registration.team = self.second_team self.second_user.registration.save() self.client.force_login(self.second_user) response = self.client.get(reverse("participation:participation_detail", args=(self.team.participation.pk,))) self.assertEqual(response.status_code, 403) def test_upload_video(self): """ Try to send a solution video link. """ self.user.registration.team = self.team self.user.registration.save() self.team.participation.valid = True self.team.participation.save() response = self.client.get(reverse("participation:upload_video", args=(self.team.participation.solution.pk,))) self.assertEqual(response.status_code, 200) response = self.client.post(reverse("participation:upload_video", args=(self.team.participation.solution.pk,)), data=dict(link="https://youtube.com/watch?v=73nsrixx7eI")) self.assertRedirects(response, reverse("participation:participation_detail", args=(self.team.participation.id,)), 302, 200) self.team.participation.refresh_from_db() self.assertEqual(self.team.participation.solution.platform, "youtube") self.assertEqual(self.team.participation.solution.youtube_code, "73nsrixx7eI") response = self.client.get(reverse("participation:participation_detail", args=(self.team.participation.pk,))) self.assertEqual(response.status_code, 200) def test_forbidden_access(self): """ Load personnal pages and ensure that these are protected. """ self.user.registration.team = self.team self.user.registration.save() resp = self.client.get(reverse("participation:team_detail", args=(self.second_team.pk,))) self.assertEqual(resp.status_code, 403) resp = self.client.get(reverse("participation:update_team", args=(self.second_team.pk,))) self.assertEqual(resp.status_code, 403) resp = self.client.get(reverse("participation:team_authorizations", args=(self.second_team.pk,))) self.assertEqual(resp.status_code, 403) resp = self.client.get(reverse("participation:participation_detail", args=(self.second_team.pk,))) self.assertEqual(resp.status_code, 403) resp = self.client.get(reverse("participation:upload_video", args=(self.second_team.participation.solution.pk,))) self.assertEqual(resp.status_code, 403) resp = self.client.get(reverse("participation:upload_video", args=(self.second_team.participation.synthesis.pk,))) self.assertEqual(resp.status_code, 403) resp = self.client.get(reverse("participation:add_question", args=(self.second_team.pk,))) self.assertEqual(resp.status_code, 403) question = Question.objects.create(participation=self.second_team.participation, question=self.question.question) resp = self.client.get(reverse("participation:update_question", args=(question.pk,))) self.assertEqual(resp.status_code, 403) resp = self.client.get(reverse("participation:delete_question", args=(question.pk,))) self.assertEqual(resp.status_code, 403) class TestAdminForbidden(TestCase): def setUp(self) -> None: self.user = User.objects.create_superuser( username="admin@example.com", email="admin@example.com", password="admin", ) self.client.force_login(self.user) def test_create_team_forbidden(self): """ Ensure that an admin can't create a team. """ response = self.client.post(reverse("participation:create_team"), data=dict( name="Test team", trigram="TES", grant_animath_access_videos=False, )) self.assertEqual(response.status_code, 403) def test_join_team_forbidden(self): """ Ensure that an admin can't join a team. """ team = Team.objects.create(name="Test", trigram="TES") response = self.client.post(reverse("participation:join_team"), data=dict( access_code=team.access_code, )) self.assertTrue(response.status_code, 403) def test_leave_team_forbidden(self): """ Ensure that an admin can't leave a team. """ response = self.client.get(reverse("participation:team_leave")) self.assertTrue(response.status_code, 403) def test_my_team_forbidden(self): """ Ensure that an admin can't access to "My team". """ response = self.client.get(reverse("participation:my_team_detail")) self.assertEqual(response.status_code, 403) def test_my_participation_forbidden(self): """ Ensure that an admin can't access to "My participation". """ response = self.client.get(reverse("participation:my_participation_detail")) self.assertEqual(response.status_code, 403)