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))
예제 #2
0
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 _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 _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__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))
예제 #6
0
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_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_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)
예제 #9
0
def populate_testing_db():
    """Populates the session with testing data."""
    from nuorisovaalit.models import Candidate
    from nuorisovaalit.models import District
    from nuorisovaalit.models import Party
    from nuorisovaalit.models import School
    from nuorisovaalit.models import Voter
    from itertools import count

    DISTRICTS = {
        (u'Ahvenanmaan maakunnan vaalipiiri', 1): {
            u'schools': (u'Brändö', u'Eckerö', u'Föglö'),
            u'candidates': (u'xxxx xxxx', u'xxxx xxxx', u'xxxx xxxx'),
            },
        (u'Etelä-Savon vaalipiiri', 2): {
            u'schools': (u'Heinävesi', u'Hirvensalmi'),
            u'candidates': (u'xxxx xxxx', u'xxxx xxxx', u'xxxx xxxx'),
        },
    }

    session = DBSession()

    # Check that there are no records in the db.
    assert session.query(Candidate).count() == 0
    assert session.query(District).count() == 0
    assert session.query(Party).count() == 0
    assert session.query(School).count() == 0
    assert session.query(Voter).count() == 0

    # Create parties
    parties = [
        Party(u'Köyhien asialla'),
        Party(u'Piraattipuolue'),
        Party(u'Suomen työväenpuolue'),
        ]

    for p in parties:
        session.add(p)
    session.flush()

    assert session.query(Party).count() == 3

    # Create the districts and schools.
    for (distname, code), rest in sorted(DISTRICTS.items()):
        district = District(distname, code, 5)

        for mname in rest['schools']:
            district.schools.append(School(u'{0} koulu'.format(mname)))

        session.add(district)
        session.flush()

        cnumber = count(1)
        for index, cname in enumerate(rest['candidates']):
            party = parties[index % len(parties)]
            candidate = Candidate(cnumber.next(), cname.split()[0], cname.split()[1], date(xxxx, xx, xx), u'xxxx', u'xxxx', party, district)
            session.add(candidate)

        session.add(district)

    session.flush()
    districts = session.query(District).order_by(District.name).all()

    session.add(Voter(
        u'http://example.com/id/matti.meikalainen',
        u'Matti', u'Meikäläinen',
        date(1970, 1, 1), u'123 456789',
        u'*****@*****.**',
        u'Mynämäkitie 1, Mynämäki',
        districts[0].schools[0]))

    session.add(Voter(
        u'http://example.com/id/maija.meikalainen',
        u'Maija', u'Meikäläinen',
        date(1979, 1, 1), u'987 654321',
        u'*****@*****.**',
        u'Vääksyntie1, Sysmä',
        districts[1].schools[0]))

    # Create the empty candidate. We need to create a district and party to
    # satisfy the database constraints but these are not used for anything.
    empty_district = District(u'Tyhjä', 3)
    empty_party = Party(u'Tyhjä')
    session.add(empty_district)
    session.add(empty_party)
    session.flush()
    empty_candidate = Candidate(Candidate.EMPTY_CANDIDATE, u'Tyhjä', u'Tyhjä', date(1999, 1, 1), u'Tyhjä', u'Tyhjä', empty_party, empty_district)
    session.add(empty_candidate)

    session.flush()
    def test_select_party_grouping_with_coalitions(self):
        from datetime import datetime
        from itertools import cycle
        from nuorisovaalit.models import Candidate
        from nuorisovaalit.models import Coalition
        from nuorisovaalit.models import District
        from nuorisovaalit.models import Party
        from nuorisovaalit.models import School
        from nuorisovaalit.models import Voter
        from nuorisovaalit.views.voting import select

        session = DBSession()

        # Populate the db.
        district = District(u'Distrïct', 1)
        session.add(district)
        session.flush()
        school = School(u'Schööl', district)
        session.add(school)
        session.flush()
        voter = Voter(u'http://[email protected]', u'test', u'user', datetime(2011, 1, 1),
                      gsm=None, email=None, address=None, school_or_id=school)
        session.add(voter)
        session.flush()

        party1 = Party(u'Först party')
        party2 = Party(u'Secönd party')
        session.add(party1)
        session.add(party2)
        session.flush()

        coalition = Coalition(u'Red coalition', district)
        coalition.parties.append(party1)
        coalition.parties.append(party2)
        session.add(coalition)

        party1.candidates.append(Candidate(2, u'Mätti2', u'Meikäläinen', datetime(2011, 1, 1),
                                           u'', u'', party1, district))
        party1.candidates.append(Candidate(3, u'Mätti3', u'Meikäläinen', datetime(2011, 1, 1),
                                           u'', u'', party1, district))
        party1.candidates.append(Candidate(4, u'Mätti4', u'Meikäläinen', datetime(2011, 1, 1),
                                           u'', u'', party1, district))
        party1.candidates.append(Candidate(5, u'Mätti5', u'Meikäläinen', datetime(2011, 1, 1),
                                           u'', u'', party1, district))
        party2.candidates.append(Candidate(2, u'Mäijä2', u'Meikäläinen', datetime(2011, 1, 1),
                                           u'', u'', party2, district))
        session.flush()

        self.config.testing_securitypolicy(userid=voter.openid)
        self.config.add_route('vote', '/aanesta/{number}')
        options = select(DummyRequest())

        # Remove the cycle generators and serialize the candidate generators
        # for easiear comparison.
        for party in options['parties']:
            self.assertTrue(isinstance(party.pop('positions'), cycle))
            party['candidates'] = list(party['candidates'])

        self.assertEquals(options, {
            'empty_vote_url': 'http://example.com/aanesta/0',
            'district': u'Distrïct',
            'coalitions': [u'Först party, Secönd party'],
            'columns': 3,
            'parties': [
                {'candidates': [
                    [{'url': 'http://example.com/aanesta/2',
                      'number': 2,
                      'name': u'Meikäläinen, Mätti2'},
                     {'url': 'http://example.com/aanesta/3',
                      'number': 3,
                      'name': u'Meikäläinen, Mätti3'}],
                    [{'url': 'http://example.com/aanesta/4',
                      'number': 4,
                      'name': u'Meikäläinen, Mätti4'}],
                    [{'url': 'http://example.com/aanesta/5',
                      'number': 5,
                      'name': u'Meikäläinen, Mätti5'}]],
                 'title': u'Först party'},
                {'candidates': [
                    [{'url': 'http://example.com/aanesta/2',
                      'number': 2,
                      'name': u'Meikäläinen, Mäijä2'}]],
                 'title': u'Secönd party'}]})
