1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-06-12 12:57:28 +02:00

Compare commits

...

3 Commits

Author SHA1 Message Date
Ehouarn
02453e07ba linters 2025-05-28 16:31:03 +02:00
Ehouarn
4479e8f97a Fix de views.py et tests de permissions 2025-05-28 16:04:19 +02:00
Ehouarn
a351415494 Fix des tests de apps/wei 2025-05-28 15:37:37 +02:00
4 changed files with 52 additions and 36 deletions

View File

@ -10,7 +10,7 @@ from django.utils import timezone
from django.utils.crypto import get_random_string
from activity.models import Activity
from member.models import Club, Membership
from note.models import NoteUser
from note.models import NoteUser, NoteClub
from wei.models import WEIClub, Bus, WEIRegistration
@ -122,10 +122,13 @@ class TestPermissionDenied(TestCase):
def test_validate_weiregistration(self):
wei = WEIClub.objects.create(
name="WEI Test",
membership_start=date.today(),
date_start=date.today() + timedelta(days=1),
date_end=date.today() + timedelta(days=1),
parent_club=Club.objects.get(name="Kfet"),
)
NoteClub.objects.create(club=wei)
registration = WEIRegistration.objects.create(wei=wei, user=self.user, birth_date="2000-01-01")
response = self.client.get(reverse("wei:validate_registration", kwargs=dict(pk=registration.pk)))
self.assertEqual(response.status_code, 403)

View File

@ -39,9 +39,11 @@ class WEIRegistrationForm(forms.ModelForm):
class Meta:
model = WEIRegistration
fields = ['user', 'soge_credit', 'birth_date', 'gender', 'clothing_size',
'health_issues', 'emergency_contact_name', 'emergency_contact_phone', 'first_year',
'information_json']
fields = [
'user', 'soge_credit', 'birth_date', 'gender', 'clothing_size',
'health_issues', 'emergency_contact_name', 'emergency_contact_phone',
'first_year', 'information_json', 'caution_check'
]
widgets = {
"user": Autocomplete(
User,
@ -51,8 +53,14 @@ class WEIRegistrationForm(forms.ModelForm):
'placeholder': 'Nom ...',
},
),
"birth_date": DatePickerInput(options={'minDate': '1900-01-01',
'maxDate': '2100-01-01'}),
"birth_date": DatePickerInput(options={
'minDate': '1900-01-01',
'maxDate': '2100-01-01'
}),
"caution_check": forms.BooleanField(
label=_("I confirm that I have read the caution and that I am aware of the risks involved."),
required=False,
),
}

View File

@ -510,7 +510,7 @@ class TestWEIRegistration(TestCase):
)
qs = WEIRegistration.objects.filter(user_id=self.user.id, soge_credit=False, clothing_size="M")
self.assertTrue(qs.exists())
self.assertRedirects(response, reverse("wei:validate_registration", kwargs=dict(pk=qs.get().pk)), 302, 200)
self.assertRedirects(response, reverse("wei:wei_detail", kwargs=dict(pk=qs.get().wei.pk)), 302, 200)
# Check the page when the registration is already validated
membership = WEIMembership(
@ -564,7 +564,7 @@ class TestWEIRegistration(TestCase):
)
qs = WEIRegistration.objects.filter(user_id=self.user.id, clothing_size="L")
self.assertTrue(qs.exists())
self.assertRedirects(response, reverse("wei:validate_registration", kwargs=dict(pk=qs.get().pk)), 302, 200)
self.assertRedirects(response, reverse("wei:wei_detail", kwargs=dict(pk=qs.get().wei.pk)), 302, 200)
# Test invalid form
response = self.client.post(
@ -632,6 +632,7 @@ class TestWEIRegistration(TestCase):
last_name="admin",
first_name="admin",
bank="Société générale",
caution_check=True,
))
self.assertEqual(response.status_code, 200)
self.assertFalse(response.context["form"].is_valid())
@ -646,8 +647,10 @@ class TestWEIRegistration(TestCase):
last_name="admin",
first_name="admin",
bank="Société générale",
caution_check=True,
))
self.assertRedirects(response, reverse("wei:wei_registrations", kwargs=dict(pk=self.registration.wei.pk)), 302, 200)
# Check if the membership is successfully created
membership = WEIMembership.objects.filter(user_id=self.user.id, club=self.wei)
self.assertTrue(membership.exists())

View File

