README.rst | 2
alembic/versions/2b8f5a6f10a4_store_fas_name_locally.py | 27 ++
fedora_elections/__init__.py | 7
fedora_elections/admin.py | 32 ++-
fedora_elections/default_config.py | 7
fedora_elections/elections.py | 150 +++++++---------
fedora_elections/forms.py | 6
fedora_elections/models.py | 5
fedora_elections/templates/admin/view_election.html | 1
fedora_elections/templates/index.html | 4
fedora_elections/utils.py | 16 -
files/fedora-elections.spec | 11 -
nosetests | 4
requirements.txt | 1
runserver.py | 44 +++-
tests/test_flask_elections.py | 11 -
tests/test_flask_irc.py | 55 +++++
tests/test_flask_range_voting.py | 69 ++++++-
tests/test_flask_select_voting.py | 56 +++++
tests/test_flask_simple_voting.py | 54 ++++-
20 files changed, 390 insertions(+), 172 deletions(-)
New commits:
commit 022191e53642cecae36667639593273c255374c3
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Feb 2 15:19:12 2016 +0100
Release 2.6
diff --git a/fedora_elections/__init__.py b/fedora_elections/__init__.py
index 2bd685e..d40b8c1 100644
--- a/fedora_elections/__init__.py
+++ b/fedora_elections/__init__.py
@@ -24,7 +24,7 @@
# Pierre-Yves Chibon <pingou(a)fedoraproject.org>
#
-__version__ = '2.5.4'
+__version__ = '2.6'
import logging
import os
@@ -40,8 +40,6 @@ from fedora.client import AuthError, AppError
from fedora.client.fas2 import AccountSystem
from flask.ext.fas_openid import FAS
-import dogpile.cache
-
import fedora_elections.fedmsgshim
import fedora_elections.mail_logging
import fedora_elections.proxy
diff --git a/files/fedora-elections.spec b/files/fedora-elections.spec
index d8619e1..e6c3eab 100644
--- a/files/fedora-elections.spec
+++ b/files/fedora-elections.spec
@@ -1,7 +1,7 @@
%define modname fedora_elections
Name: fedora-elections
-Version: 2.5.4
+Version: 2.6
Release: 1%{?dist}
Summary: Fedora elections application
@@ -109,6 +109,13 @@ install -m 644 files/update_1_to_2.sql \
%changelog
+* Mon Feb 01 2016 Pierre-Yves Chibon <pingou(a)pingoured.fr> - 2.6-1
+- Update to 2.6
+- Add the possibility to change one's vote on an election (Joshua Santos)
+- Cache the candidate's name retrieved from FAS locally
+- Improve the runserver script and adjust the README accordingly
+- Drop the requirement on dogpile.cache
+
* Thu May 28 2015 Pierre-Yves Chibon <pingou(a)pingoured.fr> - 2.5.4-1
- Update to 2.5.4
- Fix displaying information about the simplified range voting method
diff --git a/requirements.txt b/requirements.txt
index 4810410..5b19ffd 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -9,5 +9,4 @@ python-openid-cla
python-openid-teams
SQLAlchemy
wtforms
-dogpile.cache
blinker # required by Flask for the unit-tests (for signaling)
commit 1fbf8cfa5593ddd7a0211a8f5273dde9259c4c87
Merge: 995fbe6 52ae1e1
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Mon Feb 1 17:37:26 2016 +0100
Merge branch 'develop'
commit 52ae1e1c03281eefbbf6cd2de983815063797327
Merge: d33ad98 af5cd81
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jan 29 23:15:42 2016 +0100
Merge pull request #57 from fedora-infra/improved_script
Rework the runserver script to offer more options
commit af5cd8191ddf135dd68e684d9c9f8974b51b6dde
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Thu Jan 28 00:22:52 2016 +0100
Use 127.0.0.1 instead of 0.0.0.0 in the README and runserver.py
diff --git a/README.rst b/README.rst
index 5aa925e..96a39c8 100644
--- a/README.rst
+++ b/README.rst
@@ -81,7 +81,7 @@ There are 2 ways to start the application:
* with apache
-* How to start without apache on
http://0.0.0.0:5000 (useful for development):
+* How to start without apache on
http://127.0.0.1:5000 (useful for development):
::
diff --git a/runserver.py b/runserver.py
index 25c26c8..03becc0 100755
--- a/runserver.py
+++ b/runserver.py
@@ -43,4 +43,4 @@ if args.config:
os.environ['FEDORA_ELECTIONS_CONFIG'] = config
APP.debug = True
-APP.run(host='0.0.0.0', port=int(args.port))
+APP.run(host='127.0.0.1', port=int(args.port))
commit 6480b3b6212866d57b4688b1964f0d4e45b7d126
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Wed Jan 27 11:09:11 2016 +0100
Adjust README to match with the instructions of runserver.py
diff --git a/README.rst b/README.rst
index 42dc6de..5aa925e 100644
--- a/README.rst
+++ b/README.rst
@@ -81,7 +81,7 @@ There are 2 ways to start the application:
* with apache
-* How to start without apache on localhost:5000 (useful for development):
+* How to start without apache on
http://0.0.0.0:5000 (useful for development):
::
commit 9aea8e732d18962d99c99cd0233ece5428887e9c
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Wed Jan 27 11:08:55 2016 +0100
Remove mentions to pkgdb2 since this is now an elections file
diff --git a/runserver.py b/runserver.py
index b24c408..25c26c8 100755
--- a/runserver.py
+++ b/runserver.py
@@ -10,7 +10,7 @@ import os
parser = argparse.ArgumentParser(
- description='Run the packages2 app')
+ description='Run the Fedora election app')
parser.add_argument(
'--config', '-c', dest='config',
help='Configuration file to use for packages.')
@@ -21,7 +21,7 @@ parser.add_argument(
parser.add_argument(
'--profile', dest='profile', action='store_true',
default=False,
- help='Profile the packages2 application.')
+ help='Profile the application.')
parser.add_argument(
'--port', '-p', default=5000,
help='Port for the flask application.')
commit b0ccbb024fe8f50737eefa47f229dd909b61f83d
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Sun Jan 24 09:36:07 2016 +0100
Rework the runserver script to offer more options
diff --git a/runserver.py b/runserver.py
index 922f528..b24c408 100755
--- a/runserver.py
+++ b/runserver.py
@@ -1,16 +1,46 @@
-#!/usr/bin/env python
-import __main__
-__main__.__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
+#!/usr/bin/env python2
+
+# These two lines are needed to run on EL6
+__requires__ = ['SQLAlchemy >= 0.8', 'jinja2 >= 2.4']
import pkg_resources
+import argparse
import sys
-from werkzeug.contrib.profiler import ProfilerMiddleware
+import os
+
+
+parser = argparse.ArgumentParser(
+ description='Run the packages2 app')
+parser.add_argument(
+ '--config', '-c', dest='config',
+ help='Configuration file to use for packages.')
+parser.add_argument(
+ '--debug', dest='debug', action='store_true',
+ default=False,
+ help='Expand the level of data returned.')
+parser.add_argument(
+ '--profile', dest='profile', action='store_true',
+ default=False,
+ help='Profile the packages2 application.')
+parser.add_argument(
+ '--port', '-p', default=5000,
+ help='Port for the flask application.')
+
+args = parser.parse_args()
from fedora_elections import APP
-APP.debug = True
-if '--profile' in sys.argv:
+if args.profile:
+ from werkzeug.contrib.profiler import ProfilerMiddleware
APP.config['PROFILE'] = True
APP.wsgi_app = ProfilerMiddleware(APP.wsgi_app, restrictions=[30])
-APP.run()
+if args.config:
+ config = args.config
+ if not config.startswith('/'):
+ here = os.path.join(os.path.dirname(os.path.abspath(__file__)))
+ config = os.path.join(here, config)
+ os.environ['FEDORA_ELECTIONS_CONFIG'] = config
+
+APP.debug = True
+APP.run(host='0.0.0.0', port=int(args.port))
commit d33ad98b8605f81fe4996635a02741029d29d297
Merge: 20889d6 f79dd09
Author: Pierre-Yves Chibon <pingou(a)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(a)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(a)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(a)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(a)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
])
-
-
-(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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()
commit 8dfa93269c7888f97fc4ef786571683323470788
Merge: aa3ce6c 095eb79
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Sep 1 12:00:33 2015 +0200
Merge pull request #50 from fedora-infra/fix_tests
Let's not require a specific version of nose to run the tests
commit 095eb79d91b2d30a4abbba454ec56442516aecc5
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Sep 1 10:28:24 2015 +0200
Let's not require a specific version of nose to run the tests
diff --git a/nosetests b/nosetests
index 42c36f1..d050ee4 100755
--- a/nosetests
+++ b/nosetests
@@ -1,10 +1,10 @@
#!/usr/bin/env python
# EASY-INSTALL-ENTRY-SCRIPT:
'nose==1.3.0','console_scripts','nosetests'
-__requires__ = ['nose==1.3.0', 'flask>=0.10']
+__requires__ = ['nose', 'flask>=0.10']
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
- load_entry_point('nose==1.3.0', 'console_scripts',
'nosetests')()
+ load_entry_point('nose', 'console_scripts',
'nosetests')()
)
commit aa3ce6cc434433c2b072b99030ca72e24363d186
Merge: 728c885 cc5e577
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Sep 1 11:48:06 2015 +0200
Merge pull request #49 from NerdsvilleCEO/add-select-revote
Add select revote
commit cc5e57713f14e0f6cb7702eca3b1333aecbf65e2
Author: Joshua Santos <Nerdsville(a)nerdsville.net>
Date: Tue Aug 11 14:54:34 2015 -0700
Update elections.py
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index 4ca1ec3..f37cbfa 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -214,10 +214,10 @@ def vote_select(election, revote):
else:
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']
+ ]
for index in range(len(candidates)):
candidate = candidates[index]
if revote:
commit 68f4c1aa7a818a7e693a3484452902d3a0c41bea
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Tue Aug 11 10:28:20 2015 -0700
Add template condition
diff --git a/fedora_elections/templates/index.html
b/fedora_elections/templates/index.html
index 2add908..c796319 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' %}
+ {% elif election.voting_type == 'range' or election.voting_type ==
'select' %}
<a href="{{ url_for('vote', election_alias=election.alias)
}}">
Change your vote!
</a>
commit 2dbf5f16bf42ab9a7547be6b56007f5b54c0397a
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Tue Aug 11 10:25:35 2015 -0700
Fix description of select revote test
diff --git a/tests/test_flask_select_voting.py b/tests/test_flask_select_voting.py
index 845d94e..a9ba872 100644
--- a/tests/test_flask_select_voting.py
+++ b/tests/test_flask_select_voting.py
@@ -161,7 +161,7 @@ class FlaskSimpleElectionstests(ModelFlasktests):
self.assertTrue('<h3>Last 2 elections</h3>' in
output.data)
def test_vote_select_revote(self):
- """ Test the vote_range function - the re-voting part.
"""
+ """ Test the vote_select function - the re-voting part.
"""
#First we need to vote
self.setup_db()
commit 1667763a8af6b6e2aa76fa3536e90f69d50882ba
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Tue Aug 11 10:24:09 2015 -0700
Add select revote
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index 1e6706c..4ca1ec3 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -114,7 +114,7 @@ def vote(election_alias):
elif election.voting_type == 'simple':
return vote_simple(election)
elif election.voting_type == 'select':
- return vote_select(election)
+ return vote_select(election, revote)
elif election.voting_type == 'irc':
return vote_irc(election)
else: # pragma: no cover
@@ -182,9 +182,9 @@ def vote_range(election, revote):
nextaction=next_action)
-def vote_select(election):
+def vote_select(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()
@@ -213,20 +213,27 @@ def vote_select(election):
flask.flash('Too many candidates submitted', 'error')
else:
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=int(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()
diff --git a/tests/test_flask_select_voting.py b/tests/test_flask_select_voting.py
index 73d2ca0..845d94e 100644
--- a/tests/test_flask_select_voting.py
+++ b/tests/test_flask_select_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_election6', 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(
@@ -168,6 +160,54 @@ 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_select_revote(self):
+ """ Test the vote_range 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_election6')
+ csrf_token = retrieve_csrf.data.split(
+ 'name="csrf_token" type="hidden"
value="')[1].split('">')[0]
+
+ # Valid input
+ data = {
+ 'Kevin': True,
+ 'action': 'submit',
+ 'csrf_token': csrf_token,
+ }
+ self.app.post('/vote/test_election6', data=data,
follow_redirects=True)
+ vote = fedora_elections.models.Vote
+ votes = vote.of_user_on_election(self.session, "nerdsville",
'6')
+ self.assertEqual(votes[0].candidate.name, "Toshio")
+ self.assertEqual(votes[0].value, 0)
+ self.assertEqual(votes[1].candidate.name, "Kevin")
+ self.assertEqual(votes[1].value, 1)
+
+ #Next, we need to try revoting
+ newdata = {
+ 'Toshio': True,
+ 'action': 'submit',
+ 'csrf_token': csrf_token,
+ }
+ output = self.app.post('/vote/test_election6', 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",
'6')
+ self.assertEqual(votes[0].value, 1)
+ self.assertEqual(votes[1].value, 0)
+
+
+ #If we haven't failed yet, HOORAY!
+
if __name__ == '__main__':
SUITE = unittest.TestLoader().loadTestsFromTestCase(
commit 728c8852a4f107add514b81abc7ceb8ec0e1e9b2
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Mon Aug 10 18:08:48 2015 -0700
Remove extra whitespace
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index 5cfe52b..1e6706c 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -154,12 +154,12 @@ def vote_range(election, revote):
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,
- )
+ 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()
commit b250393dd0810dd0321c14ce59fabab12d9a9490
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Mon Aug 10 17:29:46 2015 -0700
Indentation fix
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index ac8c320..5cfe52b 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -154,12 +154,12 @@ def vote_range(election, revote):
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,
- )
+ 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()
commit 795df2a6d83e8697f59a8a36101e8ef5d06eada1
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Mon Aug 10 13:33:34 2015 -0700
We have only implememnted range revote, add condition
diff --git a/fedora_elections/templates/index.html
b/fedora_elections/templates/index.html
index 5d15ef8..2add908 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>
- {% else %}
+ {% elif election.voting_type == 'range' %}
<a href="{{ url_for('vote', election_alias=election.alias)
}}">
Change your vote!
</a>
commit d4db639baae8356719560aa9adbcc43ece2800f5
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Mon Aug 10 13:28:40 2015 -0700
use list comprehension instead of lambda
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index 51e20f1..ac8c320 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -141,12 +141,13 @@ def vote_range(election, revote):
if form.validate_on_submit():
if form.action.data == 'submit':
- candidate_filter = lambda item: item.short_name not in ['csrf_token',
'action']
- candidates = filter(lambda candidate: candidate_filter(candidate), form)
- sorted_form = sorted(candidates, key=lambda candidate: candidate.short_name)
- iter = 0
- for index in range(len(sorted_form)):
- candidate = sorted_form[index]
+ 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 = candidate.data
commit 981ae199fb7b9742661a19e07b7d3e5800336f83
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Mon Aug 10 13:25:14 2015 -0700
no need to sort by cand_id, already done :D
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index fe0945b..51e20f1 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -126,8 +126,6 @@ def vote_range(election, revote):
votes = models.Vote.of_user_on_election(
SESSION, flask.g.fas_user.username, election.id)
- sorted_votes = sorted(votes, key=lambda candidate: candidate.candidate_id)
-
num_candidates = election.candidates.count()
cand_ids = [str(cand.id) for cand in election.candidates]
@@ -150,7 +148,7 @@ def vote_range(election, revote):
for index in range(len(sorted_form)):
candidate = sorted_form[index]
if revote:
- vote = sorted_votes[index]
+ vote = votes[index]
vote.value = candidate.data
SESSION.add(vote)
else:
commit 7d5e55a3c96c11cb1add431f7940b7c1781cdd64
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Wed Aug 5 08:45:27 2015 -0700
Fix tests to use Vote class method for revote tests
diff --git a/tests/test_flask_range_voting.py b/tests/test_flask_range_voting.py
index a6f1eaa..c18aca9 100644
--- a/tests/test_flask_range_voting.py
+++ b/tests/test_flask_range_voting.py
@@ -307,11 +307,10 @@ class FlaskRangeElectionstests(ModelFlasktests):
}
self.app.post('/vote/test_election3', data=data,
follow_redirects=True)
vote = fedora_elections.models.Vote
- votes = self.session.query(vote).filter(vote.voter == 'nerdsville')
- sorted_votes = sorted(votes, key=lambda vote: vote.candidate_id)
- self.assertEqual(sorted_votes[0].value, 1)
- self.assertEqual(sorted_votes[1].value, 0)
- self.assertEqual(sorted_votes[2].value, 2)
+ votes = vote.of_user_on_election(self.session, "nerdsville",
'3')
+ self.assertEqual(votes[0].value, 1)
+ 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
@@ -332,11 +331,11 @@ class FlaskRangeElectionstests(ModelFlasktests):
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)
- votes = self.session.query(vote).filter(vote.voter == 'nerdsville')
- sorted_votes = sorted(votes, key=lambda vote: vote.candidate_id)
- self.assertEqual(sorted_votes[0].value, 2)
- self.assertEqual(sorted_votes[1].value, 1)
- self.assertEqual(sorted_votes[2].value, 1)
+ vote = fedora_elections.models.Vote
+ votes = vote.of_user_on_election(self.session, "nerdsville",
'3')
+ self.assertEqual(votes[0].value, 2)
+ self.assertEqual(votes[1].value, 1)
+ self.assertEqual(votes[2].value, 1)
#If we haven't failed yet, HOORAY!
commit d8690fa12ef146c5d193b66dc95ce105dbc306c2
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Wed Aug 5 08:40:26 2015 -0700
remove unused dependency
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index 2a067ff..fe0945b 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -38,7 +38,6 @@ from fedora_elections import (
is_safe_url, safe_redirect_back,
)
from fedora_elections.utils import build_name_map
-from sqlalchemy import update
def login_required(f):
@wraps(f)
commit 061c5aecb945d0dd84bfc064a694e3db23ac192b
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Wed Aug 5 08:39:16 2015 -0700
sort by candidate_id in Vote class method of_user_on_election
diff --git a/fedora_elections/models.py b/fedora_elections/models.py
index dff7cc4..b3e72cc 100644
--- a/fedora_elections/models.py
+++ b/fedora_elections/models.py
@@ -356,7 +356,7 @@ class Vote(BASE):
).filter(
cls.voter == user
).order_by(
- cls.timestamp
+ cls.candidate_id
)
if count:
commit 1b938fd60199c355866a9a68b97e5793bc3dc23a
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Wed Aug 5 08:38:43 2015 -0700
Use for idx in range for loop
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index d7e512b..2a067ff 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -148,14 +148,12 @@ def vote_range(election, revote):
candidates = filter(lambda candidate: candidate_filter(candidate), form)
sorted_form = sorted(candidates, key=lambda candidate: candidate.short_name)
iter = 0
- for candidate in sorted_form:
-
+ for index in range(len(sorted_form)):
+ candidate = sorted_form[index]
if revote:
- vote = sorted_votes[iter]
+ vote = sorted_votes[index]
vote.value = candidate.data
SESSION.add(vote)
- iter += 1
-
else:
new_vote = models.Vote(
election_id=election.id,
commit ee55ebd7e1730610d68147ee80588f9400ead879
Author: Joshua Santos <nerdsville(a)fed.dev>
Date: Fri Jul 17 14:51:39 2015 -0400
Add revote link
diff --git a/fedora_elections/templates/index.html
b/fedora_elections/templates/index.html
index 64b526b..5d15ef8 100644
--- a/fedora_elections/templates/index.html
+++ b/fedora_elections/templates/index.html
@@ -32,6 +32,10 @@
<a href="{{ url_for('vote', election_alias=election.alias)
}}">
Vote now!
</a>
+ {% else %}
+ <a href="{{ url_for('vote', election_alias=election.alias)
}}">
+ Change your vote!
+ </a>
{% endif %}
{% endif %}
</td>
commit a29d040c98f28e588b80cb4173c150bacd625144
Author: Joshua Santos <nerdsville(a)fed.dev>
Date: Fri Jul 17 14:42:57 2015 -0400
remove nose requirement
diff --git a/requirements.txt b/requirements.txt
index 4352ff8..4810410 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,4 +11,3 @@ SQLAlchemy
wtforms
dogpile.cache
blinker # required by Flask for the unit-tests (for signaling)
-nose===1.3.0
commit 0b43cb068fcd0a7d73cf1e7d740fda4eff639f1f
Author: Joshua Santos <nerdsville(a)fed.dev>
Date: Fri Jul 17 14:41:02 2015 -0400
move comment to two lines
diff --git a/tests/test_flask_range_voting.py b/tests/test_flask_range_voting.py
index e3d72eb..a6f1eaa 100644
--- a/tests/test_flask_range_voting.py
+++ b/tests/test_flask_range_voting.py
@@ -312,7 +312,9 @@ class FlaskRangeElectionstests(ModelFlasktests):
self.assertEqual(sorted_votes[0].value, 1)
self.assertEqual(sorted_votes[1].value, 0)
self.assertEqual(sorted_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
+ #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 = {
'4': 2,
commit 3a4af527cd53edba4f122822ce1c2cd9626c50f4
Author: Joshua Santos <nerdsville(a)fed.dev>
Date: Fri Jul 17 14:27:13 2015 -0400
Update revote to use ORM
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index 55c1b8d..d7e512b 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -125,7 +125,9 @@ def vote(election_alias):
def vote_range(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)
+
+ sorted_votes = sorted(votes, key=lambda candidate: candidate.candidate_id)
num_candidates = election.candidates.count()
@@ -142,27 +144,27 @@ def vote_range(election, revote):
if form.validate_on_submit():
if form.action.data == 'submit':
- for candidate in form:
- if candidate.short_name in ['csrf_token', 'action']:
- continue
+ candidate_filter = lambda item: item.short_name not in ['csrf_token',
'action']
+ candidates = filter(lambda candidate: candidate_filter(candidate), form)
+ sorted_form = sorted(candidates, key=lambda candidate: candidate.short_name)
+ iter = 0
+ for candidate in sorted_form:
+
if revote:
- vote = update(models.Vote).\
- where(models.Vote.candidate_id == candidate.short_name
- and models.Vote.voter == flask.g.fas_user.username
- and models.Vote.election == election.id).\
- values(value = candidate.data)
- SESSION.execute(vote)
- #break out of candidate loop
- continue
+ vote = sorted_votes[iter]
+ vote.value = candidate.data
+ SESSION.add(vote)
+ iter += 1
- new_vote = models.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.add(new_vote)
SESSION.commit()
flask.flash("Your vote has been recorded. Thank you!")
diff --git a/tests/test_flask_range_voting.py b/tests/test_flask_range_voting.py
index 2c7f792..e3d72eb 100644
--- a/tests/test_flask_range_voting.py
+++ b/tests/test_flask_range_voting.py
@@ -293,7 +293,7 @@ class FlaskRangeElectionstests(ModelFlasktests):
#First we need to vote
self.setup_db()
- user = FakeUser(['voters'], username='pingou')
+ user = FakeUser(['voters'], username='nerdsville')
with user_set(fedora_elections.APP, user):
retrieve_csrf = self.app.post('/vote/test_election3')
csrf_token = retrieve_csrf.data.split(
@@ -306,6 +306,12 @@ class FlaskRangeElectionstests(ModelFlasktests):
'csrf_token': csrf_token,
}
self.app.post('/vote/test_election3', data=data,
follow_redirects=True)
+ vote = fedora_elections.models.Vote
+ votes = self.session.query(vote).filter(vote.voter == 'nerdsville')
+ sorted_votes = sorted(votes, key=lambda vote: vote.candidate_id)
+ self.assertEqual(sorted_votes[0].value, 1)
+ self.assertEqual(sorted_votes[1].value, 0)
+ self.assertEqual(sorted_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
#Next, we need to try revoting
newdata = {
@@ -324,6 +330,11 @@ class FlaskRangeElectionstests(ModelFlasktests):
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)
+ votes = self.session.query(vote).filter(vote.voter == 'nerdsville')
+ sorted_votes = sorted(votes, key=lambda vote: vote.candidate_id)
+ self.assertEqual(sorted_votes[0].value, 2)
+ self.assertEqual(sorted_votes[1].value, 1)
+ self.assertEqual(sorted_votes[2].value, 1)
#If we haven't failed yet, HOORAY!
commit e7ccc3bb8b19a934d420da1478c01326cb755d47
Author: Joshua Santos <nerdsville(a)fed.dev>
Date: Fri Jul 17 10:17:22 2015 -0400
Need to filter candidates before even checking if it is revote
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index dffa9ec..55c1b8d 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -143,6 +143,8 @@ def vote_range(election, revote):
if form.validate_on_submit():
if form.action.data == 'submit':
for candidate in form:
+ if candidate.short_name in ['csrf_token', 'action']:
+ continue
if revote:
vote = update(models.Vote).\
where(models.Vote.candidate_id == candidate.short_name
@@ -152,8 +154,6 @@ def vote_range(election, revote):
SESSION.execute(vote)
#break out of candidate loop
continue
- if candidate.short_name in ['csrf_token', 'action']:
- continue
new_vote = models.Vote(
election_id=election.id,
commit 63f3ce19879b44be7d3998b63fde86e81a37dd38
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Wed Jul 15 04:23:09 2015 -0700
Apparently the last voter is not a dictator :P
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index 753e45b..dffa9ec 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -145,7 +145,9 @@ def vote_range(election, revote):
for candidate in form:
if revote:
vote = update(models.Vote).\
- where(models.Vote.candidate_id == candidate.short_name and
models.Vote.voter == flask.g.fas_user.username).\
+ where(models.Vote.candidate_id == candidate.short_name
+ and models.Vote.voter == flask.g.fas_user.username
+ and models.Vote.election == election.id).\
values(value = candidate.data)
SESSION.execute(vote)
#break out of candidate loop
commit 32a2cea381423192ab9afe6a8cbb728baa159afa
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Wed Jul 15 04:20:55 2015 -0700
Apparently the last voter is not a dictator :P
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index 07ddb02..753e45b 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -142,12 +142,10 @@ def vote_range(election, revote):
if form.validate_on_submit():
if form.action.data == 'submit':
- if revote:
- old_votes = models.Vote.of_user_on_election(SESSION,
flask.g.fas_user.username, election.id)
for candidate in form:
if revote:
vote = update(models.Vote).\
- where(models.Vote.candidate_id == candidate.short_name).\
+ where(models.Vote.candidate_id == candidate.short_name and
models.Vote.voter == flask.g.fas_user.username).\
values(value = candidate.data)
SESSION.execute(vote)
#break out of candidate loop
commit afdde721c525702ba0630511f26bf16c20843df1
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Wed Jul 15 04:13:21 2015 -0700
Use update instead of nested for
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index a8efb2a..07ddb02 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -38,7 +38,7 @@ from fedora_elections import (
is_safe_url, safe_redirect_back,
)
from fedora_elections.utils import build_name_map
-
+from sqlalchemy import update
def login_required(f):
@wraps(f)
@@ -146,13 +146,10 @@ def vote_range(election, revote):
old_votes = models.Vote.of_user_on_election(SESSION,
flask.g.fas_user.username, election.id)
for candidate in form:
if revote:
- #TODO: this could probably be done in a more efficient manner
- for vote in old_votes:
- if vote.candidate_id == candidate.short_name:
- vote.value = candidate.data
- SESSION.commit()
- #break out of this loop
- continue
+ vote = update(models.Vote).\
+ where(models.Vote.candidate_id == candidate.short_name).\
+ values(value = candidate.data)
+ SESSION.execute(vote)
#break out of candidate loop
continue
if candidate.short_name in ['csrf_token', 'action']:
commit a14f385221e59ad9c811bb3fa5541db3faa83e80
Author: Joshua Santos <nerdsville(a)nerdsville.net>
Date: Wed Jul 15 03:21:59 2015 -0700
Add range revoting
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index d46db72..a8efb2a 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -108,12 +108,10 @@ def vote(election_alias):
votes = models.Vote.of_user_on_election(
SESSION, flask.g.fas_user.username, election.id, count=True)
- if votes > 0:
- flask.flash('You have already voted in the election!')
- return safe_redirect_back()
+ revote = True if votes > 0 else False
if election.voting_type.startswith('range'):
- return vote_range(election)
+ return vote_range(election, revote)
elif election.voting_type == 'simple':
return vote_simple(election)
elif election.voting_type == 'select':
@@ -125,8 +123,7 @@ def vote(election_alias):
'Unknown election voting type: %s' % election.voting_type)
return safe_redirect_back()
-
-def vote_range(election):
+def vote_range(election, revote):
votes = models.Vote.of_user_on_election(
SESSION, flask.g.fas_user.username, election.id, count=True)
@@ -144,9 +141,20 @@ def vote_range(election):
max_range=max_selection)
if form.validate_on_submit():
-
if form.action.data == 'submit':
+ if revote:
+ old_votes = models.Vote.of_user_on_election(SESSION,
flask.g.fas_user.username, election.id)
for candidate in form:
+ if revote:
+ #TODO: this could probably be done in a more efficient manner
+ for vote in old_votes:
+ if vote.candidate_id == candidate.short_name:
+ vote.value = candidate.data
+ SESSION.commit()
+ #break out of this loop
+ continue
+ #break out of candidate loop
+ continue
if candidate.short_name in ['csrf_token', 'action']:
continue
diff --git a/requirements.txt b/requirements.txt
index 4810410..4352ff8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,3 +11,4 @@ SQLAlchemy
wtforms
dogpile.cache
blinker # required by Flask for the unit-tests (for signaling)
+nose===1.3.0
diff --git a/tests/test_flask_range_voting.py b/tests/test_flask_range_voting.py
index d0be838..2c7f792 100644
--- a/tests/test_flask_range_voting.py
+++ b/tests/test_flask_range_voting.py
@@ -55,14 +55,6 @@ class FlaskRangeElectionstests(ModelFlasktests):
self.setup_db()
- user = FakeUser(['voters'], username='toshio')
- with user_set(fedora_elections.APP, user):
- output = self.app.get(
- '/vote/test_election3', follow_redirects=True)
- self.assertTrue(
- 'class="message">You have already voted in the
election!</'
- in output.data)
-
user = FakeUser(['voters'], username='pingou')
with user_set(fedora_elections.APP, user):
output = self.app.get(
@@ -296,6 +288,44 @@ class FlaskRangeElectionstests(ModelFlasktests):
self.assertTrue('<h3>Next 1 elections</h3>' in
output.data)
self.assertTrue('<h3>Last 2 elections</h3>' in
output.data)
+ def test_vote_range_revote(self):
+ """ Test the vote_range function - the re-voting part.
"""
+ #First we need to vote
+ self.setup_db()
+
+ user = FakeUser(['voters'], username='pingou')
+ with user_set(fedora_elections.APP, user):
+ retrieve_csrf = self.app.post('/vote/test_election3')
+ csrf_token = retrieve_csrf.data.split(
+ 'name="csrf_token" type="hidden"
value="')[1].split('">')[0]
+ data = {
+ '4': 1,
+ '5': 0,
+ '6': 2,
+ 'action': 'submit',
+ 'csrf_token': csrf_token,
+ }
+ self.app.post('/vote/test_election3', data=data,
follow_redirects=True)
+ #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 = {
+ '4': 2,
+ '5': 1,
+ '6': 1,
+ 'action': 'submit',
+ 'csrf_token': csrf_token,
+ }
+ output = self.app.post('/vote/test_election3', 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)
+ #If we haven't failed yet, HOORAY!
+
if __name__ == '__main__':
SUITE = unittest.TestLoader().loadTestsFromTestCase(
commit f778ec9c556419915952e5db6fa21aa3c047b1ce
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Aug 4 15:30:48 2015 +0200
Adjust the faitout url to the new address
diff --git a/tests/__init__.py b/tests/__init__.py
index 08c6833..eecfc4a 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -49,7 +49,8 @@ from fedora_elections import models
DB_PATH = 'sqlite:///:memory:'
-FAITOUT_URL = 'http://209.132.184.152/faitout/'
+FAITOUT_URL = 'http://faitout.fedorainfracloud.org/'
+
if os.environ.get('BUILD_ID'):
try:
import requests
commit 7f01a48e58fc2bd9ed4d92217e016f0711e9df7e
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Thu May 28 11:27:16 2015 +0200
Release 2.5.4
diff --git a/fedora_elections/__init__.py b/fedora_elections/__init__.py
index 4e6273c..c08a61c 100644
--- a/fedora_elections/__init__.py
+++ b/fedora_elections/__init__.py
@@ -24,7 +24,7 @@
# Pierre-Yves Chibon <pingou(a)fedoraproject.org>
#
-__version__ = '2.5.3'
+__version__ = '2.5.4'
import logging
import os
diff --git a/files/fedora-elections.spec b/files/fedora-elections.spec
index 96660d9..1fa4d0f 100644
--- a/files/fedora-elections.spec
+++ b/files/fedora-elections.spec
@@ -1,7 +1,7 @@
%define modname fedora_elections
Name: fedora-elections
-Version: 2.5.3
+Version: 2.5.4
Release: 1%{?dist}
Summary: Fedora elections application
@@ -111,6 +111,11 @@ install -m 644 files/update_1_to_2.sql \
%changelog
+* Thu May 28 2015 Pierre-Yves Chibon <pingou(a)pingoured.fr> - 2.5.4-1
+- Update to 2.5.4
+- Fix displaying information about the simplified range voting method
+- Fix setting the max_vote value in the stats dict for the results page
+
* Tue May 05 2015 Pierre-Yves Chibon <pingou(a)pingoured.fr> - 2.5.3-1
- Update to 2.5.3
- Fix the simplified range voting
commit 1865d4f6da417788f85af6481e87922f9615d639
Merge: 996c4ea 065f677
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Thu May 21 17:37:11 2015 +0200
Merge pull request #46 from fedora-infra/fix_resultspage
Fix setting the max_vote value in the stats dict for the results page
commit 065f6779977b1531f686c88df945ab3233321de9
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Thu May 21 16:21:59 2015 +0200
Fix setting the max_vote value in the stats dict for the results page
diff --git a/fedora_elections/models.py b/fedora_elections/models.py
index 8f80914..dff7cc4 100644
--- a/fedora_elections/models.py
+++ b/fedora_elections/models.py
@@ -414,14 +414,12 @@ class Vote(BASE):
stats['candidate_voters'] = candidate_voters
stats['n_candidates'] = cnt
- if election.voting_type in ['range', 'select']:
+ stats['max_vote'] = 1
+ if election.voting_type == 'select' \
+ or election.voting_type.startswith('range'):
stats['max_vote'] = cnt
if election.max_votes:
stats['max_vote'] = election.max_votes
- elif election.voting_type == 'simple':
- stats['max_vote'] = 1
- elif election.voting_type == 'irc':
- stats['max_vote'] = 1
dates = election = session.query(
Vote.timestamp
commit 996c4ea9b0b38b75ae98fe1af1928cd3c229f0b2
Merge: a247838 6daddbe
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue May 5 15:58:25 2015 +0200
Merge pull request #45 from fedora-infra/fix_doc
Fix displaying information about the simplified range voting method
commit 6daddbeb249b99b3bab3b9255a6eb7f9ef5f5a4e
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue May 5 14:28:23 2015 +0200
Fix displaying information about the simplified range voting method
diff --git a/fedora_elections/templates/vote_range.html
b/fedora_elections/templates/vote_range.html
index 141259e..d8f3458 100644
--- a/fedora_elections/templates/vote_range.html
+++ b/fedora_elections/templates/vote_range.html
@@ -72,7 +72,7 @@
<a
href="http://rangevoting.org/">Center for Range Voting</a>.
</p>
</div>
-{% elif election.voting_type == 'range_3' %}
+{% elif election.voting_type == 'range_simple' %}
<div>
<h2>Information on Simplified Range Voting</h2>
<p>