# -*- coding:utf-8 -* # # Copyright 2023 © AE UTBM # ae@utbm.fr / ae.info@utbm.fr # # This file is part of the website of the UTBM Student Association (AE UTBM), # https://ae.utbm.fr. # # You can find the source code of the website at https://github.com/ae-utbm/sith3 # # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE # OR WITHIN THE LOCAL FILE "LICENSE" # # from datetime import timedelta from django.conf import settings from django.core.cache import cache from django.test import TestCase from django.utils import timezone, html from django.utils.timezone import now, localtime from django.utils.translation import gettext as _ from django.urls import reverse from django.core.management import call_command from core.models import User, AnonymousUser from club.models import Club, Membership, Mailing from club.forms import MailingForm from sith.settings import SITH_BAR_MANAGER, SITH_MAIN_CLUB_ID class ClubTest(TestCase): """ Set up data for test cases related to clubs and membership The generated dataset is the one created by the populate command, plus the following modifications : - `self.club` is a dummy club recreated for each test - `self.club` has two board members : skia (role 3) and comptable (role 10) - `self.club` has one regular member : richard - `self.club` has one former member : sli (who had role 2) - None of the `self.club` members are in the AE club. """ @classmethod def setUpTestData(cls): # subscribed users - initial members cls.skia = User.objects.get(username="skia") cls.richard = User.objects.get(username="rbatsbak") cls.comptable = User.objects.get(username="comptable") cls.sli = User.objects.get(username="sli") # subscribed users - not initial members cls.krophil = User.objects.get(username="krophil") cls.subscriber = User.objects.get(username="subscriber") # old subscriber cls.old_subscriber = User.objects.get(username="old_subscriber") # not subscribed cls.public = User.objects.get(username="public") cls.ae = Club.objects.filter(pk=SITH_MAIN_CLUB_ID)[0] def setUp(self): # by default, Skia is in the AE, which creates side effect self.skia.memberships.all().delete() # create a fake club self.club = Club.objects.create( name="Fake Club", unix_name="fake-club", address="5 rue de la République, 90000 Belfort", ) self.members_url = reverse( "club:club_members", kwargs={"club_id": self.club.id} ) a_month_ago = now() - timedelta(days=30) yesterday = now() - timedelta(days=1) Membership.objects.create( club=self.club, user=self.skia, start_date=a_month_ago, role=3 ) Membership.objects.create(club=self.club, user=self.richard, role=1) Membership.objects.create( club=self.club, user=self.comptable, start_date=a_month_ago, role=10 ) # sli was a member but isn't anymore Membership.objects.create( club=self.club, user=self.sli, start_date=a_month_ago, end_date=yesterday, role=2, ) cache.clear() class MembershipQuerySetTest(ClubTest): def test_ongoing(self): """ Test that the ongoing queryset method returns the memberships that are not ended. """ current_members = self.club.members.ongoing() expected = [ self.skia.memberships.get(club=self.club), self.comptable.memberships.get(club=self.club), self.richard.memberships.get(club=self.club), ] self.assertEqual(len(current_members), len(expected)) for member in current_members: self.assertIn(member, expected) def test_board(self): """ Test that the board queryset method returns the memberships of user in the club board """ board_members = list(self.club.members.board()) expected = [ self.skia.memberships.get(club=self.club), self.comptable.memberships.get(club=self.club), # sli is no more member, but he was in the board self.sli.memberships.get(club=self.club), ] self.assertEqual(len(board_members), len(expected)) for member in board_members: self.assertIn(member, expected) def test_ongoing_board(self): """ Test that combining ongoing and board returns users who are currently board members of the club """ members = list(self.club.members.ongoing().board()) expected = [ self.skia.memberships.get(club=self.club), self.comptable.memberships.get(club=self.club), ] self.assertEqual(len(members), len(expected)) for member in members: self.assertIn(member, expected) def test_update_invalidate_cache(self): """ Test that the `update` queryset method properly invalidate cache """ mem_skia = self.skia.memberships.get(club=self.club) cache.set(f"membership_{mem_skia.club_id}_{mem_skia.user_id}", mem_skia) self.skia.memberships.update(end_date=localtime(now()).date()) self.assertEqual( cache.get(f"membership_{mem_skia.club_id}_{mem_skia.user_id}"), "not_member" ) mem_richard = self.richard.memberships.get(club=self.club) cache.set( f"membership_{mem_richard.club_id}_{mem_richard.user_id}", mem_richard ) self.richard.memberships.update(role=5) new_mem = self.richard.memberships.get(club=self.club) self.assertNotEqual(new_mem, "not_member") self.assertEqual(new_mem.role, 5) def test_delete_invalidate_cache(self): """ Test that the `delete` queryset properly invalidate cache """ mem_skia = self.skia.memberships.get(club=self.club) mem_comptable = self.comptable.memberships.get(club=self.club) cache.set(f"membership_{mem_skia.club_id}_{mem_skia.user_id}", mem_skia) cache.set( f"membership_{mem_comptable.club_id}_{mem_comptable.user_id}", mem_comptable ) # should delete the subscriptions of skia and comptable self.club.members.ongoing().board().delete() self.assertEqual( cache.get(f"membership_{mem_skia.club_id}_{mem_skia.user_id}"), "not_member" ) self.assertEqual( cache.get(f"membership_{mem_comptable.club_id}_{mem_comptable.user_id}"), "not_member", ) class ClubModelTest(ClubTest): def assert_membership_just_started(self, user: User, role: int): """ Assert that the given membership is active and started today """ membership = user.memberships.ongoing().filter(club=self.club).first() self.assertIsNotNone(membership) self.assertEqual(localtime(now()).date(), membership.start_date) self.assertIsNone(membership.end_date) self.assertEqual(membership.role, role) self.assertEqual(membership.club.get_membership_for(user), membership) member_group = self.club.unix_name + settings.SITH_MEMBER_SUFFIX board_group = self.club.unix_name + settings.SITH_BOARD_SUFFIX self.assertTrue(user.is_in_group(name=member_group)) self.assertTrue(user.is_in_group(name=board_group)) def assert_membership_just_ended(self, user: User): """ Assert that the given user have a membership which ended today """ today = localtime(now()).date() self.assertIsNotNone( user.memberships.filter(club=self.club, end_date=today).first() ) self.assertIsNone(self.club.get_membership_for(user)) def test_access_unauthorized(self): """ Test that users who never subscribed and anonymous users cannot see the page """ response = self.client.post(self.members_url) self.assertEqual(response.status_code, 403) self.client.login(username="public", password="plop") response = self.client.post(self.members_url) self.assertEqual(response.status_code, 403) def test_display(self): """ Test that a GET request return a page where the requested information are displayed. """ self.client.login(username=self.skia.username, password="plop") response = self.client.get(self.members_url) self.assertEqual(response.status_code, 200) expected_html = ( "" "" "" "" ) memberships = self.club.members.ongoing().order_by("-role") input_id = 0 for membership in memberships.select_related("user"): user = membership.user expected_html += ( f"" f"" f"" f"" expected_html += "
UtilisateurRôleDescriptionDepuisMarquer comme ancien
" f"{user.get_display_name()}{settings.SITH_CLUB_ROLES[membership.role]}{membership.description}{membership.start_date}" ) if membership.role <= 3: # 3 is the role of skia expected_html += ( '' ) input_id += 1 expected_html += "
" self.assertInHTML(expected_html, response.content.decode()) def test_root_add_one_club_member(self): """ Test that root users can add members to clubs, one at a time """ self.client.login(username="root", password="plop") response = self.client.post( self.members_url, {"users": self.subscriber.id, "role": 3}, ) self.assertRedirects(response, self.members_url) self.subscriber.refresh_from_db() self.assert_membership_just_started(self.subscriber, role=3) def test_root_add_multiple_club_member(self): """ Test that root users can add multiple members at once to clubs """ self.client.login(username="root", password="plop") response = self.client.post( self.members_url, { "users": f"|{self.subscriber.id}|{self.krophil.id}|", "role": 3, }, ) self.assertRedirects(response, self.members_url) self.subscriber.refresh_from_db() self.assert_membership_just_started(self.subscriber, role=3) self.assert_membership_just_started(self.krophil, role=3) def test_add_unauthorized_members(self): """ Test that users who are not currently subscribed cannot be members of clubs. """ self.client.login(username="root", password="plop") response = self.client.post( self.members_url, {"users": self.public.id, "role": 1}, ) self.assertIsNone(self.public.memberships.filter(club=self.club).first()) self.assertTrue('