1
0
mirror of https://gitlab.com/animath/si/plateforme-corres2math.git synced 2025-02-12 09:41:18 +00:00

Compare commits

..

No commits in common. "41817421332f435deac926f35e95cd08746575a0" and "7ae2b152c62ea180d4668b5aaf26a11914a2c963" have entirely different histories.

3 changed files with 56 additions and 288 deletions

View File

@ -5,17 +5,11 @@ from django.test import TestCase
from django.urls import reverse from django.urls import reverse
from registration.models import StudentRegistration from registration.models import StudentRegistration
from .models import Participation, Question, Team from .models import Participation, Question, Team, Video
class TestStudentParticipation(TestCase): class TestStudentParticipation(TestCase):
def setUp(self) -> None: def setUp(self) -> None:
self.superuser = User.objects.create_superuser(
username="admin",
email="admin@example.com",
password="toto1234",
)
self.user = User.objects.create( self.user = User.objects.create(
first_name="Toto", first_name="Toto",
last_name="Toto", last_name="Toto",
@ -39,31 +33,16 @@ class TestStudentParticipation(TestCase):
question="Pourquoi l'existence précède l'essence ?") question="Pourquoi l'existence précède l'essence ?")
self.client.force_login(self.user) 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): def test_admin_pages(self):
""" """
Load Django-admin pages. Load Django-admin pages.
""" """
self.client.force_login(self.superuser) superuser = User.objects.create_superuser(
username="admin",
email="admin@example.com",
password="toto1234",
)
self.client.force_login(superuser)
# Test team pages # Test team pages
response = self.client.get(reverse("admin:index") + "participation/team/") response = self.client.get(reverse("admin:index") + "participation/team/")
@ -113,7 +92,8 @@ class TestStudentParticipation(TestCase):
response = self.client.get(reverse("admin:index") + "participation/phase/") response = self.client.get(reverse("admin:index") + "participation/phase/")
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
response = self.client.get(reverse("admin:index") + "participation/phase/1/change/") response = self.client.get(reverse("admin:index")
+ f"participation/phase/1/change/")
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_create_team(self): def test_create_team(self):
@ -193,161 +173,6 @@ class TestStudentParticipation(TestCase):
response = self.client.get(reverse("participation:team_detail", args=(self.team.pk,))) response = self.client.get(reverse("participation:team_detail", args=(self.team.pk,)))
self.assertEqual(response.status_code, 200) 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): def test_update_team(self):
""" """
Try to update team information. Try to update team information.
@ -390,7 +215,6 @@ class TestStudentParticipation(TestCase):
self.user.registration.team = self.team self.user.registration.team = self.team
self.user.registration.save() self.user.registration.save()
# Can't see the participation if it is not valid
response = self.client.get(reverse("participation:my_participation_detail")) response = self.client.get(reverse("participation:my_participation_detail"))
self.assertRedirects(response, self.assertRedirects(response,
reverse("participation:participation_detail", args=(self.team.participation.pk,)), reverse("participation:participation_detail", args=(self.team.participation.pk,)),
@ -406,13 +230,6 @@ class TestStudentParticipation(TestCase):
response = self.client.get(reverse("participation:participation_detail", args=(self.team.participation.pk,))) response = self.client.get(reverse("participation:participation_detail", args=(self.team.participation.pk,)))
self.assertEqual(response.status_code, 200) 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): def test_upload_video(self):
""" """
Try to send a solution video link. Try to send a solution video link.
@ -438,36 +255,6 @@ class TestStudentParticipation(TestCase):
response = self.client.get(reverse("participation:participation_detail", args=(self.team.participation.pk,))) response = self.client.get(reverse("participation:participation_detail", args=(self.team.participation.pk,)))
self.assertEqual(response.status_code, 200) 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): class TestAdminForbidden(TestCase):
def setUp(self) -> None: def setUp(self) -> None:

View File