@ -4,7 +4,7 @@
import os
import shutil
import subprocess
from datetime import date, timedelta
from datetime import date
from tempfile import mkdtemp
from django.conf import settings
@ -21,7 +21,7 @@ from django.shortcuts import redirect
from django.template.loader import render_to_string
from django.urls import reverse_lazy
from django.views import View
from django.views.generic import DetailView, UpdateView, RedirectView, TemplateView, CreateView
from django.views.generic import DetailView, UpdateView, RedirectView, TemplateView
from django.utils.translation import gettext_lazy as _
from django.views.generic.edit import BaseFormView, DeleteView
from django_tables2 import SingleTableView, MultiTableMixin
@ -39,7 +39,6 @@ from .forms import WEIForm, WEIRegistrationForm, BusForm, BusTeamForm, WEIMember
WEIMembershipForm, CurrentSurvey
from .tables import BusRepartitionTable, BusTable, BusTeamTable, WEITable, WEIRegistrationTable, \
WEIRegistration1ATable, WEIMembershipTable
from .forms.surveys import CurrentSurvey
class CurrentWEIDetailView(LoginRequiredMixin, RedirectView):
@ -443,13 +442,10 @@ class BusTeamCreateView(ProtectQuerysetMixin, ProtectedCreateView):
def get_success_url(self):
self.object.refresh_from_db()
return reverse_lazy("wei:manage_bus_team", kwargs={"pk": self.object.pk})
def get_template_names(self):
names = super().get_template_names()
return names
class BusTeamUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
@ -482,13 +478,10 @@ class BusTeamUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
def get_success_url(self):
self.object.refresh_from_db()
return reverse_lazy("wei:manage_bus_team", kwargs={"pk": self.object.pk})
def get_template_names(self):
names = super().get_template_names()
return names
class BusTeamManageView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
@ -563,7 +556,7 @@ class WEIRegister1AView(ProtectQuerysetMixin, ProtectedCreateView):
def get_form(self, form_class=None):
form = super().get_form(form_class)
form.fields["user"].initial = self.request.user
# Cacher les champs pendant l'inscription initiale
if "first_year" in form.fields:
del form.fields["first_year"]
@ -571,7 +564,7 @@ class WEIRegister1AView(ProtectQuerysetMixin, ProtectedCreateView):
del form.fields["caution_check"]
if "information_json" in form.fields:
del form.fields["information_json"]
return form
@transaction.atomic
@ -797,22 +790,22 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update
membership = form.instance.membership
if membership is None:
raise ValueError(_("No membership found for this registration"))
membership_form = self.get_membership_form(self.request.POST, instance=membership)
if not membership_form.is_valid():
return self.form_invalid(form)
# Vérifier que l'utilisateur a la permission de modifier le membership
# On vérifie d'abord si l'utilisateur a la permission générale de modification
if not self.request.user.has_perm("wei.change_weimembership"):
raise PermissionDenied(_("You don't have the permission to update memberships"))
# On vérifie ensuite les permissions spécifiques pour chaque champ modifié
for field_name in membership_form.changed_data:
perm = f"wei.change_weimembership_{field_name}"
if not self.request.user.has_perm(perm):
raise PermissionDenied(_("You don't have the permission to update the field %(field)s") % {'field': field_name})
membership_form.save()
except (WEIMembership.DoesNotExist, ValueError, PermissionDenied) as e:
form.add_error(None, str(e))
@ -876,20 +869,29 @@ class WEIDeleteRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Delete
return reverse_lazy('wei:wei_detail', args=(self.object.wei.pk,))
class WEIValidateRegistrationView(LoginRequiredMixin, CreateView):
class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView):
"""
Validate WEI Registration
"""
model = WEIMembership
extra_context = {"title": _("Validate WEI registration")}
def dispatch(self, request, *args, **kwargs):
# Vérifier d'abord si l'utilisateur a la permission générale
if not request.user.has_perm("wei.add_weimembership"):
raise PermissionDenied(_("You don't have the permission to validate registrations"))
def get_sample_object(self):
"""
Return a sample object for permission checking
"""
registration = WEIRegistration.objects.get(pk=self.kwargs["pk"])
return WEIMembership(
user=registration.user,
club=registration.wei,
date_start=registration.wei.date_start,
# Add any fields needed for proper permission checking
registration=registration,
)
def dispatch(self, request, *args, **kwargs):
registration = WEIRegistration.objects.get(pk=self.kwargs["pk"])
wei = registration.wei
today = date.today()
# We can't validate anyone once the WEI is started and before the membership start date
@ -1338,7 +1340,7 @@ class WEIAttributeBus1ANextView(LoginRequiredMixin, RedirectView):
if not wei.exists():
raise Http404
wei = wei.get()
# On cherche d'abord les 1A qui ont une inscription validée (membership) mais pas de bus
qs = WEIRegistration.objects.filter(
wei=wei,
@ -1346,14 +1348,14 @@ class WEIAttributeBus1ANextView(LoginRequiredMixin, RedirectView):
membership__isnull=False,
membership__bus__isnull=True
)
# Parmi eux, on prend ceux qui ont répondu au questionnaire (ont un bus préféré)
qs = qs.filter(information_json__contains='selected_bus_pk')
if not qs.exists():
# Si on ne trouve personne, on affiche un message et on retourne à la liste
messages.info(self.request, _("No first year student without a bus found. Either all of them have a bus, or none has filled the survey yet."))
return reverse_lazy('wei:wei_1A_list', args=(wei.pk,))
# On redirige vers la page d'attribution pour le premier étudiant trouvé
return reverse_lazy('wei:wei_bus_1A', args=(qs.first().pk,))