mirror of
https://github.com/ae-utbm/sith.git
synced 2025-07-10 11:59:23 +00:00
Better usage of cache for groups and clubs related operations (#634)
* Better usage of cache for group retrieval * Cache clearing on object deletion or update * replace signals by save and delete override * add is_anonymous check in is_owned_by Add in many is_owned_by(self, user) methods that user is not anonymous. Since many of those functions do db queries, this should reduce a little bit the load of the db. * Stricter usage of User.is_in_group Constrain the parameters that can be passed to the function to make sure only a str or an int can be used. Also force to explicitly specify if the group id or the group name is used. * write test and correct bugs * remove forgotten populate commands * Correct test
This commit is contained in:
@ -229,9 +229,7 @@ class ClubMemberForm(forms.Form):
|
||||
id__in=[
|
||||
ms.user.id
|
||||
for ms in self.club_members
|
||||
if ms.can_be_edited_by(
|
||||
self.request_user, self.request_user_membership
|
||||
)
|
||||
if ms.can_be_edited_by(self.request_user)
|
||||
]
|
||||
).all(),
|
||||
label=_("Mark as old"),
|
||||
|
203
club/models.py
203
club/models.py
@ -22,10 +22,14 @@
|
||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
#
|
||||
from typing import Optional
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.db import models
|
||||
from django.core import validators
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.core.exceptions import ValidationError, ObjectDoesNotExist
|
||||
from django.db import transaction
|
||||
@ -172,29 +176,34 @@ class Club(models.Model):
|
||||
self.page.parent = self.parent.page
|
||||
self.page.save(force_lock=True)
|
||||
|
||||
@transaction.atomic()
|
||||
def save(self, *args, **kwargs):
|
||||
with transaction.atomic():
|
||||
creation = False
|
||||
old = Club.objects.filter(id=self.id).first()
|
||||
if not old:
|
||||
creation = True
|
||||
else:
|
||||
if old.unix_name != self.unix_name:
|
||||
self._change_unixname(self.unix_name)
|
||||
super(Club, self).save(*args, **kwargs)
|
||||
if creation:
|
||||
board = MetaGroup(name=self.unix_name + settings.SITH_BOARD_SUFFIX)
|
||||
board.save()
|
||||
member = MetaGroup(name=self.unix_name + settings.SITH_MEMBER_SUFFIX)
|
||||
member.save()
|
||||
subscribers = Group.objects.filter(
|
||||
name=settings.SITH_MAIN_MEMBERS_GROUP
|
||||
).first()
|
||||
self.make_home()
|
||||
self.home.edit_groups.set([board])
|
||||
self.home.view_groups.set([member, subscribers])
|
||||
self.home.save()
|
||||
self.make_page()
|
||||
old = Club.objects.filter(id=self.id).first()
|
||||
creation = old is None
|
||||
if not creation and old.unix_name != self.unix_name:
|
||||
self._change_unixname(self.unix_name)
|
||||
super(Club, self).save(*args, **kwargs)
|
||||
if creation:
|
||||
board = MetaGroup(name=self.unix_name + settings.SITH_BOARD_SUFFIX)
|
||||
board.save()
|
||||
member = MetaGroup(name=self.unix_name + settings.SITH_MEMBER_SUFFIX)
|
||||
member.save()
|
||||
subscribers = Group.objects.filter(
|
||||
name=settings.SITH_MAIN_MEMBERS_GROUP
|
||||
).first()
|
||||
self.make_home()
|
||||
self.home.edit_groups.set([board])
|
||||
self.home.view_groups.set([member, subscribers])
|
||||
self.home.save()
|
||||
self.make_page()
|
||||
cache.set(f"sith_club_{self.unix_name}", self)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
super().delete(*args, **kwargs)
|
||||
# Invalidate the cache of this club and of its memberships
|
||||
for membership in self.members.ongoing().select_related("user"):
|
||||
cache.delete(f"membership_{self.id}_{membership.user.id}")
|
||||
cache.delete(f"sith_club_{self.unix_name}")
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@ -209,7 +218,9 @@ class Club(models.Model):
|
||||
"""
|
||||
Method to see if that object can be super edited by the given user
|
||||
"""
|
||||
return user.is_in_group(settings.SITH_MAIN_BOARD_GROUP)
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
return user.is_board_member
|
||||
|
||||
def get_full_logo_url(self):
|
||||
return "https://%s%s" % (settings.SITH_URL, self.logo.url)
|
||||
@ -229,28 +240,89 @@ class Club(models.Model):
|
||||
return False
|
||||
return sub.was_subscribed
|
||||
|
||||
_memberships = {}
|
||||
|
||||
def get_membership_for(self, user):
|
||||
def get_membership_for(self, user: User) -> Optional["Membership"]:
|
||||
"""
|
||||
Returns the current membership the given user
|
||||
Return the current membership the given user.
|
||||
The result is cached.
|
||||
"""
|
||||
try:
|
||||
return Club._memberships[self.id][user.id]
|
||||
except:
|
||||
m = self.members.filter(user=user.id).filter(end_date=None).first()
|
||||
try:
|
||||
Club._memberships[self.id][user.id] = m
|
||||
except:
|
||||
Club._memberships[self.id] = {}
|
||||
Club._memberships[self.id][user.id] = m
|
||||
return m
|
||||
if user.is_anonymous:
|
||||
return None
|
||||
membership = cache.get(f"membership_{self.id}_{user.id}")
|
||||
if membership == "not_member":
|
||||
return None
|
||||
if membership is None:
|
||||
membership = self.members.filter(user=user, end_date=None).first()
|
||||
if membership is None:
|
||||
cache.set(f"membership_{self.id}_{user.id}", "not_member")
|
||||
else:
|
||||
cache.set(f"membership_{self.id}_{user.id}", membership)
|
||||
return membership
|
||||
|
||||
def has_rights_in_club(self, user):
|
||||
m = self.get_membership_for(user)
|
||||
return m is not None and m.role > settings.SITH_MAXIMUM_FREE_ROLE
|
||||
|
||||
|
||||
class MembershipQuerySet(models.QuerySet):
|
||||
def ongoing(self) -> "MembershipQuerySet":
|
||||
"""
|
||||
Filter all memberships which are not finished yet
|
||||
"""
|
||||
# noinspection PyTypeChecker
|
||||
return self.filter(Q(end_date=None) | Q(end_date__gte=timezone.now()))
|
||||
|
||||
def board(self) -> "MembershipQuerySet":
|
||||
"""
|
||||
Filter all memberships where the user is/was in the board.
|
||||
|
||||
Be aware that users who were in the board in the past
|
||||
are included, even if there are no more members.
|
||||
|
||||
If you want to get the users who are currently in the board,
|
||||
mind combining this with the :meth:`ongoing` queryset method
|
||||
"""
|
||||
# noinspection PyTypeChecker
|
||||
return self.filter(role__gt=settings.SITH_MAXIMUM_FREE_ROLE)
|
||||
|
||||
def update(self, **kwargs):
|
||||
"""
|
||||
Work just like the default Django's update() method,
|
||||
but add a cache refresh for the elements of the queryset.
|
||||
|
||||
Be aware that this adds a db query to retrieve the updated objects
|
||||
"""
|
||||
nb_rows = super().update(**kwargs)
|
||||
if nb_rows > 0:
|
||||
# if at least a row was affected, refresh the cache
|
||||
for membership in self.all():
|
||||
if membership.end_date is not None:
|
||||
cache.set(
|
||||
f"membership_{membership.club_id}_{membership.user_id}",
|
||||
"not_member",
|
||||
)
|
||||
else:
|
||||
cache.set(
|
||||
f"membership_{membership.club_id}_{membership.user_id}",
|
||||
membership,
|
||||
)
|
||||
|
||||
def delete(self):
|
||||
"""
|
||||
Work just like the default Django's delete() method,
|
||||
but add a cache invalidation for the elements of the queryset
|
||||
before the deletion.
|
||||
|
||||
Be aware that this adds a db query to retrieve the deleted element.
|
||||
As this first query take place before the deletion operation,
|
||||
it will be performed even if the deletion fails.
|
||||
"""
|
||||
ids = list(self.values_list("club_id", "user_id"))
|
||||
nb_rows, _ = super().delete()
|
||||
if nb_rows > 0:
|
||||
for club_id, user_id in ids:
|
||||
cache.set(f"membership_{club_id}_{user_id}", "not_member")
|
||||
|
||||
|
||||
class Membership(models.Model):
|
||||
"""
|
||||
The Membership class makes the connection between User and Clubs
|
||||
@ -290,6 +362,8 @@ class Membership(models.Model):
|
||||
_("description"), max_length=128, null=False, blank=True
|
||||
)
|
||||
|
||||
objects = MembershipQuerySet.as_manager()
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
self.club.name
|
||||
@ -304,24 +378,34 @@ class Membership(models.Model):
|
||||
"""
|
||||
Method to see if that object can be super edited by the given user
|
||||
"""
|
||||
return user.is_in_group(settings.SITH_MAIN_BOARD_GROUP)
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
return user.is_board_member
|
||||
|
||||
def can_be_edited_by(self, user, membership=None):
|
||||
def can_be_edited_by(self, user: User) -> bool:
|
||||
"""
|
||||
Method to see if that object can be edited by the given user
|
||||
Check if that object can be edited by the given user
|
||||
"""
|
||||
if user.memberships:
|
||||
if membership: # This is for optimisation purpose
|
||||
ms = membership
|
||||
else:
|
||||
ms = user.memberships.filter(club=self.club, end_date=None).first()
|
||||
return (ms and ms.role >= self.role) or user.is_in_group(
|
||||
settings.SITH_MAIN_BOARD_GROUP
|
||||
)
|
||||
return user.is_in_group(settings.SITH_MAIN_BOARD_GROUP)
|
||||
if user.is_root or user.is_board_member:
|
||||
return True
|
||||
membership = self.club.get_membership_for(user)
|
||||
if membership is not None and membership.role >= self.role:
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("club:club_members", kwargs={"club_id": self.club.id})
|
||||
return reverse("club:club_members", kwargs={"club_id": self.club_id})
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
if self.end_date is None:
|
||||
cache.set(f"membership_{self.club_id}_{self.user_id}", self)
|
||||
else:
|
||||
cache.set(f"membership_{self.club_id}_{self.user_id}", "not_member")
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
super().delete(*args, **kwargs)
|
||||
cache.delete(f"membership_{self.club_id}_{self.user_id}")
|
||||
|
||||
|
||||
class Mailing(models.Model):
|
||||
@ -374,14 +458,12 @@ class Mailing(models.Model):
|
||||
return self.email + "@" + settings.SITH_MAILING_DOMAIN
|
||||
|
||||
def can_moderate(self, user):
|
||||
return user.is_root or user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
||||
return user.is_root or user.is_com_admin
|
||||
|
||||
def is_owned_by(self, user):
|
||||
return (
|
||||
user.is_in_group(self)
|
||||
or user.is_root
|
||||
or user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
||||
)
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
return user.is_root or user.is_com_admin
|
||||
|
||||
def can_view(self, user):
|
||||
return self.club.has_rights_in_club(user)
|
||||
@ -389,9 +471,8 @@ class Mailing(models.Model):
|
||||
def can_be_edited_by(self, user):
|
||||
return self.club.has_rights_in_club(user)
|
||||
|
||||
def delete(self):
|
||||
for sub in self.subscriptions.all():
|
||||
sub.delete()
|
||||
def delete(self, *args, **kwargs):
|
||||
self.subscriptions.all().delete()
|
||||
super(Mailing, self).delete()
|
||||
|
||||
def fetch_format(self):
|
||||
@ -464,10 +545,12 @@ class MailingSubscription(models.Model):
|
||||
super(MailingSubscription, self).clean()
|
||||
|
||||
def is_owned_by(self, user):
|
||||
if user.is_anonymous:
|
||||
return False
|
||||
return (
|
||||
self.mailing.club.has_rights_in_club(user)
|
||||
or user.is_root
|
||||
or self.user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
||||
or self.user.is_com_admin
|
||||
)
|
||||
|
||||
def can_be_edited_by(self, user):
|
||||
|
@ -13,13 +13,15 @@
|
||||
{% endif %}
|
||||
<table>
|
||||
<thead>
|
||||
<td>{% trans %}User{% endtrans %}</td>
|
||||
<td>{% trans %}Role{% endtrans %}</td>
|
||||
<td>{% trans %}Description{% endtrans %}</td>
|
||||
<td>{% trans %}Since{% endtrans %}</td>
|
||||
{% if users_old %}
|
||||
<td>{% trans %}Mark as old{% endtrans %}</td>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td>{% trans %}User{% endtrans %}</td>
|
||||
<td>{% trans %}Role{% endtrans %}</td>
|
||||
<td>{% trans %}Description{% endtrans %}</td>
|
||||
<td>{% trans %}Since{% endtrans %}</td>
|
||||
{% if users_old %}
|
||||
<td>{% trans %}Mark as old{% endtrans %}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for m in members %}
|
||||
|
770
club/tests.py
770
club/tests.py
@ -13,376 +13,564 @@
|
||||
# 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 django.core.exceptions import ValidationError, NON_FIELD_ERRORS
|
||||
|
||||
from core.models import User
|
||||
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
|
||||
|
||||
|
||||
# Create your tests here.
|
||||
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):
|
||||
self.skia = User.objects.filter(username="skia").first()
|
||||
self.rbatsbak = User.objects.filter(username="rbatsbak").first()
|
||||
self.guy = User.objects.filter(username="guy").first()
|
||||
self.bdf = Club.objects.filter(unix_name=SITH_BAR_MANAGER["unix_name"]).first()
|
||||
# by default, Skia is in the AE, which creates side effect
|
||||
self.skia.memberships.all().delete()
|
||||
|
||||
def test_create_add_user_to_club_from_root_ok(self):
|
||||
self.client.login(username="root", password="plop")
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": self.skia.id, "start_date": "12/06/2016", "role": 3},
|
||||
# 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",
|
||||
)
|
||||
response = self.client.get(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id})
|
||||
self.members_url = reverse(
|
||||
"club:club_members", kwargs={"club_id": self.club.id}
|
||||
)
|
||||
self.assertTrue(response.status_code == 200)
|
||||
self.assertTrue(
|
||||
"S' Kia</a></td>\\n <td>Responsable info</td>"
|
||||
in str(response.content)
|
||||
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
|
||||
)
|
||||
|
||||
def test_create_add_multiple_user_to_club_from_root_ok(self):
|
||||
# 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 = (
|
||||
"<table><thead><tr>"
|
||||
"<td>Utilisateur</td><td>Rôle</td><td>Description</td>"
|
||||
"<td>Depuis</td><td>Marquer comme ancien</td>"
|
||||
"</tr></thead><tbody>"
|
||||
)
|
||||
memberships = self.club.members.ongoing().order_by("-role")
|
||||
input_id = 0
|
||||
for membership in memberships.select_related("user"):
|
||||
user = membership.user
|
||||
expected_html += (
|
||||
f"<tr><td><a href=\"{reverse('core:user_profile', args=[user.id])}\">"
|
||||
f"{user.get_display_name()}</a></td>"
|
||||
f"<td>{settings.SITH_CLUB_ROLES[membership.role]}</td>"
|
||||
f"<td>{membership.description}</td>"
|
||||
f"<td>{membership.start_date}</td><td>"
|
||||
)
|
||||
if membership.role <= 3: # 3 is the role of skia
|
||||
expected_html += (
|
||||
'<input type="checkbox" name="users_old" '
|
||||
f'value="{user.id}" '
|
||||
f'id="id_users_old_{input_id}">'
|
||||
)
|
||||
input_id += 1
|
||||
expected_html += "</td></tr>"
|
||||
expected_html += "</tbody></table>"
|
||||
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")
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
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": "|%d|%d|" % (self.skia.id, self.rbatsbak.id),
|
||||
"start_date": "12/06/2016",
|
||||
"users": f"|{self.subscriber.id}|{self.krophil.id}|",
|
||||
"role": 3,
|
||||
},
|
||||
)
|
||||
response = self.client.get(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id})
|
||||
)
|
||||
self.assertTrue(response.status_code == 200)
|
||||
content = str(response.content)
|
||||
self.assertTrue(
|
||||
"S' Kia</a></td>\\n <td>Responsable info</td>"
|
||||
in content
|
||||
)
|
||||
self.assertTrue(
|
||||
"Richard Batsbak</a></td>\\n <td>Responsable info</td>"
|
||||
in content
|
||||
)
|
||||
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_create_add_user_to_club_from_root_fail_not_subscriber(self):
|
||||
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(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": self.guy.id, "start_date": "12/06/2016", "role": 3},
|
||||
self.members_url,
|
||||
{"users": self.public.id, "role": 1},
|
||||
)
|
||||
self.assertTrue(response.status_code == 200)
|
||||
self.assertIsNone(self.public.memberships.filter(club=self.club).first())
|
||||
self.assertTrue('<ul class="errorlist"><li>' in str(response.content))
|
||||
response = self.client.get(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id})
|
||||
)
|
||||
self.assertFalse(
|
||||
"Guy Carlier</a></td>\\n <td>Responsable info</td>"
|
||||
in str(response.content)
|
||||
)
|
||||
|
||||
def test_create_add_user_to_club_from_root_fail_already_in_club(self):
|
||||
response = self.client.post(
|
||||
self.members_url,
|
||||
{"users": self.old_subscriber.id, "role": 1},
|
||||
)
|
||||
self.assertIsNone(self.public.memberships.filter(club=self.club).first())
|
||||
self.assertIsNone(self.club.get_membership_for(self.public))
|
||||
self.assertTrue('<ul class="errorlist"><li>' in str(response.content))
|
||||
|
||||
def test_add_members_already_members(self):
|
||||
"""
|
||||
Test that users who are already members of a club
|
||||
cannot be added again to this club
|
||||
"""
|
||||
self.client.login(username="root", password="plop")
|
||||
current_membership = self.skia.memberships.ongoing().get(club=self.club)
|
||||
nb_memberships = self.skia.memberships.count()
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": self.skia.id, "start_date": "12/06/2016", "role": 3},
|
||||
)
|
||||
response = self.client.get(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id})
|
||||
)
|
||||
self.assertTrue(
|
||||
"S' Kia</a></td>\\n <td>Responsable info</td>"
|
||||
in str(response.content)
|
||||
)
|
||||
response = self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": self.skia.id, "start_date": "12/06/2016", "role": 4},
|
||||
)
|
||||
self.assertTrue(response.status_code == 200)
|
||||
self.assertFalse(
|
||||
"S' Kia</a></td>\\n <td>Secrétaire</td>"
|
||||
in str(response.content)
|
||||
self.members_url,
|
||||
{"users": self.skia.id, "role": current_membership.role + 1},
|
||||
)
|
||||
self.skia.refresh_from_db()
|
||||
self.assertEqual(nb_memberships, self.skia.memberships.count())
|
||||
new_membership = self.skia.memberships.ongoing().get(club=self.club)
|
||||
self.assertEqual(current_membership, new_membership)
|
||||
self.assertEqual(self.club.get_membership_for(self.skia), new_membership)
|
||||
|
||||
def test_create_add_user_non_existent_to_club_from_root_fail(self):
|
||||
def test_add_not_existing_users(self):
|
||||
"""
|
||||
Test that not existing users cannot be added in clubs.
|
||||
If one user in the request is invalid, no membership creation at all
|
||||
can take place.
|
||||
"""
|
||||
self.client.login(username="root", password="plop")
|
||||
nb_memberships = self.club.members.count()
|
||||
response = self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": [9999], "start_date": "12/06/2016", "role": 3},
|
||||
self.members_url,
|
||||
{"users": [9999], "role": 1},
|
||||
)
|
||||
self.assertTrue(response.status_code == 200)
|
||||
content = str(response.content)
|
||||
self.assertTrue('<ul class="errorlist"><li>' in content)
|
||||
self.assertFalse("<td>Responsable info</td>" in content)
|
||||
self.client.login(username="root", password="plop")
|
||||
self.assertContains(response, '<ul class="errorlist"><li>')
|
||||
self.club.refresh_from_db()
|
||||
self.assertEqual(self.club.members.count(), nb_memberships)
|
||||
response = self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
self.members_url,
|
||||
{
|
||||
"users": "|%d|%d|" % (self.skia.id, 9999),
|
||||
"users": f"|{self.subscriber.id}|{9999}|",
|
||||
"start_date": "12/06/2016",
|
||||
"role": 3,
|
||||
},
|
||||
)
|
||||
self.assertTrue(response.status_code == 200)
|
||||
content = str(response.content)
|
||||
self.assertTrue('<ul class="errorlist"><li>' in content)
|
||||
self.assertFalse("<td>Responsable info</td>" in content)
|
||||
self.assertContains(response, '<ul class="errorlist"><li>')
|
||||
self.club.refresh_from_db()
|
||||
self.assertEqual(self.club.members.count(), nb_memberships)
|
||||
|
||||
def test_create_add_user_to_club_from_skia_ok(self):
|
||||
self.client.login(username="root", password="plop")
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": self.skia.id, "start_date": "12/06/2016", "role": 10},
|
||||
def test_president_add_members(self):
|
||||
"""
|
||||
Test that the president of the club can add members
|
||||
"""
|
||||
president = self.club.members.get(role=10).user
|
||||
nb_club_membership = self.club.members.count()
|
||||
nb_subscriber_memberships = self.subscriber.memberships.count()
|
||||
self.client.login(username=president.username, password="plop")
|
||||
response = self.client.post(
|
||||
self.members_url,
|
||||
{"users": self.subscriber.id, "role": 9},
|
||||
)
|
||||
self.client.login(username="skia", password="plop")
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": self.rbatsbak.id, "start_date": "12/06/2016", "role": 9},
|
||||
self.assertRedirects(response, self.members_url)
|
||||
self.club.refresh_from_db()
|
||||
self.subscriber.refresh_from_db()
|
||||
self.assertEqual(self.club.members.count(), nb_club_membership + 1)
|
||||
self.assertEqual(
|
||||
self.subscriber.memberships.count(), nb_subscriber_memberships + 1
|
||||
)
|
||||
response = self.client.get(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id})
|
||||
self.assert_membership_just_started(self.subscriber, role=9)
|
||||
|
||||
def test_add_member_greater_role(self):
|
||||
"""
|
||||
Test that a member of the club member cannot create
|
||||
a membership with a greater role than its own.
|
||||
"""
|
||||
self.client.login(username=self.skia.username, password="plop")
|
||||
nb_memberships = self.club.members.count()
|
||||
response = self.client.post(
|
||||
self.members_url,
|
||||
{"users": self.subscriber.id, "role": 10},
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIn(
|
||||
"""Richard Batsbak</a></td>\n <td>Vice-Président⸱e</td>""",
|
||||
self.assertInHTML(
|
||||
"<li>Vous n'avez pas la permission de faire cela</li>",
|
||||
response.content.decode(),
|
||||
)
|
||||
self.club.refresh_from_db()
|
||||
self.assertEqual(nb_memberships, self.club.members.count())
|
||||
self.assertIsNone(self.subscriber.memberships.filter(club=self.club).first())
|
||||
|
||||
def test_create_add_user_to_club_from_richard_fail(self):
|
||||
self.client.login(username="root", password="plop")
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": self.rbatsbak.id, "start_date": "12/06/2016", "role": 3},
|
||||
)
|
||||
self.client.login(username="rbatsbak", password="plop")
|
||||
response = self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": self.skia.id, "start_date": "12/06/2016", "role": 10},
|
||||
)
|
||||
self.assertTrue(response.status_code == 200)
|
||||
self.assertTrue(
|
||||
"<li>Vous n'avez pas la permission de faire cela</li>"
|
||||
in str(response.content)
|
||||
)
|
||||
|
||||
def test_role_required_if_users_specified(self):
|
||||
def test_add_member_without_role(self):
|
||||
"""
|
||||
Test that trying to add members without specifying their role fails
|
||||
"""
|
||||
self.client.login(username="root", password="plop")
|
||||
response = self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": self.rbatsbak.id, "start_date": "12/06/2016"},
|
||||
self.members_url,
|
||||
{"users": self.subscriber.id, "start_date": "12/06/2016"},
|
||||
)
|
||||
self.assertTrue(
|
||||
'<ul class="errorlist"><li>Vous devez choisir un r' in str(response.content)
|
||||
)
|
||||
|
||||
def test_mark_old_user_to_club_from_skia_ok(self):
|
||||
self.client.login(username="root", password="plop")
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{
|
||||
"users": "|%d|%d|" % (self.skia.id, self.rbatsbak.id),
|
||||
"start_date": "12/06/2016",
|
||||
"role": 3,
|
||||
},
|
||||
)
|
||||
def test_end_membership_self(self):
|
||||
"""
|
||||
Test that a member can end its own membership
|
||||
"""
|
||||
self.client.login(username="skia", password="plop")
|
||||
response = self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users_old": self.rbatsbak.id},
|
||||
)
|
||||
self.assertTrue(response.status_code == 302)
|
||||
|
||||
response = self.client.get(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id})
|
||||
)
|
||||
self.assertTrue(response.status_code == 200)
|
||||
content = str(response.content)
|
||||
self.assertFalse(
|
||||
"Richard Batsbak</a></td>\\n <td>Responsable info</td>"
|
||||
in content
|
||||
)
|
||||
self.assertTrue(
|
||||
"S' Kia</a></td>\\n <td>Responsable info</td>"
|
||||
in content
|
||||
)
|
||||
|
||||
# Skia is board member so he should be able to mark as old even without being in the club
|
||||
response = self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
self.client.post(
|
||||
self.members_url,
|
||||
{"users_old": self.skia.id},
|
||||
)
|
||||
self.skia.refresh_from_db()
|
||||
self.assert_membership_just_ended(self.skia)
|
||||
|
||||
def test_end_membership_lower_role(self):
|
||||
"""
|
||||
Test that board members of the club can end memberships
|
||||
of users with lower roles
|
||||
"""
|
||||
# remainder : skia has role 3, comptable has role 10, richard has role 1
|
||||
self.client.login(username=self.skia.username, password="plop")
|
||||
response = self.client.post(
|
||||
self.members_url,
|
||||
{"users_old": self.richard.id},
|
||||
)
|
||||
self.assertRedirects(response, self.members_url)
|
||||
self.club.refresh_from_db()
|
||||
self.assert_membership_just_ended(self.richard)
|
||||
|
||||
def test_end_membership_higher_role(self):
|
||||
"""
|
||||
Test that board members of the club cannot end memberships
|
||||
of users with higher roles
|
||||
"""
|
||||
membership = self.comptable.memberships.filter(club=self.club).first()
|
||||
self.client.login(username=self.skia.username, password="plop")
|
||||
self.client.post(
|
||||
self.members_url,
|
||||
{"users_old": self.comptable.id},
|
||||
)
|
||||
self.club.refresh_from_db()
|
||||
new_membership = self.club.get_membership_for(self.comptable)
|
||||
self.assertIsNotNone(new_membership)
|
||||
self.assertEqual(new_membership, membership)
|
||||
|
||||
membership = self.comptable.memberships.filter(club=self.club).first()
|
||||
self.assertIsNone(membership.end_date)
|
||||
|
||||
def test_end_membership_as_main_club_board(self):
|
||||
"""
|
||||
Test that board members of the main club can end the membership
|
||||
of anyone
|
||||
"""
|
||||
# make subscriber a board member
|
||||
self.subscriber.memberships.all().delete()
|
||||
Membership.objects.create(club=self.ae, user=self.subscriber, role=3)
|
||||
|
||||
nb_memberships = self.club.members.count()
|
||||
self.client.login(username=self.subscriber.username, password="plop")
|
||||
response = self.client.post(
|
||||
self.members_url,
|
||||
{"users_old": self.comptable.id},
|
||||
)
|
||||
self.assertRedirects(response, self.members_url)
|
||||
self.assert_membership_just_ended(self.comptable)
|
||||
self.assertEqual(self.club.members.ongoing().count(), nb_memberships - 1)
|
||||
|
||||
def test_end_membership_as_root(self):
|
||||
"""
|
||||
Test that root users can end the membership of anyone
|
||||
"""
|
||||
nb_memberships = self.club.members.count()
|
||||
self.client.login(username="root", password="plop")
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": self.rbatsbak.id, "start_date": "12/06/2016", "role": 3},
|
||||
)
|
||||
self.client.login(username="skia", password="plop")
|
||||
response = self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users_old": self.rbatsbak.id},
|
||||
)
|
||||
self.assertFalse(
|
||||
"Richard Batsbak</a></td>\\n <td>Responsable info</td>"
|
||||
in str(response.content)
|
||||
self.members_url,
|
||||
{"users_old": [self.comptable.id]},
|
||||
)
|
||||
self.assertRedirects(response, self.members_url)
|
||||
self.assert_membership_just_ended(self.comptable)
|
||||
self.assertEqual(self.club.members.ongoing().count(), nb_memberships - 1)
|
||||
self.assertEqual(self.club.members.count(), nb_memberships)
|
||||
|
||||
def test_mark_old_multiple_users_from_skia_ok(self):
|
||||
self.client.login(username="root", password="plop")
|
||||
def test_end_membership_as_foreigner(self):
|
||||
"""
|
||||
Test that users who are not in this club cannot end its memberships
|
||||
"""
|
||||
nb_memberships = self.club.members.count()
|
||||
membership = self.richard.memberships.filter(club=self.club).first()
|
||||
self.client.login(username="subscriber", password="root")
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{
|
||||
"users": "|%d|%d|" % (self.skia.id, self.rbatsbak.id),
|
||||
"start_date": "12/06/2016",
|
||||
"role": 3,
|
||||
},
|
||||
self.members_url,
|
||||
{"users_old": [self.richard.id]},
|
||||
)
|
||||
self.client.login(username="skia", password="plop")
|
||||
response = self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users_old": [self.rbatsbak.id, self.skia.id]},
|
||||
)
|
||||
self.assertTrue(response.status_code == 302)
|
||||
# nothing should have changed
|
||||
new_mem = self.club.get_membership_for(self.richard)
|
||||
self.assertIsNotNone(new_mem)
|
||||
self.assertEqual(self.club.members.count(), nb_memberships)
|
||||
self.assertEqual(membership, new_mem)
|
||||
|
||||
response = self.client.get(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id})
|
||||
)
|
||||
self.assertTrue(response.status_code == 200)
|
||||
content = str(response.content)
|
||||
self.assertFalse(
|
||||
"Richard Batsbak</a></td>\\n <td>Responsable info</td>"
|
||||
in content
|
||||
)
|
||||
self.assertFalse(
|
||||
"S' Kia</a></td>\\n <td>Responsable info</td>"
|
||||
in content
|
||||
)
|
||||
def test_delete_remove_from_meta_group(self):
|
||||
"""
|
||||
Test that when a club is deleted, all its members are removed from the
|
||||
associated metagroup
|
||||
"""
|
||||
memberships = self.club.members.select_related("user")
|
||||
users = [membership.user for membership in memberships]
|
||||
meta_group = self.club.unix_name + settings.SITH_MEMBER_SUFFIX
|
||||
|
||||
def test_mark_old_user_to_club_from_richard_ok(self):
|
||||
self.client.login(username="root", password="plop")
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{
|
||||
"users": "|%d|%d|" % (self.skia.id, self.rbatsbak.id),
|
||||
"start_date": "12/06/2016",
|
||||
"role": 3,
|
||||
},
|
||||
)
|
||||
self.club.delete()
|
||||
for user in users:
|
||||
self.assertFalse(user.is_in_group(name=meta_group))
|
||||
|
||||
# Test with equal rights
|
||||
self.client.login(username="rbatsbak", password="plop")
|
||||
response = self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users_old": self.skia.id},
|
||||
)
|
||||
self.assertTrue(response.status_code == 302)
|
||||
def test_add_to_meta_group(self):
|
||||
"""
|
||||
Test that when a membership begins, the user is added to the meta group
|
||||
"""
|
||||
group_members = self.club.unix_name + settings.SITH_MEMBER_SUFFIX
|
||||
board_members = self.club.unix_name + settings.SITH_BOARD_SUFFIX
|
||||
self.assertFalse(self.subscriber.is_in_group(name=group_members))
|
||||
self.assertFalse(self.subscriber.is_in_group(name=board_members))
|
||||
Membership.objects.create(club=self.club, user=self.subscriber, role=3)
|
||||
self.assertTrue(self.subscriber.is_in_group(name=group_members))
|
||||
self.assertTrue(self.subscriber.is_in_group(name=board_members))
|
||||
|
||||
response = self.client.get(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id})
|
||||
)
|
||||
self.assertTrue(response.status_code == 200)
|
||||
content = str(response.content)
|
||||
self.assertTrue(
|
||||
"Richard Batsbak</a></td>\\n <td>Responsable info</td>"
|
||||
in content
|
||||
)
|
||||
self.assertFalse(
|
||||
"S' Kia</a></td>\\n <td>Responsable info</td>"
|
||||
in content
|
||||
)
|
||||
def test_remove_from_meta_group(self):
|
||||
"""
|
||||
Test that when a membership ends, the user is removed from meta group
|
||||
"""
|
||||
group_members = self.club.unix_name + settings.SITH_MEMBER_SUFFIX
|
||||
board_members = self.club.unix_name + settings.SITH_BOARD_SUFFIX
|
||||
self.assertTrue(self.comptable.is_in_group(name=group_members))
|
||||
self.assertTrue(self.comptable.is_in_group(name=board_members))
|
||||
self.comptable.memberships.update(end_date=localtime(now()))
|
||||
self.assertFalse(self.comptable.is_in_group(name=group_members))
|
||||
self.assertFalse(self.comptable.is_in_group(name=board_members))
|
||||
|
||||
# Test with lower rights
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": self.skia.id, "start_date": "12/06/2016", "role": 0},
|
||||
)
|
||||
def test_club_owner(self):
|
||||
"""
|
||||
Test that a club is owned only by board members of the main club
|
||||
"""
|
||||
anonymous = AnonymousUser()
|
||||
self.assertFalse(self.club.is_owned_by(anonymous))
|
||||
self.assertFalse(self.club.is_owned_by(self.subscriber))
|
||||
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users_old": self.skia.id},
|
||||
)
|
||||
response = self.client.get(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id})
|
||||
)
|
||||
self.assertTrue(response.status_code == 200)
|
||||
content = str(response.content)
|
||||
self.assertTrue(
|
||||
"Richard Batsbak</a></td>\\n <td>Responsable info</td>"
|
||||
in content
|
||||
)
|
||||
self.assertFalse(
|
||||
"S' Kia</a></td>\\n <td>Curieux</td>" in content
|
||||
)
|
||||
|
||||
def test_mark_old_user_to_club_from_richard_fail(self):
|
||||
self.client.login(username="root", password="plop")
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": self.skia.id, "start_date": "12/06/2016", "role": 3},
|
||||
)
|
||||
|
||||
# Test with richard outside of the club
|
||||
self.client.login(username="rbatsbak", password="plop")
|
||||
response = self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users_old": self.skia.id},
|
||||
)
|
||||
self.assertTrue(response.status_code == 200)
|
||||
|
||||
response = self.client.get(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id})
|
||||
)
|
||||
self.assertTrue(response.status_code == 200)
|
||||
self.assertTrue(
|
||||
"S' Kia</a></td>\\n <td>Responsable info</td>"
|
||||
in str(response.content)
|
||||
)
|
||||
|
||||
# Test with lower rights
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users": self.rbatsbak.id, "start_date": "12/06/2016", "role": 0},
|
||||
)
|
||||
|
||||
self.client.post(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id}),
|
||||
{"users_old": self.skia.id},
|
||||
)
|
||||
response = self.client.get(
|
||||
reverse("club:club_members", kwargs={"club_id": self.bdf.id})
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
content = response.content.decode()
|
||||
self.assertIn(
|
||||
"Richard Batsbak</a></td>\n <td>Curieux⸱euse</td>",
|
||||
content,
|
||||
)
|
||||
self.assertIn(
|
||||
"S' Kia</a></td>\n <td>Responsable info</td>",
|
||||
content,
|
||||
)
|
||||
# make sli a board member
|
||||
self.sli.memberships.all().delete()
|
||||
Membership(club=self.ae, user=self.sli, role=3).save()
|
||||
self.assertTrue(self.club.is_owned_by(self.sli))
|
||||
|
||||
|
||||
class MailingFormTest(TestCase):
|
||||
"""Perform validation tests for MailingForm"""
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.skia = User.objects.filter(username="skia").first()
|
||||
cls.rbatsbak = User.objects.filter(username="rbatsbak").first()
|
||||
cls.krophil = User.objects.filter(username="krophil").first()
|
||||
cls.comunity = User.objects.filter(username="comunity").first()
|
||||
cls.bdf = Club.objects.filter(unix_name=SITH_BAR_MANAGER["unix_name"]).first()
|
||||
|
||||
def setUp(self):
|
||||
self.skia = User.objects.filter(username="skia").first()
|
||||
self.rbatsbak = User.objects.filter(username="rbatsbak").first()
|
||||
self.krophil = User.objects.filter(username="krophil").first()
|
||||
self.comunity = User.objects.filter(username="comunity").first()
|
||||
self.bdf = Club.objects.filter(unix_name=SITH_BAR_MANAGER["unix_name"]).first()
|
||||
Membership(
|
||||
user=self.rbatsbak,
|
||||
club=self.bdf,
|
||||
|
@ -306,9 +306,7 @@ class ClubMembersView(ClubTabsMixin, CanViewMixin, DetailFormView):
|
||||
return resp
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.members = (
|
||||
self.get_object().members.filter(end_date=None).order_by("-role").all()
|
||||
)
|
||||
self.members = self.get_object().members.ongoing().order_by("-role")
|
||||
return super(ClubMembersView, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_success_url(self, **kwargs):
|
||||
|
Reference in New Issue
Block a user