mirror of
https://github.com/ae-utbm/sith.git
synced 2026-06-04 23:29:24 +00:00
192 lines
7.3 KiB
Python
192 lines
7.3 KiB
Python
import itertools
|
|
from datetime import timedelta
|
|
|
|
from bs4 import BeautifulSoup
|
|
from django.contrib.auth.models import Permission
|
|
from django.test import TestCase
|
|
from django.urls import reverse
|
|
from django.utils.timezone import localdate, now
|
|
from model_bakery import baker, seq
|
|
from model_bakery.recipe import Recipe
|
|
from pytest_django.asserts import assertRedirects
|
|
|
|
from club.models import Club, ClubRole, Membership
|
|
from core.baker_recipes import subscriber_user
|
|
from core.models import Group, User
|
|
from election.models import Candidature, Election, ElectionList, Role, Vote
|
|
|
|
|
|
class TestApplyResult(TestCase):
|
|
@classmethod
|
|
def setUpTestData(cls):
|
|
# setup is a little bit complicated, but we have to make a whole
|
|
# election to test result application, including the election,
|
|
# the lists, the roles, the candidates and the votes.
|
|
cls.club = baker.make(Club)
|
|
cls.club_roles = baker.make(
|
|
ClubRole,
|
|
club=cls.club,
|
|
is_presidency=iter([True, False, False]),
|
|
is_board=True,
|
|
_quantity=3,
|
|
_bulk_create=True,
|
|
)
|
|
cls.election = baker.make(
|
|
Election,
|
|
clubs=[cls.club],
|
|
edit_groups=[baker.make(Group)],
|
|
end_date=now() - timedelta(minutes=1),
|
|
)
|
|
lists = baker.make(
|
|
ElectionList, election=cls.election, _quantity=2, _bulk_create=True
|
|
)
|
|
role_recipe = Recipe(Role, election=cls.election, title=seq("election role "))
|
|
roles = [
|
|
*role_recipe.make(
|
|
club_role=iter(cls.club_roles), _quantity=len(cls.club_roles)
|
|
),
|
|
role_recipe.make(),
|
|
]
|
|
roles[1].max_choice = 2
|
|
roles[1].save()
|
|
cls.candidatures = baker.make(
|
|
Candidature,
|
|
election_list=itertools.chain(
|
|
itertools.repeat(lists[0], len(roles)),
|
|
itertools.repeat(lists[1], len(roles)),
|
|
),
|
|
role=itertools.cycle(roles),
|
|
user=iter(
|
|
baker.make(
|
|
User, username=seq("user "), _quantity=len(lists) * len(roles)
|
|
)
|
|
),
|
|
_quantity=len(lists) * len(roles),
|
|
_bulk_create=True,
|
|
)
|
|
votes = iter(
|
|
baker.make(
|
|
Vote,
|
|
role=itertools.cycle(roles),
|
|
_quantity=6 * len(roles),
|
|
_bulk_create=True,
|
|
)
|
|
)
|
|
through = []
|
|
for cand in cls.candidatures:
|
|
nb_voices = 4 if cand.election_list_id == lists[0].id else 2
|
|
through.extend(
|
|
[
|
|
Vote.candidature.through(candidature=cand, vote=v)
|
|
for v in itertools.islice(votes, nb_voices)
|
|
]
|
|
)
|
|
Vote.candidature.through.objects.bulk_create(through)
|
|
cls.election.voters.set(baker.make(User, _quantity=8, _bulk_create=True))
|
|
cls.url = reverse(
|
|
"election:apply_result", kwargs={"election_id": cls.election.id}
|
|
)
|
|
|
|
def test_election_result(self):
|
|
# we have made a complex setup, so testing the results is
|
|
# useful to be sure we didn't make mistake when generating data
|
|
assert self.election.results == {
|
|
"election role 1": {
|
|
"blank vote": {"percent": 25.0, "vote": 2},
|
|
"total vote": 8,
|
|
"user 1": {"percent": 50.0, "vote": 4},
|
|
"user 5": {"percent": 25.0, "vote": 2},
|
|
},
|
|
"election role 2": {
|
|
"blank vote": {"percent": 62.5, "vote": 10},
|
|
"total vote": 16,
|
|
"user 2": {"percent": 25.0, "vote": 4},
|
|
"user 6": {"percent": 12.5, "vote": 2},
|
|
},
|
|
"election role 3": {
|
|
"blank vote": {"percent": 25.0, "vote": 2},
|
|
"total vote": 8,
|
|
"user 3": {"percent": 50.0, "vote": 4},
|
|
"user 7": {"percent": 25.0, "vote": 2},
|
|
},
|
|
"election role 4": {
|
|
"blank vote": {"percent": 25.0, "vote": 2},
|
|
"total vote": 8,
|
|
"user 4": {"percent": 50.0, "vote": 4},
|
|
"user 8": {"percent": 25.0, "vote": 2},
|
|
},
|
|
}
|
|
|
|
def test_apply_result(self):
|
|
user = baker.make(
|
|
User, user_permissions=[Permission.objects.get(codename="add_membership")]
|
|
)
|
|
self.client.force_login(user)
|
|
response = self.client.get(self.url)
|
|
soup = BeautifulSoup(response.text, "lxml")
|
|
inputs = soup.find_all("input", attrs={"type": "checkbox"})
|
|
assert all("checked" in i.attrs for i in inputs)
|
|
ids = {int(i.attrs["value"]) for i in inputs}
|
|
assert ids == {
|
|
self.candidatures[0].id,
|
|
self.candidatures[1].id,
|
|
self.candidatures[2].id,
|
|
self.candidatures[5].id,
|
|
}
|
|
response = self.client.post(
|
|
self.url, data={"candidates": ids.difference({self.candidatures[5].id})}
|
|
)
|
|
assertRedirects(response, self.url)
|
|
for candidate in self.candidatures[0:3]:
|
|
assert Membership.objects.filter(
|
|
start_date=localdate(),
|
|
end_date=None,
|
|
user=candidate.user,
|
|
role=candidate.role.club_role,
|
|
).exists()
|
|
assert self.club.members_group.users.contains(candidate.user)
|
|
assert self.club.board_group.users.contains(candidate.user)
|
|
# candidatures[5] was unchecked, so it shouldn't receive a club role
|
|
assert not self.candidatures[5].user.memberships.exists()
|
|
|
|
# now that results are applied, it shouldn't be possible to replay the request
|
|
response = self.client.get(self.url)
|
|
assert "Les résultats de cette élection ont été appliqués" in response.text
|
|
response = self.client.post(self.url, data={"candidates": ids})
|
|
assert response.status_code == 403
|
|
|
|
def test_no_result_to_apply(self):
|
|
self.election.roles.update(club_role=None)
|
|
user = baker.make(
|
|
User, user_permissions=[Permission.objects.get(codename="add_membership")]
|
|
)
|
|
self.client.force_login(user)
|
|
response = self.client.get(self.url)
|
|
soup = BeautifulSoup(response.text, "lxml")
|
|
assert not soup.find("input", attrs={"type": "checkbox"})
|
|
assert "Pas de résultats à appliquer" in response.text
|
|
|
|
def test_access_denied(self):
|
|
user = subscriber_user.make()
|
|
self.client.force_login(user)
|
|
response = self.client.get(self.url)
|
|
assert response.status_code == 403
|
|
response = self.client.post(
|
|
self.url, data={"candidates": [self.candidatures[0].id]}
|
|
)
|
|
assert response.status_code == 403
|
|
|
|
def test_election_not_finished(self):
|
|
user = baker.make(
|
|
User, user_permissions=[Permission.objects.get(codename="add_membership")]
|
|
)
|
|
self.election.end_date = now() + timedelta(minutes=1)
|
|
self.election.save()
|
|
self.client.force_login(user)
|
|
response = self.client.get(self.url)
|
|
assert response.status_code == 403
|
|
response = self.client.post(
|
|
self.url, data={"candidates": [self.candidatures[0].id]}
|
|
)
|
|
assert response.status_code == 403
|