alembic/versions/2b8f5a6f10a4_store_fas_name_locally.py | 27 +++ fedora_elections/__init__.py | 3 fedora_elections/admin.py | 32 +++ fedora_elections/default_config.py | 7 fedora_elections/elections.py | 138 +++++++--------- fedora_elections/forms.py | 6 fedora_elections/models.py | 3 fedora_elections/templates/admin/view_election.html | 1 fedora_elections/templates/index.html | 2 fedora_elections/utils.py | 16 - files/fedora-elections.spec | 2 tests/test_flask_elections.py | 11 - tests/test_flask_irc.py | 55 +++++- tests/test_flask_range_voting.py | 11 + tests/test_flask_simple_voting.py | 54 +++++- 15 files changed, 228 insertions(+), 140 deletions(-)
New commits: commit d33ad98b8605f81fe4996635a02741029d29d297 Merge: 20889d6 f79dd09 Author: Pierre-Yves Chibon pingou@pingoured.fr Date: Fri Jan 22 15:44:09 2016 +0100
Merge pull request #56 from fedora-infra/lcl_cache_fas
Store locally the candidates' FAS name
commit f79dd094dec24318c35e20d9348449003898bd76 Author: Pierre-Yves Chibon pingou@pingoured.fr Date: Thu Jan 21 16:54:36 2016 +0100
Add the alembic revision to create the fas_name field in the candidates table
diff --git a/alembic/versions/2b8f5a6f10a4_store_fas_name_locally.py b/alembic/versions/2b8f5a6f10a4_store_fas_name_locally.py new file mode 100644 index 0000000..6d960df --- /dev/null +++ b/alembic/versions/2b8f5a6f10a4_store_fas_name_locally.py @@ -0,0 +1,27 @@ +"""Store fas_name locally + +Revision ID: 2b8f5a6f10a4 +Revises: d07c5ef2d03 +Create Date: 2016-01-21 16:53:38.956503 + +""" + +# revision identifiers, used by Alembic. +revision = '2b8f5a6f10a4' +down_revision = 'd07c5ef2d03' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + """ Add the fas_name column to the candidates table. """ + op.add_column( + 'candidates', + sa.Column('fas_name', sa.Unicode(150), nullable=True) + ) + + +def downgrade(): + """ Drop the fas_name column from the candidates table. """ + op.drop_column('candidates', 'fas_name')
commit e158baa40f360b8e00efccdd5185d613620301ab Author: Pierre-Yves Chibon pingou@pingoured.fr Date: Thu Jan 21 16:51:35 2016 +0100
Drop the dependency on dogpile-cache
diff --git a/files/fedora-elections.spec b/files/fedora-elections.spec index 1fa4d0f..d8619e1 100644 --- a/files/fedora-elections.spec +++ b/files/fedora-elections.spec @@ -24,7 +24,6 @@ BuildRequires: python-setuptools BuildRequires: python-wtforms BuildRequires: python-nose BuildRequires: python-coverage -BuildRequires: python-dogpile-cache
Requires: python-fedora Requires: python-fedora-flask @@ -34,7 +33,6 @@ Requires: python-openid Requires: python-openid-teams Requires: python-openid-cla Requires: python-wtforms -Requires: python-dogpile-cache
# EPEL6 %if ( 0%{?rhel} && 0%{?rhel} == 6 )
commit 8ab35838245e7bce5c303cc537ade5f96e5b1a51 Author: Pierre-Yves Chibon pingou@pingoured.fr Date: Thu Jan 21 16:50:58 2016 +0100
Drop the cache with dogpile
diff --git a/fedora_elections/__init__.py b/fedora_elections/__init__.py index c08a61c..2bd685e 100644 --- a/fedora_elections/__init__.py +++ b/fedora_elections/__init__.py @@ -84,8 +84,7 @@ from fedora_elections import models SESSION = models.create_session(APP.config['DB_URL']) from fedora_elections import forms
-cache = dogpile.cache.make_region() -cache.configure(**APP.config['DOGPILE_CACHE']) + from fedora_elections.utils import build_name_map
diff --git a/fedora_elections/default_config.py b/fedora_elections/default_config.py index e887840..979dd9d 100644 --- a/fedora_elections/default_config.py +++ b/fedora_elections/default_config.py @@ -22,10 +22,3 @@ FAS_BASE_URL = 'https://admin.stg.fedoraproject.org/accounts/' FAS_USERNAME = '' FAS_PASSWORD = '' FAS_CHECK_CERT = False - -DOGPILE_CACHE = { - 'backend': 'dogpile.cache.dbm', - 'arguments': { - 'filename': '/var/tmp/elections-cache.dbm', - }, -}
commit b134c1f22ac3d56b2ea13c713f91dd7fd0a416d2 Author: Pierre-Yves Chibon pingou@pingoured.fr Date: Thu Jan 21 16:50:13 2016 +0100
Drop get_fas_human_name since we store the info in the DB
diff --git a/fedora_elections/utils.py b/fedora_elections/utils.py index 66ce8cb..a36270f 100644 --- a/fedora_elections/utils.py +++ b/fedora_elections/utils.py @@ -11,20 +11,6 @@ def build_name_map(election): return {}
return dict([ - (str(candidate.id), get_fas_human_name(candidate.name)) + (str(candidate.id), candidate.fas_name) for candidate in election.candidates ]) - - -@fedora_elections.cache.cache_on_arguments() -def get_fas_human_name(username): - """ Given a fas username, return the fas human_name if possible. - - If the user has their name set to private or they don't exist, we just - return the given username as a stand-in. - """ - try: - return fedora_elections.FAS2.person_by_username(username)['human_name'] - except (KeyError, AuthError), err: - fedora_elections.APP.logger.debug(err) - return username
commit 97c32031ddbd18b7af163ae38d00ab81301ea6f7 Author: Pierre-Yves Chibon pingou@pingoured.fr Date: Thu Jan 21 16:49:52 2016 +0100
In the admin page show the candidate's FAS name next to the name
diff --git a/fedora_elections/templates/admin/view_election.html b/fedora_elections/templates/admin/view_election.html index c283de7..3448fb0 100644 --- a/fedora_elections/templates/admin/view_election.html +++ b/fedora_elections/templates/admin/view_election.html @@ -25,6 +25,7 @@ <ul> {% for candidate in election.candidates.all() %} <li>{{ candidate.name }} + {% if candidate.fas_name %} ({{ candidate.fas_name }}) {% endif %} <a href="{{ url_for('admin_edit_candidate', election_alias=election.alias, candidate_id=candidate.id) }}">
commit 63770fc488df9f56fc91f07e4ffc491256b4f8e1 Author: Pierre-Yves Chibon <pingou@pingoured.fr> Date: Thu Jan 21 16:48:52 2016 +0100
Let's present the candidate's FAS name first if there is one
diff --git a/fedora_elections/forms.py b/fedora_elections/forms.py index 7d04a90..3c1db97 100644 --- a/fedora_elections/forms.py +++ b/fedora_elections/forms.py @@ -122,7 +122,7 @@ def get_range_voting_form(candidates, max_range): action = wtforms.HiddenField()
for candidate in candidates: - title = candidate.name + title = candidate.fas_name or candidate.name if candidate.url: title = '%s <a href="%s">[Info]</a>' % (title, candidate.url) field = wtforms.SelectField( @@ -140,7 +140,7 @@ def get_simple_voting_form(candidates, fasusers):
titles = [] for candidate in candidates: - title = candidate.name + title = candidate.fas_name or candidate.name if fasusers: # pragma: no cover # We can't cover FAS integration try: @@ -179,7 +179,7 @@ def get_select_voting_form(candidates, max_selection): action = wtforms.HiddenField()
for candidate in candidates: - title = candidate.name + title = candidate.fas_name or candidate.name if candidate.url: title = '%s <a href="%s">[Info]</a>' % (title, candidate.url) field = wtforms.BooleanField(
commit c65dd9245077fb06cd0e5b219df8967e21f92ddd Author: Pierre-Yves Chibon pingou@pingoured.fr Date: Thu Jan 21 16:48:44 2016 +0100
Little style clean up
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py index 14b777c..4ebd434 100644 --- a/fedora_elections/elections.py +++ b/fedora_elections/elections.py @@ -39,6 +39,7 @@ from fedora_elections import ( ) from fedora_elections.utils import build_name_map
+ def login_required(f): @wraps(f) def decorated_function(*args, **kwargs): @@ -122,6 +123,7 @@ def vote(election_alias): 'Unknown election voting type: %s' % election.voting_type) return safe_redirect_back()
+ def vote_range(election, revote): votes = models.Vote.of_user_on_election( SESSION, flask.g.fas_user.username, election.id) @@ -142,10 +144,10 @@ def vote_range(election, revote): if form.validate_on_submit(): if form.action.data == 'submit': candidates = [ - candidate - for candidate in form - if candidate and candidate.short_name not in ['csrf_token', 'action'] - ] + candidate + for candidate in form + if candidate and candidate.short_name not in ['csrf_token', 'action'] + ] process_vote(candidates, election, votes, revote) flask.flash("Your vote has been recorded. Thank you!") return safe_redirect_back() @@ -219,6 +221,7 @@ def vote_select(election, revote): usernamemap=usernamemap, nextaction=next_action)
+ def vote_simple(election, revote): votes = models.Vote.of_user_on_election( SESSION, flask.g.fas_user.username, election.id) @@ -371,6 +374,7 @@ def election_results_text(election_alias): stats=stats, )
+ def process_vote(candidates, election, votes, revote, cand_name=None, value=None): for index in range(len(candidates)): candidate = candidates[index]
commit d33e5283a1897238e31916be0a3b027d1e1c377c Author: Pierre-Yves Chibon pingou@pingoured.fr Date: Thu Jan 21 16:48:25 2016 +0100
Store locally the user's FAS name when adding or editing candidates
diff --git a/fedora_elections/admin.py b/fedora_elections/admin.py index ad7f072..98c877c 100644 --- a/fedora_elections/admin.py +++ b/fedora_elections/admin.py @@ -238,9 +238,10 @@ def admin_add_candidate(election_alias): form = forms.CandidateForm() if form.validate_on_submit():
+ fas_name = None if election.candidates_are_fasusers: # pragma: no cover try: - FAS2.person_by_username(form.name.data)['human_name'] + fas_name = FAS2.person_by_username(form.name.data)['human_name'] except (KeyError, AuthError), err: flask.flash( 'User `%s` does not have a FAS account.' @@ -253,7 +254,8 @@ def admin_add_candidate(election_alias): candidate = models.Candidate( election=election, name=form.name.data, - url=form.url.data + url=form.url.data, + fas_name=fas_name, )
SESSION.add(candidate) @@ -291,9 +293,11 @@ def admin_add_multi_candidate(election_alias): for entry in form.candidate.data.strip().split("|"): candidate = entry.split("!")
+ fas_name = None if election.candidates_are_fasusers: # pragma: no cover try: - FAS2.person_by_username(candidate[0])['human_name'] + fas_name = FAS2.person_by_username( + candidate[0])['human_name'] except (KeyError, AuthError), err: SESSION.rollback() flask.flash( @@ -308,7 +312,8 @@ def admin_add_multi_candidate(election_alias): if len(candidate) == 1: cand = models.Candidate( election=election, - name=candidate[0]) + name=candidate[0], + fas_name=fas_name) SESSION.add(cand) candidates_name.append(cand.name) # With url @@ -316,7 +321,8 @@ def admin_add_multi_candidate(election_alias): cand = models.Candidate( election=election, name=candidate[0], - url=candidate[1]) + url=candidate[1], + fas_name=fas_name) SESSION.add(cand) candidates_name.append(cand.name) else: @@ -357,6 +363,22 @@ def admin_edit_candidate(election_alias, candidate_id): form = forms.CandidateForm(obj=candidate) if form.validate_on_submit(): form.populate_obj(candidate) + + fas_name = None + if election.candidates_are_fasusers: # pragma: no cover + try: + candidate.fas_name = FAS2.person_by_username( + candidate[0])['human_name'] + except (KeyError, AuthError), err: + SESSION.rollback() + flask.flash( + 'User `%s` does not have a FAS account.' + % candidate[0], 'error') + return flask.redirect(flask.url_for( + 'admin_edit_candidate', + election_alias=election_alias, + candidate_id=candidate_id)) + SESSION.commit() flask.flash('Candidate "%s" saved' % candidate.name) fedmsgshim.publish(
commit 10b484ebb7c437bd84a83ee221359c7e2f562e68 Author: Pierre-Yves Chibon pingou@pingoured.fr Date: Thu Jan 21 16:47:55 2016 +0100
Add a fas_name field to the candidate table where the fas_name is stored
diff --git a/fedora_elections/models.py b/fedora_elections/models.py index 31d6fea..e7d9d3d 100644 --- a/fedora_elections/models.py +++ b/fedora_elections/models.py @@ -263,6 +263,7 @@ class Candidate(BASE): nullable=False) # FAS username if candidates_are_fasusers name = sa.Column(sa.Unicode(150), nullable=False) + fas_name = sa.Column(sa.Unicode(150), nullable=True) url = sa.Column(sa.Unicode(250))
election = relationship(
commit 20889d67f5fc1f7f81ab5987fdf819e3093a44f9 Merge: 03d775b f132a47 Author: Pierre-Yves Chibon pingou@pingoured.fr Date: Thu Oct 8 09:57:42 2015 +0200
Merge pull request #55 from NerdsvilleCEO/fix_candidate_modification_bug
Candidate modification revote bug
commit f132a478397eebac23bba987a4aa323a75a907ef Author: Joshua Santos Nerdsville@nerdsville.net Date: Thu Oct 8 00:55:03 2015 -0700
Remove Trailing Spaces :)
diff --git a/tests/test_flask_range_voting.py b/tests/test_flask_range_voting.py index 5107af2..494c6e5 100644 --- a/tests/test_flask_range_voting.py +++ b/tests/test_flask_range_voting.py @@ -312,7 +312,7 @@ class FlaskRangeElectionstests(ModelFlasktests): self.assertEqual(votes[1].value, 0) self.assertEqual(votes[2].value, 2) #Let's not do repetition of what is tested above we aren't testing the - #functionality of voting as that has already been asserted + #functionality of voting as that has already been asserted
obj = fedora_elections.models.Candidate( # id:16 election_id=3,
commit 7e54b8a9a5b74d3090848642a915d9b60157b654 Author: Joshua Santos nerdsville@nerdsville.net Date: Sat Oct 3 21:39:19 2015 -0700
Add range voting revote candidate modification test
diff --git a/tests/test_flask_range_voting.py b/tests/test_flask_range_voting.py index c18aca9..5107af2 100644 --- a/tests/test_flask_range_voting.py +++ b/tests/test_flask_range_voting.py @@ -312,13 +312,23 @@ class FlaskRangeElectionstests(ModelFlasktests): self.assertEqual(votes[1].value, 0) self.assertEqual(votes[2].value, 2) #Let's not do repetition of what is tested above we aren't testing the - #functionality of voting as that has already been asserted + #functionality of voting as that has already been asserted + + obj = fedora_elections.models.Candidate( # id:16 + election_id=3, + name='Josh', + url='https://fedoraproject.org/wiki/User:Nerdsville', + ) + self.session.add(obj) + self.session.commit() +
#Next, we need to try revoting newdata = { '4': 2, '5': 1, '6': 1, + '16': 0, 'action': 'submit', 'csrf_token': csrf_token, } @@ -336,6 +346,7 @@ class FlaskRangeElectionstests(ModelFlasktests): self.assertEqual(votes[0].value, 2) self.assertEqual(votes[1].value, 1) self.assertEqual(votes[2].value, 1) + self.assertEqual(votes[3].value, 0) #If we haven't failed yet, HOORAY!
commit 677dff9bb60e5827ef29e2d58517927f6dde8db5 Author: Joshua Santos nerdsville@nerdsville.net Date: Fri Sep 25 14:48:12 2015 -0700
Fix logic to apply for any index
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py index 339645f..14b777c 100644 --- a/fedora_elections/elections.py +++ b/fedora_elections/elections.py @@ -374,7 +374,7 @@ def election_results_text(election_alias): def process_vote(candidates, election, votes, revote, cand_name=None, value=None): for index in range(len(candidates)): candidate = candidates[index] - if revote and (index+1 == len(votes)): + if revote and (index+1 <= len(votes)): vote = votes[index] if value is not None: vote.candidate_id = candidate.data
commit 689aa799bd94fa2ed419868ddc17f818c8291b7b Author: Joshua Santos nerdsville@nerdsville.net Date: Fri Sep 25 14:30:21 2015 -0700
Candidate modification revote bug
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py index 4b65e75..339645f 100644 --- a/fedora_elections/elections.py +++ b/fedora_elections/elections.py @@ -374,7 +374,7 @@ def election_results_text(election_alias): def process_vote(candidates, election, votes, revote, cand_name=None, value=None): for index in range(len(candidates)): candidate = candidates[index] - if revote: + if revote and (index+1 == len(votes)): vote = votes[index] if value is not None: vote.candidate_id = candidate.data
commit 03d775bf5b66b91a6569aafe026fcfad2fa1e28d Merge: c4e93d5 49d2f75 Author: Pierre-Yves Chibon pingou@pingoured.fr Date: Fri Sep 25 10:26:15 2015 +0200
Merge pull request #54 from NerdsvilleCEO/add-simple-revote
Add simple revote
commit 49d2f75a3e57f6e543dbbc66f63b123cc347a67a Author: Joshua Santos nerdsville@nerdsville.net Date: Thu Sep 24 10:24:25 2015 -0700
Prefer UTC time over now()
diff --git a/fedora_elections/models.py b/fedora_elections/models.py index b3e72cc..31d6fea 100644 --- a/fedora_elections/models.py +++ b/fedora_elections/models.py @@ -136,7 +136,7 @@ class Election(BASE):
@property def locked(self): - return datetime.now() >= self.start_date + return datetime.utcnow() >= self.start_date
@classmethod def search(cls, session, alias=None, shortdesc=None,
commit f1fc0829ef765296d96252c595f8d320b438cdde Author: Joshua Santos nerdsville@nerdsville.net Date: Thu Sep 24 10:24:14 2015 -0700
Prefer UTC time over now()
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py index c35a5d7..4b65e75 100644 --- a/fedora_elections/elections.py +++ b/fedora_elections/elections.py @@ -392,7 +392,7 @@ def process_vote(candidates, election, votes, revote, cand_name=None, value=None new_vote = models.Vote( election_id=election.id, voter=flask.g.fas_user.username, - timestamp=datetime.now(), + timestamp=datetime.utcnow(), candidate_id=cand_id, value= value if value else int(candidate.data), )
commit a526590d90408b738bb3346eb5a2611b4144e78d Author: Joshua Santos nerdsville@nerdsville.net Date: Tue Sep 1 16:36:11 2015 -0400
Cleanup
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py index 03c6821..c35a5d7 100644 --- a/fedora_elections/elections.py +++ b/fedora_elections/elections.py @@ -238,7 +238,7 @@ def vote_simple(election, revote): for candidate in form if candidate and candidate.short_name not in ['csrf_token', 'action'] ] - process_vote(candidates, election, votes, revote, None, 1) + process_vote(candidates, election, votes, revote, value=1) flask.flash("Your vote has been recorded. Thank you!") return safe_redirect_back()
@@ -376,13 +376,13 @@ def process_vote(candidates, election, votes, revote, cand_name=None, value=None candidate = candidates[index] if revote: vote = votes[index] - if value == 1: + if value is not None: vote.candidate_id = candidate.data else: vote.value = value if value else int(candidate.data) SESSION.add(vote) else: - if value == 1: + if value is not None: cand_id = candidate.data elif cand_name: cand_id = cand_name[candidate.short_name]
commit 211eb0456f1d312ebf16f12833b87168508d75db Author: Joshua Santos nerdsville@nerdsville.net Date: Tue Sep 1 11:32:57 2015 -0400
Fix final failed test
diff --git a/tests/test_flask_elections.py b/tests/test_flask_elections.py index 90a0230..fd24ce9 100644 --- a/tests/test_flask_elections.py +++ b/tests/test_flask_elections.py @@ -155,17 +155,6 @@ class FlaskElectionstests(ModelFlasktests): '<input type="hidden" name="action" value="preview" />' in output.data)
- user = FakeUser(['voters'], username='toshio') - with user_set(fedora_elections.APP, user): - - # Election in progress - output = self.app.get( - '/vote/test_election3', follow_redirects=True) - self.assertTrue( - 'class="message">You have already voted in the election!</' - in output.data) - self.assertTrue('<h3>Current elections</h3>' in output.data) - def test_election_results(self): """ Test the election_results function - the preview part. """ output = self.app.get(
commit 9abdca3fd5cc0343f5f5b32ef6a5f161e2d66590 Author: Joshua Santos nerdsville@nerdsville.net Date: Tue Sep 1 11:28:00 2015 -0400
Further cleanup :)
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py index 6eac5f7..03c6821 100644 --- a/fedora_elections/elections.py +++ b/fedora_elections/elections.py @@ -200,7 +200,7 @@ def vote_select(election, revote): for candidate in form if candidate and candidate.short_name not in ['csrf_token', 'action'] ] - process_vote_by_cand_name(candidates, cand_name, election, votes, revote) + process_vote(candidates, election, votes, revote, cand_name) flask.flash("Your vote has been recorded. Thank you!") return safe_redirect_back()
@@ -238,22 +238,7 @@ def vote_simple(election, revote): for candidate in form if candidate and candidate.short_name not in ['csrf_token', 'action'] ] - for index in range(len(candidates)): - candidate = candidates[index] - if revote: - vote = votes[index] - vote.candidate_id = candidate.data - SESSION.add(vote) - else: - new_vote = models.Vote( - election_id=election.id, - voter=flask.g.fas_user.username, - timestamp=datetime.now(), - candidate_id=candidate.data, - value=1, - ) - SESSION.add(new_vote) - SESSION.commit() + process_vote(candidates, election, votes, revote, None, 1) flask.flash("Your vote has been recorded. Thank you!") return safe_redirect_back()
@@ -290,7 +275,7 @@ def vote_irc(election, revote): for candidate in form if candidate and candidate.short_name not in ['csrf_token', 'action'] ] - process_vote_by_cand_name(candidates, cand_name, election, votes, revote) + process_vote(candidates, election, votes, revote, cand_name) flask.flash("Your vote has been recorded. Thank you!") return safe_redirect_back()
@@ -386,38 +371,30 @@ def election_results_text(election_alias): stats=stats, )
-def process_vote(candidates, election, votes, revote): +def process_vote(candidates, election, votes, revote, cand_name=None, value=None): for index in range(len(candidates)): candidate = candidates[index] if revote: vote = votes[index] - vote.value = int(candidate.data) + if value == 1: + vote.candidate_id = candidate.data + else: + vote.value = value if value else int(candidate.data) SESSION.add(vote) else: - new_vote = models.Vote( - election_id=election.id, - voter=flask.g.fas_user.username, - timestamp=datetime.now(), - candidate_id=candidate.short_name, - value=int(candidate.data), - ) - SESSION.add(new_vote) - SESSION.commit() + if value == 1: + cand_id = candidate.data + elif cand_name: + cand_id = cand_name[candidate.short_name] + else: + cand_id = candidate.short_name
-def process_vote_by_cand_name(candidates, cand_name, election, votes, revote): - for index in range(len(candidates)): - candidate = candidates[index] - if revote: - vote = votes[index] - vote.value = int(candidate.data) - SESSION.add(vote) - else: new_vote = models.Vote( election_id=election.id, voter=flask.g.fas_user.username, timestamp=datetime.now(), - candidate_id=cand_name[candidate.short_name], - value=int(candidate.data), + candidate_id=cand_id, + value= value if value else int(candidate.data), ) SESSION.add(new_vote) SESSION.commit()
commit 92ae688e1d2a907480d51b4417c33628941062af Author: Joshua Santos nerdsville@nerdsville.net Date: Tue Sep 1 10:49:36 2015 -0400
Else for revote logic
diff --git a/fedora_elections/templates/index.html b/fedora_elections/templates/index.html index c944703..5d15ef8 100644 --- a/fedora_elections/templates/index.html +++ b/fedora_elections/templates/index.html @@ -32,10 +32,11 @@ <a href="{{ url_for('vote', election_alias=election.alias) }}"> Vote now! </a> - {% endif %} + {% else %} <a href="{{ url_for('vote', election_alias=election.alias) }}"> Change your vote! </a> + {% endif %} {% endif %} </td> </tr>
commit 436ce71fe918cb7d47fa065964e0acc9217186ec Author: Joshua Santos nerdsville@nerdsville.net Date: Tue Sep 1 10:41:50 2015 -0400
Update tests
diff --git a/tests/test_flask_simple_voting.py b/tests/test_flask_simple_voting.py index 1eaa339..c0ea957 100644 --- a/tests/test_flask_simple_voting.py +++ b/tests/test_flask_simple_voting.py @@ -55,14 +55,6 @@ class FlaskSimpleElectionstests(ModelFlasktests):
self.setup_db()
- user = FakeUser(['packager'], username='toshio') - with user_set(fedora_elections.APP, user): - output = self.app.get( - '/vote/test_election5', follow_redirects=True) - self.assertTrue( - 'class="message">You have already voted in the election!</' - in output.data) - user = FakeUser(['packager'], username='pingou') with user_set(fedora_elections.APP, user): output = self.app.get( @@ -244,6 +236,52 @@ class FlaskSimpleElectionstests(ModelFlasktests): self.assertTrue('<h3>Next 1 elections</h3>' in output.data) self.assertTrue('<h3>Last 2 elections</h3>' in output.data)
+ def test_vote_simple_revote(self): + """ Test the vote_simple function - the re-voting part. """ + #First we need to vote + self.setup_db() + + user = FakeUser(['voters'], username='nerdsville') + with user_set(fedora_elections.APP, user): + retrieve_csrf = self.app.post('/vote/test_election5') + csrf_token = retrieve_csrf.data.split( + 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + # Valid input + data = { + 'candidate': 8, + 'action': 'submit', + 'csrf_token': csrf_token, + } + + self.app.post('/vote/test_election5', data=data, follow_redirects=True) + vote = fedora_elections.models.Vote + votes = vote.of_user_on_election(self.session, "nerdsville", '5') + self.assertEqual(votes[0].candidate_id, 8) + #Let's not do repetition of what is tested above we aren't testing the + #functionality of voting as that has already been asserted + + #Next, we need to try revoting + # Valid input + newdata = { + 'candidate': 9, + 'action': 'submit', + 'csrf_token': csrf_token, + } + output = self.app.post('/vote/test_election5', data=newdata, follow_redirects=True) + #Next, we need to check if the vote has been recorded + self.assertEqual(output.status_code, 200) + self.assertTrue( + 'class="message">Your vote has been recorded. Thank you!</' + in output.data) + self.assertTrue('<h3>Current elections</h3>' in output.data) + self.assertTrue('<h3>Next 1 elections</h3>' in output.data) + self.assertTrue('<h3>Last 2 elections</h3>' in output.data) + vote = fedora_elections.models.Vote + votes = vote.of_user_on_election(self.session, "nerdsville", '5') + self.assertEqual(votes[0].candidate_id, 9) + + #If we haven't failed yet, HOORAY! +
if __name__ == '__main__': SUITE = unittest.TestLoader().loadTestsFromTestCase(
commit 5e2964bdd72a8bc40b7707b67d44cd9549d32b12 Author: Joshua Santos nerdsville@nerdsville.net Date: Tue Sep 1 10:41:40 2015 -0400
No need to check if revote exists anymore
diff --git a/fedora_elections/templates/index.html b/fedora_elections/templates/index.html index abfcdd1..c944703 100644 --- a/fedora_elections/templates/index.html +++ b/fedora_elections/templates/index.html @@ -32,11 +32,10 @@ <a href="{{ url_for('vote', election_alias=election.alias) }}"> Vote now! </a> - {% elif election.voting_type != "simple" %} + {% endif %} <a href="{{ url_for('vote', election_alias=election.alias) }}"> Change your vote! </a> - {% endif %} {% endif %} </td> </tr>
commit f0660ec8291325607f2657c4ee077bae025afd81 Author: Joshua Santos nerdsville@nerdsville.net Date: Tue Sep 1 10:39:20 2015 -0400
Add simple revoting
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py index 3ccc00e..6eac5f7 100644 --- a/fedora_elections/elections.py +++ b/fedora_elections/elections.py @@ -112,7 +112,7 @@ def vote(election_alias): if election.voting_type.startswith('range'): return vote_range(election, revote) elif election.voting_type == 'simple': - return vote_simple(election) + return vote_simple(election, revote) elif election.voting_type == 'select': return vote_select(election, revote) elif election.voting_type == 'irc': @@ -219,9 +219,9 @@ def vote_select(election, revote): usernamemap=usernamemap, nextaction=next_action)
-def vote_simple(election): +def vote_simple(election, revote): votes = models.Vote.of_user_on_election( - SESSION, flask.g.fas_user.username, election.id, count=True) + SESSION, flask.g.fas_user.username, election.id)
num_candidates = election.candidates.count()
@@ -233,20 +233,27 @@ def vote_simple(election):
if form.validate_on_submit(): if form.action.data == 'submit': - for candidate in form: - if candidate.short_name in ['csrf_token', 'action']: - continue - - new_vote = models.Vote( - election_id=election.id, - voter=flask.g.fas_user.username, - timestamp=datetime.now(), - candidate_id=candidate.data, - value=1, - ) - SESSION.add(new_vote) - SESSION.commit() - + candidates = [ + candidate + for candidate in form + if candidate and candidate.short_name not in ['csrf_token', 'action'] + ] + for index in range(len(candidates)): + candidate = candidates[index] + if revote: + vote = votes[index] + vote.candidate_id = candidate.data + SESSION.add(vote) + else: + new_vote = models.Vote( + election_id=election.id, + voter=flask.g.fas_user.username, + timestamp=datetime.now(), + candidate_id=candidate.data, + value=1, + ) + SESSION.add(new_vote) + SESSION.commit() flask.flash("Your vote has been recorded. Thank you!") return safe_redirect_back()
commit c4e93d5d01b0f1136423e60443741348f64c625a Merge: 258625a b97dcc0 Author: Pierre-Yves Chibon pingou@pingoured.fr Date: Tue Sep 1 16:37:11 2015 +0200
Merge pull request #52 from NerdsvilleCEO/refactor
Some cleanup/refactoring
commit b97dcc099fe54bf9a6cec86898423c61ac86049b Author: Joshua Santos nerdsville@nerdsville.net Date: Tue Sep 1 10:22:54 2015 -0400
Some cleanup/refactoring
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py index 2ca8800..3ccc00e 100644 --- a/fedora_elections/elections.py +++ b/fedora_elections/elections.py @@ -146,23 +146,7 @@ def vote_range(election, revote): for candidate in form if candidate and candidate.short_name not in ['csrf_token', 'action'] ] - for index in range(len(candidates)): - candidate = candidates[index] - if revote: - vote = votes[index] - vote.value = candidate.data - SESSION.add(vote) - else: - new_vote = models.Vote( - election_id=election.id, - voter=flask.g.fas_user.username, - timestamp=datetime.now(), - candidate_id=candidate.short_name, - value=candidate.data, - ) - SESSION.add(new_vote) - SESSION.commit() - + process_vote(candidates, election, votes, revote) flask.flash("Your vote has been recorded. Thank you!") return safe_redirect_back()
@@ -202,14 +186,12 @@ def vote_select(election, revote): max_selection=max_selection)
if form.validate_on_submit(): - - cnt = 0 - for candidate in form: - if candidate.short_name in ['csrf_token', 'action']: - continue - if candidate.data: - cnt += 1 - if cnt > max_selection: + cnt = [ + candidate + for candidate in form + if candidate.data and candidate.short_name not in ['csrf_token', 'action'] + ] + if len(cnt) > max_selection: flask.flash('Too many candidates submitted', 'error') else: if form.action.data == 'submit': @@ -218,22 +200,7 @@ def vote_select(election, revote): for candidate in form if candidate and candidate.short_name not in ['csrf_token', 'action'] ] - for index in range(len(candidates)): - candidate = candidates[index] - if revote: - vote = votes[index] - vote.value = int(candidate.data) - SESSION.add(vote) - else: - new_vote = models.Vote( - election_id=election.id, - voter=flask.g.fas_user.username, - timestamp=datetime.now(), - candidate_id=cand_name[candidate.short_name], - value=int(candidate.data), - ) - SESSION.add(new_vote) - SESSION.commit() + process_vote_by_cand_name(candidates, cand_name, election, votes, revote) flask.flash("Your vote has been recorded. Thank you!") return safe_redirect_back()
@@ -252,7 +219,6 @@ def vote_select(election, revote): usernamemap=usernamemap, nextaction=next_action)
- def vote_simple(election): votes = models.Vote.of_user_on_election( SESSION, flask.g.fas_user.username, election.id, count=True) @@ -317,22 +283,7 @@ def vote_irc(election, revote): for candidate in form if candidate and candidate.short_name not in ['csrf_token', 'action'] ] - for index in range(len(candidates)): - candidate = candidates[index] - if revote: - vote = votes[index] - vote.value = int(candidate.data) - SESSION.add(vote) - else: - new_vote = models.Vote( - election_id=election.id, - voter=flask.g.fas_user.username, - timestamp=datetime.now(), - candidate_id=cand_name[candidate.short_name], - value=int(candidate.data), - ) - SESSION.add(new_vote) - SESSION.commit() + process_vote_by_cand_name(candidates, cand_name, election, votes, revote) flask.flash("Your vote has been recorded. Thank you!") return safe_redirect_back()
@@ -427,3 +378,39 @@ def election_results_text(election_alias): usernamemap=usernamemap, stats=stats, ) + +def process_vote(candidates, election, votes, revote): + for index in range(len(candidates)): + candidate = candidates[index] + if revote: + vote = votes[index] + vote.value = int(candidate.data) + SESSION.add(vote) + else: + new_vote = models.Vote( + election_id=election.id, + voter=flask.g.fas_user.username, + timestamp=datetime.now(), + candidate_id=candidate.short_name, + value=int(candidate.data), + ) + SESSION.add(new_vote) + SESSION.commit() + +def process_vote_by_cand_name(candidates, cand_name, election, votes, revote): + for index in range(len(candidates)): + candidate = candidates[index] + if revote: + vote = votes[index] + vote.value = int(candidate.data) + SESSION.add(vote) + else: + new_vote = models.Vote( + election_id=election.id, + voter=flask.g.fas_user.username, + timestamp=datetime.now(), + candidate_id=cand_name[candidate.short_name], + value=int(candidate.data), + ) + SESSION.add(new_vote) + SESSION.commit()
commit 258625ae57f4205afa88fa111e8e929ae47b3465 Merge: 8dfa932 24d827d Author: Pierre-Yves Chibon pingou@pingoured.fr Date: Tue Sep 1 15:20:55 2015 +0200
Merge pull request #51 from NerdsvilleCEO/add-irc-revote
Add irc revote
commit 24d827d00633b1320b6d6e1c8b7839eb094e5852 Author: Joshua Santos nerdsville@nerdsville.net Date: Tue Sep 1 06:49:06 2015 -0400
Modify template condition
diff --git a/fedora_elections/templates/index.html b/fedora_elections/templates/index.html index c796319..abfcdd1 100644 --- a/fedora_elections/templates/index.html +++ b/fedora_elections/templates/index.html @@ -32,7 +32,7 @@ <a href="{{ url_for('vote', election_alias=election.alias) }}"> Vote now! </a> - {% elif election.voting_type == 'range' or election.voting_type == 'select' %} + {% elif election.voting_type != "simple" %} <a href="{{ url_for('vote', election_alias=election.alias) }}"> Change your vote! </a>
commit abb42bcbb8748f3df10a681d11095c351d6bfa7a Author: Joshua Santos nerdsville@nerdsville.net Date: Tue Sep 1 06:46:47 2015 -0400
Add IRC Revote tests
diff --git a/tests/test_flask_irc.py b/tests/test_flask_irc.py index 9c45fa4..4fc6b69 100644 --- a/tests/test_flask_irc.py +++ b/tests/test_flask_irc.py @@ -55,14 +55,6 @@ class FlaskIrcElectionstests(ModelFlasktests):
self.setup_db()
- user = FakeUser(['packager'], username='toshio') - with user_set(fedora_elections.APP, user): - output = self.app.get( - '/vote/test_election7', follow_redirects=True) - self.assertTrue( - 'class="message">You have already voted in the election!</' - in output.data) - user = FakeUser(['packager'], username='nerdsville') with user_set(fedora_elections.APP, user): output = self.app.get( @@ -151,6 +143,53 @@ class FlaskIrcElectionstests(ModelFlasktests): self.assertTrue('<h3>Next 1 elections</h3>' in output.data) self.assertTrue('<h3>Last 2 elections</h3>' in output.data)
+ def test_vote_irc_revote(self): + """ Test the vote_irc function - the re-voting part. """ + #First we need to vote + self.setup_db() + + user = FakeUser(['voters'], username='nerdsville') + with user_set(fedora_elections.APP, user): + retrieve_csrf = self.app.post('/vote/test_election7') + csrf_token = retrieve_csrf.data.split( + 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + # Valid input + data = { + 'Kevin': -1, + 'Toshio': 1, + 'action': 'submit', + 'csrf_token': csrf_token, + } + self.app.post('/vote/test_election7', data=data, follow_redirects=True) + vote = fedora_elections.models.Vote + votes = vote.of_user_on_election(self.session, "nerdsville", '7') + self.assertEqual(votes[0].value, 1) + self.assertEqual(votes[1].value, -1) + #Let's not do repetition of what is tested above we aren't testing the + #functionality of voting as that has already been asserted + + #Next, we need to try revoting + newdata = { + 'Kevin': 1, + 'Toshio': -1, + 'action': 'submit', + 'csrf_token': csrf_token, + } + output = self.app.post('/vote/test_election7', data=newdata, follow_redirects=True) + #Next, we need to check if the vote has been recorded + self.assertEqual(output.status_code, 200) + self.assertTrue( + 'class="message">Your vote has been recorded. Thank you!</' + in output.data) + self.assertTrue('<h3>Current elections</h3>' in output.data) + self.assertTrue('<h3>Next 1 elections</h3>' in output.data) + self.assertTrue('<h3>Last 2 elections</h3>' in output.data) + vote = fedora_elections.models.Vote + votes = vote.of_user_on_election(self.session, "nerdsville", '7') + self.assertEqual(votes[0].value, -1) + self.assertEqual(votes[1].value, 1) + + #If we haven't failed yet, HOORAY!
if __name__ == '__main__': SUITE = unittest.TestLoader().loadTestsFromTestCase(FlaskIrcElectionstests)
commit d1499f0d4a7a4df5f98b532de837aa7b1f1e9af8 Author: Joshua Santos nerdsville@nerdsville.net Date: Tue Sep 1 06:46:28 2015 -0400
Add IRC Revoting
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py index f37cbfa..2ca8800 100644 --- a/fedora_elections/elections.py +++ b/fedora_elections/elections.py @@ -116,7 +116,7 @@ def vote(election_alias): elif election.voting_type == 'select': return vote_select(election, revote) elif election.voting_type == 'irc': - return vote_irc(election) + return vote_irc(election, revote) else: # pragma: no cover flask.flash( 'Unknown election voting type: %s' % election.voting_type) @@ -296,9 +296,9 @@ def vote_simple(election): nextaction=next_action)
-def vote_irc(election): +def vote_irc(election, revote): votes = models.Vote.of_user_on_election( - SESSION, flask.g.fas_user.username, election.id, count=True) + SESSION, flask.g.fas_user.username, election.id)
cand_name = {} for candidate in election.candidates: @@ -312,18 +312,27 @@ def vote_irc(election): fasusers=election.candidates_are_fasusers) if form.validate_on_submit(): if form.action.data == 'submit': - for candidate in form: - if candidate.short_name in ['csrf_token', 'action']: - continue - new_vote = models.Vote( - election_id=election.id, - voter=flask.g.fas_user.username, - timestamp=datetime.now(), - candidate_id=cand_name[candidate.short_name], - value=candidate.data, - ) - SESSION.add(new_vote) - SESSION.commit() + candidates = [ + candidate + for candidate in form + if candidate and candidate.short_name not in ['csrf_token', 'action'] + ] + for index in range(len(candidates)): + candidate = candidates[index] + if revote: + vote = votes[index] + vote.value = int(candidate.data) + SESSION.add(vote) + else: + new_vote = models.Vote( + election_id=election.id, + voter=flask.g.fas_user.username, + timestamp=datetime.now(), + candidate_id=cand_name[candidate.short_name], + value=int(candidate.data), + ) + SESSION.add(new_vote) + SESSION.commit() flask.flash("Your vote has been recorded. Thank you!") return safe_redirect_back()
elections-devel@lists.stg.fedorahosted.org