mirror of
https://gitlab.crans.org/bde/nk20
synced 2024-12-22 23:42:25 +00:00
Test and cover fully member app
This commit is contained in:
parent
1b8cb7abb0
commit
bf7f5b9cd6
@ -31,9 +31,7 @@ class CustomUserAdmin(UserAdmin):
|
||||
"""
|
||||
When creating a new user don't show profile one the first step
|
||||
"""
|
||||
if not obj:
|
||||
return list()
|
||||
return super().get_inline_instances(request, obj)
|
||||
return super().get_inline_instances(request, obj) if obj else []
|
||||
|
||||
|
||||
@admin.register(Club, site=admin_site)
|
||||
|
@ -339,43 +339,40 @@ class Membership(models.Model):
|
||||
return self.date_start.toordinal() <= datetime.datetime.now().toordinal()
|
||||
|
||||
def renew(self):
|
||||
if Membership.objects.filter(
|
||||
if not Membership.objects.filter(
|
||||
user=self.user,
|
||||
club=self.club,
|
||||
date_start__gte=self.club.membership_start,
|
||||
).exists():
|
||||
# Membership is already renewed
|
||||
return
|
||||
new_membership = Membership(
|
||||
user=self.user,
|
||||
club=self.club,
|
||||
date_start=max(self.date_end + datetime.timedelta(days=1), self.club.membership_start),
|
||||
)
|
||||
if hasattr(self, '_force_renew_parent') and self._force_renew_parent:
|
||||
new_membership._force_renew_parent = True
|
||||
if hasattr(self, '_soge') and self._soge:
|
||||
new_membership._soge = True
|
||||
if hasattr(self, '_force_save') and self._force_save:
|
||||
new_membership._force_save = True
|
||||
new_membership.save()
|
||||
new_membership.roles.set(self.roles.all())
|
||||
new_membership.save()
|
||||
# Membership is not renewed yet
|
||||
new_membership = Membership(
|
||||
user=self.user,
|
||||
club=self.club,
|
||||
date_start=max(self.date_end + datetime.timedelta(days=1), self.club.membership_start),
|
||||
)
|
||||
if hasattr(self, '_force_renew_parent') and self._force_renew_parent:
|
||||
new_membership._force_renew_parent = True
|
||||
if hasattr(self, '_soge') and self._soge:
|
||||
new_membership._soge = True
|
||||
if hasattr(self, '_force_save') and self._force_save:
|
||||
new_membership._force_save = True
|
||||
new_membership.save()
|
||||
new_membership.roles.set(self.roles.all())
|
||||
new_membership.save()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
"""
|
||||
Calculate fee and end date before saving the membership and creating the transaction if needed.
|
||||
"""
|
||||
|
||||
if self.pk:
|
||||
created = not self.pk
|
||||
if not created:
|
||||
for role in self.roles.all():
|
||||
club = role.for_club
|
||||
if club is not None:
|
||||
if club.pk != self.club_id:
|
||||
raise ValidationError(_('The role {role} does not apply to the club {club}.')
|
||||
.format(role=role.name, club=club.name))
|
||||
|
||||
created = not self.pk
|
||||
if created:
|
||||
else:
|
||||
if Membership.objects.filter(
|
||||
user=self.user,
|
||||
club=self.club,
|
||||
@ -384,7 +381,7 @@ class Membership(models.Model):
|
||||
).exists():
|
||||
raise ValidationError(_('User is already a member of the club'))
|
||||
|
||||
if self.club.parent_club is not None and not self.pk:
|
||||
if self.club.parent_club is not None:
|
||||
# Check that the user is already a member of the parent club if the membership is created
|
||||
if not Membership.objects.filter(
|
||||
user=self.user,
|
||||
@ -433,15 +430,10 @@ class Membership(models.Model):
|
||||
raise ValidationError(_('User is not a member of the parent club')
|
||||
+ ' ' + self.club.parent_club.name)
|
||||
|
||||
if self.user.profile.paid:
|
||||
self.fee = self.club.membership_fee_paid
|
||||
else:
|
||||
self.fee = self.club.membership_fee_unpaid
|
||||
self.fee = self.club.membership_fee_paid if self.user.profile.paid else self.club.membership_fee_unpaid
|
||||
|
||||
if self.club.membership_duration is not None:
|
||||
self.date_end = self.date_start + datetime.timedelta(days=self.club.membership_duration)
|
||||
else:
|
||||
self.date_end = self.date_start + datetime.timedelta(days=424242)
|
||||
self.date_end = self.date_start + datetime.timedelta(days=self.club.membership_duration) \
|
||||
if self.club.membership_duration is not None else self.date_start + datetime.timedelta(days=424242)
|
||||
if self.club.membership_end is not None and self.date_end > self.club.membership_end:
|
||||
self.date_end = self.club.membership_end
|
||||
|
||||
|
@ -6,11 +6,7 @@ def save_user_profile(instance, created, raw, **_kwargs):
|
||||
"""
|
||||
Hook to create and save a profile when an user is updated if it is not registered with the signup form
|
||||
"""
|
||||
if raw:
|
||||
# When provisionning data, do not try to autocreate
|
||||
return
|
||||
|
||||
if created and instance.is_active:
|
||||
if not raw and created and instance.is_active:
|
||||
from .models import Profile
|
||||
Profile.objects.get_or_create(user=instance)
|
||||
if instance.is_superuser:
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "member/base.html" %}
|
||||
{% extends "base.html" %}
|
||||
{% comment %}
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
{% endcomment %}
|
||||
|
@ -1,8 +1,10 @@
|
||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
from note.models import TransactionTemplate, TemplateCategory
|
||||
|
||||
"""
|
||||
@ -31,7 +33,20 @@ class TemplateLoggedInTests(TestCase):
|
||||
sess.save()
|
||||
|
||||
def test_login_page(self):
|
||||
response = self.client.get('/accounts/login/')
|
||||
response = self.client.get(reverse("login"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.client.logout()
|
||||
|
||||
response = self.client.post('/accounts/login/', data=dict(
|
||||
username="admin",
|
||||
password="adminadmin",
|
||||
permission_mask=3,
|
||||
))
|
||||
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL, 302, 200)
|
||||
|
||||
def test_logout(self):
|
||||
response = self.client.get(reverse("logout"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_admin_index(self):
|
||||
@ -42,21 +57,3 @@ class TemplateLoggedInTests(TestCase):
|
||||
response = self.client.get('/accounts/password_reset/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_logout_page(self):
|
||||
response = self.client.get('/accounts/logout/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_transfer_page(self):
|
||||
response = self.client.get('/note/transfer/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_consos_page(self):
|
||||
# Create one button and ensure that it is visible
|
||||
cat = TemplateCategory.objects.create()
|
||||
TransactionTemplate.objects.create(
|
||||
destination_id=5,
|
||||
category=cat,
|
||||
amount=0,
|
||||
)
|
||||
response = self.client.get('/note/consos/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
407
apps/member/tests/test_memberships.py
Normal file
407
apps/member/tests/test_memberships.py
Normal file
@ -0,0 +1,407 @@
|
||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
from datetime import date, timedelta
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.db.models import Q
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
|
||||
from member.models import Club, Membership, Profile
|
||||
from note.models import Alias, NoteSpecial
|
||||
from permission.models import Role
|
||||
from treasury.models import SogeCredit
|
||||
|
||||
"""
|
||||
Create some users and clubs and test that all pages are rendering properly
|
||||
and that memberships are working.
|
||||
"""
|
||||
|
||||
|
||||
class TestMemberships(TestCase):
|
||||
fixtures = ('initial', )
|
||||
|
||||
def setUp(self) -> None:
|
||||
"""
|
||||
Create a sample superuser, a club and a membership for all tests.
|
||||
"""
|
||||
self.user = User.objects.create_superuser(
|
||||
username="toto",
|
||||
email="toto@example.com",
|
||||
password="toto",
|
||||
)
|
||||
self.user.profile.registration_valid = True
|
||||
self.user.profile.email_confirmed = True
|
||||
self.user.profile.save()
|
||||
self.client.force_login(self.user)
|
||||
|
||||
sess = self.client.session
|
||||
sess["permission_mask"] = 42
|
||||
sess.save()
|
||||
|
||||
self.club = Club.objects.create(name="totoclub", parent_club=Club.objects.get(name="BDE"))
|
||||
self.bde_membership = Membership.objects.create(user=self.user, club=Club.objects.get(name="BDE"))
|
||||
self.membership = Membership.objects.create(user=self.user, club=self.club)
|
||||
self.membership.roles.add(Role.objects.get(name="Bureau de club"))
|
||||
self.membership.save()
|
||||
|
||||
def test_admin_pages(self):
|
||||
"""
|
||||
Check that Django Admin pages for the member app are loading successfully.
|
||||
"""
|
||||
response = self.client.get(reverse("admin:index") + "member/membership/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("admin:index") + "member/club/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("admin:index") + "auth/user/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("admin:index") + "auth/user/" + str(self.user.pk) + "/change/")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_render_club_list(self):
|
||||
"""
|
||||
Render the list of all clubs, with a search.
|
||||
"""
|
||||
response = self.client.get(reverse("member:club_list"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("member:club_list") + "?search=toto")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_render_club_create(self):
|
||||
"""
|
||||
Try to create a new club.
|
||||
"""
|
||||
response = self.client.get(reverse("member:club_create"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
response = self.client.post(reverse("member:club_create"), data=dict(
|
||||
name="Club toto",
|
||||
email="clubtoto@example.com",
|
||||
parent_club=self.club.pk,
|
||||
require_memberships=False,
|
||||
membership_fee_paid=0,
|
||||
membership_fee_unpaid=0,
|
||||
))
|
||||
self.assertTrue(Club.objects.filter(name="Club toto").exists())
|
||||
club = Club.objects.get(name="Club toto")
|
||||
self.assertRedirects(response, club.get_absolute_url(), 302, 200)
|
||||
|
||||
def test_render_club_detail(self):
|
||||
"""
|
||||
Display the detail of a club.
|
||||
"""
|
||||
response = self.client.get(reverse("member:club_detail", args=(self.club.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_render_club_update(self):
|
||||
"""
|
||||
Try to update the information about a club.
|
||||
"""
|
||||
response = self.client.get(reverse("member:club_update", args=(self.club.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
response = self.client.post(reverse("member:club_update", args=(self.club.pk, )), data=dict(
|
||||
name="Toto club updated",
|
||||
email="clubtoto@example.com",
|
||||
require_memberships=True,
|
||||
membership_fee_paid=0,
|
||||
membership_fee_unpaid=0,
|
||||
))
|
||||
self.assertRedirects(response, self.club.get_absolute_url(), 302, 200)
|
||||
self.assertTrue(Club.objects.exclude(name="Toto club updated"))
|
||||
|
||||
def test_render_club_update_picture(self):
|
||||
"""
|
||||
Try to update the picture of the note of a club.
|
||||
"""
|
||||
response = self.client.get(reverse("member:club_update_pic", args=(self.club.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
old_pic = self.club.note.display_image
|
||||
|
||||
with open("media/pic/default.png", "rb") as f:
|
||||
image = SimpleUploadedFile("image.png", f.read(), "image/png")
|
||||
response = self.client.post(reverse("member:club_update_pic", args=(self.club.pk,)), dict(
|
||||
image=image,
|
||||
x=0,
|
||||
y=0,
|
||||
width=200,
|
||||
height=200,
|
||||
))
|
||||
self.assertRedirects(response, self.club.get_absolute_url(), 302, 200)
|
||||
|
||||
self.club.note.refresh_from_db()
|
||||
self.assertTrue(os.path.exists(self.club.note.display_image.path))
|
||||
os.remove(self.club.note.display_image.path)
|
||||
|
||||
self.club.note.display_image = old_pic
|
||||
self.club.note.save()
|
||||
|
||||
def test_render_club_aliases(self):
|
||||
"""
|
||||
Display the list of the aliases of a club.
|
||||
"""
|
||||
# Alias creation and deletion is already tested in the note app
|
||||
response = self.client.get(reverse("member:club_alias", args=(self.club.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_render_club_members(self):
|
||||
"""
|
||||
Display the list of the members of a club.
|
||||
"""
|
||||
response = self.client.get(reverse("member:club_members", args=(self.club.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
response = self.client.get(reverse("member:club_members", args=(self.club.pk,)) + "?search=toto&roles="
|
||||
+ ",".join([str(role.pk) for role in
|
||||
Role.objects.filter(weirole__isnull=True).all()]))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_render_club_add_member(self):
|
||||
"""
|
||||
Try to add memberships and renew them.
|
||||
"""
|
||||
response = self.client.get(reverse("member:club_add_member", args=(Club.objects.get(name="BDE").pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
user = User.objects.create(username="totototo")
|
||||
user.profile.registration_valid = True
|
||||
user.profile.email_confirmed = True
|
||||
user.profile.save()
|
||||
user.save()
|
||||
|
||||
# We create a club without any parent and one club with parent BDE (that is the club Kfet)
|
||||
for bde_parent in False, True:
|
||||
if bde_parent:
|
||||
club = Club.objects.get(name="Kfet")
|
||||
else:
|
||||
club = Club.objects.create(
|
||||
name="Second club " + ("with BDE" if bde_parent else "without BDE"),
|
||||
parent_club=None,
|
||||
email="newclub@example.com",
|
||||
require_memberships=True,
|
||||
membership_fee_paid=1000,
|
||||
membership_fee_unpaid=500,
|
||||
membership_start=date.today(),
|
||||
membership_end=date.today() + timedelta(days=366),
|
||||
membership_duration=366,
|
||||
)
|
||||
|
||||
response = self.client.get(reverse("member:club_add_member", args=(club.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Create a new membership
|
||||
response = self.client.post(reverse("member:club_add_member", args=(club.pk,)), data=dict(
|
||||
user=user.pk,
|
||||
date_start="{:%Y-%m-%d}".format(timezone.now().date()),
|
||||
soge=False,
|
||||
credit_type=NoteSpecial.objects.get(special_type="Espèces").id,
|
||||
credit_amount=4200,
|
||||
last_name="TOTO",
|
||||
first_name="Toto",
|
||||
bank="Le matelas",
|
||||
))
|
||||
self.assertRedirects(response, club.get_absolute_url(), 302, 200)
|
||||
|
||||
self.assertTrue(Membership.objects.filter(user=user, club=club).exists())
|
||||
|
||||
# Membership is sent to the past to check renewals
|
||||
membership = Membership.objects.get(user=user, club=club)
|
||||
self.assertTrue(membership.valid)
|
||||
membership.date_start = date(year=2000, month=1, day=1)
|
||||
membership.date_end = date(year=2000, month=12, day=31)
|
||||
membership.save()
|
||||
self.assertFalse(membership.valid)
|
||||
|
||||
response = self.client.get(reverse("member:club_members", args=(club.pk,)) + "?only_active=0")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
bde_membership = self.bde_membership
|
||||
if bde_parent:
|
||||
bde_membership = Membership.objects.get(club__name="BDE", user=user)
|
||||
bde_membership.date_start = date(year=2000, month=1, day=1)
|
||||
bde_membership.date_end = date(year=2000, month=12, day=31)
|
||||
bde_membership.save()
|
||||
|
||||
response = self.client.get(reverse("member:club_renew_membership", args=(bde_membership.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
response = self.client.get(reverse("member:club_renew_membership", args=(membership.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Renew membership
|
||||
response = self.client.post(reverse("member:club_renew_membership", args=(membership.pk,)), data=dict(
|
||||
user=user.pk,
|
||||
date_start="{:%Y-%m-%d}".format(timezone.now().date()),
|
||||
soge=bde_parent,
|
||||
credit_type=NoteSpecial.objects.get(special_type="Chèque").id,
|
||||
credit_amount=14242,
|
||||
last_name="TOTO",
|
||||
first_name="Toto",
|
||||
bank="Bank",
|
||||
))
|
||||
self.assertRedirects(response, club.get_absolute_url(), 302, 200)
|
||||
|
||||
response = self.client.get(user.profile.get_absolute_url())
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_auto_join_kfet_when_join_bde_with_soge(self):
|
||||
"""
|
||||
When we join the BDE club with a Soge registration, a Kfet membership is automatically created.
|
||||
We check that it is the case.
|
||||
"""
|
||||
user = User.objects.create(username="new1A")
|
||||
user.profile.registration_valid = True
|
||||
user.profile.email_confirmed = True
|
||||
user.profile.save()
|
||||
user.save()
|
||||
|
||||
bde = Club.objects.get(name="BDE")
|
||||
kfet = Club.objects.get(name="Kfet")
|
||||
|
||||
response = self.client.post(reverse("member:club_add_member", args=(bde.pk,)), data=dict(
|
||||
user=user.pk,
|
||||
date_start="{:%Y-%m-%d}".format(timezone.now().date()),
|
||||
soge=True,
|
||||
credit_type=NoteSpecial.objects.get(special_type="Virement bancaire").id,
|
||||
credit_amount=(bde.membership_fee_paid + kfet.membership_fee_paid) / 100,
|
||||
last_name="TOTO",
|
||||
first_name="Toto",
|
||||
bank="Société générale",
|
||||
))
|
||||
self.assertRedirects(response, bde.get_absolute_url(), 302, 200)
|
||||
|
||||
self.assertTrue(Membership.objects.filter(user=user, club=bde).exists())
|
||||
self.assertTrue(Membership.objects.filter(user=user, club=kfet).exists())
|
||||
self.assertTrue(SogeCredit.objects.filter(user=user).exists())
|
||||
|
||||
def test_change_roles(self):
|
||||
"""
|
||||
Check to change the roles of a membership.
|
||||
"""
|
||||
response = self.client.get(reverse("member:club_manage_roles", args=(self.membership.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
response = self.client.post(reverse("member:club_manage_roles", args=(self.membership.pk,)), data=dict(
|
||||
roles=[role.id for role in Role.objects.filter(
|
||||
Q(name="Membre de club") | Q(name="Trésorier·ère de club") | Q(name="Bureau de club")).all()],
|
||||
))
|
||||
self.assertRedirects(response, self.user.profile.get_absolute_url(), 302, 200)
|
||||
self.membership.refresh_from_db()
|
||||
self.assertEqual(self.membership.roles.count(), 3)
|
||||
|
||||
def test_render_user_list(self):
|
||||
"""
|
||||
Display the user search page.
|
||||
"""
|
||||
response = self.client.get(reverse("member:user_list"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("member:user_list") + "?search=toto")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_render_user_detail(self):
|
||||
"""
|
||||
Display the user detail page.
|
||||
"""
|
||||
response = self.client.get(self.user.profile.get_absolute_url())
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_render_user_update(self):
|
||||
"""
|
||||
Update some data about the user.
|
||||
"""
|
||||
response = self.client.get(reverse("member:user_update_profile", args=(self.user.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
response = self.client.post(reverse("member:user_update_profile", args=(self.user.pk,)), data=dict(
|
||||
first_name="Toto",
|
||||
last_name="Toto",
|
||||
username="toto changed",
|
||||
email="updated@example.com",
|
||||
phone_number="+33600000000",
|
||||
section="",
|
||||
department="A0",
|
||||
promotion=timezone.now().year,
|
||||
address="Earth",
|
||||
paid=True,
|
||||
ml_events_registration="en",
|
||||
ml_sports_registration=True,
|
||||
ml_art_registration=True,
|
||||
report_frequency=7,
|
||||
))
|
||||
self.assertRedirects(response, self.user.profile.get_absolute_url(), 302, 200)
|
||||
self.assertTrue(User.objects.filter(username="toto changed").exists())
|
||||
self.assertTrue(Profile.objects.filter(address="Earth").exists())
|
||||
self.assertTrue(Alias.objects.filter(normalized_name="totochanged").exists())
|
||||
|
||||
def test_render_user_update_picture(self):
|
||||
"""
|
||||
Update the note picture of the user.
|
||||
"""
|
||||
response = self.client.get(reverse("member:user_update_pic", args=(self.user.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
old_pic = self.user.note.display_image
|
||||
|
||||
with open("media/pic/default.png", "rb") as f:
|
||||
image = SimpleUploadedFile("image.png", f.read(), "image/png")
|
||||
response = self.client.post(reverse("member:user_update_pic", args=(self.user.pk,)), dict(
|
||||
image=image,
|
||||
x=0,
|
||||
y=0,
|
||||
width=200,
|
||||
height=200,
|
||||
))
|
||||
self.assertRedirects(response, self.user.profile.get_absolute_url(), 302, 200)
|
||||
|
||||
self.user.note.refresh_from_db()
|
||||
self.assertTrue(os.path.exists(self.user.note.display_image.path))
|
||||
os.remove(self.user.note.display_image.path)
|
||||
|
||||
self.user.note.display_image = old_pic
|
||||
self.user.note.save()
|
||||
|
||||
def test_render_user_aliases(self):
|
||||
"""
|
||||
Display the list of aliases of the user.
|
||||
"""
|
||||
# Alias creation and deletion is already tested in the note app
|
||||
response = self.client.get(reverse("member:user_alias", args=(self.user.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_manage_auth_token(self):
|
||||
"""
|
||||
Display the page to see the API authentication token, see it and regenerate it.
|
||||
:return:
|
||||
"""
|
||||
response = self.client.get(reverse("member:auth_token"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("member:auth_token") + "?view")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(reverse("member:auth_token") + "?regenerate")
|
||||
self.assertRedirects(response, reverse("member:auth_token") + "?view", 302, 200)
|
||||
|
||||
def test_random_coverage(self):
|
||||
# Useless, only for coverage
|
||||
self.assertEqual(str(self.user), str(self.user.profile))
|
||||
self.user.profile.promotion = None
|
||||
self.assertEqual(self.user.profile.ens_year, 0)
|
||||
self.membership.date_end = None
|
||||
self.assertTrue(self.membership.valid)
|
||||
|
||||
def test_nk15_hasher(self):
|
||||
"""
|
||||
Test that NK15 passwords are successfully imported.
|
||||
"""
|
||||
salt = "42"
|
||||
password = "strongpassword42"
|
||||
hashed = hashlib.sha256((salt + password).encode("utf-8")).hexdigest()
|
||||
self.user.password = "custom_nk15$1$" + salt + "|" + hashed
|
||||
self.user.save()
|
||||
self.assertTrue(self.user.check_password(password))
|
@ -97,8 +97,7 @@ class UserUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
|
||||
note = NoteUser.objects.filter(
|
||||
alias__normalized_name=Alias.normalize(new_username))
|
||||
if note.exists() and note.get().user != self.object:
|
||||
form.add_error('username',
|
||||
_("An alias with a similar name already exists."))
|
||||
form.add_error('username', _("An alias with a similar name already exists."))
|
||||
return super().form_invalid(form)
|
||||
# Check if the username is one of user's aliases.
|
||||
alias = Alias.objects.filter(name=new_username)
|
||||
@ -142,9 +141,8 @@ class UserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
||||
We can't display information of a not registered user.
|
||||
"""
|
||||
qs = super().get_queryset()
|
||||
if self.request.user.is_superuser and self.request.session.get("permission_mask", -1) >= 42:
|
||||
return qs
|
||||
return qs.filter(profile__registration_valid=True)
|
||||
return qs if self.request.user.is_superuser and self.request.session.get("permission_mask", -1) >= 42\
|
||||
else qs.filter(profile__registration_valid=True)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""
|
||||
@ -204,14 +202,16 @@ class UserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
|
||||
"""
|
||||
Filter the user list with the given pattern.
|
||||
"""
|
||||
qs = super().get_queryset().distinct("username").annotate(alias=F("note__alias__name"))\
|
||||
qs = super().get_queryset().annotate(alias=F("note__alias__name"))\
|
||||
.annotate(normalized_alias=F("note__alias__normalized_name"))\
|
||||
.filter(profile__registration_valid=True).order_by("username")
|
||||
if "search" in self.request.GET:
|
||||
pattern = self.request.GET["search"]
|
||||
.filter(profile__registration_valid=True)
|
||||
|
||||
if not pattern:
|
||||
return qs.none()
|
||||
# Sqlite doesn't support order by in subqueries
|
||||
qs = qs.order_by("username").distinct("username")\
|
||||
if settings.DATABASES[qs.db]["ENGINE"] == 'django.db.backends.postgresql' else qs.distinct()
|
||||
|
||||
if "search" in self.request.GET and self.request.GET["search"]:
|
||||
pattern = self.request.GET["search"]
|
||||
|
||||
qs = qs.filter(
|
||||
username__iregex="^" + pattern
|
||||
@ -270,12 +270,7 @@ class PictureUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin, Det
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = self.get_form()
|
||||
self.object = self.get_object()
|
||||
if form.is_valid():
|
||||
return self.form_valid(form)
|
||||
else:
|
||||
print('is_invalid')
|
||||
print(form)
|
||||
return self.form_invalid(form)
|
||||
return self.form_valid(form) if form.is_valid() else self.form_invalid(form)
|
||||
|
||||
def form_valid(self, form):
|
||||
image_field = form.cleaned_data['image']
|
||||
@ -320,8 +315,7 @@ class ManageAuthTokens(LoginRequiredMixin, TemplateView):
|
||||
def get(self, request, *args, **kwargs):
|
||||
if 'regenerate' in request.GET and Token.objects.filter(user=request.user).exists():
|
||||
Token.objects.get(user=self.request.user).delete()
|
||||
return redirect(reverse_lazy('member:auth_token') + "?show",
|
||||
permanent=True)
|
||||
return redirect(reverse_lazy('member:auth_token') + "?show")
|
||||
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
@ -351,8 +345,9 @@ class ClubCreateView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
email="",
|
||||
)
|
||||
|
||||
def form_valid(self, form):
|
||||
return super().form_valid(form)
|
||||
def get_success_url(self):
|
||||
self.object.refresh_from_db()
|
||||
return reverse_lazy("member:club_detail", kwargs={"pk": self.object.pk})
|
||||
|
||||
|
||||
class ClubListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
|
||||
@ -655,7 +650,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
fee += c.membership_fee_paid if user.profile.paid else c.membership_fee_unpaid
|
||||
c = c.parent_club
|
||||
|
||||
if user.note.balance + credit_amount < fee and not Membership.objects.filter(
|
||||
if not soge and user.note.balance + credit_amount < fee and not Membership.objects.filter(
|
||||
club__name="Kfet",
|
||||
user=user,
|
||||
date_start__lte=date.today(),
|
||||
@ -683,7 +678,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
|
||||
if club.membership_end and form.instance.date_start > club.membership_end:
|
||||
form.add_error('user', _("The membership must begin before {:%m-%d-%Y}.")
|
||||
.format(form.instance.club.membership_start))
|
||||
.format(form.instance.club.membership_end))
|
||||
return super().form_invalid(form)
|
||||
|
||||
# Now, all is fine, the membership can be created.
|
||||
@ -719,46 +714,38 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
transaction._force_save = True
|
||||
transaction.save()
|
||||
|
||||
# Parent club memberships are automatically renewed / created.
|
||||
# For example, a Kfet membership creates a BDE membership if it does not exist.
|
||||
form.instance._force_renew_parent = True
|
||||
|
||||
ret = super().form_valid(form)
|
||||
|
||||
if club.name == "BDE":
|
||||
member_role = Role.objects.filter(Q(name="Adhérent BDE") | Q(name="Membre de club")).all()
|
||||
elif club.name == "Kfet":
|
||||
member_role = Role.objects.filter(Q(name="Adhérent Kfet") | Q(name="Membre de club")).all()
|
||||
else:
|
||||
member_role = Role.objects.filter(name="Membre de club").all()
|
||||
member_role = Role.objects.filter(Q(name="Adhérent BDE") | Q(name="Membre de club")).all() \
|
||||
if club.name == "BDE" else Role.objects.filter(Q(name="Adhérent Kfet") | Q(name="Membre de club")).all() \
|
||||
if club.name == "Kfet"else Role.objects.filter(name="Membre de club").all()
|
||||
form.instance.roles.set(member_role)
|
||||
form.instance._force_save = True
|
||||
form.instance.save()
|
||||
|
||||
# If Société générale pays, then we assume that this is the BDE membership, and we auto-renew the
|
||||
# Kfet membership.
|
||||
if soge:
|
||||
# If not already done, create BDE and Kfet memberships
|
||||
bde = Club.objects.get(name="BDE")
|
||||
if soge and club.name == "BDE":
|
||||
kfet = Club.objects.get(name="Kfet")
|
||||
fee = kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
|
||||
|
||||
soge_clubs = [bde, kfet]
|
||||
for club in soge_clubs:
|
||||
fee = club.membership_fee_paid if user.profile.paid else club.membership_fee_unpaid
|
||||
|
||||
# Get current membership, to get the end date
|
||||
old_membership = Membership.objects.filter(
|
||||
club=club,
|
||||
user=user,
|
||||
).order_by("-date_start")
|
||||
|
||||
if old_membership.filter(date_start__gte=club.membership_start).exists():
|
||||
# Membership is already renewed
|
||||
continue
|
||||
# Get current membership, to get the end date
|
||||
old_membership = Membership.objects.filter(
|
||||
club=kfet,
|
||||
user=user,
|
||||
).order_by("-date_start")
|
||||
|
||||
if not old_membership.filter(date_start__gte=kfet.membership_start).exists():
|
||||
# If the membership is not already renewed
|
||||
membership = Membership(
|
||||
club=club,
|
||||
club=kfet,
|
||||
user=user,
|
||||
fee=fee,
|
||||
date_start=max(old_membership.first().date_end + timedelta(days=1), club.membership_start)
|
||||
date_start=max(old_membership.first().date_end + timedelta(days=1), kfet.membership_start)
|
||||
if old_membership.exists() else form.instance.date_start,
|
||||
)
|
||||
membership._force_save = True
|
||||
@ -767,10 +754,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||
membership.refresh_from_db()
|
||||
if old_membership.exists():
|
||||
membership.roles.set(old_membership.get().roles.all())
|
||||
elif c.name == "BDE":
|
||||
membership.roles.set(Role.objects.filter(Q(name="Adhérent BDE") | Q(name="Membre de club")).all())
|
||||
elif c.name == "Kfet":
|
||||
membership.roles.set(Role.objects.filter(Q(name="Adhérent Kfet") | Q(name="Membre de club")).all())
|
||||
membership.roles.set(Role.objects.filter(Q(name="Adhérent Kfet") | Q(name="Membre de club")).all())
|
||||
membership.save()
|
||||
|
||||
return ret
|
||||
@ -830,9 +814,7 @@ class ClubMembersListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableV
|
||||
qs = qs.filter(date_start__lte=timezone.now().today(), date_end__gte=timezone.now().today())
|
||||
|
||||
if "roles" in self.request.GET:
|
||||
if not self.request.GET["roles"]:
|
||||
return qs.none()
|
||||
roles_str = self.request.GET["roles"].replace(' ', '').split(',')
|
||||
roles_str = self.request.GET["roles"].replace(' ', '').split(',') if self.request.GET["roles"] else ['0']
|
||||
roles_int = map(int, roles_str)
|
||||
qs = qs.filter(roles__in=roles_int)
|
||||
|
||||
|
@ -118,7 +118,7 @@ class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
|
||||
|
||||
queryset = super().get_queryset()
|
||||
# Sqlite doesn't support ORDER BY in subqueries
|
||||
queryset = queryset.order_by("username") \
|
||||
queryset = queryset.order_by("name") \
|
||||
if settings.DATABASES[queryset.db]["ENGINE"] == 'django.db.backends.postgresql' else queryset
|
||||
|
||||
alias = self.request.query_params.get("alias", ".*")
|
||||
@ -140,6 +140,9 @@ class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
|
||||
),
|
||||
all=True)
|
||||
|
||||
queryset = queryset if settings.DATABASES[queryset.db]["ENGINE"] == 'django.db.backends.postgresql' \
|
||||
else queryset.order_by("name")
|
||||
|
||||
return queryset.distinct()
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user