@ -144,8 +144,7 @@ class TeamDetailView(LoginRequiredMixin, FormMixin, ProcessFormView, DetailView)
user = request.user user = request.user
self.object = self.get_object() self.object = self.get_object()
# Ensure that the user is an admin or a member of the team # Ensure that the user is an admin or a member of the team
if user.registration.is_admin or user.registration.participates and \ if user.registration.is_admin or user.registration.participates and user.registration.team.pk == kwargs["pk"]:
user.registration.team and user.registration.team.pk == kwargs["pk"]:
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
raise PermissionDenied raise PermissionDenied
@ -172,70 +171,54 @@ class TeamDetailView(LoginRequiredMixin, FormMixin, ProcessFormView, DetailView)
return RequestValidationForm return RequestValidationForm
elif self.request.POST["_form_type"] == "ValidateParticipationForm": elif self.request.POST["_form_type"] == "ValidateParticipationForm":
return ValidateParticipationForm return ValidateParticipationForm
return None
def form_valid(self, form): def form_valid(self, form):
self.object = self.get_object() self.object = self.get_object()
if isinstance(form, RequestValidationForm): if isinstance(form, RequestValidationForm):
return self.handle_request_validation(form) if not self.request.user.registration.participates:
form.add_error(None, _("You don't participate, so you can't request the validation of the team."))
return self.form_invalid(form)
if self.object.participation.valid is not None:
form.add_error(None, _("The validation of the team is already done or pending."))
return self.form_invalid(form)
self.object.participation.valid = False
self.object.participation.save()
for admin in AdminRegistration.objects.all():
mail_context = dict(user=admin.user, team=self.object)
mail_plain = render_to_string("participation/mails/request_validation.txt", mail_context)
mail_html = render_to_string("participation/mails/request_validation.html", mail_context)
admin.user.email_user("[Corres2math] Validation d'équipe", mail_plain, html_message=mail_html)
elif isinstance(form, ValidateParticipationForm): elif isinstance(form, ValidateParticipationForm):
return self.handle_validate_participation(form) if not self.request.user.registration.is_admin:
return self.form_invalid(form) form.add_error(None, _("You are not an administrator."))
return self.form_invalid(form)
elif self.object.participation.valid is not False:
form.add_error(None, _("This team has no pending validation."))
return self.form_invalid(form)
def handle_request_validation(self, form): if "validate" in self.request.POST:
""" self.object.participation.valid = True
A team requests to be validated self.object.participation.save()
""" mail_context = dict(team=self.object, message=form.cleaned_data["message"])
if not self.request.user.registration.participates: mail_plain = render_to_string("participation/mails/team_validated.txt", mail_context)
form.add_error(None, _("You don't participate, so you can't request the validation of the team.")) mail_html = render_to_string("participation/mails/team_validated.html", mail_context)
return self.form_invalid(form) send_mail("[Corres2math] Équipe validée", mail_plain, None, [self.object.email], html_message=mail_html)
if self.object.participation.valid is not None: elif "invalidate" in self.request.POST:
form.add_error(None, _("The validation of the team is already done or pending.")) self.object.participation.valid = None
return self.form_invalid(form) self.object.participation.save()
if not self.get_context_data()["can_validate"]: mail_context = dict(team=self.object, message=form.cleaned_data["message"])
form.add_error(None, _("The team can't be validated: missing email address confirmations, " mail_plain = render_to_string("participation/mails/team_not_validated.txt", mail_context)
"photo authorizations, people or the chosen problem is not set.")) mail_html = render_to_string("participation/mails/team_not_validated.html", mail_context)
return self.form_invalid(form) send_mail("[Corres2math] Équipe non validée", mail_plain, None, [self.object.email],
html_message=mail_html)
else:
form.add_error(None, _("You must specify if you validate the registration or not."))
return self.form_invalid(form)
self.object.participation.valid = False return super().form_invalid(form)
self.object.participation.save()
for admin in AdminRegistration.objects.all():
mail_context = dict(user=admin.user, team=self.object)
mail_plain = render_to_string("participation/mails/request_validation.txt", mail_context)
mail_html = render_to_string("participation/mails/request_validation.html", mail_context)
admin.user.email_user("[Corres2math] Validation d'équipe", mail_plain, html_message=mail_html)
return self.form_valid(form)
def handle_validate_participation(self, form):
"""
An admin validates the team (or not)
"""
if not self.request.user.registration.is_admin:
form.add_error(None, _("You are not an administrator."))
return self.form_invalid(form)
elif self.object.participation.valid is not False:
form.add_error(None, _("This team has no pending validation."))
return self.form_invalid(form)
if "validate" in self.request.POST:
self.object.participation.valid = True
self.object.participation.save()
mail_context = dict(team=self.object, message=form.cleaned_data["message"])
mail_plain = render_to_string("participation/mails/team_validated.txt", mail_context)
mail_html = render_to_string("participation/mails/team_validated.html", mail_context)
send_mail("[Corres2math] Équipe validée", mail_plain, None, [self.object.email], html_message=mail_html)
elif "invalidate" in self.request.POST:
self.object.participation.valid = None
self.object.participation.save()
mail_context = dict(team=self.object, message=form.cleaned_data["message"])
mail_plain = render_to_string("participation/mails/team_not_validated.txt", mail_context)
mail_html = render_to_string("participation/mails/team_not_validated.html", mail_context)
send_mail("[Corres2math] Équipe non validée", mail_plain, None, [self.object.email],
html_message=mail_html)
else:
form.add_error(None, _("You must specify if you validate the registration or not."))
return self.form_invalid(form)
return super().form_valid(form)
def get_success_url(self): def get_success_url(self):
return self.request.path return self.request.path
@ -251,9 +234,7 @@ class TeamUpdateView(LoginRequiredMixin, UpdateView):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
user = request.user user = request.user
if user.registration.is_admin or user.registration.participates and \ if user.registration.is_admin or user.registration.participates and user.registration.team.pk == kwargs["pk"]:
user.registration.team and \
user.registration.team.pk == kwargs["pk"]:
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
raise PermissionDenied raise PermissionDenied
@ -366,7 +347,6 @@ class ParticipationDetailView(LoginRequiredMixin, DetailView):
if not self.get_object().valid: if not self.get_object().valid:
raise PermissionDenied(_("The team is not validated yet.")) raise PermissionDenied(_("The team is not validated yet."))
if user.registration.is_admin or user.registration.participates \ if user.registration.is_admin or user.registration.participates \
and user.registration.team.participation \
and user.registration.team.participation.pk == kwargs["pk"]: and user.registration.team.participation.pk == kwargs["pk"]:
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
raise PermissionDenied raise PermissionDenied

View File

@ -1,9 +1,10 @@
import os import os
from corres2math.tokens import email_validation_token
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site 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.core.management import call_command
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse