Fixed validation of default votes in assignment and motion poll. Fixed #1959.
This commit is contained in:
parent
0fe2b9cd8a
commit
60b6a7efe1
@ -1,6 +1,7 @@
|
|||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
from openslides.poll.serializers import default_votes_validator
|
||||||
from openslides.utils.rest_api import (
|
from openslides.utils.rest_api import (
|
||||||
DictField,
|
DictField,
|
||||||
IntegerField,
|
IntegerField,
|
||||||
@ -106,6 +107,7 @@ class AssignmentAllPollSerializer(ModelSerializer):
|
|||||||
'has_votes',
|
'has_votes',
|
||||||
'assignment') # js-data needs the assignment-id in the nested object to define relations.
|
'assignment') # js-data needs the assignment-id in the nested object to define relations.
|
||||||
read_only_fields = ('yesnoabstain',)
|
read_only_fields = ('yesnoabstain',)
|
||||||
|
validators = (default_votes_validator,)
|
||||||
|
|
||||||
def get_has_votes(self, obj):
|
def get_has_votes(self, obj):
|
||||||
"""
|
"""
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
from openslides.poll.serializers import default_votes_validator
|
||||||
from openslides.utils.rest_api import (
|
from openslides.utils.rest_api import (
|
||||||
CharField,
|
CharField,
|
||||||
DictField,
|
DictField,
|
||||||
@ -115,6 +116,7 @@ class MotionPollSerializer(ModelSerializer):
|
|||||||
'votescast',
|
'votescast',
|
||||||
'votes',
|
'votes',
|
||||||
'has_votes')
|
'has_votes')
|
||||||
|
validators = (default_votes_validator,)
|
||||||
|
|
||||||
def get_yes(self, obj):
|
def get_yes(self, obj):
|
||||||
try:
|
try:
|
||||||
|
15
openslides/poll/serializers.py
Normal file
15
openslides/poll/serializers.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
from ..utils.rest_api import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
def default_votes_validator(data):
|
||||||
|
"""
|
||||||
|
Use this validator in your poll serializer. It checks that the values
|
||||||
|
for the default votes (see models.CollectDefaultVotesMixin) are greater
|
||||||
|
than or equal to -2.
|
||||||
|
"""
|
||||||
|
for key in data:
|
||||||
|
if key in ('votesvalid', 'votesinvalid', 'votescast') and data[key] < -2:
|
||||||
|
raise ValidationError({'detail': _('Value for {} must not be less than -2').format(key)})
|
||||||
|
return data
|
@ -1,5 +1,6 @@
|
|||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
|
from rest_framework import status
|
||||||
from rest_framework.test import APIClient
|
from rest_framework.test import APIClient
|
||||||
|
|
||||||
from openslides.assignments.models import Assignment
|
from openslides.assignments.models import Assignment
|
||||||
@ -273,3 +274,36 @@ class MarkElectedOtherUser(TestCase):
|
|||||||
|
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertFalse(Assignment.objects.get(pk=self.assignment.pk).elected.filter(username='test_user_Oonei3rahji5jugh1eev').exists())
|
self.assertFalse(Assignment.objects.get(pk=self.assignment.pk).elected.filter(username='test_user_Oonei3rahji5jugh1eev').exists())
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateAssignmentPoll(TestCase):
|
||||||
|
"""
|
||||||
|
Tests updating polls of assignments.
|
||||||
|
"""
|
||||||
|
def setUp(self):
|
||||||
|
self.client = APIClient()
|
||||||
|
self.client.login(username='admin', password='admin')
|
||||||
|
self.assignment = Assignment.objects.create(title='test_assignment_ohneivoh9caiB8Yiungo', open_posts=1)
|
||||||
|
self.assignment.set_candidate(get_user_model().objects.get(username='admin'))
|
||||||
|
self.poll = self.assignment.create_poll()
|
||||||
|
|
||||||
|
def test_invalid_votesvalid_value(self):
|
||||||
|
response = self.client.put(
|
||||||
|
reverse('assignmentpoll-detail', args=[self.poll.pk]),
|
||||||
|
{'assignment_id': self.assignment.pk,
|
||||||
|
'votesvalid': '-3'})
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
def test_invalid_votesinvalid_value(self):
|
||||||
|
response = self.client.put(
|
||||||
|
reverse('assignmentpoll-detail', args=[self.poll.pk]),
|
||||||
|
{'assignment_id': self.assignment.pk,
|
||||||
|
'votesinvalid': '-3'})
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
def test_invalid_votescast_value(self):
|
||||||
|
response = self.client.put(
|
||||||
|
reverse('assignmentpoll-detail', args=[self.poll.pk]),
|
||||||
|
{'assignment_id': self.assignment.pk,
|
||||||
|
'votescast': '-3'})
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||||
|
@ -360,3 +360,38 @@ class SetState(TestCase):
|
|||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
self.assertEqual(response.data, {'detail': 'The state of the motion was set to submitted.'})
|
self.assertEqual(response.data, {'detail': 'The state of the motion was set to submitted.'})
|
||||||
self.assertEqual(Motion.objects.get(pk=self.motion.pk).state.name, 'submitted')
|
self.assertEqual(Motion.objects.get(pk=self.motion.pk).state.name, 'submitted')
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateMotionPoll(TestCase):
|
||||||
|
"""
|
||||||
|
Tests updating polls of motions.
|
||||||
|
"""
|
||||||
|
def setUp(self):
|
||||||
|
self.client = APIClient()
|
||||||
|
self.client.login(username='admin', password='admin')
|
||||||
|
self.motion = Motion(
|
||||||
|
title='test_title_Aiqueigh2dae9phabiqu',
|
||||||
|
text='test_text_Neekoh3zou6li5rue8iL')
|
||||||
|
self.motion.save()
|
||||||
|
self.poll = self.motion.create_poll()
|
||||||
|
|
||||||
|
def test_invalid_votesvalid_value(self):
|
||||||
|
response = self.client.put(
|
||||||
|
reverse('motionpoll-detail', args=[self.poll.pk]),
|
||||||
|
{'motion_id': self.motion.pk,
|
||||||
|
'votesvalid': '-3'})
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
def test_invalid_votesinvalid_value(self):
|
||||||
|
response = self.client.put(
|
||||||
|
reverse('motionpoll-detail', args=[self.poll.pk]),
|
||||||
|
{'motion_id': self.motion.pk,
|
||||||
|
'votesinvalid': '-3'})
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
def test_invalid_votescast_value(self):
|
||||||
|
response = self.client.put(
|
||||||
|
reverse('motionpoll-detail', args=[self.poll.pk]),
|
||||||
|
{'motion_id': self.motion.pk,
|
||||||
|
'votescast': '-3'})
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||||
|
Loading…
Reference in New Issue
Block a user