nk20/apps/member/tests/test_memberships.py

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é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("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/")