Beispiel #1
0
    def test_login__form_submission__success(self, remember):
        from nuvavaalit.models import Voter
        from nuvavaalit.views.login import login

        session = DBSession()
        session.add(Voter(u'buck.rogers', u'secret', u'Bück', u'Rögers'))
        session.flush()
        self.assertEquals(
            session.query(Voter).filter_by(username=u'buck.rogers').first().fullname(),
            u'Bück Rögers')

        remember.return_value = [('X-Login', 'buck.rogers')]
        request = testing.DummyRequest(statsd=False)
        token = request.session.new_csrf_token()
        request.POST = {
            'form.submitted': u'1',
            'username': u'buck.rogers',
            'password': u'secret',
            'csrf_token': token,
        }

        response = login(request)
        self.assertEquals(dict(response.headers), {
            'Content-Length': '0',
            'Content-Type': 'text/html; charset=UTF-8',
            'Location': 'http://example.com/valitse',
            'X-Login': '******'})
Beispiel #2
0
    def test_candidates(self):
        from nuvavaalit.models import Candidate
        from nuvavaalit.views.public import browse_candidates

        session = DBSession()
        session.add(Candidate(2, u'Steven', u'Seagal', u'No pain, no game', u''))
        session.add(Candidate(7, u'Jet', u'Li', u'Yin, yang', u''))
        session.add(Candidate(11, u'Jean-Claude', u'van Damme', u'No engrish', u''))
        session.flush()

        options = browse_candidates(testing.DummyRequest(statsd=False))
        positions = options.pop('positions')
        self.assertEquals('0 1:3 2:3 0 1:3 2:3'.split(), [positions.next() for i in xrange(6)])
        self.assertEquals(list(options.pop('candidates')), [
            [{'image_url': 'http://example.com/static/images/candidates/2.jpg',
              'name': u'Seagal, Steven',
              'number': 2,
              'slogan': u'No pain, no game'},
             {'image_url': 'http://example.com/static/images/candidates/7.jpg',
              'name': u'Li, Jet',
              'number': 7,
              'slogan': u'Yin, yang'},
             {'image_url': 'http://example.com/static/images/candidates/11.jpg',
              'name': u'van Damme, Jean-Claude',
              'number': 11,
              'slogan': u'No engrish'}]])
        self.assertEquals(options, {
            'columns': 3,
            'page_name': 'browse'})
Beispiel #3
0
    def test_login__form_submission__invalid_password(self):
        from nuvavaalit.models import Voter
        from nuvavaalit.views.login import login

        session = DBSession()
        session.add(Voter(u'buck.rogers', u'secret', u'Bück', u'Rögers'))
        session.flush()
        self.assertEquals(
            session.query(Voter).filter_by(username=u'buck.rogers').first().fullname(),
            u'Bück Rögers')

        request = testing.DummyRequest(statsd=False)
        token = request.session.new_csrf_token()
        request.POST = {
            'form.submitted': u'1',
            'username': u'buck.rogers',
            'password': u'thisiswrong',
            'csrf_token': token,
        }

        options = login(request)
        self.assertEquals(options, {
            'action_url': 'http://example.com/tunnistaudu',
            'csrf_token': token,
            'error': u'Tunnistautuminen epäonnistui. Kokeile tunnistautua uudelleen!'})
Beispiel #4
0
    def test_no_votes(self):
        from nuvavaalit.models import Candidate
        from nuvavaalit.models import Voter
        from nuvavaalit.views.results import results

        session = DBSession()
        session.add(Voter(u"buck.rogers", u"secret", u"Bück", u"Rögers"))
        session.add(Candidate(2, u"Steven", u"Seagal", u"No pain, no game", u""))
        session.add(Candidate(7, u"Jet", u"Li", u"Yin, yang", u""))
        session.add(Candidate(11, u"Jean-Claude", u"van Damme", u"No engrish", u""))
        session.flush()

        self.assertEquals(
            results(testing.DummyRequest(statsd=False)),
            {
                "others": [],
                "selected": [
                    {"name": u"Li, Jet", "number": 7, "percentage": "0.0", "votes": 0},
                    {"name": u"Seagal, Steven", "number": 2, "percentage": "0.0", "votes": 0},
                    {"name": u"van Damme, Jean-Claude", "number": 11, "percentage": "0.0", "votes": 0},
                ],
                "threshold": 8,
                "total_votes": 0,
                "show_leftovers": False,
                "voting_percentage": "0.0",
            },
        )
