|
@@ -4,6 +4,8 @@ from django.contrib.auth import get_user_model
|
|
from django.urls import reverse
|
|
from django.urls import reverse
|
|
from django.utils import timezone
|
|
from django.utils import timezone
|
|
|
|
|
|
|
|
+from misago.acl import add_acl
|
|
|
|
+from misago.core.utils import serialize_datetime
|
|
from misago.threads.models import Poll
|
|
from misago.threads.models import Poll
|
|
|
|
|
|
from .test_thread_poll_api import ThreadPollApiTestCase
|
|
from .test_thread_poll_api import ThreadPollApiTestCase
|
|
@@ -29,12 +31,61 @@ class ThreadGetVotesTests(ThreadPollApiTestCase):
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
|
|
|
|
+ def get_votes_json(self):
|
|
|
|
+ choices_votes = {choice['hash']: [] for choice in self.poll.choices}
|
|
|
|
+ queryset = self.poll.pollvote_set.order_by('-id').select_related()
|
|
|
|
+ for vote in queryset:
|
|
|
|
+ if vote.voter:
|
|
|
|
+ url = vote.voter.get_absolute_url()
|
|
|
|
+ else:
|
|
|
|
+ url = None
|
|
|
|
+
|
|
|
|
+ choices_votes[vote.choice_hash].append({
|
|
|
|
+ 'username': vote.voter_name,
|
|
|
|
+ 'voted_on': serialize_datetime(vote.voted_on),
|
|
|
|
+ 'url': url
|
|
|
|
+ })
|
|
|
|
+ return choices_votes
|
|
|
|
+
|
|
def test_anonymous(self):
|
|
def test_anonymous(self):
|
|
"""api allows guests to get poll votes"""
|
|
"""api allows guests to get poll votes"""
|
|
self.logout_user()
|
|
self.logout_user()
|
|
|
|
|
|
|
|
+ votes_json = self.get_votes_json()
|
|
|
|
+
|
|
response = self.client.get(self.api_link)
|
|
response = self.client.get(self.api_link)
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
+ self.assertEqual(response.json(), [
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'aaaaaaaaaaaa',
|
|
|
|
+ 'label': 'Alpha',
|
|
|
|
+ 'votes': 1,
|
|
|
|
+ 'voters': votes_json['aaaaaaaaaaaa'],
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'bbbbbbbbbbbb',
|
|
|
|
+ 'label': 'Beta',
|
|
|
|
+ 'votes': 0,
|
|
|
|
+ 'voters': [],
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'gggggggggggg',
|
|
|
|
+ 'label': 'Gamma',
|
|
|
|
+ 'votes': 2,
|
|
|
|
+ 'voters': votes_json['gggggggggggg'],
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'dddddddddddd',
|
|
|
|
+ 'label': 'Delta',
|
|
|
|
+ 'votes': 1,
|
|
|
|
+ 'voters': votes_json['dddddddddddd'],
|
|
|
|
+ },
|
|
|
|
+ ])
|
|
|
|
+
|
|
|
|
+ self.assertEqual(len(votes_json['aaaaaaaaaaaa']), 1)
|
|
|
|
+ self.assertEqual(len(votes_json['bbbbbbbbbbbb']), 0)
|
|
|
|
+ self.assertEqual(len(votes_json['gggggggggggg']), 2)
|
|
|
|
+ self.assertEqual(len(votes_json['dddddddddddd']), 1)
|
|
|
|
|
|
def test_invalid_thread_id(self):
|
|
def test_invalid_thread_id(self):
|
|
"""api validates that thread id is integer"""
|
|
"""api validates that thread id is integer"""
|
|
@@ -48,6 +99,9 @@ class ThreadGetVotesTests(ThreadPollApiTestCase):
|
|
|
|
|
|
response = self.client.get(api_link)
|
|
response = self.client.get(api_link)
|
|
self.assertEqual(response.status_code, 404)
|
|
self.assertEqual(response.status_code, 404)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'detail': "NOT FOUND",
|
|
|
|
+ })
|
|
|
|
|
|
def test_nonexistant_thread_id(self):
|
|
def test_nonexistant_thread_id(self):
|
|
"""api validates that thread exists"""
|
|
"""api validates that thread exists"""
|
|
@@ -61,6 +115,9 @@ class ThreadGetVotesTests(ThreadPollApiTestCase):
|
|
|
|
|
|
response = self.client.get(api_link)
|
|
response = self.client.get(api_link)
|
|
self.assertEqual(response.status_code, 404)
|
|
self.assertEqual(response.status_code, 404)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'detail': "No Thread matches the given query.",
|
|
|
|
+ })
|
|
|
|
|
|
def test_invalid_poll_id(self):
|
|
def test_invalid_poll_id(self):
|
|
"""api validates that poll id is integer"""
|
|
"""api validates that poll id is integer"""
|
|
@@ -74,6 +131,9 @@ class ThreadGetVotesTests(ThreadPollApiTestCase):
|
|
|
|
|
|
response = self.client.get(api_link)
|
|
response = self.client.get(api_link)
|
|
self.assertEqual(response.status_code, 404)
|
|
self.assertEqual(response.status_code, 404)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'detail': "NOT FOUND",
|
|
|
|
+ })
|
|
|
|
|
|
def test_nonexistant_poll_id(self):
|
|
def test_nonexistant_poll_id(self):
|
|
"""api validates that poll exists"""
|
|
"""api validates that poll exists"""
|
|
@@ -87,6 +147,9 @@ class ThreadGetVotesTests(ThreadPollApiTestCase):
|
|
|
|
|
|
response = self.client.get(api_link)
|
|
response = self.client.get(api_link)
|
|
self.assertEqual(response.status_code, 404)
|
|
self.assertEqual(response.status_code, 404)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'detail': "NOT FOUND",
|
|
|
|
+ })
|
|
|
|
|
|
def test_no_permission(self):
|
|
def test_no_permission(self):
|
|
"""api chcecks permission to see poll voters"""
|
|
"""api chcecks permission to see poll voters"""
|
|
@@ -97,6 +160,9 @@ class ThreadGetVotesTests(ThreadPollApiTestCase):
|
|
|
|
|
|
response = self.client.get(self.api_link)
|
|
response = self.client.get(self.api_link)
|
|
self.assertEqual(response.status_code, 403)
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'detail': "You dont have permission to this poll's voters.",
|
|
|
|
+ })
|
|
|
|
|
|
def test_nonpublic_poll(self):
|
|
def test_nonpublic_poll(self):
|
|
"""api validates that poll is public"""
|
|
"""api validates that poll is public"""
|
|
@@ -107,26 +173,47 @@ class ThreadGetVotesTests(ThreadPollApiTestCase):
|
|
|
|
|
|
response = self.client.get(self.api_link)
|
|
response = self.client.get(self.api_link)
|
|
self.assertEqual(response.status_code, 403)
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'detail': "You dont have permission to this poll's voters.",
|
|
|
|
+ })
|
|
|
|
|
|
def test_get_votes(self):
|
|
def test_get_votes(self):
|
|
"""api returns list of voters"""
|
|
"""api returns list of voters"""
|
|
|
|
+ votes_json = self.get_votes_json()
|
|
|
|
+
|
|
response = self.client.get(self.api_link)
|
|
response = self.client.get(self.api_link)
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response.status_code, 200)
|
|
-
|
|
|
|
- response_json = response.json()
|
|
|
|
- self.assertEqual(len(response_json), 4)
|
|
|
|
-
|
|
|
|
- self.assertEqual([c['label'] for c in response_json], ['Alpha', 'Beta', 'Gamma', 'Delta'])
|
|
|
|
- self.assertEqual([c['votes'] for c in response_json], [1, 0, 2, 1])
|
|
|
|
- self.assertEqual([len(c['voters']) for c in response_json], [1, 0, 2, 1])
|
|
|
|
-
|
|
|
|
- self.assertEqual([[v['username'] for v in c['voters']] for c in response_json][0][0],
|
|
|
|
- 'bob')
|
|
|
|
-
|
|
|
|
- user = UserModel.objects.get(slug='bob')
|
|
|
|
-
|
|
|
|
- self.assertEqual([[v['url'] for v in c['voters']] for c in response_json][0][0],
|
|
|
|
- user.get_absolute_url())
|
|
|
|
|
|
+ self.assertEqual(response.json(), [
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'aaaaaaaaaaaa',
|
|
|
|
+ 'label': 'Alpha',
|
|
|
|
+ 'votes': 1,
|
|
|
|
+ 'voters': votes_json['aaaaaaaaaaaa'],
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'bbbbbbbbbbbb',
|
|
|
|
+ 'label': 'Beta',
|
|
|
|
+ 'votes': 0,
|
|
|
|
+ 'voters': [],
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'gggggggggggg',
|
|
|
|
+ 'label': 'Gamma',
|
|
|
|
+ 'votes': 2,
|
|
|
|
+ 'voters': votes_json['gggggggggggg'],
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'dddddddddddd',
|
|
|
|
+ 'label': 'Delta',
|
|
|
|
+ 'votes': 1,
|
|
|
|
+ 'voters': votes_json['dddddddddddd'],
|
|
|
|
+ },
|
|
|
|
+ ])
|
|
|
|
+
|
|
|
|
+ self.assertEqual(len(votes_json['aaaaaaaaaaaa']), 1)
|
|
|
|
+ self.assertEqual(len(votes_json['bbbbbbbbbbbb']), 0)
|
|
|
|
+ self.assertEqual(len(votes_json['gggggggggggg']), 2)
|
|
|
|
+ self.assertEqual(len(votes_json['dddddddddddd']), 1)
|
|
|
|
|
|
def test_get_votes_private_poll(self):
|
|
def test_get_votes_private_poll(self):
|
|
"""api returns list of voters on private poll for user with permission"""
|
|
"""api returns list of voters on private poll for user with permission"""
|
|
@@ -135,23 +222,41 @@ class ThreadGetVotesTests(ThreadPollApiTestCase):
|
|
self.poll.is_public = False
|
|
self.poll.is_public = False
|
|
self.poll.save()
|
|
self.poll.save()
|
|
|
|
|
|
|
|
+ votes_json = self.get_votes_json()
|
|
|
|
+
|
|
response = self.client.get(self.api_link)
|
|
response = self.client.get(self.api_link)
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response.status_code, 200)
|
|
-
|
|
|
|
- response_json = response.json()
|
|
|
|
- self.assertEqual(len(response_json), 4)
|
|
|
|
-
|
|
|
|
- self.assertEqual([c['label'] for c in response_json], ['Alpha', 'Beta', 'Gamma', 'Delta'])
|
|
|
|
- self.assertEqual([c['votes'] for c in response_json], [1, 0, 2, 1])
|
|
|
|
- self.assertEqual([len(c['voters']) for c in response_json], [1, 0, 2, 1])
|
|
|
|
-
|
|
|
|
- self.assertEqual([[v['username'] for v in c['voters']] for c in response_json][0][0],
|
|
|
|
- 'bob')
|
|
|
|
-
|
|
|
|
- user = UserModel.objects.get(slug='bob')
|
|
|
|
-
|
|
|
|
- self.assertEqual([[v['url'] for v in c['voters']] for c in response_json][0][0],
|
|
|
|
- user.get_absolute_url())
|
|
|
|
|
|
+ self.assertEqual(response.json(), [
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'aaaaaaaaaaaa',
|
|
|
|
+ 'label': 'Alpha',
|
|
|
|
+ 'votes': 1,
|
|
|
|
+ 'voters': votes_json['aaaaaaaaaaaa'],
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'bbbbbbbbbbbb',
|
|
|
|
+ 'label': 'Beta',
|
|
|
|
+ 'votes': 0,
|
|
|
|
+ 'voters': [],
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'gggggggggggg',
|
|
|
|
+ 'label': 'Gamma',
|
|
|
|
+ 'votes': 2,
|
|
|
|
+ 'voters': votes_json['gggggggggggg'],
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'dddddddddddd',
|
|
|
|
+ 'label': 'Delta',
|
|
|
|
+ 'votes': 1,
|
|
|
|
+ 'voters': votes_json['dddddddddddd'],
|
|
|
|
+ },
|
|
|
|
+ ])
|
|
|
|
+
|
|
|
|
+ self.assertEqual(len(votes_json['aaaaaaaaaaaa']), 1)
|
|
|
|
+ self.assertEqual(len(votes_json['bbbbbbbbbbbb']), 0)
|
|
|
|
+ self.assertEqual(len(votes_json['gggggggggggg']), 2)
|
|
|
|
+ self.assertEqual(len(votes_json['dddddddddddd']), 1)
|
|
|
|
|
|
|
|
|
|
class ThreadPostVotesTests(ThreadPollApiTestCase):
|
|
class ThreadPostVotesTests(ThreadPollApiTestCase):
|
|
@@ -182,6 +287,9 @@ class ThreadPostVotesTests(ThreadPollApiTestCase):
|
|
|
|
|
|
response = self.post(self.api_link)
|
|
response = self.post(self.api_link)
|
|
self.assertEqual(response.status_code, 403)
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'detail': "This action is not available to guests.",
|
|
|
|
+ })
|
|
|
|
|
|
def test_empty_vote_json(self):
|
|
def test_empty_vote_json(self):
|
|
"""api validates if vote that user has made was empty"""
|
|
"""api validates if vote that user has made was empty"""
|
|
@@ -190,30 +298,48 @@ class ThreadPostVotesTests(ThreadPollApiTestCase):
|
|
response = self.client.post(
|
|
response = self.client.post(
|
|
self.api_link, '[]', content_type='application/json'
|
|
self.api_link, '[]', content_type='application/json'
|
|
)
|
|
)
|
|
- self.assertContains(response, "You have to make a choice.", status_code=400)
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'choices': ["You have to make a choice."],
|
|
|
|
+ })
|
|
|
|
|
|
def test_empty_vote_form(self):
|
|
def test_empty_vote_form(self):
|
|
"""api validates if vote that user has made was empty"""
|
|
"""api validates if vote that user has made was empty"""
|
|
self.delete_user_votes()
|
|
self.delete_user_votes()
|
|
|
|
|
|
response = self.client.post(self.api_link)
|
|
response = self.client.post(self.api_link)
|
|
- self.assertContains(response, "You have to make a choice.", status_code=400)
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'choices': ["You have to make a choice."],
|
|
|
|
+ })
|
|
|
|
|
|
def test_malformed_vote(self):
|
|
def test_malformed_vote(self):
|
|
"""api validates if vote that user has made was correctly structured"""
|
|
"""api validates if vote that user has made was correctly structured"""
|
|
self.delete_user_votes()
|
|
self.delete_user_votes()
|
|
|
|
|
|
response = self.post(self.api_link)
|
|
response = self.post(self.api_link)
|
|
- self.assertContains(response, "Expected a list of items", status_code=400)
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'choices': ['Expected a list of items but got type "dict".'],
|
|
|
|
+ })
|
|
|
|
|
|
response = self.post(self.api_link, data={})
|
|
response = self.post(self.api_link, data={})
|
|
- self.assertContains(response, "Expected a list of items", status_code=400)
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'choices': ['Expected a list of items but got type "dict".'],
|
|
|
|
+ })
|
|
|
|
|
|
response = self.post(self.api_link, data='hello')
|
|
response = self.post(self.api_link, data='hello')
|
|
- self.assertContains(response, "Expected a list of items", status_code=400)
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'choices': ['Expected a list of items but got type "str".'],
|
|
|
|
+ })
|
|
|
|
|
|
response = self.post(self.api_link, data=123)
|
|
response = self.post(self.api_link, data=123)
|
|
- self.assertContains(response, "Expected a list of items", status_code=400)
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'choices': ['Expected a list of items but got type "int".'],
|
|
|
|
+ })
|
|
|
|
|
|
def test_invalid_choices(self):
|
|
def test_invalid_choices(self):
|
|
"""api validates if vote that user has made overlaps with allowed votes"""
|
|
"""api validates if vote that user has made overlaps with allowed votes"""
|
|
@@ -229,19 +355,23 @@ class ThreadPostVotesTests(ThreadPollApiTestCase):
|
|
self.poll.save()
|
|
self.poll.save()
|
|
|
|
|
|
response = self.post(self.api_link, data=['aaaaaaaaaaaa', 'bbbbbbbbbbbb'])
|
|
response = self.post(self.api_link, data=['aaaaaaaaaaaa', 'bbbbbbbbbbbb'])
|
|
- self.assertContains(
|
|
|
|
- response, "This poll disallows voting for more than 1 choice.", status_code=400
|
|
|
|
- )
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'choices': ["This poll disallows voting for more than 1 choice."],
|
|
|
|
+ })
|
|
|
|
|
|
def test_revote(self):
|
|
def test_revote(self):
|
|
"""api validates if user is trying to change vote in poll that disallows revoting"""
|
|
"""api validates if user is trying to change vote in poll that disallows revoting"""
|
|
response = self.post(self.api_link, data=['lorem', 'ipsum'])
|
|
response = self.post(self.api_link, data=['lorem', 'ipsum'])
|
|
- self.assertContains(response, "You have already voted in this poll.", status_code=403)
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 403)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'detail': "You have already voted in this poll.",
|
|
|
|
+ })
|
|
|
|
|
|
self.delete_user_votes()
|
|
self.delete_user_votes()
|
|
|
|
|
|
response = self.post(self.api_link)
|
|
response = self.post(self.api_link)
|
|
- self.assertContains(response, "Expected a list of items", status_code=400)
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
|
|
|
def test_vote_in_closed_thread(self):
|
|
def test_vote_in_closed_thread(self):
|
|
"""api validates is user has permission to vote poll in closed thread"""
|
|
"""api validates is user has permission to vote poll in closed thread"""
|
|
@@ -253,12 +383,15 @@ class ThreadPostVotesTests(ThreadPollApiTestCase):
|
|
self.delete_user_votes()
|
|
self.delete_user_votes()
|
|
|
|
|
|
response = self.post(self.api_link)
|
|
response = self.post(self.api_link)
|
|
- self.assertContains(response, "thread is closed", status_code=403)
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 403)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'detail': "This thread is closed. You can't vote in it.",
|
|
|
|
+ })
|
|
|
|
|
|
self.override_acl(category={'can_close_threads': 1})
|
|
self.override_acl(category={'can_close_threads': 1})
|
|
|
|
|
|
response = self.post(self.api_link)
|
|
response = self.post(self.api_link)
|
|
- self.assertContains(response, "Expected a list of items", status_code=400)
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
|
|
|
def test_vote_in_closed_category(self):
|
|
def test_vote_in_closed_category(self):
|
|
"""api validates is user has permission to vote poll in closed category"""
|
|
"""api validates is user has permission to vote poll in closed category"""
|
|
@@ -270,12 +403,15 @@ class ThreadPostVotesTests(ThreadPollApiTestCase):
|
|
self.delete_user_votes()
|
|
self.delete_user_votes()
|
|
|
|
|
|
response = self.post(self.api_link)
|
|
response = self.post(self.api_link)
|
|
- self.assertContains(response, "category is closed", status_code=403)
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 403)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'detail': "This category is closed. You can't vote in it.",
|
|
|
|
+ })
|
|
|
|
|
|
self.override_acl(category={'can_close_threads': 1})
|
|
self.override_acl(category={'can_close_threads': 1})
|
|
|
|
|
|
response = self.post(self.api_link)
|
|
response = self.post(self.api_link)
|
|
- self.assertContains(response, "Expected a list of items", status_code=400)
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
|
|
|
def test_vote_in_finished_poll(self):
|
|
def test_vote_in_finished_poll(self):
|
|
"""api valdiates if poll has finished before letting user to vote in it"""
|
|
"""api valdiates if poll has finished before letting user to vote in it"""
|
|
@@ -286,63 +422,190 @@ class ThreadPostVotesTests(ThreadPollApiTestCase):
|
|
self.delete_user_votes()
|
|
self.delete_user_votes()
|
|
|
|
|
|
response = self.post(self.api_link)
|
|
response = self.post(self.api_link)
|
|
- self.assertContains(response, "This poll is over. You can't vote in it.", status_code=403)
|
|
|
|
-
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 403)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'detail': "This poll is over. You can't vote in it.",
|
|
|
|
+ })
|
|
|
|
+
|
|
self.poll.length = 50
|
|
self.poll.length = 50
|
|
self.poll.save()
|
|
self.poll.save()
|
|
|
|
|
|
response = self.post(self.api_link)
|
|
response = self.post(self.api_link)
|
|
- self.assertContains(response, "Expected a list of items", status_code=400)
|
|
|
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
|
|
|
def test_fresh_vote(self):
|
|
def test_fresh_vote(self):
|
|
"""api handles first vote in poll"""
|
|
"""api handles first vote in poll"""
|
|
self.delete_user_votes()
|
|
self.delete_user_votes()
|
|
|
|
|
|
|
|
+ add_acl(self.user, self.poll)
|
|
|
|
+ self.poll.acl['can_vote'] = False
|
|
|
|
+
|
|
response = self.post(self.api_link, data=['aaaaaaaaaaaa', 'bbbbbbbbbbbb'])
|
|
response = self.post(self.api_link, data=['aaaaaaaaaaaa', 'bbbbbbbbbbbb'])
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'id': self.poll.id,
|
|
|
|
+ 'poster_name': self.user.username,
|
|
|
|
+ 'posted_on': serialize_datetime(self.poll.posted_on),
|
|
|
|
+ 'length': 0,
|
|
|
|
+ 'question': "Lorem ipsum dolor met?",
|
|
|
|
+ 'allowed_choices': 2,
|
|
|
|
+ 'allow_revotes': False,
|
|
|
|
+ 'votes': 4,
|
|
|
|
+ 'is_public': False,
|
|
|
|
+ 'acl': self.poll.acl,
|
|
|
|
+ 'choices': [
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'aaaaaaaaaaaa',
|
|
|
|
+ 'label': 'Alpha',
|
|
|
|
+ 'selected': True,
|
|
|
|
+ 'votes': 2
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'bbbbbbbbbbbb',
|
|
|
|
+ 'label': 'Beta',
|
|
|
|
+ 'selected': True,
|
|
|
|
+ 'votes': 1
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'gggggggggggg',
|
|
|
|
+ 'label': 'Gamma',
|
|
|
|
+ 'selected': False,
|
|
|
|
+ 'votes': 1
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'dddddddddddd',
|
|
|
|
+ 'label': 'Delta',
|
|
|
|
+ 'selected': False,
|
|
|
|
+ 'votes': 0
|
|
|
|
+ },
|
|
|
|
+ ],
|
|
|
|
+ 'api': {
|
|
|
|
+ 'index': self.poll.get_api_url(),
|
|
|
|
+ 'votes': self.poll.get_votes_api_url(),
|
|
|
|
+ },
|
|
|
|
+ 'url': {
|
|
|
|
+ 'poster': self.user.get_absolute_url(),
|
|
|
|
+ },
|
|
|
|
+ })
|
|
|
|
|
|
# validate state change
|
|
# validate state change
|
|
poll = Poll.objects.get(pk=self.poll.pk)
|
|
poll = Poll.objects.get(pk=self.poll.pk)
|
|
self.assertEqual(poll.votes, 4)
|
|
self.assertEqual(poll.votes, 4)
|
|
- self.assertEqual([c['votes'] for c in poll.choices], [2, 1, 1, 0])
|
|
|
|
-
|
|
|
|
- for choice in poll.choices:
|
|
|
|
- self.assertNotIn('selected', choice)
|
|
|
|
|
|
+ self.assertEqual(poll.choices, [
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'aaaaaaaaaaaa',
|
|
|
|
+ 'label': 'Alpha',
|
|
|
|
+ 'votes': 2
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'bbbbbbbbbbbb',
|
|
|
|
+ 'label': 'Beta',
|
|
|
|
+ 'votes': 1
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'gggggggggggg',
|
|
|
|
+ 'label': 'Gamma',
|
|
|
|
+ 'votes': 1
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'dddddddddddd',
|
|
|
|
+ 'label': 'Delta',
|
|
|
|
+ 'votes': 0
|
|
|
|
+ },
|
|
|
|
+ ])
|
|
|
|
|
|
self.assertEqual(poll.pollvote_set.count(), 4)
|
|
self.assertEqual(poll.pollvote_set.count(), 4)
|
|
|
|
|
|
- # validate response json
|
|
|
|
- response_json = response.json()
|
|
|
|
- self.assertEqual(response_json['votes'], 4)
|
|
|
|
- self.assertEqual([c['votes'] for c in response_json['choices']], [2, 1, 1, 0])
|
|
|
|
- self.assertEqual([c['selected'] for c in response_json['choices']],
|
|
|
|
- [True, True, False, False])
|
|
|
|
-
|
|
|
|
- self.assertFalse(response_json['acl']['can_vote'])
|
|
|
|
|
|
+ # validate poll disallows for revote
|
|
|
|
+ response = self.post(self.api_link, data=['aaaaaaaaaaaa'])
|
|
|
|
+ self.assertEqual(response.status_code, 403)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'detail': "You have already voted in this poll.",
|
|
|
|
+ })
|
|
|
|
|
|
def test_vote_change(self):
|
|
def test_vote_change(self):
|
|
"""api handles vote change"""
|
|
"""api handles vote change"""
|
|
self.poll.allow_revotes = True
|
|
self.poll.allow_revotes = True
|
|
self.poll.save()
|
|
self.poll.save()
|
|
|
|
|
|
|
|
+ add_acl(self.user, self.poll)
|
|
|
|
+
|
|
response = self.post(self.api_link, data=['aaaaaaaaaaaa', 'bbbbbbbbbbbb'])
|
|
response = self.post(self.api_link, data=['aaaaaaaaaaaa', 'bbbbbbbbbbbb'])
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
+ self.assertEqual(response.json(), {
|
|
|
|
+ 'id': self.poll.id,
|
|
|
|
+ 'poster_name': self.user.username,
|
|
|
|
+ 'posted_on': serialize_datetime(self.poll.posted_on),
|
|
|
|
+ 'length': 0,
|
|
|
|
+ 'question': "Lorem ipsum dolor met?",
|
|
|
|
+ 'allowed_choices': 2,
|
|
|
|
+ 'allow_revotes': True,
|
|
|
|
+ 'votes': 4,
|
|
|
|
+ 'is_public': False,
|
|
|
|
+ 'acl': self.poll.acl,
|
|
|
|
+ 'choices': [
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'aaaaaaaaaaaa',
|
|
|
|
+ 'label': 'Alpha',
|
|
|
|
+ 'selected': True,
|
|
|
|
+ 'votes': 2
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'bbbbbbbbbbbb',
|
|
|
|
+ 'label': 'Beta',
|
|
|
|
+ 'selected': True,
|
|
|
|
+ 'votes': 1
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'gggggggggggg',
|
|
|
|
+ 'label': 'Gamma',
|
|
|
|
+ 'selected': False,
|
|
|
|
+ 'votes': 1
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'dddddddddddd',
|
|
|
|
+ 'label': 'Delta',
|
|
|
|
+ 'selected': False,
|
|
|
|
+ 'votes': 0
|
|
|
|
+ },
|
|
|
|
+ ],
|
|
|
|
+ 'api': {
|
|
|
|
+ 'index': self.poll.get_api_url(),
|
|
|
|
+ 'votes': self.poll.get_votes_api_url(),
|
|
|
|
+ },
|
|
|
|
+ 'url': {
|
|
|
|
+ 'poster': self.user.get_absolute_url(),
|
|
|
|
+ },
|
|
|
|
+ })
|
|
|
|
|
|
# validate state change
|
|
# validate state change
|
|
poll = Poll.objects.get(pk=self.poll.pk)
|
|
poll = Poll.objects.get(pk=self.poll.pk)
|
|
self.assertEqual(poll.votes, 4)
|
|
self.assertEqual(poll.votes, 4)
|
|
- self.assertEqual([c['votes'] for c in poll.choices], [2, 1, 1, 0])
|
|
|
|
-
|
|
|
|
- for choice in poll.choices:
|
|
|
|
- self.assertNotIn('selected', choice)
|
|
|
|
|
|
+ self.assertEqual(poll.choices, [
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'aaaaaaaaaaaa',
|
|
|
|
+ 'label': 'Alpha',
|
|
|
|
+ 'votes': 2
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'bbbbbbbbbbbb',
|
|
|
|
+ 'label': 'Beta',
|
|
|
|
+ 'votes': 1
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'gggggggggggg',
|
|
|
|
+ 'label': 'Gamma',
|
|
|
|
+ 'votes': 1
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ 'hash': 'dddddddddddd',
|
|
|
|
+ 'label': 'Delta',
|
|
|
|
+ 'votes': 0
|
|
|
|
+ },
|
|
|
|
+ ])
|
|
|
|
|
|
self.assertEqual(poll.pollvote_set.count(), 4)
|
|
self.assertEqual(poll.pollvote_set.count(), 4)
|
|
|
|
|
|
- # validate response json
|
|
|
|
- response_json = response.json()
|
|
|
|
- self.assertEqual(response_json['votes'], 4)
|
|
|
|
- self.assertEqual([c['votes'] for c in response_json['choices']], [2, 1, 1, 0])
|
|
|
|
- self.assertEqual([c['selected'] for c in response_json['choices']],
|
|
|
|
- [True, True, False, False])
|
|
|
|
-
|
|
|
|
- self.assertTrue(response_json['acl']['can_vote'])
|
|
|
|
|
|
+ # validate poll allows for revote
|
|
|
|
+ response = self.post(self.api_link, data=['aaaaaaaaaaaa'])
|
|
|
|
+ self.assertEqual(response.status_code, 200)
|