diff --git a/election/forms.py b/election/forms.py index 00e76ead..8c318d91 100644 --- a/election/forms.py +++ b/election/forms.py @@ -1,4 +1,8 @@ +from datetime import timedelta + from django import forms +from django.conf import settings +from django.utils.timezone import localtime from django.utils.translation import gettext_lazy as _ from club.forms import ClubRoleChoiceField @@ -149,3 +153,30 @@ class ElectionForm(forms.ModelForm): "start_candidature": SelectDateTime, "end_candidature": SelectDateTime, } + + +class ElectionCreateForm(ElectionForm): + """ElectionForm, but specifically for creation.""" + + def __init__(self, *args, initial: dict | None = None, **kwargs): + # propose sound default timestamps : + # start of candidatures at tomorrow 00h01, start of votes a week later. + start = localtime().replace(hour=0, minute=1, second=0) + timedelta(days=1) + default_initial = { + "start_candidature": start, + "end_candidature": start + timedelta(days=7, minutes=-2), # 23h59 + "start_date": start + timedelta(days=7), # 00h01 + "end_date": start + timedelta(days=14, minutes=-2), # 23h59 + "view_groups": [settings.SITH_GROUP_PUBLIC_ID], + "vote_groups": [settings.SITH_GROUP_SUBSCRIBERS_ID], + "candidature_groups": [settings.SITH_GROUP_SUBSCRIBERS_ID], + } + if initial: + default_initial.update(initial) + super().__init__(*args, initial=default_initial, **kwargs) + + def save(self, commit=True): # noqa: FBT002 + instance = super().save(commit=commit) + if commit: + ElectionList.objects.create(title="Candidat⸱e libre", election=instance) + return instance diff --git a/election/tests.py b/election/tests.py index b4f78ff8..c2429557 100644 --- a/election/tests.py +++ b/election/tests.py @@ -2,13 +2,15 @@ from datetime import timedelta import pytest from django.conf import settings +from django.contrib.auth.models import Permission from django.test import Client, TestCase from django.urls import reverse -from django.utils.timezone import now +from django.utils.timezone import localtime, now from model_bakery import baker from model_bakery.recipe import Recipe from pytest_django.asserts import assertRedirects +from club.models import Club from core.baker_recipes import subscriber_user from core.models import Group, User from election.models import Candidature, Election, ElectionList, Role, Vote @@ -213,3 +215,42 @@ def test_election_results(): "total vote": 100, }, } + + +@pytest.mark.django_db +def test_create_election(client: Client): + user_group = baker.make(Group) + user = baker.make( + User, + user_permissions=[Permission.objects.get(codename="add_election")], + groups=[user_group], + ) + club = baker.make(Club) + client.force_login(user) + url = reverse("election:create") + + res = client.get(url) + assert res.status_code == 200 + + start = localtime().replace(hour=0, minute=1, second=0) + timedelta(days=1) + res = client.post( + url, + data={ + "title": "foo", + "clubs": [club.id], + "view_groups": [user_group.id], + "start_candidature": start, + "end_candidature": start + timedelta(days=7, minutes=-2), + "start_date": start + timedelta(days=7), + "end_date": start + timedelta(days=14, minutes=-2), + }, + ) + election = Election.objects.last() + assertRedirects( + res, reverse("election:detail", kwargs={"election_id": election.id}) + ) + assert election.title == "foo" + assert list(election.clubs.all()) == [club] + assert list(election.election_lists.values_list("title", flat=True)) == [ + "Candidat⸱e libre" + ] diff --git a/election/views.py b/election/views.py index 67b89e78..56fc513c 100644 --- a/election/views.py +++ b/election/views.py @@ -19,6 +19,7 @@ from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateVi from core.auth.mixins import CanEditMixin, CanViewMixin from election.forms import ( CandidateForm, + ElectionCreateForm, ElectionForm, ElectionListForm, RoleForm, @@ -208,7 +209,7 @@ class CandidatureCreateView(LoginRequiredMixin, CreateView): class ElectionCreateView(PermissionRequiredMixin, CreateView): model = Election - form_class = ElectionForm + form_class = ElectionCreateForm template_name = "core/create.jinja" permission_required = "election.add_election"