Beispiel #5
0
    def test_encrypted_link_matches_selection(self):
        from nuvavaalit.models import Candidate
        from nuvavaalit.models import Voter

        session = DBSession()
        session.add(Voter(u'buck.rogers', u'secret', u'Bück', u'Rögers'))
        session.add(Candidate(2, u'Steven', u'Seagal', u'No pain, no game', u''))
        session.add(Candidate(7, u'Jet', u'Li', u'Yin, yang', u''))
        session.add(Candidate(11, u'Jean-Claude', u'van Damme', u'No engrish', u''))
        session.flush()

        response = self.testapp.get('/tunnistaudu')
        response.form['username'] = u'buck.rogers'
        response.form['password'] = u'secret'
        response = response.form.submit()

        self.assertEquals(response.status, '302 Found')
        self.assertEquals(response.location, 'http://localhost/valitse')
        response = response.follow()

        self.assertEquals(response.request.url, 'http://localhost/valitse')
        voting_links = response.html.findAll('a', attrs={'href': re.compile('^http://localhost/aanesta/')})
        self.assertEquals(voting_links[1]['href'], voting_links[2]['href'])
        self.assertEquals(voting_links[2].text, u'Seagal, Steven, 2')
        # Click the voting link
        response = self.testapp.get(voting_links[2]['href'])
        # Assert that we get a matching candidate selection
        self.assertEquals(response.html.find('p', attrs={'class': 'candidate-name'}).text, u'2 Seagal, Steven')
Beispiel #6
0
    def run(self):
        session = DBSession()
        session.bind.echo = False

        # Join the repoze.filesafe manager in the transaction so that files will
        # be written only when a transaction commits successfully.
        filesafe = FileSafeDataManager()
        transaction.get().join(filesafe)

        # Query the currently existing usernames to avoid UNIQUE violations.
        self.usernames.update(username for cols in session.query(Voter.username).all() for username in cols)

        fh_itella = filesafe.createFile(self.output, 'w')

        # Excel worksheet for Itella
        wb_itella = xlwt.Workbook(encoding='utf-8')
        ws_itella = wb_itella.add_sheet('Hexagon IT')
        text_formatting = xlwt.easyxf(num_format_str='@')
        for col, header in enumerate([u'Tunnus', u'Salasana', u'Nimi', u'Osoite', u'Postinumero', u'Postitoimipaikka']):
            ws_itella.write(0, col, header, text_formatting)
        rows_itella = count(1)
        voter_count = 0

        self.header('Starting to process {}'.format(self.source_file))
        src_sheet = xlrd.open_workbook(self.source_file).sheet_by_index(0)
        pbar = progressbar.ProgressBar(widgets=[progressbar.Percentage(), progressbar.Bar()], maxval=src_sheet.nrows).start()

        for row in xrange(1, src_sheet.nrows):
            token, lastname, names, address, zipcode, city = [c.value for c in src_sheet.row_slice(row, 0, 6)]
            names = names.split()
            firstname = names[0]

            username = self.genusername(names, lastname)
            password = self.genpasswd()

            # Create the voter instance.
            session.add(Voter(username, password, firstname, lastname, token))

            # Write the Itella information
            row = rows_itella.next()

            for col, item in enumerate([username, password, u'{} {}'.format(u' '.join(names), lastname), address, zipcode, city]):
                ws_itella.write(row, col, item, text_formatting)

            voter_count += 1
            pbar.update(voter_count)

        wb_itella.save(fh_itella)
        fh_itella.close()

        session.flush()
        transaction.commit()
        pbar.finish()

        self.header('Finished processing')
        print 'Processed', voter_count, 'voters.'
Beispiel #7
0
    def test_voting_forbidden_authorized_after_election_period(self):
        from nuvavaalit.models import Voter

        session = DBSession()
        session.add(Voter(u'buck.rogers', u'secret', u'Bück', u'Rögers'))
        session.flush()

        self.authenticate(u'buck.rogers')
        response = self.testapp.get('/aanesta/abcdefg', expect_errors=True)
        self.assertEquals(response.status, '403 Forbidden')
