[Fedora Elections] #20: Candidate and Community Q/A feature
by fedora-badges
#20: Candidate and Community Q/A feature
-------------------------+--------------------------------------------------
Reporter: jspaleta | Owner: nigelj
Type: enhancement | Status: new
Priority: major | Milestone: Release 0.1.5
Component: General | Version: 0.1.0
Keywords: |
-------------------------+--------------------------------------------------
Purpose: To generate a slate of community questions to ask each candidate
in an election to help people do a side by side comparison of candidates's
thoughts on important Fedora project issues as seen by the voting
community.
This involves 4 things
1)A way for community to write in questions for candidates
2)A way for community to vote for questions previously submitted by a
certain deadline
3)A way for each candidate to answer "top" questions, by a certain
deadline
4)Displaying all candidate answers to all "top" questions together side by
side in context with the question. No commenting or revisioning beyond the
deadline
Notes:
I am told that lmacken is working on a community idea storm like app which
should be able to do
1) and 2)
3) is essentially setting some arbitrary limit to the number of questions
candidates will be expected to ask, as part of the election announcement.
You may want to supplement the community vote process with a small group
selection step to weed out a highly inappropriate question.
Once the slate of questions are selected the app would need to provide a
space for each candidate to answer each of those selected questions. Such
a space should be limited to a finite number of words per question, to
discourage people like me from writing overly detailed responses.
4) just makes it fair. If an issue or answer is hotly contested a
candidate-candidate debate can be done in a mailinglist or the
blogosphere.
--
Ticket URL: <https://fedorahosted.org/elections/ticket/20>
Fedora Elections <https://fedorahosted.org/elections/>
Fedora Elections
9 years, 10 months
[Fedora Elections] #24: Allow other Fedora Groups to use the voting system
by fedora-badges
#24: Allow other Fedora Groups to use the voting system
-------------------------+--------------------------------------------------
Reporter: nigelj | Owner: nigelj
Type: enhancement | Status: new
Priority: major | Milestone: Release 0.3.0
Component: General | Version: trunk
Keywords: kevin |
-------------------------+--------------------------------------------------
Just to keep a note here about it:
Kevin (nirik) queried if the irc-support group could use the voting system
to hold votes for themselves that are unrelated to board votes etc.
This opens the door to a new feature where we have 'official' and
'unofficial' elections, for instance a Board election would be considered
Official and would appear on the main page, but a irc-support group vote
would be unofficial and appear on a page off the main page.
It would also lower the permissions required to create such elections to
something like:
Create election requires would require either group: elections (official
elections), or, group administrator of groups allowed to vote (unofficial
elections) - extra groups could be added by 'elections' members if a case
is made.
This requires (for a totally self managed solution) that we go to a system
where the UI is nicer (#8) and elections can be closed out by the election
administrator.
Kevin: What do you think?
--
Ticket URL: <https://fedorahosted.org/elections/ticket/24>
Fedora Elections <https://fedorahosted.org/elections/>
Fedora Elections
9 years, 10 months
Branch 'develop' - 4 commits - fedora_elections/__init__.py fedora_elections/models.py files/fedora-elections.spec
by Pierre-YvesChibon
fedora_elections/__init__.py | 8 ++++++--
fedora_elections/models.py | 18 ++++++++++++++++++
files/fedora-elections.spec | 10 +++++++++-
3 files changed, 33 insertions(+), 3 deletions(-)
New commits:
commit 1e60b1b4bebda906044aab2dce70e223d26fbdd7
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Wed Jul 16 15:56:25 2014 +0200
Release 2.3
diff --git a/fedora_elections/__init__.py b/fedora_elections/__init__.py
index fc4f4c8..fd5f3e5 100644
--- a/fedora_elections/__init__.py
+++ b/fedora_elections/__init__.py
@@ -24,7 +24,7 @@
# Pierre-Yves Chibon <pingou(a)fedoraproject.org>
#
-__version__ = '2.2'
+__version__ = '2.3'
import os
diff --git a/files/fedora-elections.spec b/files/fedora-elections.spec
index 221b519..c1e9996 100644
--- a/files/fedora-elections.spec
+++ b/files/fedora-elections.spec
@@ -1,7 +1,7 @@
%define modname fedora_elections
Name: fedora-elections
-Version: 2.2
+Version: 2.3
Release: 1%{?dist}
Summary: Fedora elections application
@@ -109,6 +109,14 @@ install -m 644 files/update_1_to_2.sql \
%changelog
+* Wed Jul 16 2014 Pierre-Yves Chibon <pingou(a)pingoured.fr> - 2.3-1
+- Update to 2.3
+- Restrict the groups asked upon login (Allows Dennis to log in)
+- Check that candidates are FAS user when adding them to an election that
+ turned on the option
+- More links to the about page
+- Improved unit-tests suite
+
* Thu Jul 10 2014 Pierre-Yves Chibon <pingou(a)pingoured.fr> - 2.2-1
- Update to 2.2
- Better description of the different types of election
commit e5482acc2e59e523cd0b8b5e5faf3115f7801790
Merge: b2e5f17 d5167ef
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Wed Jul 16 15:44:05 2014 +0200
Merge pull request #32 from fedora-infra/restrict_groups
Restrict groups
commit d5167efe02be510e1645d6313e2ecfa57b39084f
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Wed Jul 16 09:19:46 2014 +0200
When login in, ask for the groups used in the database and admin groups set in the configuration
diff --git a/fedora_elections/__init__.py b/fedora_elections/__init__.py
index 103cade..fc4f4c8 100644
--- a/fedora_elections/__init__.py
+++ b/fedora_elections/__init__.py
@@ -259,7 +259,11 @@ def auth_login():
if hasattr(flask.g, 'fas_user') and flask.g.fas_user is not None:
return safe_redirect_back(next_url)
else:
- return FAS.login(return_url=next_url)
+ groups = APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'][:]
+ if isinstance(groups, basestring):
+ groups = [groups]
+ groups.extend(models.get_groups(SESSION))
+ return FAS.login(return_url=next_url, groups=groups)
@APP.route('/logout')
commit 0871db40e1c64562f23a95355ee3540e55b3e6e4
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Wed Jul 16 09:18:23 2014 +0200
Add a get_groups method that returns all the groups of interest in the database
These groups are the one used to restrict an election to a group of legal
voters or to specify a group as admin for an election.
We are interested in this list to ask OpenID to only return the groups
of interest rather than asking for all of them.
diff --git a/fedora_elections/models.py b/fedora_elections/models.py
index e0e5941..d35096f 100644
--- a/fedora_elections/models.py
+++ b/fedora_elections/models.py
@@ -415,3 +415,21 @@ class Vote(BASE):
stats['n_candidates'] = cnt
return stats
+
+
+def get_groups(session):
+ """ Return the list of groups of interest.
+
+ These groups are the groups used to find out the admins or the legal
+ voters of all the elections.
+ """
+
+ voters = [item[0] for item in session.query(
+ sa.distinct(LegalVoter.group_name)
+ ).order_by(LegalVoter.group_name).all()]
+
+ admins = [item[0] for item in session.query(
+ sa.distinct(ElectionAdminGroup.group_name)
+ ).order_by(ElectionAdminGroup.group_name).all()]
+
+ return voters + admins
9 years, 10 months
Changes to 'refs/tags/v2.3'
by Pierre-YvesChibon
Tag 'v2.3' created by Pierre-Yves Chibon <pingou(a)pingoured.fr> at 2014-07-16 13:56 +0000
Release 2.3
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iEYEABECAAYFAlPGhJYACgkQ2HRbBxDocwo8awCfZpBxKV+C7qHXHoRfDhtfofIH
NXYAoI1OLGO4WoBlZ1bFNYR09w7rXASs
=JPOX
-----END PGP SIGNATURE-----
Changes since v2.2:
Pierre-Yves Chibon (25):
Add link to the about page on the index and open pages
Use url_for() in the archive template to build the links
Fix the `More information` link to actually point to the about page
Adjust the unit-test now that we are using url_for() to build the links
Move the voting range election unit-tests to their own file
Move the simple voting unit-tests to their own file
Add a new election of select voting type and open
Adjust the unit-tests on the UI for the new election added
Add candidates to the last election added
Add votes to the last election added in the tests suite
Adjust the unit-tests now that Toshio voted on the election #6
Set a max_votes to election #6
Remove checking if the candidate submitted is in the list as wtforms handles it for us
Add a max_votes to 2 for the range voting and adjust the unit-tests accordingly
Add unit-tests for select voting
Add unit-tests for the is_safe_url method
Do not include FAS integration in test coverage
Check that new user are FAS users when adding them (if election is set to)
Ensure adding multiple users are once are FAS users when adding them (if election is set to)
Update the documentation in the README file
Make the README file an rst file
Add a get_groups method that returns all the groups of interest in the database
When login in, ask for the groups used in the database and admin groups set in the configuration
Merge pull request #32 from fedora-infra/restrict_groups
Release 2.3
---
README | 100 -------
README.rst | 132 +++++++++
fedora_elections/__init__.py | 8
fedora_elections/admin.py | 30 ++
fedora_elections/elections.py | 4
fedora_elections/forms.py | 3
fedora_elections/models.py | 18 +
fedora_elections/templates/archive.html | 9
fedora_elections/templates/index.html | 6
files/fedora-elections.spec | 10
tests/test_candidate.py | 22 +
tests/test_election.py | 37 ++
tests/test_flask.py | 34 +-
tests/test_flask_elections.py | 438 --------------------------------
tests/test_flask_range_voting.py | 302 ++++++++++++++++++++++
tests/test_flask_select_voting.py | 174 ++++++++++++
tests/test_flask_simple_voting.py | 250 ++++++++++++++++++
tests/test_vote.py | 12
18 files changed, 1024 insertions(+), 565 deletions(-)
---
9 years, 10 months
25 commits - fedora_elections/admin.py fedora_elections/elections.py fedora_elections/forms.py fedora_elections/__init__.py fedora_elections/models.py fedora_elections/templates files/fedora-elections.spec README README.rst tests/test_candidate.py tests/test_election.py tests/test_flask_elections.py tests/test_flask.py tests/test_flask_range_voting.py tests/test_flask_select_voting.py tests/test_flask_simple_voting.py tests/test_vote.py
by Pierre-YvesChibon
README | 100 -------
README.rst | 132 +++++++++
fedora_elections/__init__.py | 8
fedora_elections/admin.py | 30 ++
fedora_elections/elections.py | 4
fedora_elections/forms.py | 3
fedora_elections/models.py | 18 +
fedora_elections/templates/archive.html | 9
fedora_elections/templates/index.html | 6
files/fedora-elections.spec | 10
tests/test_candidate.py | 22 +
tests/test_election.py | 37 ++
tests/test_flask.py | 34 +-
tests/test_flask_elections.py | 438 --------------------------------
tests/test_flask_range_voting.py | 302 ++++++++++++++++++++++
tests/test_flask_select_voting.py | 174 ++++++++++++
tests/test_flask_simple_voting.py | 250 ++++++++++++++++++
tests/test_vote.py | 12
18 files changed, 1024 insertions(+), 565 deletions(-)
New commits:
commit 1e60b1b4bebda906044aab2dce70e223d26fbdd7
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Wed Jul 16 15:56:25 2014 +0200
Release 2.3
diff --git a/fedora_elections/__init__.py b/fedora_elections/__init__.py
index fc4f4c8..fd5f3e5 100644
--- a/fedora_elections/__init__.py
+++ b/fedora_elections/__init__.py
@@ -24,7 +24,7 @@
# Pierre-Yves Chibon <pingou(a)fedoraproject.org>
#
-__version__ = '2.2'
+__version__ = '2.3'
import os
diff --git a/files/fedora-elections.spec b/files/fedora-elections.spec
index 221b519..c1e9996 100644
--- a/files/fedora-elections.spec
+++ b/files/fedora-elections.spec
@@ -1,7 +1,7 @@
%define modname fedora_elections
Name: fedora-elections
-Version: 2.2
+Version: 2.3
Release: 1%{?dist}
Summary: Fedora elections application
@@ -109,6 +109,14 @@ install -m 644 files/update_1_to_2.sql \
%changelog
+* Wed Jul 16 2014 Pierre-Yves Chibon <pingou(a)pingoured.fr> - 2.3-1
+- Update to 2.3
+- Restrict the groups asked upon login (Allows Dennis to log in)
+- Check that candidates are FAS user when adding them to an election that
+ turned on the option
+- More links to the about page
+- Improved unit-tests suite
+
* Thu Jul 10 2014 Pierre-Yves Chibon <pingou(a)pingoured.fr> - 2.2-1
- Update to 2.2
- Better description of the different types of election
commit e5482acc2e59e523cd0b8b5e5faf3115f7801790
Merge: b2e5f17 d5167ef
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Wed Jul 16 15:44:05 2014 +0200
Merge pull request #32 from fedora-infra/restrict_groups
Restrict groups
commit d5167efe02be510e1645d6313e2ecfa57b39084f
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Wed Jul 16 09:19:46 2014 +0200
When login in, ask for the groups used in the database and admin groups set in the configuration
diff --git a/fedora_elections/__init__.py b/fedora_elections/__init__.py
index 103cade..fc4f4c8 100644
--- a/fedora_elections/__init__.py
+++ b/fedora_elections/__init__.py
@@ -259,7 +259,11 @@ def auth_login():
if hasattr(flask.g, 'fas_user') and flask.g.fas_user is not None:
return safe_redirect_back(next_url)
else:
- return FAS.login(return_url=next_url)
+ groups = APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'][:]
+ if isinstance(groups, basestring):
+ groups = [groups]
+ groups.extend(models.get_groups(SESSION))
+ return FAS.login(return_url=next_url, groups=groups)
@APP.route('/logout')
commit 0871db40e1c64562f23a95355ee3540e55b3e6e4
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Wed Jul 16 09:18:23 2014 +0200
Add a get_groups method that returns all the groups of interest in the database
These groups are the one used to restrict an election to a group of legal
voters or to specify a group as admin for an election.
We are interested in this list to ask OpenID to only return the groups
of interest rather than asking for all of them.
diff --git a/fedora_elections/models.py b/fedora_elections/models.py
index e0e5941..d35096f 100644
--- a/fedora_elections/models.py
+++ b/fedora_elections/models.py
@@ -415,3 +415,21 @@ class Vote(BASE):
stats['n_candidates'] = cnt
return stats
+
+
+def get_groups(session):
+ """ Return the list of groups of interest.
+
+ These groups are the groups used to find out the admins or the legal
+ voters of all the elections.
+ """
+
+ voters = [item[0] for item in session.query(
+ sa.distinct(LegalVoter.group_name)
+ ).order_by(LegalVoter.group_name).all()]
+
+ admins = [item[0] for item in session.query(
+ sa.distinct(ElectionAdminGroup.group_name)
+ ).order_by(ElectionAdminGroup.group_name).all()]
+
+ return voters + admins
commit b2e5f17a90146dc0d70b12633c2b4103c465f258
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Sat Jul 12 00:07:21 2014 +0200
Make the README file an rst file
diff --git a/README b/README
deleted file mode 100644
index 42dc6de..0000000
--- a/README
+++ /dev/null
@@ -1,132 +0,0 @@
-================
-Fedora Elections
-================
-
-* What is fedora-election?
-
-fedora-elections is a web application written in python and based on flask.
-It implements the Range Voting system (http://rangevoting.org).
-
-This project was developed using fedoraproject requests, but, can be easily
-adapted to other projects. Fedora-elections is integrated with the Fedora
-Account System (FAS).
-
-
-Running from a checkout:
-========================
-
-Install Prerequisites
----------------------
-Before launching fedora-elections, the following packages should be installed:
- - httpd
- - libxslt
- - python
- - python-backports-ssl_match_hostname
- - python-bunch
- - python-chardet
- - python-fedora
- - python-fedora-flask
- - python-flask
- - python-flask-sqlalchemy
- - python-flask-wtf
- - python-jinja2
- - python-kitchen
- - python-lxml
- - python-openid
- - python-ordereddict
- - python-ordereddict
- - python-setuptools
- - python-simplejson
- - python-six
- - python-sqlalchemy0.7
- - python-urllib3
- - python-wtforms
-
-
-Get the source code
--------------------
-The project is hosted on https://fedorahosted.org/
-
-More precisely at: https://fedorahosted.org/elections
-
-You can obtain the code via:
-
- ::
-
- git clone http://git.fedorahosted.org/git/elections.git
-
-For commodity reason, a clone is available on github:
-https://github.com/fedora-infra/elections
-
-
-Configure the application
--------------------------
-An example configuration file is provided at: ``files/fedora-elections.cfg``
-
-
-Create a database
------------------
-Run:
-
- ::
-
- python createdb.py
-
-
-Starting the Application
-------------------------
-
-There are 2 ways to start the application:
- * without apache
- * with apache
-
-
-* How to start without apache on localhost:5000 (useful for development):
-
- ::
-
- ./runserver
-
-
-* How to start with http
-
- Next copy the file ``fedora-elections.conf`` file to your apache conf.d
- directory:
-
- ::
-
- sudo cp files/fedora-elections.conf /etc/httpd/conf.d/.
-
- Place the file ``fedora-elections.wsgi`` for example in /var/www
-
- ::
-
- sudo cp files/fedora-elections.wsgi /var/www
-
- Adjust the apache configuration file to point to it
-
- Adjust the wsgi file installed in /var/www to point to fedora_elections
-
-
- Place the fedora-elections configuration file in
- ``/etc/fedora-elections/fedora-elections.cfg``
-
- ::
-
- sudo mkdir -p /etc/fedora-elections/
- sudo cp files/fedora-elections.cfg /etc/fedora-elections/
-
- Restart apache:
-
- sudo /etc/init.d/httpd restart
-
-* How to contribute
-
-If you find bug or want to propose ideas or stuff to be implemented or if
-you are interested to became a developer for this project just
-ask on #fedora-admin irc channel on irc.freenode.net or use our
-web site https://fedorahosted.org/elections.
-
-* Licence
-
-fedora-elections is licenced under GPL v2.
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..42dc6de
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,132 @@
+================
+Fedora Elections
+================
+
+* What is fedora-election?
+
+fedora-elections is a web application written in python and based on flask.
+It implements the Range Voting system (http://rangevoting.org).
+
+This project was developed using fedoraproject requests, but, can be easily
+adapted to other projects. Fedora-elections is integrated with the Fedora
+Account System (FAS).
+
+
+Running from a checkout:
+========================
+
+Install Prerequisites
+---------------------
+Before launching fedora-elections, the following packages should be installed:
+ - httpd
+ - libxslt
+ - python
+ - python-backports-ssl_match_hostname
+ - python-bunch
+ - python-chardet
+ - python-fedora
+ - python-fedora-flask
+ - python-flask
+ - python-flask-sqlalchemy
+ - python-flask-wtf
+ - python-jinja2
+ - python-kitchen
+ - python-lxml
+ - python-openid
+ - python-ordereddict
+ - python-ordereddict
+ - python-setuptools
+ - python-simplejson
+ - python-six
+ - python-sqlalchemy0.7
+ - python-urllib3
+ - python-wtforms
+
+
+Get the source code
+-------------------
+The project is hosted on https://fedorahosted.org/
+
+More precisely at: https://fedorahosted.org/elections
+
+You can obtain the code via:
+
+ ::
+
+ git clone http://git.fedorahosted.org/git/elections.git
+
+For commodity reason, a clone is available on github:
+https://github.com/fedora-infra/elections
+
+
+Configure the application
+-------------------------
+An example configuration file is provided at: ``files/fedora-elections.cfg``
+
+
+Create a database
+-----------------
+Run:
+
+ ::
+
+ python createdb.py
+
+
+Starting the Application
+------------------------
+
+There are 2 ways to start the application:
+ * without apache
+ * with apache
+
+
+* How to start without apache on localhost:5000 (useful for development):
+
+ ::
+
+ ./runserver
+
+
+* How to start with http
+
+ Next copy the file ``fedora-elections.conf`` file to your apache conf.d
+ directory:
+
+ ::
+
+ sudo cp files/fedora-elections.conf /etc/httpd/conf.d/.
+
+ Place the file ``fedora-elections.wsgi`` for example in /var/www
+
+ ::
+
+ sudo cp files/fedora-elections.wsgi /var/www
+
+ Adjust the apache configuration file to point to it
+
+ Adjust the wsgi file installed in /var/www to point to fedora_elections
+
+
+ Place the fedora-elections configuration file in
+ ``/etc/fedora-elections/fedora-elections.cfg``
+
+ ::
+
+ sudo mkdir -p /etc/fedora-elections/
+ sudo cp files/fedora-elections.cfg /etc/fedora-elections/
+
+ Restart apache:
+
+ sudo /etc/init.d/httpd restart
+
+* How to contribute
+
+If you find bug or want to propose ideas or stuff to be implemented or if
+you are interested to became a developer for this project just
+ask on #fedora-admin irc channel on irc.freenode.net or use our
+web site https://fedorahosted.org/elections.
+
+* Licence
+
+fedora-elections is licenced under GPL v2.
commit 177eb298c8c4e0251d48dbb58ee1dce1487e0f8d
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Sat Jul 12 00:06:02 2014 +0200
Update the documentation in the README file
diff --git a/README b/README
index 4ab94e0..42dc6de 100644
--- a/README
+++ b/README
@@ -1,8 +1,9 @@
================
Fedora Elections
-===============
+================
* What is fedora-election?
+
fedora-elections is a web application written in python and based on flask.
It implements the Range Voting system (http://rangevoting.org).
@@ -12,7 +13,7 @@ Account System (FAS).
Running from a checkout:
-=======================
+========================
Install Prerequisites
---------------------
@@ -44,57 +45,88 @@ Before launching fedora-elections, the following packages should be installed:
Get the source code
-------------------
-You can obtain the code from github:
- https://github.com/fedora-infra/elections.git
+The project is hosted on https://fedorahosted.org/
+
+More precisely at: https://fedorahosted.org/elections
+
+You can obtain the code via:
+
+ ::
+
+ git clone http://git.fedorahosted.org/git/elections.git
-git clone https://github.com/fedora-infra/elections.git
+For commodity reason, a clone is available on github:
+https://github.com/fedora-infra/elections
Configure the application
-------------------------
-cd fedora_elections
-../configure.py --install-conf=${PWD%/*} --install-data=${PWD%/*} --shared-state=${PWD%/*}
+An example configuration file is provided at: ``files/fedora-elections.cfg``
-This will create createdb, fedora-elections.cfg, fedora-elections.wsgi and
-http-fedora-elections.conf.
-
-Modify fedora-elections.cfg to change FAS_PASSWORD to the correct password.
Create a database
-----------------
-Copy development.cfg.sample to development.cfg.
-Review the file and make changes as appropriate.
Run:
- ./createdb
+
+ ::
+
+ python createdb.py
Starting the Application
------------------------
There are 2 ways to start the application:
- o without http
- o with http
+ * without apache
+ * with apache
-* How to start without http on localhost:5000:
- cd elections
+* How to start without apache on localhost:5000 (useful for development):
+
+ ::
+
./runserver
* How to start with http
- Next copy the httpd-pkgdb.conf file to your apache conf.d directory:
- sudo cp httpd-fedora-elections.conf /etc/httpd/conf.d/.
+ Next copy the file ``fedora-elections.conf`` file to your apache conf.d
+ directory:
+
+ ::
+
+ sudo cp files/fedora-elections.conf /etc/httpd/conf.d/.
+
+ Place the file ``fedora-elections.wsgi`` for example in /var/www
+
+ ::
+
+ sudo cp files/fedora-elections.wsgi /var/www
+
+ Adjust the apache configuration file to point to it
+
+ Adjust the wsgi file installed in /var/www to point to fedora_elections
+
+
+ Place the fedora-elections configuration file in
+ ``/etc/fedora-elections/fedora-elections.cfg``
+
+ ::
+
+ sudo mkdir -p /etc/fedora-elections/
+ sudo cp files/fedora-elections.cfg /etc/fedora-elections/
Restart apache:
sudo /etc/init.d/httpd restart
* How to contribute
+
If you find bug or want to propose ideas or stuff to be implemented or if
you are interested to became a developer for this project just
ask on #fedora-admin irc channel on irc.freenode.net or use our
web site https://fedorahosted.org/elections.
* Licence
+
fedora-elections is licenced under GPL v2.
commit d5f78c9ac9d4fb6071198106308c44db3cefe3bb
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 17:24:45 2014 +0200
Ensure adding multiple users are once are FAS users when adding them (if election is set to)
Fixes to https://fedorahosted.org/elections/ticket/34
diff --git a/fedora_elections/admin.py b/fedora_elections/admin.py
index 5ddb80f..ad7f072 100644
--- a/fedora_elections/admin.py
+++ b/fedora_elections/admin.py
@@ -290,6 +290,20 @@ def admin_add_multi_candidate(election_alias):
candidates_name = []
for entry in form.candidate.data.strip().split("|"):
candidate = entry.split("!")
+
+ if election.candidates_are_fasusers: # pragma: no cover
+ try:
+ 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_add_candidate',
+ election_alias=election_alias))
+
# No url
if len(candidate) == 1:
cand = models.Candidate(
commit 019b3a74af77be421fcc773e3a0b0b3fbcf82bb4
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 17:20:23 2014 +0200
Check that new user are FAS users when adding them (if election is set to)
Relates to https://fedorahosted.org/elections/ticket/34
diff --git a/fedora_elections/admin.py b/fedora_elections/admin.py
index dd1abb0..5ddb80f 100644
--- a/fedora_elections/admin.py
+++ b/fedora_elections/admin.py
@@ -29,12 +29,13 @@ from functools import wraps
import flask
from sqlalchemy.exc import SQLAlchemyError
+from fedora.client import AuthError
from fedora_elections import fedmsgshim
from fedora_elections import forms
from fedora_elections import models
from fedora_elections import (
- APP, SESSION, is_authenticated, is_admin, is_election_admin,
+ APP, SESSION, FAS2, is_authenticated, is_admin, is_election_admin,
is_safe_url, safe_redirect_back
)
@@ -236,6 +237,19 @@ def admin_add_candidate(election_alias):
form = forms.CandidateForm()
if form.validate_on_submit():
+
+ if election.candidates_are_fasusers: # pragma: no cover
+ try:
+ FAS2.person_by_username(form.name.data)['human_name']
+ except (KeyError, AuthError), err:
+ flask.flash(
+ 'User `%s` does not have a FAS account.'
+ % form.name.data, 'error')
+ return flask.redirect(
+ flask.url_for(
+ 'admin_add_candidate',
+ election_alias=election_alias))
+
candidate = models.Candidate(
election=election,
name=form.name.data,
commit 443a5354f6328638d68ed785d9375c54d8d87632
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 16:35:14 2014 +0200
Do not include FAS integration in test coverage
diff --git a/fedora_elections/forms.py b/fedora_elections/forms.py
index 345056e..46c14ee 100644
--- a/fedora_elections/forms.py
+++ b/fedora_elections/forms.py
@@ -140,7 +140,8 @@ def get_simple_voting_form(candidates, fasusers):
titles = []
for candidate in candidates:
title = candidate.name
- if fasusers:
+ if fasusers: # pragma: no cover
+ # We can't cover FAS integration
try:
title = \
FAS2.person_by_username(candidate.name)['human_name']
commit 9231479a568eabab067c2e4409542e35554c60b6
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 16:32:25 2014 +0200
Add unit-tests for the is_safe_url method
diff --git a/tests/test_flask.py b/tests/test_flask.py
index 0f39e3e..b9da2cd 100644
--- a/tests/test_flask.py
+++ b/tests/test_flask.py
@@ -43,6 +43,22 @@ from tests import ModelFlasktests, FakeUser, user_set
class Flasktests(ModelFlasktests):
""" Flask application tests. """
+ def test_is_safe_url(self):
+ """ Test the is_safe_url function. """
+ app = flask.Flask('elections')
+
+ with app.test_request_context():
+ self.assertTrue(
+ fedora_elections.is_safe_url('http://localhost'))
+ self.assertTrue(
+ fedora_elections.is_safe_url('https://localhost'))
+ self.assertTrue(
+ fedora_elections.is_safe_url('http://localhost/test'))
+ self.assertFalse(
+ fedora_elections.is_safe_url('http://fedoraproject.org/'))
+ self.assertFalse(
+ fedora_elections.is_safe_url('https://fedoraproject.org/'))
+
def test_index_empty(self):
""" Test the index function. """
output = self.app.get('/')
commit 987452eb2e799ab3c9555fe12f45bb4d86a6121e
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 16:18:11 2014 +0200
Add unit-tests for select voting
diff --git a/tests/test_flask_select_voting.py b/tests/test_flask_select_voting.py
new file mode 100644
index 0000000..cc248b3
--- /dev/null
+++ b/tests/test_flask_select_voting.py
@@ -0,0 +1,174 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""
+ (c) 2014 - Copyright Pierre-Yves Chibon
+ Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
+
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2, or (at your option) any later version. This
+# program is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details. You should have received a copy of the GNU
+# General Public License along with this program; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the source
+# code or documentation are not subject to the GNU General Public License and
+# may only be used or replicated with the express permission of Red Hat, Inc.
+
+ fedora_elections.elections test script
+"""
+__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
+import pkg_resources
+
+import logging
+import unittest
+import sys
+import os
+
+from datetime import time
+from datetime import timedelta
+
+import flask
+
+sys.path.insert(0, os.path.join(os.path.dirname(
+ os.path.abspath(__file__)), '..'))
+
+import fedora_elections
+from tests import ModelFlasktests, Modeltests, TODAY, FakeUser, user_set
+
+
+# pylint: disable=R0904
+class FlaskSimpleElectionstests(ModelFlasktests):
+ """ Flask application tests range voting. """
+
+ def test_vote_select(self):
+ """ Test the vote_select function - the preview part. """
+ output = self.app.get(
+ '/vote/test_election', follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<title>OpenID transaction in progress</title>' in output.data
+ or 'discoveryfailure' in output.data)
+
+ 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(
+ '/vote/test_election6')
+ self.assertTrue(
+ '<h2>test election 6 shortdesc</h2>' in output.data)
+ self.assertTrue(
+ '<input type="hidden" name="action" value="preview" />'
+ in output.data)
+
+ csrf_token = output.data.split(
+ 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
+
+ # Invalid vote: No candidate
+ data = {
+ 'action': 'preview',
+ }
+
+ output = self.app.post('/vote/test_election6', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<h2>test election 6 shortdesc</h2>' in output.data)
+
+ # Invalid vote: Too many candidates
+ data = {
+ 'Kevin': True,
+ 'Toshio': True,
+ 'action': 'preview',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post('/vote/test_election6', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<h2>test election 6 shortdesc</h2>' in output.data)
+ self.assertTrue(
+ '<input type="hidden" name="action" value="preview" />'
+ in output.data)
+ self.assertTrue(
+ '<li class="error">Too many candidates submitted</li>'
+ in output.data)
+
+ # Valid input
+ data = {
+ 'Kevin': True,
+ 'action': 'preview',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post('/vote/test_election6', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<h2>test election 6 shortdesc</h2>' in output.data)
+ self.assertTrue(
+ '<input type="hidden" name="action" value="submit" />'
+ in output.data)
+ self.assertTrue(
+ '<li class="message">Please confirm your vote!</li>'
+ in output.data)
+
+ def test_vote_select_process(self):
+ """ Test the vote_select function - the voting part. """
+ output = self.app.get(
+ '/vote/test_election', follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<title>OpenID transaction in progress</title>' in output.data
+ or 'discoveryfailure' in output.data)
+
+ self.setup_db()
+
+ user = FakeUser(['packager'], username='pingou')
+ with user_set(fedora_elections.APP, user):
+ # Invalid candidate id - no csrf
+ data = {
+ 'candidate': 1,
+ 'action': 'submit',
+ }
+
+ output = self.app.post(
+ '/vote/test_election6', data=data,
+ follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+
+ csrf_token = output.data.split(
+ 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
+
+ # Valid input
+ data = {
+ 'Toshio': True,
+ 'action': 'submit',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post(
+ '/vote/test_election6', data=data,
+ follow_redirects=True)
+ 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 __name__ == '__main__':
+ SUITE = unittest.TestLoader().loadTestsFromTestCase(FlaskSimpleElectionstests)
+ unittest.TextTestRunner(verbosity=2).run(SUITE)
commit 275f76159479f6827e4eff3ba572df706422a93d
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 16:17:51 2014 +0200
Add a max_votes to 2 for the range voting and adjust the unit-tests accordingly
diff --git a/tests/test_election.py b/tests/test_election.py
index 024af37..2370716 100644
--- a/tests/test_election.py
+++ b/tests/test_election.py
@@ -102,6 +102,7 @@ class Electiontests(Modeltests):
embargoed=1,
voting_type='range',
candidates_are_fasusers=0,
+ max_votes=2,
fas_user='pingou',
)
self.session.add(obj)
diff --git a/tests/test_flask_range_voting.py b/tests/test_flask_range_voting.py
index bf6cb95..0cc94fd 100644
--- a/tests/test_flask_range_voting.py
+++ b/tests/test_flask_range_voting.py
@@ -108,7 +108,7 @@ class FlaskRangeElectionstests(ModelFlasktests):
# Invalid vote: too low
data = {
'9': -1,
- '6': 3,
+ '6': 0,
'5': 2,
'action': 'preview',
'csrf_token': csrf_token,
@@ -125,7 +125,7 @@ class FlaskRangeElectionstests(ModelFlasktests):
output.data.count('<td class="error">Not a valid choice</td>'),
1)
- # Invalid vote: too high
+ # Invalid vote: 2 are too high
data = {
'9': 5,
'6': 3,
@@ -143,12 +143,12 @@ class FlaskRangeElectionstests(ModelFlasktests):
in output.data)
self.assertEqual(
output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
+ 2)
# Invalid vote: Not numeric
data = {
'9': 'a',
- '6': 3,
+ '6': 0,
'5': 2,
'action': 'preview',
'csrf_token': csrf_token,
@@ -168,7 +168,7 @@ class FlaskRangeElectionstests(ModelFlasktests):
# Valid input
data = {
'4': 1,
- '6': 3,
+ '6': 0,
'5': 2,
'action': 'preview',
'csrf_token': csrf_token,
@@ -182,7 +182,7 @@ class FlaskRangeElectionstests(ModelFlasktests):
'<input type="hidden" name="action" value="submit" />'
in output.data)
self.assertTrue('<div class="vtmedcool">' in output.data)
- self.assertTrue('<div class="vthot">' in output.data)
+ self.assertTrue('<div class="vtcold">' in output.data)
self.assertTrue('<div class="vtmedwarm">' in output.data)
def test_vote_range_process(self):
@@ -215,10 +215,24 @@ class FlaskRangeElectionstests(ModelFlasktests):
csrf_token = output.data.split(
'name="csrf_token" type="hidden" value="')[1].split('">')[0]
+ # Invalid vote: invalid username
+ data = {
+ 'Toshio': 1,
+ 'Kevin': 3,
+ 'Ralph': 2,
+ 'action': 'submit',
+ }
+
+ output = self.app.post('/vote/test_election3', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 3)
+
# Invalid vote: too low
data = {
'4': -1,
- '5': 3,
+ '5': 0,
'6': 2,
'action': 'submit',
'csrf_token': csrf_token,
@@ -231,7 +245,7 @@ class FlaskRangeElectionstests(ModelFlasktests):
output.data.count('<td class="error">Not a valid choice</td>'),
1)
- # Invalid vote: too high
+ # Invalid vote: 2 are too high
data = {
'4': 5,
'5': 3,
@@ -245,12 +259,12 @@ class FlaskRangeElectionstests(ModelFlasktests):
self.assertEqual(output.status_code, 200)
self.assertEqual(
output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
+ 2)
# Invalid vote: Not numeric
data = {
'4': 'a',
- '5': 3,
+ '5': 0,
'6': 2,
'action': 'submit',
'csrf_token': csrf_token,
@@ -266,7 +280,7 @@ class FlaskRangeElectionstests(ModelFlasktests):
# Valid input
data = {
'4': 1,
- '5': 3,
+ '5': 0,
'6': 2,
'action': 'submit',
'csrf_token': csrf_token,
commit e19da887631ab8a24be57cdee7eb8dbcc8482a53
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 16:17:05 2014 +0200
Remove checking if the candidate submitted is in the list as wtforms handles it for us
diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py
index 9a3fcd7..2b5c407 100644
--- a/fedora_elections/elections.py
+++ b/fedora_elections/elections.py
@@ -147,10 +147,6 @@ def vote_range(election):
if candidate.short_name in ['csrf_token', 'action']:
continue
- if candidate.short_name not in cand_ids:
- flask.flash('Invalid input submitted', 'error')
- return safe_redirect_back()
-
new_vote = models.Vote(
election_id=election.id,
voter=flask.g.fas_user.username,
commit 271506f5a8f7947d944fbed197b333ef8192eb37
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 16:05:09 2014 +0200
Set a max_votes to election #6
diff --git a/tests/test_election.py b/tests/test_election.py
index 90037ed..024af37 100644
--- a/tests/test_election.py
+++ b/tests/test_election.py
@@ -165,6 +165,7 @@ class Electiontests(Modeltests):
embargoed=1,
voting_type='select',
candidates_are_fasusers=0,
+ max_votes=1,
fas_user='skvidal',
)
self.session.add(obj)
commit e13214a162132d7906fe9907633903ea29596419
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 16:04:45 2014 +0200
Adjust the unit-tests now that Toshio voted on the election #6
diff --git a/tests/test_flask.py b/tests/test_flask.py
index 38c9961..0f39e3e 100644
--- a/tests/test_flask.py
+++ b/tests/test_flask.py
@@ -83,7 +83,7 @@ class Flasktests(ModelFlasktests):
self.assertTrue('<a href="/vote/' in output.data)
self.assertTrue(
'<span class="text">logged in as </span>' in output.data)
- self.assertTrue('Vote now!' in output.data)
+ self.assertEqual(output.data.count('Vote now!'), 3)
user = FakeUser([], username='toshio')
with user_set(fedora_elections.APP, user):
@@ -95,7 +95,7 @@ class Flasktests(ModelFlasktests):
self.assertTrue('<h3>Last 2 elections</h3>' in output.data)
self.assertTrue(
'<span class="text">logged in as </span>' in output.data)
- self.assertEqual(output.data.count('Vote now!'), 1)
+ self.assertEqual(output.data.count('Vote now!'), 0)
def test_is_admin(self):
""" Test the is_admin function. """
@@ -304,7 +304,7 @@ class Flasktests(ModelFlasktests):
self.assertTrue('<h3>Next 3 elections</h3>' in output.data)
self.assertTrue(
'<span class="text">logged in as </span>' in output.data)
- self.assertEqual(output.data.count('Vote now!'), 1)
+ self.assertEqual(output.data.count('Vote now!'), 0)
if __name__ == '__main__':
commit 7ec3bd02e2f86989bee7df79f4e863f8c8ad877a
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 16:04:23 2014 +0200
Add votes to the last election added in the tests suite
diff --git a/tests/test_vote.py b/tests/test_vote.py
index 09a4135..c3d81e5 100644
--- a/tests/test_vote.py
+++ b/tests/test_vote.py
@@ -164,6 +164,18 @@ class Votetests(Modeltests):
self.session.commit()
self.assertNotEqual(obj, None)
+ # Election 6
+
+ obj = models.Vote( # id:1
+ election_id=6,
+ voter='toshio',
+ candidate_id=12,
+ value='1',
+ )
+ self.session.add(obj)
+ self.session.commit()
+ self.assertNotEqual(obj, None)
+
def test_vote_count_with_votes(self):
""" Test the Candidate.vote_count function with votes in. """
self.test_init_vote()
commit 6b91d773dae1ec00637057c575f6d01d1786ecca
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 16:04:03 2014 +0200
Add candidates to the last election added
diff --git a/tests/test_candidate.py b/tests/test_candidate.py
index 3c0d6ba..aa87e95 100644
--- a/tests/test_candidate.py
+++ b/tests/test_candidate.py
@@ -165,6 +165,28 @@ class Candidatetests(Modeltests):
self.session.commit()
self.assertNotEqual(obj, None)
+ #
+ # Election #6
+ #
+
+ obj = models.Candidate( # id:12
+ election_id=6,
+ name='Toshio',
+ url='https://fedoraproject.org/wiki/User:Toshio',
+ )
+ self.session.add(obj)
+ self.session.commit()
+ self.assertNotEqual(obj, None)
+
+ obj = models.Candidate( # id:13
+ election_id=6,
+ name='Kevin',
+ url='https://fedoraproject.org/wiki/User:Kevin',
+ )
+ self.session.add(obj)
+ self.session.commit()
+ self.assertNotEqual(obj, None)
+
def test_to_json(self):
""" Test the Candidate.to_json function. """
self.test_init_candidate()
commit aeab747da63f0389d1369088ac02ff83152ccf52
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 15:26:53 2014 +0200
Adjust the unit-tests on the UI for the new election added
diff --git a/tests/test_flask.py b/tests/test_flask.py
index 6013d88..38c9961 100644
--- a/tests/test_flask.py
+++ b/tests/test_flask.py
@@ -95,7 +95,7 @@ class Flasktests(ModelFlasktests):
self.assertTrue('<h3>Last 2 elections</h3>' in output.data)
self.assertTrue(
'<span class="text">logged in as </span>' in output.data)
- self.assertFalse('Vote now!' in output.data)
+ self.assertEqual(output.data.count('Vote now!'), 1)
def test_is_admin(self):
""" Test the is_admin function. """
@@ -280,7 +280,7 @@ class Flasktests(ModelFlasktests):
output = self.app.get('/open')
self.assertEqual(output.status_code, 200)
self.assertTrue('<title>Fedora elections</title>' in output.data)
- self.assertTrue('<h3>Next 2 elections</h3>' in output.data)
+ self.assertTrue('<h3>Next 3 elections</h3>' in output.data)
self.assertTrue('<td>test election 3 shortdesc</td>' in output.data)
self.assertTrue('<a href="/vote/' in output.data)
self.assertTrue('<a href="/login">login</a>' in output.data)
@@ -290,21 +290,21 @@ class Flasktests(ModelFlasktests):
output = self.app.get('/open')
self.assertEqual(output.status_code, 200)
self.assertTrue('<title>Fedora elections</title>' in output.data)
- self.assertTrue('<h3>Next 2 elections</h3>' in output.data)
+ self.assertTrue('<h3>Next 3 elections</h3>' in output.data)
self.assertTrue('<a href="/vote/' in output.data)
self.assertTrue(
'<span class="text">logged in as </span>' in output.data)
- self.assertTrue('Vote now!' in output.data)
+ self.assertEqual(output.data.count('Vote now!'), 3)
user = FakeUser([], username='toshio')
with user_set(fedora_elections.APP, user):
output = self.app.get('/open')
self.assertEqual(output.status_code, 200)
self.assertTrue('<title>Fedora elections</title>' in output.data)
- self.assertTrue('<h3>Next 2 elections</h3>' in output.data)
+ self.assertTrue('<h3>Next 3 elections</h3>' in output.data)
self.assertTrue(
'<span class="text">logged in as </span>' in output.data)
- self.assertFalse('Vote now!' in output.data)
+ self.assertEqual(output.data.count('Vote now!'), 1)
if __name__ == '__main__':
commit f31265d0d013f6d6af521e471d633608c2e774d9
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 15:17:24 2014 +0200
Add a new election of select voting type and open
diff --git a/tests/test_election.py b/tests/test_election.py
index 342c253..90037ed 100644
--- a/tests/test_election.py
+++ b/tests/test_election.py
@@ -153,6 +153,24 @@ class Electiontests(Modeltests):
self.session.commit()
self.assertNotEqual(obj, None)
+ # Election - select voting - Open
+ obj = models.Election( # id:6
+ shortdesc='test election 6 shortdesc',
+ alias='test_election6',
+ description='test election 6 description',
+ url='https://fedoraproject.org',
+ start_date=TODAY - timedelta(days=1),
+ end_date=TODAY + timedelta(days=3),
+ seats_elected=1,
+ embargoed=1,
+ voting_type='select',
+ candidates_are_fasusers=0,
+ fas_user='skvidal',
+ )
+ self.session.add(obj)
+ self.session.commit()
+ self.assertNotEqual(obj, None)
+
def test_get_election(self):
""" Test the Election.get function. """
self.test_init_election()
@@ -218,19 +236,21 @@ class Electiontests(Modeltests):
self.session, fas_user='skvidal')
self.assertNotEqual(obj, None)
self.assertNotEqual(obj, [])
- self.assertEqual(len(obj), 2)
+ self.assertEqual(len(obj), 3)
self.assertEqual(obj[0].description, 'test election 4 description')
self.assertEqual(obj[1].description, 'test election 5 description')
+ self.assertEqual(obj[2].description, 'test election 6 description')
obj = models.Election.search(self.session)
self.assertNotEqual(obj, None)
self.assertNotEqual(obj, [])
- self.assertEqual(len(obj), 5)
+ self.assertEqual(len(obj), 6)
self.assertEqual(obj[0].description, 'test election 4 description')
self.assertEqual(obj[1].description, 'test election 5 description')
- self.assertEqual(obj[2].description, 'test election 3 description')
- self.assertEqual(obj[3].description, 'test election 2 description')
- self.assertEqual(obj[4].description, 'test election description')
+ self.assertEqual(obj[2].description, 'test election 6 description')
+ self.assertEqual(obj[3].description, 'test election 3 description')
+ self.assertEqual(obj[4].description, 'test election 2 description')
+ self.assertEqual(obj[5].description, 'test election description')
def test_get_older_election(self):
""" Test the Election.get_older_election function. """
@@ -248,9 +268,10 @@ class Electiontests(Modeltests):
obj = models.Election.get_open_election(self.session, limit=TODAY)
self.assertNotEqual(obj, None)
self.assertNotEqual(obj, [])
- self.assertEqual(len(obj), 2)
+ self.assertEqual(len(obj), 3)
self.assertEqual(obj[0].shortdesc, 'test election 5 shortdesc')
- self.assertEqual(obj[1].shortdesc, 'test election 3 shortdesc')
+ self.assertEqual(obj[1].shortdesc, 'test election 6 shortdesc')
+ self.assertEqual(obj[2].shortdesc, 'test election 3 shortdesc')
def test_get_next_election(self):
""" Test the Election.get_next_election function. """
commit a02269ecca991a7e616b0062c688273e2820e69d
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 15:09:49 2014 +0200
Move the simple voting unit-tests to their own file
diff --git a/tests/test_flask_elections.py b/tests/test_flask_elections.py
index b12353e..397db4a 100644
--- a/tests/test_flask_elections.py
+++ b/tests/test_flask_elections.py
@@ -166,206 +166,6 @@ class FlaskElectionstests(ModelFlasktests):
in output.data)
self.assertTrue('<h3>Current elections</h3>' in output.data)
- def test_vote_simple(self):
- """ Test the vote_simple function - the preview part. """
- output = self.app.get(
- '/vote/test_election', follow_redirects=True)
- self.assertEqual(output.status_code, 200)
- self.assertTrue(
- '<title>OpenID transaction in progress</title>' in output.data
- or 'discoveryfailure' in output.data)
-
- 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(
- '/vote/test_election5')
- self.assertTrue(
- '<h2>test election 5 shortdesc</h2>' in output.data)
- self.assertTrue(
- '<input type="hidden" name="action" value="preview" />'
- in output.data)
-
- # Invalid vote: No candidate
- data = {
- 'action': 'preview',
- }
-
- output = self.app.post('/vote/test_election5', data=data)
- self.assertEqual(output.status_code, 200)
- self.assertTrue(
- '<h2>test election 5 shortdesc</h2>' in output.data)
- self.assertTrue(
- '<td class="error">Not a valid choice</td>'
- in output.data)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
- self.assertTrue(
- '<input type="hidden" name="action" value="preview" />'
- in output.data)
-
- csrf_token = output.data.split(
- 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
-
- # Invalid vote: No candidate
- data = {
- 'action': 'preview',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post('/vote/test_election5', data=data)
- self.assertEqual(output.status_code, 200)
- self.assertTrue(
- '<h2>test election 5 shortdesc</h2>' in output.data)
- self.assertTrue(
- '<td class="error">Not a valid choice</td>'
- in output.data)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
- self.assertTrue(
- '<input type="hidden" name="action" value="preview" />'
- in output.data)
-
- # Invalid vote: Not numeric
- data = {
- 'candidate': 'a',
- 'action': 'preview',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post('/vote/test_election5', data=data)
- self.assertEqual(output.status_code, 200)
- self.assertTrue(
- '<h2>test election 5 shortdesc</h2>' in output.data)
- self.assertTrue(
- '<input type="hidden" name="action" value="preview" />'
- in output.data)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
-
- # Valid input
- data = {
- 'candidate': 7,
- 'action': 'preview',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post('/vote/test_election5', data=data)
- self.assertEqual(output.status_code, 200)
- self.assertTrue(
- '<h2>test election 5 shortdesc</h2>' in output.data)
- self.assertTrue(
- '<input type="hidden" name="action" value="submit" />'
- in output.data)
- self.assertTrue(
- '<li class="message">Please confirm your vote!</li>'
- in output.data)
-
- def test_vote_simple_process(self):
- """ Test the vote_simple function - the voting part. """
- output = self.app.get(
- '/vote/test_election', follow_redirects=True)
- self.assertEqual(output.status_code, 200)
- self.assertTrue(
- '<title>OpenID transaction in progress</title>' in output.data
- or 'discoveryfailure' in output.data)
-
- self.setup_db()
-
- user = FakeUser(['packager'], username='pingou')
- with user_set(fedora_elections.APP, user):
- # Invalid candidate id - no csrf
- data = {
- 'candidate': 1,
- 'action': 'submit',
- }
-
- output = self.app.post(
- '/vote/test_election5', data=data,
- follow_redirects=True)
- self.assertEqual(output.status_code, 200)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
-
- csrf_token = output.data.split(
- 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
-
- # Invalid candidate id
- data = {
- 'candidate': 1,
- 'action': 'submit',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post(
- '/vote/test_election5', data=data,
- follow_redirects=True)
- self.assertEqual(output.status_code, 200)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
-
- # Invalid vote: too low
- data = {
- 'candidate': -1,
- 'action': 'submit',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post(
- '/vote/test_election5', data=data,
- follow_redirects=True)
- self.assertEqual(output.status_code, 200)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
-
- # Invalid vote: Not numeric
- data = {
- 'candidate': 'a',
- 'action': 'submit',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post(
- '/vote/test_election5', data=data,
- follow_redirects=True)
- self.assertEqual(output.status_code, 200)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
-
- # Valid input
- data = {
- 'candidate': 8,
- 'action': 'submit',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post(
- '/vote/test_election5', data=data,
- follow_redirects=True)
- 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)
-
def test_election_results(self):
""" Test the election_results function - the preview part. """
output = self.app.get(
diff --git a/tests/test_flask_simple_voting.py b/tests/test_flask_simple_voting.py
new file mode 100644
index 0000000..aa28980
--- /dev/null
+++ b/tests/test_flask_simple_voting.py
@@ -0,0 +1,250 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""
+ (c) 2014 - Copyright Pierre-Yves Chibon
+ Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
+
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2, or (at your option) any later version. This
+# program is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details. You should have received a copy of the GNU
+# General Public License along with this program; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the source
+# code or documentation are not subject to the GNU General Public License and
+# may only be used or replicated with the express permission of Red Hat, Inc.
+
+ fedora_elections.elections test script
+"""
+__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
+import pkg_resources
+
+import logging
+import unittest
+import sys
+import os
+
+from datetime import time
+from datetime import timedelta
+
+import flask
+
+sys.path.insert(0, os.path.join(os.path.dirname(
+ os.path.abspath(__file__)), '..'))
+
+import fedora_elections
+from tests import ModelFlasktests, Modeltests, TODAY, FakeUser, user_set
+
+
+# pylint: disable=R0904
+class FlaskSimpleElectionstests(ModelFlasktests):
+ """ Flask application tests range voting. """
+
+ def test_vote_simple(self):
+ """ Test the vote_simple function - the preview part. """
+ output = self.app.get(
+ '/vote/test_election', follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<title>OpenID transaction in progress</title>' in output.data
+ or 'discoveryfailure' in output.data)
+
+ 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(
+ '/vote/test_election5')
+ self.assertTrue(
+ '<h2>test election 5 shortdesc</h2>' in output.data)
+ self.assertTrue(
+ '<input type="hidden" name="action" value="preview" />'
+ in output.data)
+
+ # Invalid vote: No candidate
+ data = {
+ 'action': 'preview',
+ }
+
+ output = self.app.post('/vote/test_election5', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<h2>test election 5 shortdesc</h2>' in output.data)
+ self.assertTrue(
+ '<td class="error">Not a valid choice</td>'
+ in output.data)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 1)
+ self.assertTrue(
+ '<input type="hidden" name="action" value="preview" />'
+ in output.data)
+
+ csrf_token = output.data.split(
+ 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
+
+ # Invalid vote: No candidate
+ data = {
+ 'action': 'preview',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post('/vote/test_election5', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<h2>test election 5 shortdesc</h2>' in output.data)
+ self.assertTrue(
+ '<td class="error">Not a valid choice</td>'
+ in output.data)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 1)
+ self.assertTrue(
+ '<input type="hidden" name="action" value="preview" />'
+ in output.data)
+
+ # Invalid vote: Not numeric
+ data = {
+ 'candidate': 'a',
+ 'action': 'preview',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post('/vote/test_election5', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<h2>test election 5 shortdesc</h2>' in output.data)
+ self.assertTrue(
+ '<input type="hidden" name="action" value="preview" />'
+ in output.data)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 1)
+
+ # Valid input
+ data = {
+ 'candidate': 7,
+ 'action': 'preview',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post('/vote/test_election5', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<h2>test election 5 shortdesc</h2>' in output.data)
+ self.assertTrue(
+ '<input type="hidden" name="action" value="submit" />'
+ in output.data)
+ self.assertTrue(
+ '<li class="message">Please confirm your vote!</li>'
+ in output.data)
+
+ def test_vote_simple_process(self):
+ """ Test the vote_simple function - the voting part. """
+ output = self.app.get(
+ '/vote/test_election', follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<title>OpenID transaction in progress</title>' in output.data
+ or 'discoveryfailure' in output.data)
+
+ self.setup_db()
+
+ user = FakeUser(['packager'], username='pingou')
+ with user_set(fedora_elections.APP, user):
+ # Invalid candidate id - no csrf
+ data = {
+ 'candidate': 1,
+ 'action': 'submit',
+ }
+
+ output = self.app.post(
+ '/vote/test_election5', data=data,
+ follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 1)
+
+ csrf_token = output.data.split(
+ 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
+
+ # Invalid candidate id
+ data = {
+ 'candidate': 1,
+ 'action': 'submit',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post(
+ '/vote/test_election5', data=data,
+ follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 1)
+
+ # Invalid vote: too low
+ data = {
+ 'candidate': -1,
+ 'action': 'submit',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post(
+ '/vote/test_election5', data=data,
+ follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 1)
+
+ # Invalid vote: Not numeric
+ data = {
+ 'candidate': 'a',
+ 'action': 'submit',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post(
+ '/vote/test_election5', data=data,
+ follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 1)
+
+ # Valid input
+ data = {
+ 'candidate': 8,
+ 'action': 'submit',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post(
+ '/vote/test_election5', data=data,
+ follow_redirects=True)
+ 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 __name__ == '__main__':
+ SUITE = unittest.TestLoader().loadTestsFromTestCase(FlaskSimpleElectionstests)
+ unittest.TextTestRunner(verbosity=2).run(SUITE)
commit e0417f7b4ac8e5ff5d99a152092b3610db2dcccf
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 15:07:54 2014 +0200
Move the voting range election unit-tests to their own file
diff --git a/tests/test_flask_elections.py b/tests/test_flask_elections.py
index abda30e..b12353e 100644
--- a/tests/test_flask_elections.py
+++ b/tests/test_flask_elections.py
@@ -166,244 +166,6 @@ class FlaskElectionstests(ModelFlasktests):
in output.data)
self.assertTrue('<h3>Current elections</h3>' in output.data)
- def test_vote_range(self):
- """ Test the vote_range function - the preview part. """
- output = self.app.get(
- '/vote/test_election', follow_redirects=True)
- self.assertEqual(output.status_code, 200)
- self.assertTrue(
- '<title>OpenID transaction in progress</title>' in output.data
- or 'discoveryfailure' in output.data)
-
- 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(
- '/vote/test_election3')
- self.assertTrue(
- '<h2>test election 3 shortdesc</h2>' in output.data)
- self.assertTrue(
- '<input type="hidden" name="action" value="preview" />'
- in output.data)
-
- # Invalid candidate id
- data = {
- 'Toshio': 1,
- 'kevin': 3,
- 'Ralph': 2,
- 'action': 'preview',
- }
-
- output = self.app.post('/vote/test_election3', data=data)
- self.assertEqual(output.status_code, 200)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 3)
-
- csrf_token = output.data.split(
- 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
-
- # Invalid candidate id
- data = {
- 'Toshio': 1,
- 'Kevin': 3,
- 'Ralph': 2,
- 'action': 'preview',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post('/vote/test_election3', data=data)
- self.assertEqual(output.status_code, 200)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 3)
-
- # Invalid vote: too low
- data = {
- '9': -1,
- '6': 3,
- '5': 2,
- 'action': 'preview',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post('/vote/test_election3', data=data)
- self.assertEqual(output.status_code, 200)
- self.assertTrue(
- '<h2>test election 3 shortdesc</h2>' in output.data)
- self.assertTrue(
- '<input type="hidden" name="action" value="preview" />'
- in output.data)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
-
- # Invalid vote: too high
- data = {
- '9': 5,
- '6': 3,
- '5': 2,
- 'action': 'preview',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post('/vote/test_election3', data=data)
- self.assertEqual(output.status_code, 200)
- self.assertTrue(
- '<h2>test election 3 shortdesc</h2>' in output.data)
- self.assertTrue(
- '<input type="hidden" name="action" value="preview" />'
- in output.data)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
-
- # Invalid vote: Not numeric
- data = {
- '9': 'a',
- '6': 3,
- '5': 2,
- 'action': 'preview',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post('/vote/test_election3', data=data)
- self.assertEqual(output.status_code, 200)
- self.assertTrue(
- '<h2>test election 3 shortdesc</h2>' in output.data)
- self.assertTrue(
- '<input type="hidden" name="action" value="preview" />'
- in output.data)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
-
- # Valid input
- data = {
- '4': 1,
- '6': 3,
- '5': 2,
- 'action': 'preview',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post('/vote/test_election3', data=data)
- self.assertEqual(output.status_code, 200)
- self.assertTrue(
- '<h2>test election 3 shortdesc</h2>' in output.data)
- self.assertTrue(
- '<input type="hidden" name="action" value="submit" />'
- in output.data)
- self.assertTrue('<div class="vtmedcool">' in output.data)
- self.assertTrue('<div class="vthot">' in output.data)
- self.assertTrue('<div class="vtmedwarm">' in output.data)
-
- def test_vote_range_process(self):
- """ Test the vote_range function - the voting part. """
- output = self.app.get(
- '/vote/test_election', follow_redirects=True)
- self.assertEqual(output.status_code, 200)
- self.assertTrue(
- '<title>OpenID transaction in progress</title>' in output.data
- or 'discoveryfailure' in output.data)
-
- self.setup_db()
-
- user = FakeUser(['voters'], username='pingou')
- with user_set(fedora_elections.APP, user):
- # No csrf token provided
- data = {
- 'Toshio': 1,
- 'Kevin': 3,
- 'Ralph': 2,
- 'action': 'submit',
- }
-
- output = self.app.post('/vote/test_election3', data=data)
- self.assertEqual(output.status_code, 200)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 3)
-
- csrf_token = output.data.split(
- 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
-
- # Invalid vote: too low
- data = {
- '4': -1,
- '5': 3,
- '6': 2,
- 'action': 'submit',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post(
- '/vote/test_election3', data=data)
- self.assertEqual(output.status_code, 200)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
-
- # Invalid vote: too high
- data = {
- '4': 5,
- '5': 3,
- '6': 2,
- 'action': 'submit',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post(
- '/vote/test_election3', data=data, follow_redirects=True)
- self.assertEqual(output.status_code, 200)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
-
- # Invalid vote: Not numeric
- data = {
- '4': 'a',
- '5': 3,
- '6': 2,
- 'action': 'submit',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post(
- '/vote/test_election3', data=data, follow_redirects=True)
- self.assertEqual(output.status_code, 200)
- self.assertEqual(
- output.data.count('<td class="error">Not a valid choice</td>'),
- 1)
-
- # Valid input
- data = {
- '4': 1,
- '5': 3,
- '6': 2,
- 'action': 'submit',
- 'csrf_token': csrf_token,
- }
-
- output = self.app.post(
- '/vote/test_election3', data=data, follow_redirects=True)
- 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)
-
def test_vote_simple(self):
""" Test the vote_simple function - the preview part. """
output = self.app.get(
diff --git a/tests/test_flask_range_voting.py b/tests/test_flask_range_voting.py
new file mode 100644
index 0000000..bf6cb95
--- /dev/null
+++ b/tests/test_flask_range_voting.py
@@ -0,0 +1,288 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""
+ (c) 2014 - Copyright Pierre-Yves Chibon
+ Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
+
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2, or (at your option) any later version. This
+# program is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details. You should have received a copy of the GNU
+# General Public License along with this program; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the source
+# code or documentation are not subject to the GNU General Public License and
+# may only be used or replicated with the express permission of Red Hat, Inc.
+
+ fedora_elections.elections test script
+"""
+__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
+import pkg_resources
+
+import logging
+import unittest
+import sys
+import os
+
+from datetime import time
+from datetime import timedelta
+
+import flask
+
+sys.path.insert(0, os.path.join(os.path.dirname(
+ os.path.abspath(__file__)), '..'))
+
+import fedora_elections
+from tests import ModelFlasktests, Modeltests, TODAY, FakeUser, user_set
+
+
+# pylint: disable=R0904
+class FlaskRangeElectionstests(ModelFlasktests):
+ """ Flask application tests range voting. """
+
+ def test_vote_range(self):
+ """ Test the vote_range function - the preview part. """
+ output = self.app.get(
+ '/vote/test_election', follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<title>OpenID transaction in progress</title>' in output.data
+ or 'discoveryfailure' in output.data)
+
+ 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(
+ '/vote/test_election3')
+ self.assertTrue(
+ '<h2>test election 3 shortdesc</h2>' in output.data)
+ self.assertTrue(
+ '<input type="hidden" name="action" value="preview" />'
+ in output.data)
+
+ # Invalid candidate id
+ data = {
+ 'Toshio': 1,
+ 'kevin': 3,
+ 'Ralph': 2,
+ 'action': 'preview',
+ }
+
+ output = self.app.post('/vote/test_election3', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 3)
+
+ csrf_token = output.data.split(
+ 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
+
+ # Invalid candidate id
+ data = {
+ 'Toshio': 1,
+ 'Kevin': 3,
+ 'Ralph': 2,
+ 'action': 'preview',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post('/vote/test_election3', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 3)
+
+ # Invalid vote: too low
+ data = {
+ '9': -1,
+ '6': 3,
+ '5': 2,
+ 'action': 'preview',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post('/vote/test_election3', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<h2>test election 3 shortdesc</h2>' in output.data)
+ self.assertTrue(
+ '<input type="hidden" name="action" value="preview" />'
+ in output.data)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 1)
+
+ # Invalid vote: too high
+ data = {
+ '9': 5,
+ '6': 3,
+ '5': 2,
+ 'action': 'preview',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post('/vote/test_election3', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<h2>test election 3 shortdesc</h2>' in output.data)
+ self.assertTrue(
+ '<input type="hidden" name="action" value="preview" />'
+ in output.data)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 1)
+
+ # Invalid vote: Not numeric
+ data = {
+ '9': 'a',
+ '6': 3,
+ '5': 2,
+ 'action': 'preview',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post('/vote/test_election3', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<h2>test election 3 shortdesc</h2>' in output.data)
+ self.assertTrue(
+ '<input type="hidden" name="action" value="preview" />'
+ in output.data)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 1)
+
+ # Valid input
+ data = {
+ '4': 1,
+ '6': 3,
+ '5': 2,
+ 'action': 'preview',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post('/vote/test_election3', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<h2>test election 3 shortdesc</h2>' in output.data)
+ self.assertTrue(
+ '<input type="hidden" name="action" value="submit" />'
+ in output.data)
+ self.assertTrue('<div class="vtmedcool">' in output.data)
+ self.assertTrue('<div class="vthot">' in output.data)
+ self.assertTrue('<div class="vtmedwarm">' in output.data)
+
+ def test_vote_range_process(self):
+ """ Test the vote_range function - the voting part. """
+ output = self.app.get(
+ '/vote/test_election', follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+ self.assertTrue(
+ '<title>OpenID transaction in progress</title>' in output.data
+ or 'discoveryfailure' in output.data)
+
+ self.setup_db()
+
+ user = FakeUser(['voters'], username='pingou')
+ with user_set(fedora_elections.APP, user):
+ # No csrf token provided
+ data = {
+ 'Toshio': 1,
+ 'Kevin': 3,
+ 'Ralph': 2,
+ 'action': 'submit',
+ }
+
+ output = self.app.post('/vote/test_election3', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 3)
+
+ csrf_token = output.data.split(
+ 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
+
+ # Invalid vote: too low
+ data = {
+ '4': -1,
+ '5': 3,
+ '6': 2,
+ 'action': 'submit',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post(
+ '/vote/test_election3', data=data)
+ self.assertEqual(output.status_code, 200)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 1)
+
+ # Invalid vote: too high
+ data = {
+ '4': 5,
+ '5': 3,
+ '6': 2,
+ 'action': 'submit',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post(
+ '/vote/test_election3', data=data, follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 1)
+
+ # Invalid vote: Not numeric
+ data = {
+ '4': 'a',
+ '5': 3,
+ '6': 2,
+ 'action': 'submit',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post(
+ '/vote/test_election3', data=data, follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+ self.assertEqual(
+ output.data.count('<td class="error">Not a valid choice</td>'),
+ 1)
+
+ # Valid input
+ data = {
+ '4': 1,
+ '5': 3,
+ '6': 2,
+ 'action': 'submit',
+ 'csrf_token': csrf_token,
+ }
+
+ output = self.app.post(
+ '/vote/test_election3', data=data, follow_redirects=True)
+ 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 __name__ == '__main__':
+ SUITE = unittest.TestLoader().loadTestsFromTestCase(FlaskRangeElectionstests)
+ unittest.TextTestRunner(verbosity=2).run(SUITE)
commit 91f9f68a666aef47402a8b3d46221b87571bf6ec
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 13:05:33 2014 +0200
Adjust the unit-test now that we are using url_for() to build the links
diff --git a/tests/test_flask.py b/tests/test_flask.py
index f05a563..6013d88 100644
--- a/tests/test_flask.py
+++ b/tests/test_flask.py
@@ -258,8 +258,8 @@ class Flasktests(ModelFlasktests):
'<td>test election 2 shortdesc</td>' in output.data)
self.assertTrue(
'<td>test election shortdesc</td>' in output.data)
- self.assertEqual(output.data.count('<a href="results/'), 2)
- self.assertEqual(output.data.count('<a href="about/'), 2)
+ self.assertEqual(output.data.count('<a href="/results/'), 2)
+ self.assertEqual(output.data.count('<a href="/about/'), 2)
self.assertTrue('<a href="/login">login</a>' in output.data)
def test_open_elections(self):
commit d692f524e7aa0d43bf5ff1fc9ce101da606ffb3e
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 13:05:13 2014 +0200
Fix the `More information` link to actually point to the about page
diff --git a/fedora_elections/templates/archive.html b/fedora_elections/templates/archive.html
index 38303d7..ea5d6db 100644
--- a/fedora_elections/templates/archive.html
+++ b/fedora_elections/templates/archive.html
@@ -18,7 +18,7 @@
<td>{{election.start_date}}</td>
<td>{{election.end_date}}</td>
<td>
- <a href="{{ url_for('vote', election_alias=election.alias) }}">
+ <a href="{{ url_for('about_election', election_alias=election.alias) }}">
More information
</a>
</td>
diff --git a/fedora_elections/templates/index.html b/fedora_elections/templates/index.html
index bda9b02..1381b41 100644
--- a/fedora_elections/templates/index.html
+++ b/fedora_elections/templates/index.html
@@ -22,7 +22,7 @@
<td>{{ election.end_date }}</td>
<td>{{ election.status }}</td>
<td>
- <a href="{{ url_for('vote', election_alias=election.alias) }}">
+ <a href="{{ url_for('about_election', election_alias=election.alias) }}">
More information
</a>
</td>
commit 1235e86a32cb9d71f12b5ebb8e9c48e225bacf24
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 12:49:06 2014 +0200
Use url_for() in the archive template to build the links
diff --git a/fedora_elections/templates/archive.html b/fedora_elections/templates/archive.html
index ec46f15..38303d7 100644
--- a/fedora_elections/templates/archive.html
+++ b/fedora_elections/templates/archive.html
@@ -18,10 +18,15 @@
<td>{{election.start_date}}</td>
<td>{{election.end_date}}</td>
<td>
- <a href="about/{{ election.alias }}">More information</a>
+ <a href="{{ url_for('vote', election_alias=election.alias) }}">
+ More information
+ </a>
</td>
<td>
- <a href="results/{{ election.alias }}">Results</a>
+ <a href="{{ url_for('election_results',
+ election_alias=election.alias) }}">
+ Results
+ </a>
</td>
</tr>
{% endfor %}
commit d85529b324595b08190b15088fa890c1cc91ef73
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Jul 11 12:48:45 2014 +0200
Add link to the about page on the index and open pages
diff --git a/fedora_elections/templates/index.html b/fedora_elections/templates/index.html
index 45518d4..bda9b02 100644
--- a/fedora_elections/templates/index.html
+++ b/fedora_elections/templates/index.html
@@ -13,6 +13,7 @@
<th>End date (UTC)</th>
<th>Status</th>
<th></th>
+ <th></th>
</tr>
{% for election in election_list %}
<tr>
@@ -21,6 +22,11 @@
<td>{{ election.end_date }}</td>
<td>{{ election.status }}</td>
<td>
+ <a href="{{ url_for('vote', election_alias=election.alias) }}">
+ More information
+ </a>
+ </td>
+ <td>
{% if election.status == "In progress" %}
{% if election not in voted %}
<a href="{{ url_for('vote', election_alias=election.alias) }}">
9 years, 10 months
Changes to 'refs/tags/v2.1'
by Pierre-YvesChibon
Tag 'v2.1' created by Pierre-Yves Chibon <pingou(a)pingoured.fr> at 2014-07-16 07:06 +0000
Release 2.1
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iEUEABECAAYFAlPGJFwACgkQ2HRbBxDocwrCwgCXRa9vsjzNlHNQVTcji0nt9ZQ8
CACeJQKTBAVucTNx96W2IXzuD0d4RMU=
=GDRa
-----END PGP SIGNATURE-----
Changes since v2.0.2:
Pierre-Yves Chibon (162):
Update the content of the fedmsg.d folder, simplify it
Add a json compatible representation of an election object
Broadcast on fedmsg when an election is added or edited
Fix the conversion of the election objects into a json structure for fedmsg
Add method to convert a Candidate object into a json representation of it
Publish fedmsg messages upon adding, editing and deleting candidates
Move the index template one level up
Move the templates in the `election` folder one level up
Adjust the flask application for the new template paths
Remove the redirect.py file
Split the one controller into three
Give a warning information message to admins seeing an embargoed election
Make the runserver.py file executable
Remove import of the redirect file since the file no longer exists
Rename the column usefas to candidates_are_fasusers
Adjust the database mapping of candidates_are_fasusers to its type in the DB
Remove current tests
Make the minimal flask version be 0.10
pep8 fixes on the controllers
Add default datetime in the timestamp field of the Vote table
Format the start and end dates in the json representation of an election
Order votes by timestamp
Ignore a small piece of the createdb function in the unit-tests
Add first code for the unit-tests
Add unit-tests for the Election object
Add unit-tests for the Candidate object
Add unit-tests for the Vote object
Add a local nosetests script ensuring we run the proper version of the libraries
Add the runtest.sh script for easy testings of the project
Ignore the .coverage file created when running the tests with coverage
Ignore reading the config file specified by environment variable
Add missing docstrings
Ignore some other lines in the unit-tests coverage report
Add some more votes on the election #3
Add unit-tests for the generic flask endpoints
Ignore fedmsg in the unit-tests
Add a generic unit-test class for the Flask tests
Port the flask applications to the ModelFlasktests class
Update the auth_login method to remove duplicated checks
Do not show voting page on election embargoed, these are just ended embargoed
Remove double spaces on a flashed message
Add missing spaces in flashed messages
Add missing import in the elections controller
Add a new simple and open election and adjust the tests to this election
Add candidates to the new election having simple voting
Add votes to the new election #5 with simple voting
Add missing shebang to the runserver.py script
Adjust the flask tests to new election added
Ignore case where we don't know the election's voting type for the unit-tests
Add candidates to the election #3 and adjust the candidate.id
Adjust the candidate.id for the candidates that were added to elections #3
Ignore case where we would not get a valid election object from get_valid_election
Fix typo in the Preview (in case of wrong input)
In case the input is invalid (not an int), the next_action is vote
Ignore FAS integration for the unit-tests
Handle the case the id submitted is not an integer
Fix the simple voting, make sure the candidate submitted belong to the election
Ignore FAS integration for the unit-tests
Ignore in the unit-test the possibility that get_valid_election does not return an election
One more place where we do not want to cover FAS integration in the unit-tests
Add unit-tests for the elections controller
Remove un-used imports
Add couple of candidates to the election #4
Handle error if someone tries to delete a candidate that already has votes
Update the behavior of the ForeinKey upon update or delete
Add unit-tests for the admin controller
Fix import and session for the unit-tests for the elections and admin controllers
Add a little bit of documentation in the admin tests
Add missing import and fix the validate_shortdesc to actually be used
Add tests for the form fields validations when creating a new elections
Fix the database session for the forms, if we want the tests to run :)
Fix dependency in setup.py, the package is named kitchen not python-kitchen
Specify where to find the tests so that python setup.py test works
Adjust the requirements file
Convert the boolean into integer as in the DB model (and required by postgresql)
pep8 fixes on fedora_elections
pep8 fixes on setup.py
pep8 fixes on the tests
Change comment as suggested by @abadger
'##' is not allowed, and @abadger is right '# #' doesn't look right either
Remove un-used script
Add elections.proxy and set elections as an application behind a reverse proxy
Fix the reverse proxy
Implement the election admin groups
Make the tests pass offline
Elections admins are now admins of every elections
Enhance coverage of the is_admin function
Specify an admin group for the election #2
Test the is_election_admin when the user is and is not in an AdminGroup of that election
Sort the election's admin groups
Add unit-test testing the addition and removal of admin groups when editing an election
Add unit-tests for the is_safe_url method
pep8 fixes
Explain a little what the admin groups are
No need to have different URL for the different voting type, one is enough
Adjust the action url in the vote templates now that there is a unique URL for voting
Adjust unit-tests to the unique URL for voting
Simplify vote_range and vote_simple since they are no longer flask endpoints
Implement legal_voters adding/editing/deleting
Voting to an election requires CLA+1 at minimum
Use safe_redirect_back instead of forcing the return to index
If there are legal voters and the user is not one of them, redirect him/her back
Add test for the redirect from the voting page is the user did not sign the CLA
Fix the @login_required to check to cla_done and groups > 0
Fix the unit-tests so that the FakeFasUser used has at least 1 group
Add test checking the error message if the user has 0 groups
Specify a group of user allowed to vote on election #3
Adjust the tests so that the FakeFasUser is part of the group allowed to vote
Add test for editing an election with legal voters
Add test checking the behavior when the user is not part of the LegalVoters
Split the tests for editing admin groups or legal voters into their own method
Cover adding admin groups when testing admin_new_election
Avoid adding empty legal voter groups
Show the actual results in the result page
Comment the logic of the conditions to select where to place the limit
Let's be a little more precise/concrete about what the check allows
Add dynamically generated form used for range voting
Add macro to render the choices when confirming a vote
Update the range voting method to relying on a wtforms form
Adjust the range voting form to make use of the wtforms form created for it
Allow to vote up to the number of candidates
Fix the tests for the change in range voting
Rename get_voting_range_form to get_range_voting_form and VotingRange to RangeVoting
Add forms.get_simple_voting_form that dynamically generate the form for simple voting
Port the simple voting logic to use the forms just created
Adjust the simple voting template to rely on the form just added
Use candidate instead of candidates to be consistent with the old behavior
Ignore the [more] link for the candidates for the moment, we need a better solution
Fix the tests for the change in the simple voting processing and integration of wtforms
No layout change when confirming for the moment
If there is a usernamemap specified, use it instead of the field label
Fixed presenting the fields of the form with their appropriate label/value
Drop the cand_name dict as we already have the usernamemap dict
Fill in the usernamemap for all the candidates
The form now provides the candidate id directly as value (instead of its name before)
Allow to rely on the usernamemap also in render_field_in_row
Make use the usernamemap for range voting
The usernamemap converts the field label (username) for FAS full names
Simple voting directly use the candidate identifier now, adjust the tests accordingly
Have the vote_range function accept a max_range argument
Update the information message according to the type of voting used for this election
Offer the simplified range voting (max range = 3) in the options when creating an election
If the election is of type range_3, call the appropriately vote_range
Add a form for SelectVoting
Add select voting as an option when creating an election
Add the logic for vote select
Add a max_votes field in the election table
Add the max_votes field in the election form
Adjust the edit and view election templates to display the max_votes field/info
Use the max_votes field of the election to set the maximum ranges or vote
The simple voting form has no use of the maximum votes/range
Add basic alembic structure for alembic integration
Add sample alembic.ini file in the files folder
Ignore alembic.ini files
Add alembic revision adding max_votes to the elections table
Small pep8 fixes
Take the max_votes into account when creating an election
Take into account max_votes when editing an election
Include the alembic files in the sources
Install the alembic files in the spec
Install the sample/default alembic.ini file as no-replace
Bump to 2.1
---
.gitignore | 2
MANIFEST.in | 1
alembic/env.py | 72 +
alembic/script.py.mako | 22
alembic/versions/d07c5ef2d03_add_max_votes_to_ele.py | 28
fedmsg.d/base.py | 39
fedmsg.d/elections.py | 20
fedmsg.d/endpoints.py | 44
fedmsg.d/ssl.py | 41
fedora_elections/__init__.py | 563 ------------
fedora_elections/admin.py | 393 ++++++++
fedora_elections/default_config.py | 1
fedora_elections/elections.py | 361 +++++++
fedora_elections/fedmsgshim.py | 2
fedora_elections/forms.py | 79 +
fedora_elections/models.py | 120 ++
fedora_elections/proxy.py | 65 +
fedora_elections/redirect.py | 23
fedora_elections/static/elections.css | 13
fedora_elections/templates/_formhelpers.html | 33
fedora_elections/templates/about.html | 40
fedora_elections/templates/admin/election_form.html | 3
fedora_elections/templates/admin/view_election.html | 3
fedora_elections/templates/archive.html | 29
fedora_elections/templates/election/about.html | 40
fedora_elections/templates/election/archive.html | 29
fedora_elections/templates/election/results.html | 65 -
fedora_elections/templates/election/vote_range.html | 116 --
fedora_elections/templates/election/vote_simple.html | 53 -
fedora_elections/templates/index.html | 66 +
fedora_elections/templates/list/index.html | 70 -
fedora_elections/templates/results.html | 93 ++
fedora_elections/templates/vote_range.html | 99 ++
fedora_elections/templates/vote_simple.html | 46 +
files/alembic.ini | 54 +
files/fedora-elections.spec | 25
files/update_1_to_2.sql | 6
nosetests | 10
requirements.txt | 6
runserver.py | 1
runtests.sh | 4
setup.py | 5
testing | 3
tests/__init__.py | 180 +++
tests/base.py | 59 -
tests/test_candidate.py | 202 ++++
tests/test_election.py | 287 ++++++
tests/test_flask.py | 312 ++++++
tests/test_flask_admin.py | 860 +++++++++++++++++++
tests/test_flask_elections.py | 682 +++++++++++++++
tests/test_smoke.py | 100 --
tests/test_vote.py | 214 ++++
52 files changed, 4443 insertions(+), 1241 deletions(-)
---
9 years, 10 months
Changes to 'refs/tags/v2.2'
by Pierre-YvesChibon
Tag 'v2.2' created by Pierre-Yves Chibon <pingou(a)pingoured.fr> at 2014-07-16 07:04 +0000
Release 2.2
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iEYEABECAAYFAlPGJBMACgkQ2HRbBxDocwrobQCfcB3h9F2mJjSdrmERqCmAc4Fm
PWcAnj5TXdXQYNXI8WFR+Fj8bt4/ZfRj
=J6gA
-----END PGP SIGNATURE-----
Changes since v2.1.1:
Chaoyi Zha (2):
small typo
fix unit tests
Pierre-Yves Chibon (19):
Improve the description of the different election types
Improve again the description of select voting
Include the runtest.sh and nosetests scripts in the releases
Prepare running the unit-tests at build time but cannot be activated for the moment
Fix integrating candidate name with FAS when the election is set as such
Fix displaying the FAS name when the FAS integration is activated
Use the shortdesc rather than the description in the archive list/page
Forward the usernamemap to the render_field_in_row macro to display the FAS user name correctly
Drop the usernamemap from the single vote election type
For single vote election, do the FAS integration when building the form
Fix the situation where the candidate.name has accent by using the candidate identifier
Only run the unit-tests against faitout when the tests are ran in jenkins
Fix the range voting to be sure the user is not voting on a candidate of another election
Adjust unit-tests for the archive page
Adjust the unit-tests now that the range voting relies on candidate identifier rather than their name
Expand the coverage to test for max_votes not being an int and adding lgl_voters groups when creating the election
Fix adding voter groups w/o spaces in their name
Expand the unit-tests to include a test w/ no max_votes set upon creation
Release 2.2
---
MANIFEST.in | 2
fedora_elections/__init__.py | 2
fedora_elections/admin.py | 2
fedora_elections/elections.py | 46 +++++++----------
fedora_elections/forms.py | 20 +++++--
fedora_elections/templates/_formhelpers.html | 4 -
fedora_elections/templates/archive.html | 2
fedora_elections/templates/vote_range.html | 2
files/fedora-elections.spec | 30 ++++++++---
tests/__init__.py | 17 +++---
tests/test_flask.py | 4 -
tests/test_flask_admin.py | 48 ++++++++++++++++++
tests/test_flask_elections.py | 70 +++++++++++++--------------
13 files changed, 156 insertions(+), 93 deletions(-)
---
9 years, 10 months
Changes to 'refs/tags/v2.1.1'
by Pierre-YvesChibon
Tag 'v2.1.1' created by Pierre-Yves Chibon <pingou(a)pingoured.fr> at 2014-07-16 07:04 +0000
Release 2.1.1
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iEYEABECAAYFAlPGI+gACgkQ2HRbBxDocwqtUQCcD4KTmu9n2Z44PMUtDQ4gMS1G
3wMAn0U8Tjbz9mG8zkHB/wIzlSzmhgpa
=YqVu
-----END PGP SIGNATURE-----
Changes since v2.1:
Pierre-Yves Chibon (3):
Fix missing imports
Adjust the 1_to_2.sql file for 2.1+
Bump to 2.1.1
---
fedora_elections/__init__.py | 2 +-
fedora_elections/elections.py | 3 ++-
files/fedora-elections.spec | 6 +++++-
files/update_1_to_2.sql | 4 ++++
4 files changed, 12 insertions(+), 3 deletions(-)
---
9 years, 10 months
Changes to 'refs/tags/v2.0.2'
by Pierre-YvesChibon
Tag 'v2.0.2' created by Pierre-Yves Chibon <pingou(a)pingoured.fr> at 2014-07-16 07:06 +0000
Release 2.0.2
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iEYEABECAAYFAlPGJI4ACgkQ2HRbBxDocwp00ACeKJgegO/pulmsETuaVtGmZhJN
5zMAn0aBiDb57PGPPewgL9PX7rS08vU3
=PWdg
-----END PGP SIGNATURE-----
Changes since v2.0.1:
Pierre-Yves Chibon (2):
Fix the is_safe_url method, the import differs here
Bump to 2.0.2
---
fedora_elections/__init__.py | 8 ++++----
files/fedora-elections.spec | 6 +++++-
2 files changed, 9 insertions(+), 5 deletions(-)
---
9 years, 10 months
Changes to 'refs/tags/v2.0.1'
by Pierre-YvesChibon
Tag 'v2.0.1' created by Pierre-Yves Chibon <pingou(a)pingoured.fr> at 2014-07-16 07:07 +0000
Release 2.0.1
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iEYEABECAAYFAlPGJKYACgkQ2HRbBxDocwpBJgCaAyJRidHhscL/MP03HRcYra9Z
uVkAoJc4eYKQCCkajzX2z5XuI4KBdGpc
=/zSW
-----END PGP SIGNATURE-----
Changes since v2.0:
Pierre-Yves Chibon (2):
Fix redirection bug in the login mechanism
Bump to 2.0.1
---
fedora_elections/__init__.py | 16 ++++++++++++++--
files/fedora-elections.spec | 6 +++++-
2 files changed, 19 insertions(+), 3 deletions(-)
---
9 years, 10 months