Skip to content

Commit

Permalink
polls: add new signal which is called after a user voted on a poll
Browse files Browse the repository at this point in the history
  • Loading branch information
goapunk committed Nov 13, 2024
1 parent 79867f6 commit fc7d8fc
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 1 deletion.
4 changes: 4 additions & 0 deletions adhocracy4/polls/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from .models import Question
from .models import Vote
from .serializers import PollSerializer
from .signals import poll_voted


class PollViewSet(
Expand Down Expand Up @@ -178,6 +179,9 @@ def vote(self, request, pk):
self.save_vote(question, vote_data, creator, content_id)

poll = self.get_object()
poll_voted.send(
sender=self.__class__, poll=poll, creator=creator, content_id=content_id
)
poll_serializer = self.get_serializer(poll)
poll_data = self.add_terms_of_use_info(request, poll_serializer.data)
if not self.request.user.is_authenticated:
Expand Down
9 changes: 9 additions & 0 deletions adhocracy4/polls/signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.dispatch import Signal

"""Signal which is called after a user participated in a poll. The signal
receives the following arguments:
poll: Poll
creator: User
content_id: uuid4
"""
poll_voted = Signal()
2 changes: 1 addition & 1 deletion changelog/8381.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
- add option to allow unregistered users to vote in a poll:
- the feature is controlled via a new django setting `A4_POLL_ENABLE_UNREGISTERED_USERS` to enable or disable it
- add a new captcha react component to integrate the captcha in the poll

- add a poll_voted signal which is sent when a user has voted on a poll.
67 changes: 67 additions & 0 deletions tests/polls/test_vote_api.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
from unittest.mock import MagicMock

import pytest
from django.urls import reverse
from rest_framework import status

from adhocracy4.polls.api import PollViewSet
from adhocracy4.polls.models import Answer
from adhocracy4.polls.models import OtherVote
from adhocracy4.polls.models import Vote
from adhocracy4.polls.phases import VotingPhase
from adhocracy4.polls.signals import poll_voted
from adhocracy4.projects.enums import Access
from tests.helpers import active_phase

Expand Down Expand Up @@ -700,3 +704,66 @@ def test_validate_question_belongs_to_poll(
"Question has to belong to the poll set in the url."
in response.content.decode()
)


@pytest.mark.django_db
def test_poll_voted_signal_is_dispatched_on_vote(
user, apiclient, poll_factory, question_factory, choice_factory
):
signal_handler = MagicMock()
poll_voted.connect(signal_handler)

poll = poll_factory()
poll.allow_unregistered_users = True
poll.save()
question = question_factory(poll=poll)
choice1 = choice_factory(question=question)
choice_factory(question=question)
open_question = question_factory(poll=poll, is_open=True)

assert Vote.objects.count() == 0

apiclient.force_authenticate(user=user)

url = reverse("polls-vote", kwargs={"pk": poll.pk})

data = {
"votes": {
question.pk: {
"choices": [choice1.pk],
"other_choice_answer": "",
"open_answer": "",
},
open_question.pk: {
"choices": [],
"other_choice_answer": "",
"open_answer": "an open answer",
},
}
}

with active_phase(poll.module, VotingPhase):
response = apiclient.post(url, data, format="json")
assert response.status_code == status.HTTP_201_CREATED
signal_handler.assert_called_once_with(
signal=poll_voted,
sender=PollViewSet,
poll=poll,
creator=user,
content_id=None,
)

# test for unregistered user
signal_handler.reset_mock()
apiclient.logout()
data["captcha"] = "testpass:0"
response = apiclient.post(url, data, format="json")
assert response.status_code == status.HTTP_201_CREATED
content_id = Vote.objects.filter(content_id__isnull=False).first().content_id
signal_handler.assert_called_once_with(
signal=poll_voted,
sender=PollViewSet,
poll=poll,
creator=None,
content_id=content_id,
)

0 comments on commit fc7d8fc

Please sign in to comment.