Beispiel #8
0
    def test_stable_sorting_of_equals(self):
        """Test that in case of a tie we get a stable but random sorting of candidates."""
        from nuvavaalit.models import Candidate
        from nuvavaalit.models import Vote
        from nuvavaalit.models import Voter
        from nuvavaalit.views.results import results

        session = DBSession()
        session.add(Voter(u"buck.rogers", u"secret", u"Bück", u"Rögers"))
        session.add(Candidate(2, u"Steven", u"Seagal", u"No pain, no game", u""))
        session.add(Candidate(7, u"Jet", u"Li", u"Yin, yang", u""))
        session.add(Candidate(11, u"Jean-Claude", u"van Damme", u"No engrish", u""))
        session.flush()

        candidate_two = session.query(Candidate).filter_by(number=2).first()
        candidate_seven = session.query(Candidate).filter_by(number=7).first()

        session.add(Vote(candidate_two))
        session.add(Vote(candidate_seven))
        session.flush()

        self.assertEquals(
            results(testing.DummyRequest(statsd=False)),
            {
                "others": [],
                "selected": [
                    {"name": u"Li, Jet", "number": 7, "percentage": "50.0", "votes": 1},
                    {"name": u"Seagal, Steven", "number": 2, "percentage": "50.0", "votes": 1},
                    {"name": u"van Damme, Jean-Claude", "number": 11, "percentage": "0.0", "votes": 0},
                ],
                "threshold": 8,
                "total_votes": 2,
                "show_leftovers": False,
                "voting_percentage": "200.0",
            },
        )

        # Rendering the results again will result in the same relative ordering
        # of the equal votes.
        self.assertEquals(
            results(testing.DummyRequest(statsd=False)),
            {
                "others": [],
                "selected": [
                    {"name": u"Li, Jet", "number": 7, "percentage": "50.0", "votes": 1},
                    {"name": u"Seagal, Steven", "number": 2, "percentage": "50.0", "votes": 1},
                    {"name": u"van Damme, Jean-Claude", "number": 11, "percentage": "0.0", "votes": 0},
                ],
                "threshold": 8,
                "total_votes": 2,
                "show_leftovers": False,
                "voting_percentage": "200.0",
            },
        )
Beispiel #9
0
def populate_test_users():
    """Populates the database with test users."""
    parser = argparse.ArgumentParser(description='Generates test users in the database.')
    parser.add_argument('config', help='Path to a Paste configuration file, e.g. development.ini.')
    parser.add_argument('quantity', nargs='?', default=10, type=int, help='Number of test users to generate.')
    args = parser.parse_args()

    env = bootstrap(relpath(args.config))
    session = DBSession()
    session.bind.echo = False

    for i in xrange(1, args.quantity + 1):
        session.add(Voter(u'user{}'.format(i), u'testi', u'User #{}'.format(i), u'Fööbär'))

    session.flush()
    transaction.commit()

    print "Created {} test users".format(args.quantity)
    env['closer']()
Beispiel #10
0
    def test_empty_votes_removed_from_results_listing(self):
        """Test that in case of a tie we get a stable but random sorting of candidates."""
        from nuvavaalit.models import Candidate
        from nuvavaalit.models import Vote
        from nuvavaalit.models import Voter
        from nuvavaalit.views.results import results

        session = DBSession()
        session.add(Voter(u"buck.rogers", u"secret", u"Bück", u"Rögers"))
        session.add(Candidate(Candidate.EMPTY_CANDIDATE, u"empty", u"empty", u"empty", u"empty"))
        session.add(Candidate(2, u"Steven", u"Seagal", u"No pain, no game", u""))
        session.add(Candidate(7, u"Jet", u"Li", u"Yin, yang", u""))
        session.add(Candidate(11, u"Jean-Claude", u"van Damme", u"No engrish", u""))
        session.flush()

        candidate_two = session.query(Candidate).filter_by(number=2).first()
        candidate_seven = session.query(Candidate).filter_by(number=7).first()
        candidate_empty = session.query(Candidate).filter_by(number=Candidate.EMPTY_CANDIDATE).first()

        session.add(Vote(candidate_two))
        session.add(Vote(candidate_seven))
        session.add(Vote(candidate_empty))
        session.add(Vote(candidate_empty))
        session.flush()

        # The empty votes do not show up in the results listing but do
        # affect the number of votes, percentages, etc.
        self.assertEquals(
            results(testing.DummyRequest(statsd=False)),
            {
                "others": [],
                "selected": [
                    {"name": u"Li, Jet", "number": 7, "percentage": "25.0", "votes": 1},
                    {"name": u"Seagal, Steven", "number": 2, "percentage": "25.0", "votes": 1},
                    {"name": u"van Damme, Jean-Claude", "number": 11, "percentage": "0.0", "votes": 0},
                ],
                "threshold": 8,
                "total_votes": 4,
                "show_leftovers": False,
                "voting_percentage": "400.0",
            },
        )
