mirror of https://gitlab.crans.org/bde/nk20
452 lines
18 KiB
Python
452 lines
18 KiB
Python
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
import hashlib
|
|
import os
|
|
from datetime import date, timedelta
|
|
|
|
from api.tests import TestAPI
|
|
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 note.models import Alias, NoteSpecial
|
|
from permission.models import Role
|
|
from treasury.models import SogeCredit
|
|
|
|
from ..api.views import ClubViewSet, MembershipViewSet, ProfileViewSet
|
|
from ..models import Club, Membership, Profile
|
|
|
|
"""
|
|
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("apps/member/static/member/img/default_picture.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(date.today()),
|
|
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, user.profile.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(date.today()),
|
|
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, user.profile.get_absolute_url(), 302, 200)
|
|
|
|
response = self.client.get(club.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(date.today()),
|
|
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, user.profile.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ésorièr⋅e 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("apps/member/static/member/img/default_picture.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))
|
|
|
|
|
|
class TestMemberAPI(TestAPI):
|
|
def setUp(self) -> None:
|
|
super().setUp()
|
|
|
|
self.user.profile.registration_valid = True
|
|
self.user.profile.email_confirmed = True
|
|
self.user.profile.phone_number = "0600000000"
|
|
self.user.profile.section = "1A0"
|
|
self.user.profile.department = "A0"
|
|
self.user.profile.address = "Earth"
|
|
self.user.profile.save()
|
|
|
|
self.club = Club.objects.create(
|
|
name="totoclub",
|
|
parent_club=Club.objects.get(name="BDE"),
|
|
membership_start=date(year=1970, month=1, day=1),
|
|
membership_end=date(year=2040, month=1, day=1),
|
|
membership_duration=365 * 10,
|
|
)
|
|
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_club_api(self):
|
|
"""
|
|
Load Club API page and test all filters and permissions
|
|
"""
|
|
self.check_viewset(ClubViewSet, "/api/members/club/")
|
|
|
|
def test_profile_api(self):
|
|
"""
|
|
Load Profile API page and test all filters and permissions
|
|
"""
|
|
self.check_viewset(ProfileViewSet, "/api/members/profile/")
|
|
|
|
def test_membership_api(self):
|
|
"""
|
|
Load Membership API page and test all filters and permissions
|
|
"""
|
|
self.check_viewset(MembershipViewSet, "/api/members/membership/")
|