"""
Unit Tests for Helios
"""
import datetime
import re
import urllib
import django_webtest
import uuid
from django.conf import settings
from django.core import mail
from django.core.files import File
from django.test import TestCase
from django.utils.html import escape as html_escape
import helios.datatypes as datatypes
import helios.models as models
import helios.utils as utils
import helios.views as views
from helios_auth import models as auth_models
class ElectionModelTests(TestCase):
fixtures = ['users.json']
allow_database_queries = True
def create_election(self):
return models.Election.get_or_create(
short_name='demo',
name='Demo Election',
description='Demo Election Description',
admin=self.user)
def setup_questions(self):
QUESTIONS = [{"answer_urls": [None, None, None], "answers": ["a", "b", "c"], "choice_type": "approval", "max": 1, "min": 0, "question": "w?", "result_type": "absolute", "short_name": "w?", "tally_type": "homomorphic"}]
self.election.questions = QUESTIONS
def setup_trustee(self):
self.election.generate_trustee(views.ELGAMAL_PARAMS)
def setup_openreg(self):
self.election.openreg=True
self.election.save()
def setUp(self):
self.user = auth_models.User.objects.get(user_id='ben@adida.net', user_type='google')
self.fb_user = auth_models.User.objects.filter(user_type='facebook')[0]
self.election, self.created_p = self.create_election()
def test_create_election(self):
# election should be created
self.assertTrue(self.created_p)
# should have a creation time
self.assertNotEquals(self.election.created_at, None)
self.assertTrue(self.election.created_at < datetime.datetime.utcnow())
def test_find_election(self):
election = models.Election.get_by_user_as_admin(self.user)[0]
self.assertEquals(self.election, election)
election = models.Election.get_by_uuid(self.election.uuid)
self.assertEquals(self.election, election)
election = models.Election.get_by_short_name(self.election.short_name)
self.assertEquals(self.election, election)
def test_setup_trustee(self):
self.setup_trustee()
self.assertEquals(self.election.num_trustees, 1)
def test_add_voters_file(self):
election = self.election
FILE = "helios/fixtures/voter-file.csv"
vf = models.VoterFile.objects.create(election = election, voter_file = File(open(FILE), "voter_file.css"))
vf.process()
# make sure that we stripped things correctly
voter = election.voter_set.get(voter_login_id = 'benadida5')
self.assertEquals(voter.voter_email, 'ben5@adida.net')
self.assertEquals(voter.voter_name, 'Ben5 Adida')
def test_check_issues_before_freeze(self):
# should be three issues: no trustees, and no questions, and no voters
issues = self.election.issues_before_freeze
self.assertEquals(len(issues), 3)
self.setup_questions()
# should be two issues: no trustees, and no voters
issues = self.election.issues_before_freeze
self.assertEquals(len(issues), 2)
self.election.questions = None
self.setup_trustee()
# should be two issues: no questions, and no voters
issues = self.election.issues_before_freeze
self.assertEquals(len(issues), 2)
self.setup_questions()
# move to open reg
self.setup_openreg()
issues = self.election.issues_before_freeze
self.assertEquals(len(issues), 0)
def test_helios_trustee(self):
self.election.generate_trustee(views.ELGAMAL_PARAMS)
self.assertTrue(self.election.has_helios_trustee())
trustee = self.election.get_helios_trustee()
self.assertNotEquals(trustee, None)
def test_log(self):
LOGS = ["testing 1", "testing 2", "testing 3"]
for l in LOGS:
self.election.append_log(l)
pulled_logs = [l.log for l in self.election.get_log().all()]
pulled_logs.reverse()
self.assertEquals(LOGS,pulled_logs)
def test_eligibility(self):
self.election.eligibility = [{'auth_system': self.user.user_type}]
# without openreg, this should be false
self.assertFalse(self.election.user_eligible_p(self.user))
# what about after saving?
self.election.save()
e = models.Election.objects.get(uuid = self.election.uuid)
self.assertEquals(e.eligibility, [{'auth_system': self.user.user_type}])
self.election.openreg = True
# without openreg, and now true
self.assertTrue(self.election.user_eligible_p(self.user))
# try getting pretty eligibility, make sure it doesn't throw an exception
assert self.user.user_type in self.election.pretty_eligibility
def test_facebook_eligibility(self):
self.election.eligibility = [{'auth_system': 'facebook', 'constraint':[{'group': {'id': '123', 'name':'Fake Group'}}]}]
# without openreg, this should be false
self.assertFalse(self.election.user_eligible_p(self.fb_user))
self.election.openreg = True
# fake out the facebook constraint checking, since
# our access_token is obviously wrong
from helios_auth.auth_systems import facebook
def fake_check_constraint(constraint, user):
return constraint == {'group': {'id': '123', 'name':'Fake Group'}} and user == self.fb_user
facebook.check_constraint = fake_check_constraint
self.assertTrue(self.election.user_eligible_p(self.fb_user))
# also check that eligibility_category_id does the right thing
self.assertEquals(self.election.eligibility_category_id('facebook'), '123')
def test_freeze(self):
# freezing without trustees and questions, no good
def try_freeze():
self.election.freeze()
self.assertRaises(Exception, try_freeze)
self.setup_questions()
self.setup_trustee()
self.setup_openreg()
# this time it should work
try_freeze()
# make sure it logged something
self.assertTrue(len(self.election.get_log().all()) > 0)
def test_archive(self):
self.election.archived_at = datetime.datetime.utcnow()
self.assertTrue(self.election.is_archived)
self.election.archived_at = None
self.assertFalse(self.election.is_archived)
def test_voter_registration(self):
# before adding a voter
voters = models.Voter.get_by_election(self.election)
self.assertEquals(0, len(voters))
# make sure no voter yet
voter = models.Voter.get_by_election_and_user(self.election, self.user)
self.assertIsNone(voter)
# make sure no voter at all across all elections
voters = models.Voter.get_by_user(self.user)
self.assertEquals(0, len(voters))
# register the voter
voter = models.Voter.register_user_in_election(self.user, self.election)
# make sure voter is there now
voter_2 = models.Voter.get_by_election_and_user(self.election, self.user)
self.assertIsNotNone(voter)
self.assertIsNotNone(voter_2)
self.assertEquals(voter, voter_2)
# make sure voter is there in this call too
voters = models.Voter.get_by_user(self.user)
self.assertEquals(1, len(voters))
self.assertEquals(voter, voters[0])
voter_2 = models.Voter.get_by_election_and_uuid(self.election, voter.uuid)
self.assertEquals(voter, voter_2)
self.assertEquals(voter.user, self.user)
class VoterModelTests(TestCase):
fixtures = ['users.json', 'election.json']
allow_database_queries = True
def setUp(self):
self.election = models.Election.objects.get(short_name='test')
def test_create_password_voter(self):
v = models.Voter(uuid = str(uuid.uuid1()), election = self.election, voter_login_id = 'voter_test_1', voter_name = 'Voter Test 1', voter_email='foobar@acme.com')
v.generate_password()
v.save()
# password has been generated!
self.assertFalse(v.voter_password == None)
# can't generate passwords twice
self.assertRaises(Exception, lambda: v.generate_password())
# check that you can get at the voter user structure
self.assertEquals(v.get_user().user_id, v.voter_email)
class CastVoteModelTests(TestCase):
fixtures = ['users.json', 'election.json']
allow_database_queries = True
def setUp(self):
self.election = models.Election.objects.get(short_name='test')
self.user = auth_models.User.objects.get(user_id='ben@adida.net', user_type='google')
# register the voter
self.voter = models.Voter.register_user_in_election(self.user, self.election)
def test_cast_vote(self):
pass
class DatatypeTests(TestCase):
fixtures = ['users.json', 'election.json']
allow_database_queries = True
def setUp(self):
self.election = models.Election.objects.all()[0]
self.election.generate_trustee(views.ELGAMAL_PARAMS)
def test_instantiate(self):
ld_obj = datatypes.LDObject.instantiate(self.election.get_helios_trustee(), '2011/01/Trustee')
foo = ld_obj.serialize()
def test_from_dict(self):
ld_obj = datatypes.LDObject.fromDict({
'y' : '1234',
'p' : '23434',
'g' : '2343243242',
'q' : '2343242343434'}, type_hint = 'pkc/elgamal/PublicKey')
def test_dictobject_from_dict(self):
original_dict = {
'A' : '35423432',
'B' : '234324243'}
ld_obj = datatypes.LDObject.fromDict(original_dict, type_hint = 'legacy/EGZKProofCommitment')
self.assertEquals(original_dict, ld_obj.toDict())
##
## Black box tests
##
class DataFormatBlackboxTests(object):
def setUp(self):
self.election = models.Election.objects.all()[0]
def assertEqualsToFile(self, response, file_path):
expected = open(file_path)
self.assertEquals(response.content, expected.read())
expected.close()
def test_election(self):
response = self.client.get("/helios/elections/%s" % self.election.uuid, follow=False)
self.assertEqualsToFile(response, self.EXPECTED_ELECTION_FILE)
def test_election_metadata(self):
response = self.client.get("/helios/elections/%s/meta" % self.election.uuid, follow=False)
self.assertEqualsToFile(response, self.EXPECTED_ELECTION_METADATA_FILE)
def test_voters_list(self):
response = self.client.get("/helios/elections/%s/voters/" % self.election.uuid, follow=False)
self.assertEqualsToFile(response, self.EXPECTED_VOTERS_FILE)
def test_trustees_list(self):
response = self.client.get("/helios/elections/%s/trustees/" % self.election.uuid, follow=False)
self.assertEqualsToFile(response, self.EXPECTED_TRUSTEES_FILE)
def test_ballots_list(self):
response = self.client.get("/helios/elections/%s/ballots/" % self.election.uuid, follow=False)
self.assertEqualsToFile(response, self.EXPECTED_BALLOTS_FILE)
## now we have a set of fixtures and expected results for various formats
## note how TestCase is used as a "mixin" here, so that the generic DataFormatBlackboxTests
## does not register as a set of test cases to run, but each concrete data format does.
class LegacyElectionBlackboxTests(DataFormatBlackboxTests, TestCase):
fixtures = ['legacy-data.json']
allow_database_queries = True
EXPECTED_ELECTION_FILE = 'helios/fixtures/legacy-election-expected.json'
EXPECTED_ELECTION_METADATA_FILE = 'helios/fixtures/legacy-election-metadata-expected.json'
EXPECTED_VOTERS_FILE = 'helios/fixtures/legacy-election-voters-expected.json'
EXPECTED_TRUSTEES_FILE = 'helios/fixtures/legacy-trustees-expected.json'
EXPECTED_BALLOTS_FILE = 'helios/fixtures/legacy-ballots-expected.json'
#class V3_1_ElectionBlackboxTests(DataFormatBlackboxTests, TestCase):
# fixtures = ['v3.1-data.json']
# EXPECTED_ELECTION_FILE = 'helios/fixtures/v3.1-election-expected.json'
# EXPECTED_VOTERS_FILE = 'helios/fixtures/v3.1-election-voters-expected.json'
# EXPECTED_TRUSTEES_FILE = 'helios/fixtures/v3.1-trustees-expected.json'
# EXPECTED_BALLOTS_FILE = 'helios/fixtures/v3.1-ballots-expected.json'
class WebTest(django_webtest.WebTest):
def assertStatusCode(self, response, status_code):
if hasattr(response, 'status_code'):
assert response.status_code == status_code, response.status_code
else:
assert response.status_int == status_code, response.status_int
def assertRedirects(self, response, url):
"""
reimplement this in case it's a WebOp response
and it seems to be screwing up in a few places too
thus the localhost exception
"""
if hasattr(response, 'location'):
assert url in response.location, response.location
else:
assert url in response['location'], response['location']
self.assertStatusCode(response, 302)
#return super(django_webtest.WebTest, self).assertRedirects(response, url)
#assert url in response.location, "redirected to %s instead of %s" % (response.location, url)
def assertContains(self, response, text):
self.assertStatusCode(response, 200)
if hasattr(response, "testbody"):
assert text in response.testbody, "missing text %s" % text
elif hasattr(response, "body"):
assert text in response.body, "missing text %s" % text
else:
assert text in response.content, "missing text %s" % text
##
## overall operation of the system
##
class ElectionBlackboxTests(WebTest):
fixtures = ['users.json', 'election.json']
allow_database_queries = True
def setUp(self):
self.election = models.Election.objects.all()[0]
self.user = auth_models.User.objects.get(user_id='ben@adida.net', user_type='google')
def setup_login(self, from_scratch=False, **kwargs):
if from_scratch:
# a bogus call to set up the session
self.client.get("/")
# set up the session
session = self.client.session
if kwargs:
user = auth_models.User.objects.get(**kwargs)
else:
user = self.user
session['user'] = {'type': user.user_type, 'user_id': user.user_id}
session.save()
# set up the app, too
# this does not appear to work, boohoo
#session = self.app.session
#session['user'] = {'type': self.user.user_type, 'user_id': self.user.user_id}
def clear_login(self):
session = self.client.session
del session['user']
session.save()
def test_election_params(self):
response = self.client.get("/helios/elections/params")
self.assertEquals(response.content, views.ELGAMAL_PARAMS_LD_OBJECT.serialize())
def test_election_404(self):
response = self.client.get("/helios/elections/foobar")
self.assertStatusCode(response, 404)
def test_election_bad_trustee(self):
response = self.client.get("/helios/t/%s/foobar@bar.com/badsecret" % self.election.short_name)
self.assertStatusCode(response, 404)
def test_get_election_shortcut(self):
response = self.client.get("/helios/e/%s" % self.election.short_name, follow=True)
self.assertContains(response, self.election.description)
def test_get_election_raw(self):
response = self.client.get("/helios/elections/%s" % self.election.uuid, follow=False)
self.assertEquals(response.content, self.election.toJSON())
def test_get_election(self):
response = self.client.get("/helios/elections/%s/view" % self.election.uuid, follow=False)
self.assertContains(response, self.election.description)
def test_get_election_questions(self):
response = self.client.get("/helios/elections/%s/questions" % self.election.uuid, follow=False)
for q in self.election.questions:
self.assertContains(response, q['question'])
def test_get_election_trustees(self):
response = self.client.get("/helios/elections/%s/trustees" % self.election.uuid, follow=False)
for t in self.election.trustee_set.all():
self.assertContains(response, t.name)
def test_get_election_voters(self):
response = self.client.get("/helios/elections/%s/voters/list" % self.election.uuid, follow=False)
# check total count of voters
if self.election.num_voters == 0:
self.assertContains(response, "no voters")
else:
self.assertContains(response, "(of %s)" % self.election.num_voters)
def test_get_election_voters_raw(self):
response = self.client.get("/helios/elections/%s/voters/" % self.election.uuid, follow=False)
self.assertEquals(len(utils.from_json(response.content)), self.election.num_voters)
def test_election_creation_not_logged_in(self):
response = self.client.post("/helios/elections/new", {
"short_name" : "test-complete",
"name" : "Test Complete",
"description" : "A complete election test",
"election_type" : "referendum",
"use_voter_aliases": "0",
"use_advanced_audit_features": "1",
"private_p" : "False"})
self.assertRedirects(response, "/auth/?return_url=/helios/elections/new")
def test_election_edit(self):
self.setup_login(from_scratch=True)
response = self.client.get("/helios/elections/%s/edit" % self.election.uuid)
response = self.client.post("/helios/elections/%s/edit" % self.election.uuid, {
"short_name" : self.election.short_name + "-2",
"name" : self.election.name,
"description" : self.election.description,
"election_type" : self.election.election_type,
"use_voter_aliases": self.election.use_voter_aliases,
'csrf_token': self.client.session['csrf_token']
})
self.assertRedirects(response, "/helios/elections/%s/view" % self.election.uuid)
new_election = models.Election.objects.get(uuid = self.election.uuid)
self.assertEquals(new_election.short_name, self.election.short_name + "-2")
def test_get_election_stats(self):
self.setup_login(from_scratch=True, user_id='mccio@github.com', user_type='google')
response = self.client.get("/helios/stats/", follow=False)
self.assertStatusCode(response, 200)
response = self.client.get("/helios/stats/force-queue", follow=False)
self.assertRedirects(response, "/helios/stats/")
response = self.client.get("/helios/stats/elections", follow=False)
self.assertStatusCode(response, 200)
response = self.client.get("/helios/stats/problem-elections", follow=False)
self.assertStatusCode(response, 200)
response = self.client.get("/helios/stats/recent-votes", follow=False)
self.assertStatusCode(response, 200)
self.clear_login()
response = self.client.get("/helios/stats/", follow=False)
self.assertStatusCode(response, 403)
self.setup_login()
response = self.client.get("/helios/stats/", follow=False)
self.assertStatusCode(response, 403)
self.clear_login()
def _setup_complete_election(self, election_params=None):
"do the setup part of a whole election"
# REPLACE with params?
self.setup_login(from_scratch=True)
# create the election
full_election_params = {
"short_name" : "test-complete",
"name" : "Test Complete",
"description" : "A complete election test",
"election_type" : "referendum",
"use_voter_aliases": "0",
"use_advanced_audit_features": "1",
"private_p" : "False",
'csrf_token': self.client.session['csrf_token']
}
# override with the given
full_election_params.update(election_params or {})
response = self.client.post("/helios/elections/new", full_election_params)
# we are redirected to the election, let's extract the ID out of the URL
election_id = re.search('/elections/([^/]+)/', str(response['Location']))
self.assertIsNotNone(election_id, "Election id not found in redirect: %s" % str(response['Location']))
election_id = election_id.group(1)
# helios is automatically added as a trustee
# check that helios is indeed a trustee
response = self.client.get("/helios/elections/%s/trustees/view" % election_id)
self.assertContains(response, "Trustee #1")
# add a few voters with an improperly placed email address
FILE = "helios/fixtures/voter-badfile.csv"
voters_file = open(FILE)
response = self.client.post("/helios/elections/%s/voters/upload" % election_id, {'voters_file': voters_file})
voters_file.close()
self.assertContains(response, "HOLD ON")
# add a few voters, via file upload
# this file now includes a UTF-8 encoded unicode character
# yes I know that's not how you spell Ernesto.
# I just needed some unicode quickly.
FILE = "helios/fixtures/voter-file.csv"
voters_file = open(FILE)
response = self.client.post("/helios/elections/%s/voters/upload" % election_id, {'voters_file': voters_file})
voters_file.close()
self.assertContains(response, "first few rows of this file")
# now we confirm the upload
response = self.client.post("/helios/elections/%s/voters/upload" % election_id, {'confirm_p': "1"})
self.assertRedirects(response, "/helios/elections/%s/voters/list" % election_id)
# and we want to check that there are now voters
response = self.client.get("/helios/elections/%s/voters/" % election_id)
NUM_VOTERS = 4
self.assertEquals(len(utils.from_json(response.content)), NUM_VOTERS)
# let's get a single voter
single_voter = models.Election.objects.get(uuid = election_id).voter_set.all()[0]
response = self.client.get("/helios/elections/%s/voters/%s" % (election_id, single_voter.uuid))
self.assertContains(response, '"uuid": "%s"' % single_voter.uuid)
response = self.client.get("/helios/elections/%s/voters/foobar" % election_id)
self.assertStatusCode(response, 404)
# add questions
response = self.client.post("/helios/elections/%s/save_questions" % election_id, {
'questions_json': utils.to_json([{"answer_urls": ["http://example.com",None], "answers": ["Alice", "Bob"], "choice_type": "approval", "max": 1, "min": 0, "question": "Who should be president?", "result_type": "absolute", "short_name": "Who should be president?", "tally_type": "homomorphic"}]),
'csrf_token': self.client.session['csrf_token']})
self.assertContains(response, "SUCCESS")
# freeze election
response = self.client.post("/helios/elections/%s/freeze" % election_id, {
"csrf_token" : self.client.session['csrf_token']})
self.assertRedirects(response, "/helios/elections/%s/view" % election_id)
# email the voters
num_messages_before = len(mail.outbox)
response = self.client.post("/helios/elections/%s/voters/email" % election_id, {
"csrf_token" : self.client.session['csrf_token'],
"subject" : "your password",
"body" : "time to vote",
"suppress_election_links" : "0",
"send_to" : "all"
})
self.assertRedirects(response, "/helios/elections/%s/view" % election_id)
num_messages_after = len(mail.outbox)
self.assertEquals(num_messages_after - num_messages_before, NUM_VOTERS)
email_message = mail.outbox[num_messages_before]
assert "your password" in email_message.subject, "bad subject in email"
# get the username and password
username = re.search('voter ID: (.*)', email_message.body).group(1)
password = re.search('password: (.*)', email_message.body).group(1)
# now log out as administrator
self.clear_login()
self.assertEquals(self.client.session.has_key('user'), False)
# return the voter username and password to vote
return election_id, username, password
def _cast_ballot(self, election_id, username, password, need_login=True, check_user_logged_in=False):
"""
check_user_logged_in looks for the "you're already logged" message
"""
# vote by preparing a ballot via the server-side encryption
response = self.app.post("/helios/elections/%s/encrypt-ballot" % election_id,
params={'answers_json': utils.to_json([[1]])})
self.assertContains(response, "answers")
# parse it as an encrypted vote with randomness, and make sure randomness is there
the_ballot = utils.from_json(response.testbody)
assert the_ballot['answers'][0].has_key('randomness'), "no randomness"
assert len(the_ballot['answers'][0]['randomness']) == 2, "not enough randomness"
# parse it as an encrypted vote, and re-serialize it
ballot = datatypes.LDObject.fromDict(utils.from_json(response.testbody), type_hint='legacy/EncryptedVote')
encrypted_vote = ballot.serialize()
# cast the ballot
response = self.app.post("/helios/elections/%s/cast" % election_id,
params={'encrypted_vote': encrypted_vote})
self.assertRedirects(response, "%s/helios/elections/%s/cast_confirm" % (settings.SECURE_URL_HOST, election_id))
cast_confirm_page = response.follow()
if need_login:
if check_user_logged_in:
self.assertContains(cast_confirm_page, "You are logged in as")
self.assertContains(cast_confirm_page, "requires election-specific credentials")
# set the form
login_form = cast_confirm_page.form
login_form['voter_id'] = username
login_form['password'] = password
response = login_form.submit()
else:
# here we should be at the cast-confirm page and logged in
self.assertContains(cast_confirm_page, "CAST this ballot")
# confirm the vote, now with the actual form
cast_form = cast_confirm_page.form
if 'status_update' in cast_form.fields.keys():
cast_form['status_update'] = False
response = cast_form.submit()
self.assertRedirects(response, "%s/helios/elections/%s/cast_done" % (settings.URL_HOST, election_id))
# at this point an email should have gone out to the user
# at position num_messages after, since that was the len() before we cast this ballot
email_message = mail.outbox[len(mail.outbox) - 1]
url = re.search('https?://[^/]+(/[^ \n]*)', email_message.body).group(1)
# check that we can get at that URL
if not need_login:
# confusing piece: if need_login is True, that means it was a public election
# that required login before casting a ballot.
# so if need_login is False, it was a private election, and we do need to re-login here
# we need to re-login if it's a private election, because all data, including ballots
# is otherwise private
login_page = self.app.get("/helios/elections/%s/password_voter_login" % election_id)
# if we redirected, that's because we can see the page, I think
if login_page.status_int != 302:
login_form = login_page.form
# try with extra spaces
login_form['voter_id'] = ' ' + username + ' '
login_form['password'] = ' ' + password + ' '
login_form.submit()
response = self.app.get(url, auto_follow=True)
self.assertContains(response, ballot.hash)
self.assertContains(response, html_escape(encrypted_vote))
# if we request the redirect to cast_done, the voter should be logged out, but not the user
response = self.app.get("/helios/elections/%s/cast_done" % election_id)
# FIXME: how to check this? We can't do it by checking session that we're doign webtes
# assert not self.client.session.has_key('CURRENT_VOTER')
def _do_tally(self, election_id):
# log back in as administrator
self.setup_login()
# encrypted tally
response = self.client.post("/helios/elections/%s/compute_tally" % election_id, {
"csrf_token" : self.client.session['csrf_token']
})
self.assertRedirects(response, "/helios/elections/%s/view" % election_id)
# should trigger helios decryption automatically
self.assertNotEquals(models.Election.objects.get(uuid=election_id).get_helios_trustee().decryption_proofs, None)
# combine decryptions
response = self.client.post("/helios/elections/%s/combine_decryptions" % election_id, {
"csrf_token" : self.client.session['csrf_token'],
})
# after tallying, we now go back to election_view
self.assertRedirects(response, "/helios/elections/%s/view" % election_id)
# check that we can't get the tally yet
response = self.client.get("/helios/elections/%s/result" % election_id)
self.assertStatusCode(response, 403)
# release
response = self.client.post("/helios/elections/%s/release_result" % election_id, {
"csrf_token" : self.client.session['csrf_token'],
})
# check that tally matches
response = self.client.get("/helios/elections/%s/result" % election_id)
self.assertEquals(utils.from_json(response.content), [[0,1]])
def test_do_complete_election(self):
election_id, username, password = self._setup_complete_election()
# cast a ballot while not logged in
self._cast_ballot(election_id, username, password, check_user_logged_in=False)
# cast a ballot while logged in as a user (not a voter)
self.setup_login()
## for now the above does not work, it's a testing problem
## where the cookie isn't properly set. We'll have to figure this out.
## FIXME FIXME FIXME
#self._cast_ballot(election_id, username, password, check_user_logged_in=True)
self._cast_ballot(election_id, username, password, check_user_logged_in=False)
self.clear_login()
self._do_tally(election_id)
def test_do_complete_election_private(self):
# private election
election_id, username, password = self._setup_complete_election({'private_p' : "True"})
# get the password_voter_login_form via the front page
# (which will test that redirects are doing the right thing)
response = self.app.get("/helios/elections/%s/view" % election_id)
# ensure it redirects
self.assertRedirects(response, "/helios/elections/%s/password_voter_login?%s" % (election_id, urllib.urlencode({"return_url": "/helios/elections/%s/view" % election_id})))
login_form = response.follow().form
login_form['voter_id'] = username
login_form['password'] = password
response = login_form.submit()
self.assertRedirects(response, "/helios/elections/%s/view" % election_id)
self._cast_ballot(election_id, username, password, need_login = False)
self._do_tally(election_id)
def test_election_voters_eligibility(self):
# create the election
self.setup_login(from_scratch=True)
response = self.client.post("/helios/elections/new", {
"short_name" : "test-eligibility",
"name" : "Test Eligibility",
"description" : "An election test for voter eligibility",
"election_type" : "election",
"use_voter_aliases": "0",
"use_advanced_audit_features": "1",
"private_p" : "False",
'csrf_token': self.client.session['csrf_token']})
election_id = re.match("(.*)/elections/(.*)/view", str(response['Location']))
self.assertIsNotNone(election_id, "Election id not found in redirect: %s" % str(response['Location']))
election_id = election_id.group(2)
# update eligiblity
response = self.client.post("/helios/elections/%s/voters/eligibility" % election_id, {
"csrf_token" : self.client.session['csrf_token'],
"eligibility": "openreg"})
self.clear_login()
response = self.client.get("/helios/elections/%s/voters/list" % election_id)
self.assertContains(response, "Anyone can vote")
self.setup_login()
response = self.client.post("/helios/elections/%s/voters/eligibility" % election_id, {
"csrf_token" : self.client.session['csrf_token'],
"eligibility": "closedreg"})
self.clear_login()
response = self.client.get("/helios/elections/%s/voters/list" % election_id)
self.assertContains(response, "Only the voters listed here")
def test_do_complete_election_with_trustees(self):
"""
FIXME: do the this test
"""
pass