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_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 setUp(self):
        from nuorisovaalit.run import main

        self.lock_dir = tempfile.mkdtemp()
        config = TEST_CONFIG.copy()
        config["session.lock_dir"] = self.lock_dir
        config["nuorisovaalit.skip_voting_period_check"] = "true"
        app = main({}, **config)
        self.testapp = webtest.TestApp(app, extra_environ=dict(REMOTE_ADDR="127.0.0.1"))
        self.config = testing.setUp()
        populate_testing_db()
    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 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 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_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_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_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_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_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_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_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_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_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 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)
    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_vote_finish__unauthenticated(self):
        from nuorisovaalit.views.voting import vote_finish

        populate_testing_db()
        self.assertRaises(Forbidden, lambda: vote_finish(DummyRequest()))