Beispiel #11
0
    def test_already_voted_user_is_logged_out(self):
        from nuvavaalit.models import Voter
        from nuvavaalit.models import VotingLog

        session = DBSession()
        voter = Voter(u'buck.rogers', u'secret', u'Bück', u'Rögers')
        session.add(voter)
        session.flush()
        session.add(VotingLog(voter))
        session.flush()

        self.assertTrue(voter.has_voted())
        self.authenticate(u'buck.rogers')
        response = self.testapp.get('/valitse')

        # An already voted user is redirected to the thank you page.
        self.assertEquals(response.status, '302 Found')
        self.assertEquals(response.location, 'http://localhost/kiitos')

        # Assert that we get cookies that log out the user.
        self.assertLogoutCookies(response)
Beispiel #12
0
    def test_different_sessions_get_different_vote_links(self):
        from nuvavaalit.models import Candidate
        from nuvavaalit.models import Voter

        session = DBSession()
        session.add(Voter(u'buck.rogers', u'secret', u'Bück', u'Rögers'))
        session.add(Candidate(2, u'Steven', u'Seagal', u'No pain, no game', u''))
        session.add(Candidate(7, u'Jet', u'Li', u'Yin, yang', u''))
        session.add(Candidate(11, u'Jean-Claude', u'van Damme', u'No engrish', u''))
        session.flush()

        response = self.testapp.get('/tunnistaudu')
        response.form['username'] = u'buck.rogers'
        response.form['password'] = u'secret'
        response = response.form.submit()

        self.assertEquals(response.status, '302 Found')
        self.assertEquals(response.location, 'http://localhost/valitse')
        response = response.follow()

        self.assertEquals(response.request.url, 'http://localhost/valitse')
        # Get a list of voting links
        voting_links = [str(tag) for tag in response.html.findAll('a', attrs={'href': re.compile('^http://localhost/aanesta/')})]

        # Login again to the application, creating a new session
        response = self.testapp.get('/tunnistaudu')
        response.form['username'] = u'buck.rogers'
        response.form['password'] = u'secret'
        response = response.form.submit()

        self.assertEquals(response.status, '302 Found')
        self.assertEquals(response.location, 'http://localhost/valitse')
        response = response.follow()

        self.assertEquals(response.request.url, 'http://localhost/valitse')
        new_voting_links = [str(tag) for tag in response.html.findAll('a', attrs={'href': re.compile('^http://localhost/aanesta/')})]

        self.assertEquals(len(voting_links), len(new_voting_links))
        self.assertNotEqual(voting_links, new_voting_links)
Beispiel #13
0
def populate_candidates():
    """Populates the database with candidate information."""
    parser = argparse.ArgumentParser(description='Generates candidates in the database.')
    parser.add_argument('config', help='Path to a Paste configuration file, e.g. development.ini.')
    parser.add_argument('candidates', nargs='?', help='Path to a CSV file containing the candidate information.')
    args = parser.parse_args()

    env = bootstrap(relpath(args.config))

    session = DBSession()
    session.bind.echo = False
    # Create the candidate for empty votes.
    session.add(Candidate(Candidate.EMPTY_CANDIDATE, u'Tyhjä', u'', u'', u''))

    csv_file = relpath(args.candidates)
    reader = csv.reader(open(csv_file))

    print 'Reading candidates from', csv_file

    cnt = 0
    reader.next()

    for row in reader:
        number, firstname, lastname, slogan = row[:4]
        try:
            number = int(number.strip())
        except (TypeError, ValueError):
            print 'Invalid data: {}'.format(str(row))
            continue

        session.add(Candidate(number, univalue(firstname), univalue(lastname), univalue(slogan), u''))
        print 'Added {} {}, {}'.format(firstname, lastname, number)
        cnt += 1

    session.flush()
    transaction.commit()

    print "Created {} candidates.".format(cnt)
    env['closer']()
