From 7e763e8c072d57eaf15ec2b47271918309145c9e Mon Sep 17 00:00:00 2001
From: Finn Stutzenstein
Date: Tue, 24 Nov 2020 09:56:20 +0100
Subject: [PATCH] Minumum amount of votes
renamed votes_amount to max_votes_amount
---
.../models/assignments/assignment-poll.ts | 3 +-
.../assignment-poll-vote.component.html | 5 +-
.../assignment-poll-vote.component.ts | 10 +-
.../poll-form/poll-form.component.html | 18 ++-
.../poll-form/poll-form.component.ts | 15 +-
.../app/site/polls/models/view-base-poll.ts | 10 +-
.../assignment-poll-slide-data.ts | 3 +-
.../migrations/0018_votes_amount.py | 26 ++++
server/openslides/assignments/models.py | 10 +-
server/openslides/assignments/projector.py | 3 +-
server/openslides/assignments/serializers.py | 3 +-
server/openslides/assignments/views.py | 13 +-
.../integration/assignments/test_polls.py | 133 ++++++++++++++++--
13 files changed, 212 insertions(+), 40 deletions(-)
create mode 100644 server/openslides/assignments/migrations/0018_votes_amount.py
diff --git a/client/src/app/shared/models/assignments/assignment-poll.ts b/client/src/app/shared/models/assignments/assignment-poll.ts
index 4711b99ae..0a99b254b 100644
--- a/client/src/app/shared/models/assignments/assignment-poll.ts
+++ b/client/src/app/shared/models/assignments/assignment-poll.ts
@@ -41,7 +41,8 @@ export class AssignmentPoll extends BasePoll<
public id: number;
public assignment_id: number;
- public votes_amount: number;
+ public min_votes_amount: number;
+ public max_votes_amount: number;
public allow_multiple_votes_per_candidate: boolean;
public global_yes: boolean;
public global_no: boolean;
diff --git a/client/src/app/site/assignments/modules/assignment-poll/components/assignment-poll-vote/assignment-poll-vote.component.html b/client/src/app/site/assignments/modules/assignment-poll/components/assignment-poll-vote/assignment-poll-vote.component.html
index 6c84ba026..9d3dbc9c0 100644
--- a/client/src/app/site/assignments/modules/assignment-poll/components/assignment-poll-vote/assignment-poll-vote.component.html
+++ b/client/src/app/site/assignments/modules/assignment-poll/components/assignment-poll-vote/assignment-poll-vote.component.html
@@ -28,10 +28,9 @@
- 1">
+ 1">
{{ 'Available votes' | translate }}:
-
- {{ getVotesAvailable(delegation) }}/{{ poll.votes_amount }}
+ {{ getVotesAvailable(delegation) }}/{{ poll.max_votes_amount }}
diff --git a/client/src/app/site/assignments/modules/assignment-poll/components/assignment-poll-vote/assignment-poll-vote.component.ts b/client/src/app/site/assignments/modules/assignment-poll/components/assignment-poll-vote/assignment-poll-vote.component.ts
index d38d879ab..333909319 100644
--- a/client/src/app/site/assignments/modules/assignment-poll/components/assignment-poll-vote/assignment-poll-vote.component.ts
+++ b/client/src/app/site/assignments/modules/assignment-poll/components/assignment-poll-vote/assignment-poll-vote.component.ts
@@ -141,7 +141,7 @@ export class AssignmentPollVoteComponent extends BasePollVoteComponentDirective<
}
public getVotesAvailable(user: ViewUser = this.user): number {
- return this.poll.votes_amount - this.getVotesCount(user);
+ return this.poll.max_votes_amount - this.getVotesCount(user);
}
private isGlobalOptionSelected(user: ViewUser = this.user): boolean {
@@ -177,12 +177,12 @@ export class AssignmentPollVoteComponent extends BasePollVoteComponentDirective<
}
if (this.poll.isMethodY || this.poll.isMethodN) {
- const votesAmount = this.poll.votes_amount;
+ const maxVotesAmount = this.poll.max_votes_amount;
const tmpVoteRequest = this.poll.options
.map(option => option.id)
.reduce((o, n) => {
o[n] = 0;
- if (votesAmount === 1) {
+ if (maxVotesAmount === 1) {
if (n === optionId && this.voteRequestData[user.id].votes[n] !== 1) {
o[n] = 1;
}
@@ -195,11 +195,11 @@ export class AssignmentPollVoteComponent extends BasePollVoteComponentDirective<
// check if you can still vote
const countedVotes = Object.keys(tmpVoteRequest).filter(key => tmpVoteRequest[key]).length;
- if (countedVotes <= votesAmount) {
+ if (countedVotes <= maxVotesAmount) {
this.voteRequestData[user.id].votes = tmpVoteRequest;
// if you have no options anymore, try to send
- if (this.getVotesCount(user) === votesAmount) {
+ if (this.getVotesCount(user) === maxVotesAmount) {
this.submitVote(user);
}
} else {
diff --git a/client/src/app/site/polls/components/poll-form/poll-form.component.html b/client/src/app/site/polls/components/poll-form/poll-form.component.html
index f2c4b248f..14aeafebb 100644
--- a/client/src/app/site/polls/components/poll-form/poll-form.component.html
+++ b/client/src/app/site/polls/components/poll-form/poll-form.component.html
@@ -57,13 +57,25 @@
{{ 'This field is required.' | translate }}
-
+
+
+
+
+
+
diff --git a/client/src/app/site/polls/components/poll-form/poll-form.component.ts b/client/src/app/site/polls/components/poll-form/poll-form.component.ts
index 61591f350..64aa00509 100644
--- a/client/src/app/site/polls/components/poll-form/poll-form.component.ts
+++ b/client/src/app/site/polls/components/poll-form/poll-form.component.ts
@@ -133,8 +133,8 @@ export class PollFormComponent
}
if (this.data instanceof ViewAssignmentPoll) {
- if (this.data.assignment && !this.data.votes_amount) {
- this.data.votes_amount = this.data.assignment.open_posts;
+ if (this.data.assignment && !this.data.max_votes_amount) {
+ this.data.max_votes_amount = this.data.assignment.open_posts;
}
if (!this.data.pollmethod) {
this.data.pollmethod = this.configService.instant('assignment_poll_method');
@@ -279,6 +279,14 @@ export class PollFormComponent
if (data.pollmethod === 'Y' || data.pollmethod === 'N') {
this.pollValues.push([this.pollService.getVerboseNameForKey('votes_amount'), data.votes_amount]);
this.pollValues.push([this.pollService.getVerboseNameForKey('global_yes'), data.global_yes]);
+ this.pollValues.push([
+ this.pollService.getVerboseNameForKey('max_votes_amount'),
+ data.max_votes_amount
+ ]);
+ this.pollValues.push([
+ this.pollService.getVerboseNameForKey('min_votes_amount'),
+ data.min_votes_amount
+ ]);
this.pollValues.push([this.pollService.getVerboseNameForKey('global_no'), data.global_no]);
this.pollValues.push([this.pollService.getVerboseNameForKey('global_abstain'), data.global_abstain]);
}
@@ -292,7 +300,8 @@ export class PollFormComponent
pollmethod: ['', Validators.required],
onehundred_percent_base: ['', Validators.required],
majority_method: ['', Validators.required],
- votes_amount: [1, [Validators.required, Validators.min(1)]],
+ max_votes_amount: [1, [Validators.required, Validators.min(1)]],
+ min_votes_amount: [1, [Validators.required, Validators.min(1)]],
groups_id: [],
global_yes: [false],
global_no: [false],
diff --git a/client/src/app/site/polls/models/view-base-poll.ts b/client/src/app/site/polls/models/view-base-poll.ts
index c9285cf98..3741fb785 100644
--- a/client/src/app/site/polls/models/view-base-poll.ts
+++ b/client/src/app/site/polls/models/view-base-poll.ts
@@ -39,16 +39,18 @@ export const PollTypeVerbose = {
};
export const PollPropertyVerbose = {
- majority_method: 'Required majority',
- onehundred_percent_base: '100% base',
+ majority_method: _('Required majority'),
+ onehundred_percent_base: _('100% base'),
type: _('Voting type'),
pollmethod: _('Voting method'),
- state: 'State',
+ state: _('State'),
groups: _('Entitled to vote'),
votes_amount: _('Amount of votes'),
global_yes: _('General approval'),
global_no: _('General rejection'),
- global_abstain: _('General abstain')
+ global_abstain: _('General abstain'),
+ max_votes_amount: _('Maximum amount of votes'),
+ min_votes_amount: _('Minimum amount of votes')
};
export const MajorityMethodVerbose = {
diff --git a/client/src/app/slides/assignments/assignment-poll/assignment-poll-slide-data.ts b/client/src/app/slides/assignments/assignment-poll/assignment-poll-slide-data.ts
index de4512813..7b7c87a5b 100644
--- a/client/src/app/slides/assignments/assignment-poll/assignment-poll-slide-data.ts
+++ b/client/src/app/slides/assignments/assignment-poll/assignment-poll-slide-data.ts
@@ -9,7 +9,8 @@ export interface AssignmentPollSlideData extends BasePollSlideData {
title: string;
type: PollType;
pollmethod: AssignmentPollMethod;
- votes_amount: number;
+ max_votes_amount: number;
+ min_votes_amount: number;
description: string;
state: PollState;
onehundred_percent_base: PercentBase;
diff --git a/server/openslides/assignments/migrations/0018_votes_amount.py b/server/openslides/assignments/migrations/0018_votes_amount.py
new file mode 100644
index 000000000..5a3558e88
--- /dev/null
+++ b/server/openslides/assignments/migrations/0018_votes_amount.py
@@ -0,0 +1,26 @@
+# Generated by Django 2.2.15 on 2020-11-24 08:12
+
+import django.core.validators
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("assignments", "0017_vote_to_y"),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name="assignmentpoll",
+ old_name="votes_amount",
+ new_name="max_votes_amount",
+ ),
+ migrations.AddField(
+ model_name="assignmentpoll",
+ name="min_votes_amount",
+ field=models.IntegerField(
+ default=1, validators=[django.core.validators.MinValueValidator(1)]
+ ),
+ ),
+ ]
diff --git a/server/openslides/assignments/models.py b/server/openslides/assignments/models.py
index b8fa9e91f..887b5110c 100644
--- a/server/openslides/assignments/models.py
+++ b/server/openslides/assignments/models.py
@@ -14,6 +14,7 @@ from openslides.utils.autoupdate import inform_changed_data
from openslides.utils.exceptions import OpenSlidesError
from openslides.utils.manager import BaseManager
from openslides.utils.models import RESTModelMixin
+from openslides.utils.rest_api import ValidationError
from ..utils.models import CASCADE_AND_AUTOUPDATE, SET_NULL_AND_AUTOUPDATE
from .access_permissions import (
@@ -377,7 +378,7 @@ class AssignmentPoll(RESTModelMixin, BasePoll):
decimal_places=6,
)
- votes_amount = models.IntegerField(default=1, validators=[MinValueValidator(1)])
+ max_votes_amount = models.IntegerField(default=1, validators=[MinValueValidator(1)])
""" For "votes" mode: The amount of votes a voter can give. """
allow_multiple_votes_per_candidate = models.BooleanField(default=False)
@@ -447,6 +448,13 @@ class AssignmentPoll(RESTModelMixin, BasePoll):
get_amount_global_abstain, set_amount_global_abstain
)
+ def save(self, *args, **kwargs):
+ if self.max_votes_amount < self.min_votes_amount:
+ raise ValidationError(
+ {"detail": "max votes must be larger or equal to min votes"}
+ )
+ super().save(*args, **kwargs)
+
def create_options(self, skip_autoupdate=False):
related_users = AssignmentRelatedUser.objects.filter(
assignment__id=self.assignment.id
diff --git a/server/openslides/assignments/projector.py b/server/openslides/assignments/projector.py
index 1cd07523d..a07e4d73d 100644
--- a/server/openslides/assignments/projector.py
+++ b/server/openslides/assignments/projector.py
@@ -60,7 +60,8 @@ async def assignment_poll_slide(
"title",
"type",
"pollmethod",
- "votes_amount",
+ "min_votes_amount",
+ "max_votes_amount",
"description",
"state",
"onehundred_percent_base",
diff --git a/server/openslides/assignments/serializers.py b/server/openslides/assignments/serializers.py
index 2ca605e5c..7bcca9043 100644
--- a/server/openslides/assignments/serializers.py
+++ b/server/openslides/assignments/serializers.py
@@ -93,7 +93,8 @@ class AssignmentPollSerializer(BasePollSerializer):
"assignment",
"description",
"pollmethod",
- "votes_amount",
+ "min_votes_amount",
+ "max_votes_amount",
"allow_multiple_votes_per_candidate",
"global_yes",
"amount_global_yes",
diff --git a/server/openslides/assignments/views.py b/server/openslides/assignments/views.py
index ef072754d..ad9e00803 100644
--- a/server/openslides/assignments/views.py
+++ b/server/openslides/assignments/views.py
@@ -377,7 +377,7 @@ class AssignmentPollViewSet(BasePollViewSet):
- ids should be integers of valid option ids for this poll
- amounts must be 0 or 1, if poll.allow_multiple_votes_per_candidate is False
- if an option is not given, 0 is assumed
- - The sum of all amounts must be grater than 0 and <= poll.votes_amount
+ - The sum of all amounts must be >= poll.min_votes_amount and <= poll.max_votes_amount
YN/YNA:
{: 'Y' | 'N' [|'A']}
@@ -471,11 +471,18 @@ class AssignmentPollViewSet(BasePollViewSet):
)
amount_sum += amount
- if amount_sum > poll.votes_amount:
+ if amount_sum > poll.max_votes_amount:
raise ValidationError(
{
"detail": "You can give a maximum of {0} votes",
- "args": [poll.votes_amount],
+ "args": [poll.max_votes_amount],
+ }
+ )
+ if amount_sum < poll.min_votes_amount:
+ raise ValidationError(
+ {
+ "detail": "You must give a minimum of {0} votes",
+ "args": [poll.min_votes_amount],
}
)
# return, if there is a global vote, because we dont have to check option presence
diff --git a/server/tests/integration/assignments/test_polls.py b/server/tests/integration/assignments/test_polls.py
index 1bbdfff20..d6b5ddfa0 100644
--- a/server/tests/integration/assignments/test_polls.py
+++ b/server/tests/integration/assignments/test_polls.py
@@ -136,7 +136,8 @@ class CreateAssignmentPoll(TestCase):
self.assertEqual(poll.amount_global_no, None)
self.assertEqual(poll.amount_global_abstain, None)
self.assertFalse(poll.allow_multiple_votes_per_candidate)
- self.assertEqual(poll.votes_amount, 1)
+ self.assertEqual(poll.min_votes_amount, 1)
+ self.assertEqual(poll.max_votes_amount, 1)
self.assertEqual(poll.assignment.id, self.assignment.id)
self.assertEqual(poll.description, "")
self.assertTrue(poll.options.exists())
@@ -157,7 +158,8 @@ class CreateAssignmentPoll(TestCase):
"global_no": False,
"global_abstain": False,
"allow_multiple_votes_per_candidate": True,
- "votes_amount": 5,
+ "min_votes_amount": 5,
+ "max_votes_amount": 8,
"description": "test_description_ieM8ThuasoSh8aecai8p",
},
)
@@ -171,7 +173,8 @@ class CreateAssignmentPoll(TestCase):
self.assertFalse(poll.global_no)
self.assertFalse(poll.global_abstain)
self.assertTrue(poll.allow_multiple_votes_per_candidate)
- self.assertEqual(poll.votes_amount, 5)
+ self.assertEqual(poll.min_votes_amount, 5)
+ self.assertEqual(poll.max_votes_amount, 8)
self.assertEqual(poll.description, "test_description_ieM8ThuasoSh8aecai8p")
def test_no_candidates(self):
@@ -521,6 +524,44 @@ class CreateAssignmentPoll(TestCase):
self.assertFalse(AssignmentPoll.objects.exists())
self.assertFalse(AssignmentVote.objects.exists())
+ def test_create_with_unmatched_votes_amount(self):
+ response = self.client.post(
+ reverse("assignmentpoll-list"),
+ {
+ "title": "test_title_9FP4m2f2k09f4gni2sqq",
+ "pollmethod": AssignmentPoll.POLLMETHOD_VOTES,
+ "type": "named",
+ "assignment_id": self.assignment.id,
+ "onehundred_percent_base": AssignmentPoll.PERCENT_BASE_YNA,
+ "majority_method": AssignmentPoll.MAJORITY_SIMPLE,
+ "min_votes_amount": 5,
+ "max_votes_amount": 4,
+ },
+ )
+ self.assertHttpStatusVerbose(response, status.HTTP_400_BAD_REQUEST)
+ self.assertFalse(AssignmentPoll.objects.exists())
+ self.assertFalse(AssignmentVote.objects.exists())
+
+ def test_create_with_equal_votes_amount(self):
+ response = self.client.post(
+ reverse("assignmentpoll-list"),
+ {
+ "title": "test_title_9FP4m2f2k09f4gni2sqq",
+ "pollmethod": AssignmentPoll.POLLMETHOD_VOTES,
+ "type": "named",
+ "assignment_id": self.assignment.id,
+ "onehundred_percent_base": AssignmentPoll.PERCENT_BASE_YNA,
+ "majority_method": AssignmentPoll.MAJORITY_SIMPLE,
+ "min_votes_amount": 4,
+ "max_votes_amount": 4,
+ },
+ )
+ self.assertHttpStatusVerbose(response, status.HTTP_201_CREATED)
+ self.assertTrue(AssignmentPoll.objects.exists())
+ poll = AssignmentPoll.objects.get()
+ self.assertEqual(poll.min_votes_amount, 4)
+ self.assertEqual(poll.max_votes_amount, 4)
+
class UpdateAssignmentPoll(TestCase):
"""
@@ -697,7 +738,8 @@ class UpdateAssignmentPoll(TestCase):
"global_no": True,
"global_abstain": False,
"allow_multiple_votes_per_candidate": True,
- "votes_amount": 42,
+ "min_votes_amount": 32,
+ "max_votes_amount": 42,
},
)
self.assertHttpStatusVerbose(response, status.HTTP_200_OK)
@@ -711,7 +753,32 @@ class UpdateAssignmentPoll(TestCase):
self.assertEqual(poll.amount_global_no, Decimal("0"))
self.assertEqual(poll.amount_global_abstain, None)
self.assertTrue(poll.allow_multiple_votes_per_candidate)
- self.assertEqual(poll.votes_amount, 42)
+ self.assertEqual(poll.min_votes_amount, 32)
+ self.assertEqual(poll.max_votes_amount, 42)
+
+ def test_patch_unmatched_votes_amounts(self):
+ response = self.client.patch(
+ reverse("assignmentpoll-detail", args=[self.poll.pk]),
+ {
+ "min_votes_amount": 50,
+ "max_votes_amount": 42,
+ },
+ )
+ self.assertHttpStatusVerbose(response, status.HTTP_400_BAD_REQUEST)
+
+ def test_patch_equal_votes_amounts(self):
+ response = self.client.patch(
+ reverse("assignmentpoll-detail", args=[self.poll.pk]),
+ {
+ "min_votes_amount": 42,
+ "max_votes_amount": 42,
+ },
+ )
+ self.assertHttpStatusVerbose(response, status.HTTP_200_OK)
+ self.assertTrue(AssignmentPoll.objects.exists())
+ poll = AssignmentPoll.objects.get()
+ self.assertEqual(poll.min_votes_amount, 42)
+ self.assertEqual(poll.max_votes_amount, 42)
def test_patch_majority_method_state_not_created(self):
self.poll.state = 2
@@ -1268,7 +1335,7 @@ class VoteAssignmentPollNamedY(VoteAssignmentPollBaseTestClass):
def setup_for_multiple_votes(self):
self.poll.allow_multiple_votes_per_candidate = True
- self.poll.votes_amount = 3
+ self.poll.max_votes_amount = 3
self.poll.save()
self.add_candidate()
@@ -1446,7 +1513,7 @@ class VoteAssignmentPollNamedY(VoteAssignmentPollBaseTestClass):
self.assertEqual(option2.no, Decimal("0"))
self.assertEqual(option2.abstain, Decimal("0"))
- def test_multiple_votes_wrong_amount(self):
+ def test_multiple_votes_wrong_max_amount(self):
self.setup_for_multiple_votes()
self.start_poll()
response = self.client.post(
@@ -1457,6 +1524,19 @@ class VoteAssignmentPollNamedY(VoteAssignmentPollBaseTestClass):
self.assertHttpStatusVerbose(response, status.HTTP_400_BAD_REQUEST)
self.assertFalse(AssignmentPoll.objects.get().get_votes().exists())
+ def test_multiple_votes_wrong_min_amount(self):
+ self.setup_for_multiple_votes()
+ self.poll.min_votes_amount = 2
+ self.poll.save()
+ self.start_poll()
+ response = self.client.post(
+ reverse("assignmentpoll-vote", args=[self.poll.pk]),
+ {"data": {"1": 1}},
+ format="json",
+ )
+ self.assertHttpStatusVerbose(response, status.HTTP_400_BAD_REQUEST)
+ self.assertFalse(AssignmentPoll.objects.get().get_votes().exists())
+
def test_too_many_options(self):
self.setup_for_multiple_votes()
self.start_poll()
@@ -1896,6 +1976,12 @@ class VoteAssignmentPollPseudoanonymousYNA(VoteAssignmentPollBaseTestClass):
type=BasePoll.TYPE_PSEUDOANONYMOUS,
)
+ def setup_for_multiple_votes(self):
+ self.poll.allow_multiple_votes_per_candidate = True
+ self.poll.max_votes_amount = 3
+ self.poll.save()
+ self.add_candidate()
+
def test_start_poll(self):
response = self.client.post(
reverse("assignmentpoll-start", args=[self.poll.pk])
@@ -2189,7 +2275,7 @@ class VoteAssignmentPollPseudoanonymousY(VoteAssignmentPollBaseTestClass):
for vote in poll.get_votes():
self.assertIsNone(vote.user)
- def test_multiple_votes_wrong_amount(self):
+ def test_multiple_votes_wrong_max_amount(self):
self.setup_for_multiple_votes()
self.start_poll()
response = self.client.post(
@@ -2200,6 +2286,19 @@ class VoteAssignmentPollPseudoanonymousY(VoteAssignmentPollBaseTestClass):
self.assertHttpStatusVerbose(response, status.HTTP_400_BAD_REQUEST)
self.assertFalse(AssignmentPoll.objects.get().get_votes().exists())
+ def test_multiple_votes_wrong_min_amount(self):
+ self.setup_for_multiple_votes()
+ self.poll.min_votes_amount = 2
+ self.poll.save()
+ self.start_poll()
+ response = self.client.post(
+ reverse("assignmentpoll-vote", args=[self.poll.pk]),
+ {"data": {"1": 1}},
+ format="json",
+ )
+ self.assertHttpStatusVerbose(response, status.HTTP_400_BAD_REQUEST)
+ self.assertFalse(AssignmentPoll.objects.get().get_votes().exists())
+
def test_too_many_options(self):
self.setup_for_multiple_votes()
self.start_poll()
@@ -2627,7 +2726,8 @@ class VoteAssignmentPollNamedAutoupdates(VoteAssignmentPollAutoupdatesBaseClass)
"type": AssignmentPoll.TYPE_NAMED,
"onehundred_percent_base": AssignmentPoll.PERCENT_BASE_CAST,
"majority_method": AssignmentPoll.MAJORITY_TWO_THIRDS,
- "votes_amount": 1,
+ "min_votes_amount": 1,
+ "max_votes_amount": 1,
"votescast": "1.000000",
"votesinvalid": "0.000000",
"votesvalid": "1.000000",
@@ -2696,7 +2796,8 @@ class VoteAssignmentPollNamedAutoupdates(VoteAssignmentPollAutoupdatesBaseClass)
"groups_id": [GROUP_DELEGATE_PK],
"options_id": [1],
"id": 1,
- "votes_amount": 1,
+ "min_votes_amount": 1,
+ "max_votes_amount": 1,
"user_has_voted": user == self.user,
"user_has_voted_for_delegations": [],
},
@@ -2751,7 +2852,8 @@ class VoteAssignmentPollNamedAutoupdates(VoteAssignmentPollAutoupdatesBaseClass)
"state": 4,
"title": self.poll.title,
"type": "named",
- "votes_amount": 1,
+ "min_votes_amount": 1,
+ "max_votes_amount": 1,
"votescast": "1.000000",
"votesinvalid": "0.000000",
"votesvalid": "1.000000",
@@ -2827,7 +2929,8 @@ class VoteAssignmentPollPseudoanonymousAutoupdates(
"voted_id": [self.user.id],
"onehundred_percent_base": AssignmentPoll.PERCENT_BASE_CAST,
"majority_method": AssignmentPoll.MAJORITY_TWO_THIRDS,
- "votes_amount": 1,
+ "min_votes_amount": 1,
+ "max_votes_amount": 1,
"votescast": "1.000000",
"votesinvalid": "0.000000",
"votesvalid": "1.000000",
@@ -2878,7 +2981,8 @@ class VoteAssignmentPollPseudoanonymousAutoupdates(
"groups_id": [GROUP_DELEGATE_PK],
"options_id": [1],
"id": 1,
- "votes_amount": 1,
+ "min_votes_amount": 1,
+ "max_votes_amount": 1,
"user_has_voted": user == self.user,
"user_has_voted_for_delegations": [],
},
@@ -2933,7 +3037,8 @@ class VoteAssignmentPollPseudoanonymousAutoupdates(
"state": 4,
"title": self.poll.title,
"type": AssignmentPoll.TYPE_PSEUDOANONYMOUS,
- "votes_amount": 1,
+ "min_votes_amount": 1,
+ "max_votes_amount": 1,
"votescast": "1.000000",
"votesinvalid": "0.000000",
"votesvalid": "1.000000",