def test_vote__returned_options(self): from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import vote from pyramid.session import UnencryptedCookieSessionFactoryConfig from pyramid.url import route_url session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.config.add_route('select', '/valitse') self.config.testing_securitypolicy(userid=voter.openid) self.config.set_session_factory(UnencryptedCookieSessionFactoryConfig) request = DummyRequest() csrf_token = request.session.new_csrf_token() request.matchdict['number'] = '1' options = vote(request) self.assertEquals({ 'action_url': request.path_url, 'select_url': route_url('select', request), 'candidate': { 'number': 1, 'name': u'Turhapuro, Uuno', }, 'profile': { 'fullname': u'Matti Meikäläinen', 'district': u'Ahvenanmaan maakunnan vaalipiiri', }, 'error': False, 'csrf_token': csrf_token }, options)
def test_valid_voting_process__accept_openid(self): from nuorisovaalit.models import Voter # Fake the OpenID authentication. self.authenticate(u"http://example.com/id/matti.meikalainen") # Select a candidate. response = self.testapp.get("/valitse") response = response.click(href="/aanesta/1$") # Vote for the candidate. response.form[u"vote"] = u"1" response = response.form.submit() # Follow the redirect to the OpenID preference page. response = response.follow() # Fill in valid information and choose to keep the OpenID. response.form[u"gsm"] = u"0401234567" response.form[u"email"] = u"*****@*****.**" response.form[u"street"] = u"Söme street 16" response.form[u"zipcode"] = u"01234" response.form[u"city"] = u"Söme city, Länd" response.form[u"use_open_identity"] = u"yes" response = response.form.submit() self.assertEquals("302 Found", response.status) response = response.follow() self.assertEquals("200 OK", response.status) # Assert that the voter information is correct. session = DBSession() voter = session.query(Voter).filter_by(openid=u"http://example.com/id/matti.meikalainen").one() self.assertTrue(voter.accept_openid) self.assertEquals(u"0401234567", voter.gsm) self.assertEquals(u"*****@*****.**", voter.email) self.assertEquals(u"Söme street 16, 01234, Söme city, Länd", voter.address)
def test_vote_finish__declined(self): from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import vote_finish from pyramid.session import UnencryptedCookieSessionFactoryConfig from webob.exc import HTTPFound session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.assertEquals(False, voter.has_preference()) self.config.set_session_factory(UnencryptedCookieSessionFactoryConfig) self.config.testing_securitypolicy(userid=voter.openid) self.config.add_route('close-window', '/close-window') self.config.add_route('vote-finish', '/valmis') request = DummyRequest() csrf_token = request.session.new_csrf_token() request.POST = { 'form.submitted': u'1', 'csrf_token': csrf_token, 'use_open_identity': u'no', } response = vote_finish(request) self.assertTrue(isinstance(response, HTTPFound)) self.assertEquals('http://example.com/close-window', response.location) self.assertEquals(False, voter.accept_openid) self.assertEquals(True, voter.has_preference())
def test_valid_voting_process__decline_openid(self): from nuorisovaalit.models import Vote from nuorisovaalit.models import Voter from nuorisovaalit.models import VotingLog # Fake the OpenID authentication. self.authenticate(u"http://example.com/id/matti.meikalainen") # Select a candidate response = self.testapp.get("/valitse") self.assertEquals("200 OK", response.status) # Select a candidate response = response.click(href="/aanesta/1$") self.assertEquals("200 OK", response.status) # Assert we are showing the correct voter information self.assertEquals( [tag.text for tag in response.html.find("table", id="voter").findAll("td")], [u"Matti Meikäläinen", u"Ahvenanmaan maakunnan vaalipiiri"], ) # Assert we got the candidate we selected self.assertEquals(response.html.find("p", "candidate-name").text, u"1 Turhapuro, Uuno") # Vote for the candidate response.form[u"vote"] = u"1" response = response.form.submit() # The form submission uses a redirect to avoid accidental resubmissions. self.assertEquals("302 Found", response.status) response = response.follow() self.assertEquals("200 OK", response.status) # Assert the vote was registered self.assertEquals(response.html.find("h1").text, u"Äänesi on tallennettu") session = DBSession() self.assertEquals( 1, session.query(VotingLog).join(Voter).filter_by(openid=u"http://example.com/id/matti.meikalainen").count() ) self.assertEquals(1, session.query(Vote).count()) # Submit the OpenID preference form with default values which will # decline the offer to use OpenID in the future. response = response.form.submit() self.assertEquals("302 Found", response.status) response = response.follow() self.assertEquals("200 OK", response.status) # Assert that the accept_openid is False for the voter. session = DBSession() voter = session.query(Voter).filter_by(openid=u"http://example.com/id/matti.meikalainen").one() self.assertFalse(voter.accept_openid) # Assert we got logged out. self.assertEquals(self.testapp.cookies["auth_tkt"], "") # Assert we are suggested to close the browser window. self.assertEquals(response.html.h1.text, u"Sulje ikkuna")
def openid_response(request): """Processes the response of the OpenID provider and upon successful response authenticates the user. In order for a user to be authenticated the following criteria must be met: * the OpenID provider has responded with a positive assertation. * the verified OpenID identity must match an existing :py:attr:`nuorisovaalit.models.Voter.openid` record. In case the above criteria are not met the user is presented with an error page. :param request: The currently active request. :type request: :py:class:`pyramid.request.Request` """ log = logging.getLogger('nuorisovaalit') mode = request.params.get('openid.mode', None) if mode == 'id_res': # We received a positive authentication response. consumer = make_consumer(request) response = consumer.complete(request.params, request.url) if response.status == SUCCESS: identity = response.identity_url.rstrip('/') session = DBSession() user = session.query(Voter).filter(Voter.openid == identity).first() if user is None: log.warn('Failed to authenticate "{0}": unknown user.'.format(identity)) return openid_failure(request) log.info('Authenticated "{0}".'.format(identity)) if user.has_voted(): url = route_url('vote-finish', request) request.session['vote_registered'] = 'yes' log.info('User "{0}" has already voted.'.format(identity)) else: url = route_url('select', request) headers = remember(request, identity) return HTTPFound(location=url, headers=headers) else: log.warn('Failed to authenticate "{0}".'.format(response.identity_url)) return openid_failure(request) elif mode == 'cancel': # We received an explicit negative authentication response. log.info('OpenID authentication canceled.') return openid_canceled(request) else: log.warn('Unknown OpenID response mode: {0}.'.format(mode)) return openid_failure(request)
def _add_coalition(self, name, district, *parties): """Creates a new coalition containing the given parties.""" from nuorisovaalit.models import Coalition session = DBSession() coalition = Coalition(name, district) for party in parties: coalition.parties.append(party) session.add(coalition) session.flush()
def test_coalition__multiple_coalitions_in_different_districts(self): from nuorisovaalit.models import Coalition from nuorisovaalit.models import District from nuorisovaalit.models import Party district_x = District(u'District X', 1) district_y = District(u'District Y', 2) party = Party(u'Foobar') session = DBSession() session.add_all([district_x, district_y, party]) session.flush() coalition_x = Coalition(u'Reds', district_x) coalition_y = Coalition(u'Blues', district_y) session.add_all([coalition_x, coalition_y]) coalition_x.parties.append(party) coalition_y.parties.append(party) session.flush() self.assertEquals(coalition_x, party.coalition(district_x)) self.assertEquals(coalition_y, party.coalition(district_y))
def test_coalition__no_coalition(self): from nuorisovaalit.models import District from nuorisovaalit.models import Party district = District(u'District X', 1) party = Party(u'Foobar') session = DBSession() session.add_all([district, party]) session.flush() self.assertEquals(None, party.coalition(district))
def test_has_voted__negative(self): from nuorisovaalit.models import Voter from nuorisovaalit.models import VotingLog session = DBSession() populate_testing_db() # Make sure no-one has voted self.assertEquals(0, session.query(VotingLog).count()) # Make sure that a given user has not voted. voter = session.query(Voter).first() self.failIf(voter.has_voted())
def create_districts(): """Populates the database with information about the voting districts. """ session = DBSession() districts = parse_districts( seats=datafile("../data/paikkamaarat.txt"), municipalities=datafile("../data/luokitusavain_kunta_teksti.txt") ) # Create voting districts and municipalities for (distname, code, seats), municipalities in districts.iteritems(): session.add(District(u"{0} vaalipiiri".format(distname), code, seats)) session.flush()
def test_vote_finish__accepted_empty_fields(self): from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import vote_finish from pyramid.session import UnencryptedCookieSessionFactoryConfig session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.assertEquals(False, voter.has_preference()) self.config.set_session_factory(UnencryptedCookieSessionFactoryConfig) self.config.testing_securitypolicy(userid=voter.openid) self.config.add_route('close-window', '/close-window') self.config.add_route('vote-finish', '/valmis') request = DummyRequest() csrf_token = request.session.new_csrf_token() request.POST = { 'csrf_token': csrf_token, 'use_open_identity': 'yes', 'gsm': u'', 'email': u'', 'street': u'', 'zipcode': u'', 'city': u'', 'form.submitted': u'1', } self.assertEquals({ 'action_url': 'http://example.com/valmis', 'csrf_token': csrf_token, 'accept_openid': True, 'message': u'Äänesi on tallennettu', 'has_preference': False, 'pref_selected': True, 'errors': [ u'GSM-numero on virheellinen, esimerkki oikeasta muodosta "0501234567".', u'Sähköpostiosoite on virheellinen, esimerkki oikeasta muodosta "*****@*****.**".', u'Katuosoite puuttuu.', u'Postinumero on virheellinen, esimerkki oikeasta muodosta "12345".', u'Postitoimipaikka puuttuu.', ], 'voter': voter, 'gsm': u'', 'email': u'', 'street': u'', 'zipcode': u'', 'city': u'', }, vote_finish(request)) self.assertEquals(False, voter.has_preference())
def test_vote__invalid_candidate_number(self): from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import vote from pyramid.exceptions import NotFound session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.config.testing_securitypolicy(userid=voter.openid) request = DummyRequest() request.matchdict['number'] = 666 self.assertRaises(NotFound, lambda: vote(request))
def test_vote_finish__message_vote_saved(self): from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import vote_finish from pyramid.session import UnencryptedCookieSessionFactoryConfig session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.config.set_session_factory(UnencryptedCookieSessionFactoryConfig) self.config.testing_securitypolicy(userid=voter.openid) self.config.add_route('vote-finish', '/valmis') self.assertEquals(u'Äänesi on tallennettu', vote_finish(DummyRequest())['message'])
def populate_demo(): """Populates a database with demo content.""" config = get_config() engine = engine_from_config(config, "sqlalchemy.") initialize_sql(engine) engine.echo = False session = DBSession() districts = session.query(District).order_by(District.code) provider = urlparse(config["nuorisovaalit.openid_provider"]) provider_tmpl = u"{0}://{{0}}.{1}".format(provider.scheme, provider.netloc) # Create voters for district in districts: username = u"test.user{0:02}".format(district.code) school = School(u"Koulu vaalipiirissä {0}".format(district.name), district) session.add(school) session.flush() session.add( Voter( provider_tmpl.format(username), u"Testi", u"Käyttäjä #{0:02}".format(district.code), date(1990, 4, 5), u"040 123 4567", u"*****@*****.**", u"Nowhere street 5, 00000 Helsinki", school, ) ) transaction.commit() print ("Created demo structure.")
def test_vote_finish__message_already_voted(self): from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import vote_finish from pyramid.session import UnencryptedCookieSessionFactoryConfig session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.config.set_session_factory(UnencryptedCookieSessionFactoryConfig) self.config.testing_securitypolicy(userid=voter.openid) self.config.add_route('vote-finish', '/valmis') request = DummyRequest() request.session['vote_registered'] = 'yes' self.assertEquals(u'Olet jo äänestänyt', vote_finish(request)['message'])
def test_vote_finish__preference_selection_missing(self): """Tests a case where the OpenID selection (yes or no) is missing.""" from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import vote_finish from pyramid.session import UnencryptedCookieSessionFactoryConfig session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.assertEquals(False, voter.has_preference()) self.config.set_session_factory(UnencryptedCookieSessionFactoryConfig) self.config.testing_securitypolicy(userid=voter.openid) self.config.add_route('close-window', '/close-window') self.config.add_route('vote-finish', '/valmis') request = DummyRequest() csrf_token = request.session.new_csrf_token() request.POST = { 'form.submitted': u'1', 'csrf_token': csrf_token, 'gsm': u' 00358- 40 1234 567', 'email': u'[email protected] \t', 'street': u' söme stréét', 'zipcode': u' 09123', 'city': u' citÜ', } self.assertEquals({ 'action_url': 'http://example.com/valmis', 'csrf_token': csrf_token, 'accept_openid': None, 'message': u'Äänesi on tallennettu', 'has_preference': False, 'pref_selected': False, 'errors': [ u'Valitse haluatko verkkovaikuttajaidentiteetin.', ], 'voter': voter, 'gsm': u' 00358- 40 1234 567', 'email': u'[email protected] \t', 'street': u' söme stréét', 'zipcode': u' 09123', 'city': u' citÜ', }, vote_finish(request)) self.failIf(voter.has_preference())
def test_exit_voting__declined(self): from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import exit_voting from pyramid.session import UnencryptedCookieSessionFactoryConfig from pyramid.url import route_url from webob.exc import HTTPFound session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.config.set_session_factory(UnencryptedCookieSessionFactoryConfig) self.config.testing_securitypolicy(userid=voter.openid) self.config.add_route('close-window', '/close-window') request = DummyRequest(post=dict(use_open_identity='no')) response = exit_voting(request) self.assertTrue(isinstance(response, HTTPFound)) self.assertEquals(route_url('close-window', request), response.location)
def test_select__already_voted(self): from nuorisovaalit.models import Voter from nuorisovaalit.models import VotingLog from nuorisovaalit.views.voting import select from pyramid.url import route_url from webob.exc import HTTPFound session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.config.testing_securitypolicy(userid=voter.openid) self.config.add_route('vote-finish', '/valmis') session = DBSession() session.add(VotingLog(voter.id)) request = DummyRequest() response = select(request) self.assertTrue(isinstance(response, HTTPFound)) self.assertEquals(route_url('vote-finish', request), response.location)
def test_vote__candidate_number_mismatch(self): from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import vote from pyramid.session import UnencryptedCookieSessionFactoryConfig session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.config.add_route('select', '/valitse') self.config.testing_securitypolicy(userid=voter.openid) self.config.set_session_factory(UnencryptedCookieSessionFactoryConfig) request = DummyRequest(post=dict(vote='1')) csrf_token = request.session.new_csrf_token() request.POST['csrf_token'] = csrf_token request.matchdict['number'] = '2' options = vote(request) self.assertTrue(options['error']) self.assertEquals(csrf_token, options['csrf_token'])
def test_select__with_candidates(self): from itertools import cycle from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import select session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.config.testing_securitypolicy(userid=voter.openid) self.config.add_route('vote', '/aanesta/{number}') options = select(DummyRequest()) for party in options['parties']: self.assertTrue(isinstance(party.pop('positions'), cycle)) party['candidates'] = list(party['candidates']) self.assertEquals({ 'coalitions': [], 'columns': 3, 'district': u'Ahvenanmaan maakunnan vaalipiiri', 'empty_vote_url': 'http://example.com/aanesta/0', 'parties': [{ 'candidates': [[{'name': u'Turhapuro, Uuno', 'number': 1, 'url': 'http://example.com/aanesta/1'}]], 'title': u'Köyhien asialla' }, { 'candidates': [[{'name': u'Hartikainen, Härski', 'number': 2, 'url': 'http://example.com/aanesta/2'}]], 'title': u'Piraattipuolue' }, { 'candidates': [[{'name': u'Sörsselssön, Sami', 'number': 3, 'url': 'http://example.com/aanesta/3'}]], 'title': u'Suomen työväenpuolue'} ] }, options)
def test_coalition__single_coalition(self): from nuorisovaalit.models import Coalition from nuorisovaalit.models import District from nuorisovaalit.models import Party district = District(u'District X', 1) party = Party(u'Foobar') session = DBSession() session.add_all([district, party]) session.flush() coalition = Coalition(u'Reds', district) session.add(coalition) coalition.parties.append(party) session.flush() self.assertEquals(coalition, party.coalition(district))
def test_vote_finish__invalid_csrf_token(self): from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import vote_finish from pyramid.session import UnencryptedCookieSessionFactoryConfig session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.config.set_session_factory(UnencryptedCookieSessionFactoryConfig) self.config.testing_securitypolicy(userid=voter.openid) self.config.add_route('exit-voting', '/exit') self.config.add_route('vote-finish', '/valmis') request = DummyRequest() csrf_token = request.session.new_csrf_token() request.POST = { 'form.submitted': u'1', 'csrf_token': 'invalid {0}'.format(csrf_token), } self.assertRaises(Forbidden, lambda: vote_finish(request))
def test_vote_finish__accepted_valid_submission(self): from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import vote_finish from pyramid.session import UnencryptedCookieSessionFactoryConfig from webob.exc import HTTPFound session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.assertEquals(False, voter.has_preference()) self.config.set_session_factory(UnencryptedCookieSessionFactoryConfig) self.config.testing_securitypolicy(userid=voter.openid) self.config.add_route('close-window', '/close-window') self.config.add_route('vote-finish', '/valmis') request = DummyRequest() csrf_token = request.session.new_csrf_token() request.POST = { 'form.submitted': u'1', 'csrf_token': csrf_token, 'use_open_identity': 'yes', 'gsm': u' 00358- 40 1234 567', 'email': u'[email protected] \t', 'street': u' söme stréét', 'zipcode': u' 09123', 'city': u' citÜ', } response = vote_finish(request) self.assertTrue(isinstance(response, HTTPFound)) self.assertEquals('http://example.com/close-window', response.location) self.assertEquals(True, voter.accept_openid) self.assertTrue(voter.has_preference()) self.assertEquals(u'00358401234567', voter.gsm) self.assertEquals(u'*****@*****.**', voter.email) self.assertEquals(u'söme stréét, 09123, citÜ', voter.address)
def test_openid_response__already_voted(self, make_consumer, openid_failure): from datetime import datetime from nuorisovaalit.models import District from nuorisovaalit.models import School from nuorisovaalit.models import Voter from nuorisovaalit.models import VotingLog from nuorisovaalit.views.login import openid_response from openid.consumer.consumer import SUCCESS from pyramid.url import route_url from webob.exc import HTTPFound self.config.add_route('vote-finish', '/valmis') self.config.add_route('select', '/valitse') session = DBSession() # Add the needed records. district = District(u'district', 1) school = School(u'Mynämäen koulu', district) school.id = 1 district.schools.append(school) session.add(district) openid_url = u'http://matti.meikalainen.oid.fi' # Add a voter to the session. voter = Voter(openid_url, u'Matti', u'Meikäläinen', datetime.now(), None, None, None, school) session.add(voter) session.flush() # Add a vote for the user. session.add(VotingLog(voter.id)) response = mock.Mock() response.status = SUCCESS response.identity_url = openid_url consumer = mock.Mock() consumer.complete.return_value = response make_consumer.return_value = consumer request = DummyRequest({'openid.mode': 'id_res'}) response = openid_response(request) self.assertTrue(isinstance(response, HTTPFound)) self.assertEquals(route_url('vote-finish', request), response.location)
def test_vote__successful_voting_response(self): from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import vote from pyramid.session import UnencryptedCookieSessionFactoryConfig from pyramid.url import route_url from webob.exc import HTTPFound session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.config.add_route('select', '/valitse') self.config.add_route('vote-finish', '/valmis') self.config.testing_securitypolicy(userid=voter.openid) self.config.set_session_factory(UnencryptedCookieSessionFactoryConfig) request = DummyRequest(post=dict(vote='1')) request.POST['csrf_token'] = request.session.new_csrf_token() request.matchdict['number'] = '1' response = vote(request) self.assertTrue(isinstance(response, HTTPFound)) self.assertEquals(route_url('vote-finish', request), response.location)
def _add_votes(self, candidate, votes): """Adds votes to the given candidate.""" from nuorisovaalit.models import School from nuorisovaalit.models import Vote kind = Vote.ELECTRONIC if votes == 1 else Vote.PAPER session = DBSession() session.add(Vote(candidate, session.query(School).first(), kind, votes)) session.flush()
def test_vote_finish__no_pref_selected_valid_address(self): from nuorisovaalit.models import Voter from nuorisovaalit.views.voting import vote_finish from pyramid.session import UnencryptedCookieSessionFactoryConfig session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.assertEquals(False, voter.has_preference()) voter.address = u'Äyrävänpolku 666, 09123 Mikä-mikämaa, Pohjoisnapa' self.config.set_session_factory(UnencryptedCookieSessionFactoryConfig) self.config.testing_securitypolicy(userid=voter.openid) self.config.add_route('exit-voting', '/exit') self.config.add_route('vote-finish', '/valmis') request = DummyRequest() csrf_token = request.session.new_csrf_token() request.POST['csrf_token'] = csrf_token self.assertEquals({ 'action_url': 'http://example.com/valmis', 'csrf_token': csrf_token, 'accept_openid': None, 'message': u'Äänesi on tallennettu', 'has_preference': False, 'pref_selected': False, 'errors': [], 'voter': voter, 'gsm': voter.gsm, 'email': voter.email, 'street': u'Äyrävänpolku 666', 'zipcode': u'09123', 'city': u'Mikä-mikämaa, Pohjoisnapa', }, vote_finish(request)) self.assertEquals(False, voter.has_preference())
def test_has_voted__positive(self): from nuorisovaalit.models import Voter from nuorisovaalit.models import VotingLog session = DBSession() populate_testing_db() voter = session.query(Voter).first() session = DBSession() # Create a voting log entry for the voter id. session.add(VotingLog(voter.id)) self.assertEquals(1, session.query(VotingLog).count()) # Assert self.failUnless(voter.has_voted())
def test_has_voted__negative_with_other_user_voted(self): from nuorisovaalit.models import Voter from nuorisovaalit.models import VotingLog session = DBSession() populate_testing_db() voter = session.query(Voter).first() session = DBSession() # Add a voting log entry for a different voter id. session.add(VotingLog(voter.id + 1)) self.assertEquals(1, session.query(VotingLog).count()) # Assert that the voter has not voted. self.failIf(voter.has_voted())
def test_vote__successful_vote_log(self): from nuorisovaalit.models import Vote from nuorisovaalit.models import Voter from nuorisovaalit.models import VotingLog from nuorisovaalit.views.voting import vote from pyramid.session import UnencryptedCookieSessionFactoryConfig session = DBSession() populate_testing_db() voter = session.query(Voter).first() self.config.add_route('select', '/valitse') self.config.add_route('vote-finish', '/valmis') self.config.testing_securitypolicy(userid=voter.openid) self.config.set_session_factory(UnencryptedCookieSessionFactoryConfig) session = DBSession() request = DummyRequest(post=dict(vote='1')) request.POST['csrf_token'] = request.session.new_csrf_token() request.matchdict['number'] = '1' # Check the initial conditions. self.assertEquals(0, session.query(VotingLog).count()) self.assertEquals(0, session.query(Vote).count()) vote(request) # Check that the vote was recorded. self.assertEquals(1, session.query(VotingLog).count()) self.assertEquals(1, session.query(Vote).count()) # Check that the vote record info is correct. vote_record = session.query(Vote).first() self.assertEquals(u'Uuno', vote_record.candidate.firstname) self.assertEquals(u'Turhapuro', vote_record.candidate.lastname) self.assertEquals(u'xxxx xxxx', vote_record.school.name)