Beispiel #14
0
    def test_successful_voting_process(self):
        from nuvavaalit.models import Candidate
        from nuvavaalit.models import Vote
        from nuvavaalit.models import Voter
        from nuvavaalit.models import VotingLog

        # Create a user we will authenticate as.
        session = DBSession()
        session.add(Voter(u'buck.rogers', u'secret', u'Bück', u'Rögers'))
        session.add(Candidate(2, u'Steven', u'Seägäl', u'No pain, no game', u''))
        session.add(Candidate(7, u'Jët', u'Li', u'Yin, yang', u''))
        session.add(Candidate(11, u'Jeän-Claüde', u'van Damme', u'No engrish', u''))
        session.flush()

        self.assertEquals(0, session.query(Vote).count())
        self.assertEquals(0, session.query(VotingLog).count())

        self.authenticate(u'buck.rogers')

        # Accessing the system front page will redirect us to the login page
        # during the elections.
        response = self.testapp.get('/')
        self.assertEquals(response.status, '302 Found')
        self.assertEquals(response.location, 'http://localhost/tunnistaudu')
        response = response.follow()

        # Logging in the system successfully will bring us to the candidate
        # selection page.
        response.form['username'] = u'buck.rogers'
        response.form['password'] = u'secret'
        response = response.form.submit()
        self.assertEquals(response.status, '302 Found')
        self.assertEquals(response.location, 'http://localhost/valitse')
        response = response.follow()

        # Selecting a candidate brings us to the voting page.
        self.assertEquals(response.request.url, 'http://localhost/valitse')
        voting_links = response.html.findAll('a', attrs={'href': re.compile('^http://localhost/aanesta/')})
        # Assert we have two links to the candidate.
        self.assertEquals(voting_links[1]['href'], voting_links[2]['href'])
        self.assertEquals(voting_links[2].text, u'Seägäl, Steven, 2')
        # Click the voting link
        response = self.testapp.get(voting_links[2]['href'])
        self.assertTrue(response.request.url.startswith('http://localhost/aanesta/'))
        # Assert that we get a matching candidate selection
        self.assertEquals(response.html.find('p', attrs={'class': 'candidate-name'}).text, u'2 Seägäl, Steven')

        # Attempting to vote a non-selected candidate gives us an error message.
        response.form['vote'] = u'69'
        response = response.form.submit()
        self.assertTrue(response.html.find('div', attrs={'class': 'error'}).text.startswith(u'Antamasi ehdokasnumero ei vastaa valintaasi'))
        self.assertTrue(response.request.url.startswith('http://localhost/aanesta/'))

        # Voting for the selected candidate stores the vote and logs out the user.
        response.form['vote'] = u'2'
        response = response.form.submit()
        self.assertEquals(response.status, '302 Found')
        self.assertEquals(response.location, 'http://localhost/kiitos')
        # Assert that we get cookies that log out the user.
        self.assertLogoutCookies(response)

        # Assert that the vote was recorded correctly.
        self.assertEquals(2, session.query(Vote).one().candidate.number)
        self.assertEquals(u'buck.rogers', session.query(VotingLog).one().voter.username)

        # Assert that subsequent attempts to login results in automatic logout.
        response = self.testapp.get('/tunnistaudu')
        response.form['username'] = u'buck.rogers'
        response.form['password'] = u'secret'
        response = response.form.submit()

        self.assertEquals(response.status, '302 Found')
        self.assertEquals(response.location, 'http://localhost/kiitos')
        # Assert that we get cookies that log out the user.
        self.assertLogoutCookies(response)