mirror of
https://github.com/ae-utbm/sith.git
synced 2026-01-22 02:40:12 +00:00
Compare commits
4 Commits
test_elect
...
taiste
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5af894060a | ||
| 679b8dac1c | |||
|
e9eb3dc17d
|
|||
|
|
53a3dc0060 |
@@ -104,7 +104,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
<li x-show="getBasketSize() === 0">{% trans %}This basket is empty{% endtrans %}</li>
|
<li x-show="getBasketSize() === 0">{% trans %}This basket is empty{% endtrans %}</li>
|
||||||
<template x-for="(item, index) in Object.values(basket)">
|
<template x-for="(item, index) in Object.values(basket)" :key="item.product.id">
|
||||||
<li>
|
<li>
|
||||||
<template x-for="error in item.errors">
|
<template x-for="error in item.errors">
|
||||||
<div class="alert alert-red" x-text="error">
|
<div class="alert alert-red" x-text="error">
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ class CandidateForm(forms.ModelForm):
|
|||||||
class VoteForm(forms.Form):
|
class VoteForm(forms.Form):
|
||||||
def __init__(self, election: Election, user: User, *args, **kwargs):
|
def __init__(self, election: Election, user: User, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
if not election.can_vote(user):
|
||||||
|
return
|
||||||
for role in election.roles.all():
|
for role in election.roles.all():
|
||||||
cand = role.candidatures
|
cand = role.candidatures
|
||||||
if role.max_choice > 1:
|
if role.max_choice > 1:
|
||||||
@@ -72,7 +74,6 @@ class VoteForm(forms.Form):
|
|||||||
required=False,
|
required=False,
|
||||||
widget=forms.RadioSelect(),
|
widget=forms.RadioSelect(),
|
||||||
empty_label=_("Blank vote"),
|
empty_label=_("Blank vote"),
|
||||||
blank=True,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,6 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h3 class="election__title">{{ election.title }}</h3>
|
<h3 class="election__title">{{ election.title }}</h3>
|
||||||
{% if user.is_anonymous %}
|
|
||||||
<div class="alert alert-red">
|
|
||||||
{% trans %}You are not logged in, candidate pictures won't display for privacy reasons.{% endtrans %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<p class="election__description">{{ election.description }}</p>
|
<p class="election__description">{{ election.description }}</p>
|
||||||
<hr>
|
<hr>
|
||||||
<section class="election_details">
|
<section class="election_details">
|
||||||
@@ -122,7 +117,7 @@
|
|||||||
{%- if role.max_choice == 1 and show_vote_buttons %}
|
{%- if role.max_choice == 1 and show_vote_buttons %}
|
||||||
<div class="radio-btn">
|
<div class="radio-btn">
|
||||||
{% set input_id = "blank_vote_" + role.id|string %}
|
{% set input_id = "blank_vote_" + role.id|string %}
|
||||||
<input id="{{ input_id }}" type="radio" name="{{ role.title }}" value="" checked>
|
<input id="{{ input_id }}" type="radio" name="{{ role.title }}">
|
||||||
<label for="{{ input_id }}">
|
<label for="{{ input_id }}">
|
||||||
<span>{% trans %}Choose blank vote{% endtrans %}</span>
|
<span>{% trans %}Choose blank vote{% endtrans %}</span>
|
||||||
</label>
|
</label>
|
||||||
@@ -190,7 +185,6 @@
|
|||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
{% if not user.is_anonymous %}
|
|
||||||
<section class="buttons">
|
<section class="buttons">
|
||||||
{%- if (election.can_candidate(user) and election.is_candidature_active) or (user.can_edit(election) and election.is_vote_editable) %}
|
{%- if (election.can_candidate(user) and election.is_candidature_active) or (user.can_edit(election) and election.is_vote_editable) %}
|
||||||
<a class="button" href="{{ url('election:candidate', election_id=object.id) }}">{% trans %}Candidate{% endtrans %}</a>
|
<a class="button" href="{{ url('election:candidate', election_id=object.id) }}">{% trans %}Candidate{% endtrans %}</a>
|
||||||
@@ -213,5 +207,4 @@
|
|||||||
<button class="button button_send" form="vote-form">{% trans %}Submit the vote !{% endtrans %}</button>
|
<button class="button button_send" form="vote-form">{% trans %}Submit the vote !{% endtrans %}</button>
|
||||||
</section>
|
</section>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -115,72 +115,3 @@ def test_election_results():
|
|||||||
"total vote": 100,
|
"total vote": 100,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
|
||||||
def test_election_form(client : Client):
|
|
||||||
election = baker.make(
|
|
||||||
Election,
|
|
||||||
end_date = now() + timedelta(days=1),
|
|
||||||
)
|
|
||||||
group = baker.make(Group)
|
|
||||||
election.vote_groups.add(group)
|
|
||||||
lists = baker.make(ElectionList, election=election, _quantity=2, _bulk_create=True)
|
|
||||||
roles = baker.make(Role, election=election, _quantity=2, _bulk_create=True)
|
|
||||||
users = baker.make(User, _quantity=4, _bulk_create=True)
|
|
||||||
cand = [
|
|
||||||
baker.make(Candidature, role=roles[0], user=users[0], election_list=lists[0]),
|
|
||||||
baker.make(Candidature, role=roles[0], user=users[1], election_list=lists[1]),
|
|
||||||
baker.make(Candidature, role=roles[1], user=users[2], election_list=lists[0]),
|
|
||||||
baker.make(Candidature, role=roles[1], user=users[3], election_list=lists[1]),
|
|
||||||
]
|
|
||||||
url = reverse("election:vote", kwargs={"election_id": election.id})
|
|
||||||
|
|
||||||
votes = [
|
|
||||||
{
|
|
||||||
roles[0].title : "",
|
|
||||||
roles[1].title : str(cand[2].id),
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
roles[0].title : "",
|
|
||||||
roles[1].title : "",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
roles[0].title : str(cand[0].id),
|
|
||||||
roles[1].title : str(cand[2].id),
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
roles[0].title : str(cand[0].id),
|
|
||||||
roles[1].title : str(cand[3].id),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
NB_VOTER = len(votes)
|
|
||||||
voters = [subscriber_user.make() for _ in range(NB_VOTER)]
|
|
||||||
|
|
||||||
for i in range(NB_VOTER):
|
|
||||||
voter = voters[i]
|
|
||||||
voter.groups.add(group)
|
|
||||||
if not election.can_vote(voter):
|
|
||||||
assert False
|
|
||||||
client.force_login(voter)
|
|
||||||
reponse = client.post(url, data = votes[i])
|
|
||||||
assert reponse.status_code == 302
|
|
||||||
|
|
||||||
assert election.results == {
|
|
||||||
roles[0].title: {
|
|
||||||
cand[0].user.username: {"percent": 50.0, "vote": 2},
|
|
||||||
cand[1].user.username: {"percent": 0.0, "vote": 0},
|
|
||||||
"blank vote": {"percent": 50.0, "vote": 2},
|
|
||||||
"total vote": 4,
|
|
||||||
},
|
|
||||||
roles[1].title: {
|
|
||||||
cand[2].user.username: {"percent": 50.0, "vote": 2},
|
|
||||||
cand[3].user.username: {"percent": 25.0, "vote": 1},
|
|
||||||
"blank vote": {"percent": 25.0, "vote": 1},
|
|
||||||
"total vote": 4,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,6 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
from cryptography.utils import cached_property
|
from cryptography.utils import cached_property
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
|
||||||
from django.contrib.auth.mixins import (
|
from django.contrib.auth.mixins import (
|
||||||
LoginRequiredMixin,
|
LoginRequiredMixin,
|
||||||
PermissionRequiredMixin,
|
PermissionRequiredMixin,
|
||||||
@@ -11,9 +10,8 @@ from django.contrib.auth.mixins import (
|
|||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import QuerySet
|
from django.db.models import QuerySet
|
||||||
from django.shortcuts import get_object_or_404, redirect
|
from django.shortcuts import get_object_or_404
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
from django.views.generic import DetailView, ListView
|
from django.views.generic import DetailView, ListView
|
||||||
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
|
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
|
||||||
|
|
||||||
@@ -55,7 +53,7 @@ class ElectionListArchivedView(CanViewMixin, ListView):
|
|||||||
|
|
||||||
|
|
||||||
class ElectionDetailView(CanViewMixin, DetailView):
|
class ElectionDetailView(CanViewMixin, DetailView):
|
||||||
"""Details an election responsibility by responsibility."""
|
"""Details an election responsability by responsability."""
|
||||||
|
|
||||||
model = Election
|
model = Election
|
||||||
template_name = "election/election_detail.jinja"
|
template_name = "election/election_detail.jinja"
|
||||||
@@ -85,7 +83,7 @@ class ElectionDetailView(CanViewMixin, DetailView):
|
|||||||
return super().get(request, *arg, **kwargs)
|
return super().get(request, *arg, **kwargs)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
"""Add additional data to the template."""
|
"""Add additionnal data to the template."""
|
||||||
user: User = self.request.user
|
user: User = self.request.user
|
||||||
return super().get_context_data(**kwargs) | {
|
return super().get_context_data(**kwargs) | {
|
||||||
"election_form": VoteForm(self.object, user),
|
"election_form": VoteForm(self.object, user),
|
||||||
@@ -103,7 +101,7 @@ class ElectionDetailView(CanViewMixin, DetailView):
|
|||||||
|
|
||||||
|
|
||||||
class VoteFormView(LoginRequiredMixin, UserPassesTestMixin, FormView):
|
class VoteFormView(LoginRequiredMixin, UserPassesTestMixin, FormView):
|
||||||
"""Allows users to vote."""
|
"""Alows users to vote."""
|
||||||
|
|
||||||
form_class = VoteForm
|
form_class = VoteForm
|
||||||
template_name = "election/election_detail.jinja"
|
template_name = "election/election_detail.jinja"
|
||||||
@@ -113,9 +111,6 @@ class VoteFormView(LoginRequiredMixin, UserPassesTestMixin, FormView):
|
|||||||
return get_object_or_404(Election, pk=self.kwargs["election_id"])
|
return get_object_or_404(Election, pk=self.kwargs["election_id"])
|
||||||
|
|
||||||
def test_func(self):
|
def test_func(self):
|
||||||
if not self.election.can_vote(self.request.user):
|
|
||||||
return False
|
|
||||||
|
|
||||||
groups = set(self.election.vote_groups.values_list("id", flat=True))
|
groups = set(self.election.vote_groups.values_list("id", flat=True))
|
||||||
if (
|
if (
|
||||||
settings.SITH_GROUP_SUBSCRIBERS_ID in groups
|
settings.SITH_GROUP_SUBSCRIBERS_ID in groups
|
||||||
@@ -155,17 +150,11 @@ class VoteFormView(LoginRequiredMixin, UserPassesTestMixin, FormView):
|
|||||||
self.vote(data)
|
self.vote(data)
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
def form_invalid(self, form):
|
|
||||||
messages.error(self.request, _("Form is invalid"))
|
|
||||||
return redirect(
|
|
||||||
reverse("election:detail", kwargs={"election_id": self.election.id}),
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_success_url(self, **kwargs):
|
def get_success_url(self, **kwargs):
|
||||||
return reverse_lazy("election:detail", kwargs={"election_id": self.election.id})
|
return reverse_lazy("election:detail", kwargs={"election_id": self.election.id})
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
"""Add additional data to the template."""
|
"""Add additionnal data to the template."""
|
||||||
kwargs = super().get_context_data(**kwargs)
|
kwargs = super().get_context_data(**kwargs)
|
||||||
kwargs["object"] = self.election
|
kwargs["object"] = self.election
|
||||||
kwargs["election"] = self.election
|
kwargs["election"] = self.election
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2026-01-14 11:34+0100\n"
|
"POT-Creation-Date: 2025-12-19 23:10+0100\n"
|
||||||
"PO-Revision-Date: 2016-07-18\n"
|
"PO-Revision-Date: 2016-07-18\n"
|
||||||
"Last-Translator: Maréchal <thomas.girod@utbm.fr\n"
|
"Last-Translator: Maréchal <thomas.girod@utbm.fr\n"
|
||||||
"Language-Team: AE info <ae.info@utbm.fr>\n"
|
"Language-Team: AE info <ae.info@utbm.fr>\n"
|
||||||
@@ -4108,11 +4108,6 @@ msgstr "Candidater"
|
|||||||
msgid "Candidature are closed for this election"
|
msgid "Candidature are closed for this election"
|
||||||
msgstr "Les candidatures sont fermées pour cette élection"
|
msgstr "Les candidatures sont fermées pour cette élection"
|
||||||
|
|
||||||
#: election/templates/election/election_detail.jinja
|
|
||||||
msgid ""
|
|
||||||
"You are not logged in, candidate pictures won't display for privacy reasons."
|
|
||||||
msgstr "Vous n'êtes pas connecté, les photos des candidats ne s'afficheront pas pour des raisons de respect de la vie privée."
|
|
||||||
|
|
||||||
#: election/templates/election/election_detail.jinja
|
#: election/templates/election/election_detail.jinja
|
||||||
msgid "Polls close "
|
msgid "Polls close "
|
||||||
msgstr "Votes fermés"
|
msgstr "Votes fermés"
|
||||||
@@ -4188,10 +4183,6 @@ msgstr "au"
|
|||||||
msgid "Polls open from"
|
msgid "Polls open from"
|
||||||
msgstr "Votes ouverts du"
|
msgstr "Votes ouverts du"
|
||||||
|
|
||||||
#: election/views.py
|
|
||||||
msgid "Form is invalid"
|
|
||||||
msgstr "Formulaire invalide"
|
|
||||||
|
|
||||||
#: forum/models.py
|
#: forum/models.py
|
||||||
msgid "is a category"
|
msgid "is a category"
|
||||||
msgstr "est une catégorie"
|
msgstr "est une catégorie"
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ document.addEventListener("alpine:init", () => {
|
|||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
this.downloadPictures.map(async (p: PictureSchema) => {
|
this.downloadPictures.map(async (p: PictureSchema) => {
|
||||||
const imgName = `${p.album}/IMG_${p.date.replace(/[:\-]/g, "_")}${p.name.slice(p.name.lastIndexOf("."))}`;
|
const imgName = `${p.album.name}/IMG_${p.id}_${p.date.replace(/[:\-]/g, "_")}${p.name.slice(p.name.lastIndexOf("."))}`;
|
||||||
return zipWriter.add(imgName, new HttpReader(p.full_size_url), {
|
return zipWriter.add(imgName, new HttpReader(p.full_size_url), {
|
||||||
level: 9,
|
level: 9,
|
||||||
lastModDate: new Date(p.date),
|
lastModDate: new Date(p.date),
|
||||||
|
|||||||
Reference in New Issue
Block a user