diff --git a/club/forms.py b/club/forms.py index ab8f5757..da0f5fb7 100644 --- a/club/forms.py +++ b/club/forms.py @@ -196,9 +196,7 @@ class ClubMemberForm(forms.Form): self.request_user = kwargs.pop("request_user") self.club_members = kwargs.pop("club_members", None) if not self.club_members: - self.club_members = ( - self.club.members.filter(end_date=None).order_by("-role").all() - ) + self.club_members = self.club.members.ongoing().order_by("-role").all() self.request_user_membership = self.club.get_membership_for(self.request_user) super().__init__(*args, **kwargs) diff --git a/club/templates/club/club_members.jinja b/club/templates/club/club_members.jinja index a64d43ce..0778b486 100644 --- a/club/templates/club/club_members.jinja +++ b/club/templates/club/club_members.jinja @@ -11,7 +11,7 @@ {{ select_all_checkbox("users_old") }}

{% endif %} - +
diff --git a/club/tests/base.py b/club/tests/base.py index 47f50264..8ae8f3f4 100644 --- a/club/tests/base.py +++ b/club/tests/base.py @@ -6,8 +6,10 @@ from django.test import TestCase from django.urls import reverse from django.utils.timezone import now from model_bakery import baker +from model_bakery.recipe import Recipe from club.models import Club, Membership +from core.baker_recipes import old_subscriber_user, subscriber_user from core.models import User @@ -17,8 +19,9 @@ class TestClub(TestCase): 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` is a dummy club + - `self.club` has two board members : + simple_board_member (role 3) and president (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. @@ -27,44 +30,30 @@ class TestClub(TestCase): @classmethod def setUpTestData(cls): # subscribed users - initial members - cls.skia = User.objects.get(username="skia") - # by default, Skia is in the AE, which creates side effect - cls.skia.memberships.all().delete() + cls.president, cls.simple_board_member = subscriber_user.make(_quantity=2) cls.richard = User.objects.get(username="rbatsbak") - cls.comptable = User.objects.get(username="comptable") cls.sli = User.objects.get(username="sli") - cls.root = User.objects.get(username="root") + cls.root = baker.make(User, is_superuser=True) + cls.old_subscriber = old_subscriber_user.make() + cls.public = baker.make(User) - # subscribed users - not initial members + # subscribed users - not initial member 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.subscriber = subscriber_user.make() cls.ae = Club.objects.get(pk=settings.SITH_MAIN_CLUB_ID) cls.club = baker.make(Club) cls.members_url = reverse("club:club_members", kwargs={"club_id": cls.club.id}) a_month_ago = now() - timedelta(days=30) yesterday = now() - timedelta(days=1) - Membership.objects.create( - club=cls.club, user=cls.skia, start_date=a_month_ago, role=3 + membership_recipe = Recipe(Membership, club=cls.club) + membership_recipe.make( + user=cls.simple_board_member, start_date=a_month_ago, role=3 ) - Membership.objects.create(club=cls.club, user=cls.richard, role=1) - Membership.objects.create( - club=cls.club, user=cls.comptable, start_date=a_month_ago, role=10 - ) - - # sli was a member but isn't anymore - Membership.objects.create( - club=cls.club, - user=cls.sli, - start_date=a_month_ago, - end_date=yesterday, - role=2, + membership_recipe.make(user=cls.richard, role=1) + membership_recipe.make(user=cls.president, start_date=a_month_ago, role=10) + membership_recipe.make( # sli was a member but isn't anymore + user=cls.sli, start_date=a_month_ago, end_date=yesterday, role=2 ) def setUp(self): diff --git a/club/tests/test_membership.py b/club/tests/test_membership.py index dd77e52e..ff668498 100644 --- a/club/tests/test_membership.py +++ b/club/tests/test_membership.py @@ -1,9 +1,12 @@ +from bs4 import BeautifulSoup from django.conf import settings from django.core.cache import cache +from django.db.models import Max from django.urls import reverse from django.utils.timezone import localdate, localtime, now from model_bakery import baker +from club.forms import ClubMemberForm from club.models import Membership from club.tests.base import TestClub from core.baker_recipes import subscriber_user @@ -17,8 +20,8 @@ class TestMembershipQuerySet(TestClub): """ current_members = list(self.club.members.ongoing().order_by("id")) expected = [ - self.skia.memberships.get(club=self.club), - self.comptable.memberships.get(club=self.club), + self.simple_board_member.memberships.get(club=self.club), + self.president.memberships.get(club=self.club), self.richard.memberships.get(club=self.club), ] expected.sort(key=lambda i: i.id) @@ -30,8 +33,8 @@ class TestMembershipQuerySet(TestClub): self.richard.memberships.filter(club=self.club).update(end_date=today) current_members = list(self.club.members.ongoing().order_by("id")) expected = [ - self.skia.memberships.get(club=self.club), - self.comptable.memberships.get(club=self.club), + self.simple_board_member.memberships.get(club=self.club), + self.president.memberships.get(club=self.club), ] expected.sort(key=lambda i: i.id) assert current_members == expected @@ -42,8 +45,8 @@ class TestMembershipQuerySet(TestClub): """ board_members = list(self.club.members.board().order_by("id")) expected = [ - self.skia.memberships.get(club=self.club), - self.comptable.memberships.get(club=self.club), + self.simple_board_member.memberships.get(club=self.club), + self.president.memberships.get(club=self.club), # sli is no more member, but he was in the board self.sli.memberships.get(club=self.club), ] @@ -56,17 +59,17 @@ class TestMembershipQuerySet(TestClub): """ members = list(self.club.members.ongoing().board().order_by("id")) expected = [ - self.skia.memberships.get(club=self.club), - self.comptable.memberships.get(club=self.club), + self.simple_board_member.memberships.get(club=self.club), + self.president.memberships.get(club=self.club), ] expected.sort(key=lambda i: i.id) assert members == 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) + mem_skia = self.simple_board_member.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.simple_board_member.memberships.update(end_date=localtime(now()).date()) assert ( cache.get(f"membership_{mem_skia.club_id}_{mem_skia.user_id}") == "not_member" @@ -104,14 +107,14 @@ class TestMembershipQuerySet(TestClub): 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) + mem_skia = self.simple_board_member.memberships.get(club=self.club) + mem_comptable = self.president.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 + # should delete the subscriptions of simple_board_member and president self.club.members.ongoing().board().delete() for membership in (mem_skia, mem_comptable): @@ -167,36 +170,43 @@ class TestMembership(TestClub): """Test that a GET request return a page where the requested information are displayed. """ - self.client.force_login(self.skia) + self.client.force_login(self.simple_board_member) response = self.client.get(self.members_url) assert response.status_code == 200 - expected_html = ( - "
{% trans %}User{% endtrans %}
" - "" - "" - "" - ) + soup = BeautifulSoup(response.text, "lxml") + table = soup.find("table", id="club_members_table") + assert [r.text for r in table.find("thead").find_all("td")] == [ + "Utilisateur", + "Rôle", + "Description", + "Depuis", + "Marquer comme ancien", + ] + rows = table.find("tbody").find_all("tr") memberships = self.club.members.ongoing().order_by("-role") - input_id = 0 - for membership in memberships.select_related("user"): + for row, membership in zip( + rows, memberships.select_related("user"), strict=False + ): 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()) + user_url = reverse("core:user_profile", args=[user.id]) + cols = row.find_all("td") + user_link = cols[0].find("a") + assert user_link.attrs["href"] == user_url + assert user_link.text == user.get_display_name() + assert cols[1].text == settings.SITH_CLUB_ROLES[membership.role] + assert cols[2].text == membership.description + assert cols[3].text == str(membership.start_date) + + if membership.role <= 3: # 3 is the role of simple_board_member + form_input = cols[4].find("input") + expected_attrs = { + "type": "checkbox", + "name": "users_old", + "value": str(user.id), + } + assert form_input.attrs.items() >= expected_attrs.items() + else: + assert cols[4].find_all() == [] def test_root_add_one_club_member(self): """Test that root users can add members to clubs, one at a time.""" @@ -228,64 +238,61 @@ class TestMembership(TestClub): """Test that users who are not currently subscribed cannot be members of clubs. """ - self.client.force_login(self.root) - response = self.client.post( - self.members_url, - {"users": self.public.id, "role": 1}, - ) - assert not self.public.memberships.filter(club=self.club).exists() - assert '