예제 #11
0
def populate_candidates():
    """Populates the database with candidate information.

    The information is read from two files. The first file contains the list
    of candidates and parties and the second file contains the information
    about coalitions.

    Based on the information we create the following types of objects in the
    database:

        * Candidate
        * Party
        * Coalition

    It is also assumed that the database has already been populated with the
    voting districts because both candidates and coalitions are always
    directly related to a given voting district.

    Additionally, this script creates the necessary objects to facilitate
    casting an empty vote.
    """
    config = get_config()
    engine = engine_from_config(config, "sqlalchemy.")
    initialize_sql(engine)
    engine.echo = False

    if len(sys.argv) < 4:
        print ("Usage: {0} <config> <candidate> <coalitions>".format(sys.argv[0]))
        transaction.abort()
        sys.exit(1)

    def fail_unless(condition, message):
        """Assert the given condition and upon failure prints out the message
        and aborts the current transaction.
        """
        if not condition:
            print message
            print "Aborting transaction"
            transaction.abort()
            # Raise an error instead of calling sys.exit(1) to better facilitate testing
            raise ValueError(message)

    # Mapping for party abbreviations to full titles.
    party_names = {
        u"AFÅ": u"Gemensam lista Alliansen för Åland - samarbete för självstyrelse och utveckling",
        u"ÅS": u"Åländsk samling gemensam lista",
        u"E109": u"Yhteislistoihin kuulumattomien valitsijayhdistysten ehdokkaat",  # u'xxxx xxxx',
        u"E119": u"Yhteislistoihin kuulumattomien valitsijayhdistysten ehdokkaat",  # u'xxxx xxxx',
        u"E133": u"Yhteislistoihin kuulumattomien valitsijayhdistysten ehdokkaat",  # u'xxxx xxxx',
        u"E157": u"Yhteislistoihin kuulumattomien valitsijayhdistysten ehdokkaat",  # u'xxxx xxxx',
        u"E159": u"Yhteislistoihin kuulumattomien valitsijayhdistysten ehdokkaat",  # u'xxxx xxxx',
        u"E266": u"Yhteislistoihin kuulumattomien valitsijayhdistysten ehdokkaat",  # u'xxxx xxxx',
        u"E267": u"Yhteislistoihin kuulumattomien valitsijayhdistysten ehdokkaat",  # u'xxxx xxxx',
        u"E268": u"Yhteislistoihin kuulumattomien valitsijayhdistysten ehdokkaat",  # u'xxxx xxxx',
        u"E404": u"Yhteislistoihin kuulumattomien valitsijayhdistysten ehdokkaat",  # u'xxxx xxxx',
        u"E405": u"Yhteislistoihin kuulumattomien valitsijayhdistysten ehdokkaat",  # u'xxxx xxxx',
        u"E406": u"Yhteislistoihin kuulumattomien valitsijayhdistysten ehdokkaat",  # u'xxxx xxxx',
        u"E407": u"Yhteislistoihin kuulumattomien valitsijayhdistysten ehdokkaat",  # u'xxxx xxxx',
        u"ITSP": u"Itsenäisyyspuolue",
        u"KD": u"Suomen Kristillisdemokraatit (KD)",
        u"KESK": u"Suomen Keskusta",
        u"KOK": u"Kansallinen Kokoomus",
        u"KÖY": u"Köyhien Asialla",
        u"KTP": u"Kommunistinen Työväenpuolue - Rauhan ja Sosialismin puolesta",
        u"M11": u"Muutos 2011",
        u"PIR": u"Piraattipuolue",
        u"PS": u"Perussuomalaiset",
        u"RKP": u"Suomen ruotsalainen kansanpuolue",
        u"SDP": u"Suomen Sosialidemokraattinen Puolue",
        u"SKP": u"Suomen Kommunistinen Puolue",
        u"SSP": u"Suomen Senioripuolue",
        u"STP": u"Suomen Työväenpuolue STP",
        u"VAS": u"Vasemmistoliitto",
        u"VIHR": u"Vihreä liitto",
        u"VP": u"Vapauspuolue (VP) - Suomen tulevaisuus",
        u"YS": u"Yhteislista sitoutumattomat",
    }

    session = DBSession()

    # Create the objects to support casting an empty vote.
    print "Setting up support for empty votes."
    empty_district = District(u"Tyhjä", 0)
    empty_party = Party(u"Tyhjä")
    session.add_all([empty_district, empty_party])
    session.flush()
    session.add(
        Candidate(
            Candidate.EMPTY_CANDIDATE, u"Tyhjä", u"", date(1999, 1, 1), u"Tyhjä", u"Tyhjä", empty_party, empty_district
        )
    )

    # Create Party objects.
    parties = {}
    print "Creating parties"
    for abbr, title in party_names.iteritems():
        party = Party(title)
        session.add(party)
        parties[abbr] = party
        print " - ", party.name.encode("utf-8")
    print
    session.flush()

    party_abbrevs = set(parties.keys())
    districts = dict((d.code, d) for d in session.query(District).all())

    # Read in the coalition information.
    # The excel sheet contains the district code, district name and a comma
    # separated list of party abbreviations.
    wb = xlrd.open_workbook(filename=os.path.join(os.getcwd(), sys.argv[3]))
    ws = wb.sheet_by_index(0)
    coalition_count = 0
    print "Creating coalitions"
    for row in xrange(ws.nrows):
        code = int(ws.cell_value(row, 0))
        abbrevs = set(p.strip() for p in ws.cell_value(row, 2).strip().split(u",") if p.strip())

        # Assert that the party abbreviations are all known.
        fail_unless(abbrevs.issubset(party_abbrevs), "Unknown parties in: {0}".format(abbrevs))
        # Assert the voting district code refers to a valid district.
        fail_unless(code in districts, "Unknown voting district code: {0}".format(code))

        if len(abbrevs):
            coalition = Coalition(u", ".join(sorted(abbrevs)), districts[code])
            for party_id in abbrevs:
                coalition.parties.append(parties[party_id])

            session.add(coalition)
            coalition_count += 1
            print " - '{0}' in {1}.".format(coalition.name.encode("utf-8"), districts[code].name.encode("utf-8"))
    session.flush()

    # Read in the candidate information
    wb = xlrd.open_workbook(filename=os.path.join(os.getcwd(), sys.argv[2]))
    ws = wb.sheet_by_index(0)
    candidate_count = 0
    print
    print "Creating candidates"
    for row in xrange(1, ws.nrows):
        code = int(ws.cell_value(row, 0))
        number = int(ws.cell_value(row, 2))
        firstname = unicode(ws.cell_value(row, 5).strip())
        lastname = unicode(ws.cell_value(row, 4).strip())
        municipality = unicode(ws.cell_value(row, 6).strip())
        occupation = unicode(ws.cell_value(row, 7).strip())
        party_id = unicode(ws.cell_value(row, 8).strip())

        # Assert the party abbreviation refers to a known party.
        fail_unless(party_id in parties, "Unknown party {0}".format(party_id.encode("utf-8")))
        # Assert the voting district code refers to a valid district.
        fail_unless(code in districts, "Unknown voting district code: {0}".format(code))

        dob_match = RE_DOB.match(ws.cell_value(row, 3).strip())
        fail_unless(dob_match is not None, "Invalid dob: {0}".format(ws.cell_value(row, 3)))
        dob = date(int(dob_match.group(3)) + 1900, int(dob_match.group(2)), int(dob_match.group(1)))

        fail_unless(dob.strftime("%d%m%y") == ws.cell_value(row, 3).strip(), "Failed dob parsing.")

        # Create the Candidate object
        candidate = Candidate(
            number, firstname, lastname, dob, municipality, occupation, parties[party_id], districts[code]
        )
        session.add(candidate)
        print " - ", candidate.fullname().encode("utf-8"), candidate.number
        candidate_count += 1

    session.flush()
    # Assert that we created the right number of candidates, which is
    # ws.nrows - 1 + 1 (all rows, minus header row, plus the empty candidate)
    fail_unless(ws.nrows == session.query(Candidate).count(), "Failed to create correct number of candidates.")

    print
    print "Created", len(parties), "parties."
    print "Created", coalition_count, "coalitions."
    print "Created", candidate_count, "candidates."

    transaction.commit()
    def _populate(self, quota=3):
        """Populates the database with data."""
        from nuorisovaalit.models import Candidate
        from nuorisovaalit.models import Coalition
        from nuorisovaalit.models import District
        from nuorisovaalit.models import DBSession
        from nuorisovaalit.models import Party
        from nuorisovaalit.models import School
        from nuorisovaalit.models import Vote

        session = DBSession()

        # Pre-conditions
        self.assertEquals(0, session.query(Candidate).count())
        self.assertEquals(0, session.query(Coalition).count())
        self.assertEquals(0, session.query(District).count())
        self.assertEquals(0, session.query(Party).count())
        self.assertEquals(0, session.query(School).count())
        self.assertEquals(0, session.query(Vote).count())

        # Create parties
        parties = [
            Party(u'Köyhien asialla'),
            Party(u'Piraattipuolue'),
            Party(u'Suomen työväenpuolue'),
            Party(u'Valitsijalista'),
            ]

        for p in parties:
            session.add(p)
        session.flush()

        self.assertEquals(4, session.query(Party).count())

        # Create district and school
        district = District(u'Tëst District', 1, quota)
        district.schools.append(School(u'Tëst Schööl'))
        session.add(district)
        session.flush()

        dob = date(1945, 12, 13)

        # Create candidates
        session.add(Candidate(1, u'Candidate', u'0', dob, u'', u'', parties[0], district))
        session.add(Candidate(2, u'Candidate', u'1', dob, u'', u'', parties[0], district))

        session.add(Candidate(3, u'Candidate', u'2', dob, u'', u'', parties[1], district))
        session.add(Candidate(4, u'Candidate', u'3', dob, u'', u'', parties[1], district))

        session.add(Candidate(5, u'Candidate', u'4', dob, u'', u'', parties[2], district))
        session.add(Candidate(6, u'Candidate', u'5', dob, u'', u'', parties[2], district))
        session.add(Candidate(7, u'Candidate', u'6', dob, u'', u'', parties[2], district))

        session.add(Candidate(8, u'Candidate', u'7', dob, u'', u'', parties[3], district))

        session.add(Candidate(Candidate.EMPTY_CANDIDATE, u'Empty', u'candidate', dob, u'', u'', parties[3], district))

        session.flush()
        self.assertEquals(9, len(district.candidates))

        return district