From af363597aed2852dd32f5f5c2e186f24d2193e92 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Apr 08 2021 19:47:28 +0000 Subject: [PATCH 1/6] Add a bandit test to ensure we code is somewhat secure Signed-off-by: Pierre-Yves Chibon --- diff --git a/tox.ini b/tox.ini index 3728341..4039ae8 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py36,py37,py38,diff-cover +envlist = py36,py37,py38,diff-cover,bandit skipsdist = True [testenv] @@ -24,3 +24,8 @@ deps = commands = diff-cover coverage.xml --compare-branch=origin/develop --fail-under=100 +[testenv:bandit] +deps = bandit +commands = + bandit -r fedora_elections/ -ll + From 77df2d48f46c2baecdf6f549f86b07820ebdaea6 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Apr 08 2021 19:47:28 +0000 Subject: [PATCH 2/6] Port the test runner to pytest instead of nose that is deprecated Signed-off-by: Pierre-Yves Chibon --- diff --git a/tox.ini b/tox.ini index 4039ae8..d34b945 100644 --- a/tox.ini +++ b/tox.ini @@ -8,15 +8,13 @@ passenv = HOME deps = -rrequirements.txt mock - nose - coverage + pytest + pytest-cov setenv = PYTHONPATH={toxinidir} FEDORA_ELECTIONS_CONFIG={toxinidir}/tests/config commands = - nosetests --with-coverage --cover-erase \ - --cover-package=fedora_elections --cover-xml \ - {posargs} + pytest --cov=fedora_elections --cov-report=xml --cov-report=term-missing {posargs} [testenv:diff-cover] deps = From 523376d5b9137f7a27848d0e04d46aad0695ae8e Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Apr 08 2021 19:47:28 +0000 Subject: [PATCH 3/6] Add and enforce code formatting with black Signed-off-by: Pierre-Yves Chibon --- diff --git a/tox.ini b/tox.ini index d34b945..a88b890 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py36,py37,py38,diff-cover,bandit +envlist = py36,py37,py38,diff-cover,bandit,format skipsdist = True [testenv] @@ -22,6 +22,12 @@ deps = commands = diff-cover coverage.xml --compare-branch=origin/develop --fail-under=100 + +[testenv:format] +deps = black +commands = + black --check --diff {posargs:.} + [testenv:bandit] deps = bandit commands = From ee5b144ba84b2a80021c3ac9c285536730826298 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Apr 08 2021 19:47:28 +0000 Subject: [PATCH 4/6] Run black over the entire code base Signed-off-by: Pierre-Yves Chibon --- diff --git a/alembic/env.py b/alembic/env.py index 95f4087..8298c0a 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -27,7 +27,7 @@ target_metadata = fedora_elections.models.BASE DBURL = config.get_main_option("sqlalchemy.url") if not DBURL: - DBURL = fedora_elections.APP.config['DB_URL'] + DBURL = fedora_elections.APP.config["DB_URL"] def run_migrations_offline(): @@ -58,9 +58,7 @@ def run_migrations_online(): connectable = create_engine(DBURL, poolclass=pool.NullPool) with connectable.connect() as connection: - context.configure( - connection=connection, - target_metadata=target_metadata) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/alembic/versions/2b8f5a6f10a4_store_fas_name_locally.py b/alembic/versions/2b8f5a6f10a4_store_fas_name_locally.py index 6d960df..56c8773 100644 --- a/alembic/versions/2b8f5a6f10a4_store_fas_name_locally.py +++ b/alembic/versions/2b8f5a6f10a4_store_fas_name_locally.py @@ -7,8 +7,8 @@ Create Date: 2016-01-21 16:53:38.956503 """ # revision identifiers, used by Alembic. -revision = '2b8f5a6f10a4' -down_revision = 'd07c5ef2d03' +revision = "2b8f5a6f10a4" +down_revision = "d07c5ef2d03" from alembic import op import sqlalchemy as sa @@ -16,12 +16,9 @@ import sqlalchemy as sa def upgrade(): """ Add the fas_name column to the candidates table. """ - op.add_column( - 'candidates', - sa.Column('fas_name', sa.Unicode(150), nullable=True) - ) + op.add_column("candidates", sa.Column("fas_name", sa.Unicode(150), nullable=True)) def downgrade(): """ Drop the fas_name column from the candidates table. """ - op.drop_column('candidates', 'fas_name') + op.drop_column("candidates", "fas_name") diff --git a/alembic/versions/5ecdd55b4af4_add_badge_support_to_elections.py b/alembic/versions/5ecdd55b4af4_add_badge_support_to_elections.py index e1e0b2e..d933a18 100644 --- a/alembic/versions/5ecdd55b4af4_add_badge_support_to_elections.py +++ b/alembic/versions/5ecdd55b4af4_add_badge_support_to_elections.py @@ -7,8 +7,8 @@ Create Date: 2019-03-18 12:21:59.536380 """ # revision identifiers, used by Alembic. -revision = '5ecdd55b4af4' -down_revision = '2b8f5a6f10a4' +revision = "5ecdd55b4af4" +down_revision = "2b8f5a6f10a4" from alembic import op import sqlalchemy as sa @@ -16,12 +16,9 @@ import sqlalchemy as sa def upgrade(): """ Add the url_badge column to the Elections table. """ - op.add_column( - 'elections', - sa.Column('url_badge', sa.Unicode(250), nullable=True) - ) + op.add_column("elections", sa.Column("url_badge", sa.Unicode(250), nullable=True)) def downgrade(): """ Drop the url_badge column from the Elections table. """ - op.drop_column('elections', 'url_badge') + op.drop_column("elections", "url_badge") diff --git a/alembic/versions/d07c5ef2d03_add_max_votes_to_ele.py b/alembic/versions/d07c5ef2d03_add_max_votes_to_ele.py index 4a922ff..44aa1af 100644 --- a/alembic/versions/d07c5ef2d03_add_max_votes_to_ele.py +++ b/alembic/versions/d07c5ef2d03_add_max_votes_to_ele.py @@ -8,7 +8,7 @@ Create Date: 2014-05-26 16:33:50.812050 """ # revision identifiers, used by Alembic. -revision = 'd07c5ef2d03' +revision = "d07c5ef2d03" down_revision = None from alembic import op @@ -17,12 +17,9 @@ import sqlalchemy as sa def upgrade(): """ Add the max_votes column to the Elections table. """ - op.add_column( - 'elections', - sa.Column('max_votes', sa.Integer, nullable=True) - ) + op.add_column("elections", sa.Column("max_votes", sa.Integer, nullable=True)) def downgrade(): """ Drop the max_votes column from the Elections table. """ - op.drop_column('elections', 'max_votes') + op.drop_column("elections", "max_votes") diff --git a/createdb.py b/createdb.py index 89a4a1e..27f1fff 100644 --- a/createdb.py +++ b/createdb.py @@ -1,7 +1,9 @@ import __main__ -__main__.__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4'] + +__main__.__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] import pkg_resources from fedora_elections import APP from fedora_elections.models import create_tables -create_tables(APP.config['DB_URL'], debug=True) + +create_tables(APP.config["DB_URL"], debug=True) diff --git a/fedora_elections/__init__.py b/fedora_elections/__init__.py index 2a34232..8c82ab0 100644 --- a/fedora_elections/__init__.py +++ b/fedora_elections/__init__.py @@ -25,7 +25,7 @@ # from __future__ import unicode_literals, absolute_import -__version__ = '2.9' +__version__ = "2.9" import logging # noqa import os # noqa @@ -52,9 +52,9 @@ import fedora_elections.fedmsgshim # noqa import fedora_elections.proxy # noqa APP = flask.Flask(__name__) -APP.config.from_object('fedora_elections.default_config') -if 'FEDORA_ELECTIONS_CONFIG' in os.environ: # pragma: no cover - APP.config.from_envvar('FEDORA_ELECTIONS_CONFIG') +APP.config.from_object("fedora_elections.default_config") +if "FEDORA_ELECTIONS_CONFIG" in os.environ: # pragma: no cover + APP.config.from_envvar("FEDORA_ELECTIONS_CONFIG") # set up FAS OIDC = OpenIDConnect(APP, credentials_store=flask.session) @@ -65,23 +65,22 @@ LOG = APP.logger APP.wsgi_app = fedora_elections.proxy.ReverseProxied(APP.wsgi_app) -if APP.config.get('FASJSON'): - ACCOUNTS = Client( - url=APP.config['FAS_BASE_URL'] - ) +if APP.config.get("FASJSON"): + ACCOUNTS = Client(url=APP.config["FAS_BASE_URL"]) else: # FAS for usernames. ACCOUNTS = AccountSystem( - APP.config['FAS_BASE_URL'], - username=APP.config['FAS_USERNAME'], - password=APP.config['FAS_PASSWORD'], - insecure=not APP.config['FAS_CHECK_CERT'] + APP.config["FAS_BASE_URL"], + username=APP.config["FAS_USERNAME"], + password=APP.config["FAS_PASSWORD"], + insecure=not APP.config["FAS_CHECK_CERT"], ) # modular imports from fedora_elections import models # noqa -SESSION = models.create_session(APP.config['DB_URL']) + +SESSION = models.create_session(APP.config["DB_URL"]) from fedora_elections import forms # noqa @@ -89,24 +88,21 @@ from fedora_elections.utils import build_name_map # noqa def is_authenticated(): - ''' Return a boolean specifying if the user is authenticated or not. - ''' - return hasattr(flask.g, 'fas_user') and flask.g.fas_user is not None + """Return a boolean specifying if the user is authenticated or not.""" + return hasattr(flask.g, "fas_user") and flask.g.fas_user is not None def is_safe_url(target): - """ Checks that the target url is safe and sending to the current + """Checks that the target url is safe and sending to the current website not some other malicious one. """ ref_url = urlparse(flask.request.host_url) test_url = urlparse(urljoin(flask.request.host_url, target)) - return test_url.scheme in ('http', 'https') and \ - ref_url.netloc == test_url.netloc + return test_url.scheme in ("http", "https") and ref_url.netloc == test_url.netloc def is_admin(user, user_groups=None): - ''' Is the user an elections admin. - ''' + """Is the user an elections admin.""" if not user_groups: user_groups = [] @@ -117,12 +113,12 @@ def is_admin(user, user_groups=None): user_groups = [] if is_authenticated() and OIDC.user_loggedin: - user_groups = OIDC.user_getfield('groups') + user_groups = OIDC.user_getfield("groups") if len(user_groups) < 1: return False - admins = APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'] + admins = APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"] if isinstance(admins, six.string_types): # pragma: no cover admins = set([admins]) else: @@ -132,9 +128,9 @@ def is_admin(user, user_groups=None): def is_election_admin(user, election_id): - ''' Check if the provided user is in one of the admin group of the + """Check if the provided user is in one of the admin group of the specified election. - ''' + """ if not user: return False if not user.cla_done or len(user.groups) < 1: @@ -145,20 +141,20 @@ def is_election_admin(user, election_id): admingroups = [ group.group_name for group in models.ElectionAdminGroup.by_election_id( - SESSION, election_id=election_id) - ] + SESSION, election_id=election_id + ) + ] return len(set(user.groups).intersection(set(admingroups))) > 0 -def safe_redirect_back(next=None, fallback=('index', {})): - ''' Safely redirect the user to its previous page. ''' +def safe_redirect_back(next=None, fallback=("index", {})): + """ Safely redirect the user to its previous page. """ targets = [] if next: # pragma: no cover targets.append(next) - if 'next' in flask.request.args and \ - flask.request.args['next']: # pragma: no cover - targets.append(flask.request.args['next']) + if "next" in flask.request.args and flask.request.args["next"]: # pragma: no cover + targets.append(flask.request.args["next"]) targets.append(flask.url_for(fallback[0], **fallback[1])) for target in targets: if is_safe_url(target): @@ -167,39 +163,37 @@ def safe_redirect_back(next=None, fallback=('index', {})): @APP.context_processor def inject_variables(): - ''' Inject a set of variable that we want for every pages (every + """Inject a set of variable that we want for every pages (every template). - ''' + """ user = None if is_authenticated() and OIDC.user_loggedin: user = flask.g.fas_user - return dict(is_admin=is_admin(user), - version=__version__) + return dict(is_admin=is_admin(user), version=__version__) -@APP.template_filter('rjust') +@APP.template_filter("rjust") def rjust_filter(text, length): - """ Run a rjust command on the text for the given length - """ + """Run a rjust command on the text for the given length""" return str(text).rjust(length) -@APP.template_filter('avatar') -def avatar_filter(openid, size=64, default='retro'): - query = urlencode({'s': size, 'd': default}) +@APP.template_filter("avatar") +def avatar_filter(openid, size=64, default="retro"): + query = urlencode({"s": size, "d": default}) openid = openid.encode("utf-8") hashhex = hashlib.sha256(openid).hexdigest() return "https://seccdn.libravatar.org/avatar/%s?%s" % (hashhex, query) -@APP.template_filter('humanize') +@APP.template_filter("humanize") def humanize_date(date): return arrow.get(date).humanize() -@APP.template_filter('prettydate') +@APP.template_filter("prettydate") def prettydate(date): - return date.strftime('%A %B %d %Y %X UTC') + return date.strftime("%A %B %d %Y %X UTC") # pylint: disable=W0613 @@ -209,16 +203,15 @@ def set_session(): # pragma: no-cover flask.session.permanent = True if OIDC.user_loggedin: - if not hasattr(flask.session, 'fas_user') \ - or not flask.session.fas_user: - flask.session.fas_user = munch.Munch({ - 'username': OIDC.user_getfield('nickname'), - 'email': OIDC.user_getfield('email') or '', - 'timezone': OIDC.user_getfield('zoneinfo'), - 'cla_done': - 'FPCA' - in (OIDC.user_getfield('agreements') or []), - }) + if not hasattr(flask.session, "fas_user") or not flask.session.fas_user: + flask.session.fas_user = munch.Munch( + { + "username": OIDC.user_getfield("nickname"), + "email": OIDC.user_getfield("email") or "", + "timezone": OIDC.user_getfield("zoneinfo"), + "cla_done": "FPCA" in (OIDC.user_getfield("agreements") or []), + } + ) flask.g.fas_user = flask.session.fas_user else: flask.session.fas_user = None @@ -234,7 +227,8 @@ def shutdown_session(exception=None): # LIST VIEWS ############################################# -@APP.route('/') + +@APP.route("/") def index(): now = datetime.utcnow() @@ -246,39 +240,39 @@ def index(): if is_authenticated(): for elec in cur_elections: votes = models.Vote.of_user_on_election( - SESSION, flask.g.fas_user.username, elec.id, count=True) + SESSION, flask.g.fas_user.username, elec.id, count=True + ) if votes > 0: voted.append(elec) return flask.render_template( - 'index.html', + "index.html", prev_elections=prev_elections, cur_elections=cur_elections, next_elections=next_elections, voted=voted, - tag='index', - title="Elections") + tag="index", + title="Elections", + ) -@APP.route('/about/') +@APP.route("/about/") def about_election(election_alias): election = models.Election.get(SESSION, alias=election_alias) stats = [] evolution_label = [] evolution_data = [] if not election: - flask.flash('The election, %s, does not exist.' % election_alias) + flask.flash("The election, %s, does not exist." % election_alias) return safe_redirect_back() - elif election.status in ['Embargoed', 'Ended']: + elif election.status in ["Embargoed", "Ended"]: stats = models.Vote.get_election_stats(SESSION, election.id) cnt = 1 for delta in range((election.end_date - election.start_date).days + 1): - day = ( - election.start_date + timedelta(days=delta) - ).strftime('%d-%m-%Y') + day = (election.start_date + timedelta(days=delta)).strftime("%d-%m-%Y") evolution_label.append([cnt, day]) - evolution_data.append([cnt, stats['vote_timestamps'].count(day)]) + evolution_data.append([cnt, stats["vote_timestamps"].count(day)]) cnt += 1 usernamemap = build_name_map(election) @@ -286,12 +280,13 @@ def about_election(election_alias): voted = [] if is_authenticated(): votes = models.Vote.of_user_on_election( - SESSION, flask.g.fas_user.username, election.id, count=True) + SESSION, flask.g.fas_user.username, election.id, count=True + ) if votes > 0: voted.append(election) return flask.render_template( - 'about.html', + "about.html", election=election, usernamemap=usernamemap, stats=stats, @@ -299,46 +294,45 @@ def about_election(election_alias): evolution_label=evolution_label, evolution_data=evolution_data, candidates=sorted( - election.candidates, key=lambda x: x.vote_count, reverse=True), + election.candidates, key=lambda x: x.vote_count, reverse=True + ), ) -@APP.route('/archives') +@APP.route("/archives") def archived_elections(): now = datetime.utcnow() old_elections = models.Election.get_older_election(SESSION, now) if not old_elections: - flask.flash('There are no archived elections.') + flask.flash("There are no archived elections.") return safe_redirect_back() - return flask.render_template( - 'archive.html', - elections=old_elections) + return flask.render_template("archive.html", elections=old_elections) -@APP.route('/login', methods=('GET', 'POST')) +@APP.route("/login", methods=("GET", "POST")) @OIDC.require_login def auth_login(): next_url = None - if 'next' in flask.request.args: - if is_safe_url(flask.request.args['next']): - next_url = flask.request.args['next'] + if "next" in flask.request.args: + if is_safe_url(flask.request.args["next"]): + next_url = flask.request.args["next"] - if not next_url or next_url == flask.url_for('.auth_login'): - next_url = flask.url_for('.index') + if not next_url or next_url == flask.url_for(".auth_login"): + next_url = flask.url_for(".index") return safe_redirect_back(next_url) -@APP.route('/logout') +@APP.route("/logout") def auth_logout(): - if hasattr(flask.g, 'fas_user') and flask.g.fas_user is not None: + if hasattr(flask.g, "fas_user") and flask.g.fas_user is not None: OIDC.logout() flask.g.fas_user = None flask.session.fas_user = None - flask.flash('You have been logged out') + flask.flash("You have been logged out") return safe_redirect_back() diff --git a/fedora_elections/admin.py b/fedora_elections/admin.py index 3c013fd..f54d3cd 100644 --- a/fedora_elections/admin.py +++ b/fedora_elections/admin.py @@ -42,9 +42,7 @@ from fedora_elections_messages import ( from fedora_elections import fedmsgshim from fedora_elections import forms from fedora_elections import models -from fedora_elections import ( - APP, SESSION, ACCOUNTS, is_authenticated, is_admin -) +from fedora_elections import APP, SESSION, ACCOUNTS, is_authenticated, is_admin from fasjson_client.errors import APIError @@ -52,15 +50,15 @@ def election_admin_required(f): @wraps(f) def decorated_function(*args, **kwargs): if not is_authenticated(): - return flask.redirect(flask.url_for( - 'auth_login', next=flask.request.url)) + return flask.redirect(flask.url_for("auth_login", next=flask.request.url)) if not is_admin(flask.g.fas_user): flask.abort(403) return f(*args, **kwargs) + return decorated_function -@APP.route('/admin/new', methods=('GET', 'POST')) +@APP.route("/admin/new", methods=("GET", "POST")) @election_admin_required def admin_new_election(): form = forms.ElectionForm() @@ -92,12 +90,11 @@ def admin_new_election(): # Fix start_date and end_date to use datetime election.start_date = datetime.combine(election.start_date, time()) - election.end_date = datetime.combine(election.end_date, - time(23, 59, 59)) + election.end_date = datetime.combine(election.end_date, time(23, 59, 59)) SESSION.add(election) # Add admin groups if there are any - for admin_grp in form.admin_grp.data.split(','): + for admin_grp in form.admin_grp.data.split(","): if admin_grp.strip(): admin = models.ElectionAdminGroup( election=election, @@ -106,7 +103,7 @@ def admin_new_election(): SESSION.add(admin) # Add legal voters groups if there are any - for voter_grp in form.lgl_voters.data.split(','): + for voter_grp in form.lgl_voters.data.split(","): if voter_grp.strip(): lglvoters = models.LegalVoter( election=election, @@ -116,28 +113,31 @@ def admin_new_election(): SESSION.commit() - fedmsgshim.publish(NewElectionV1(body=dict( - agent=flask.g.fas_user.username, - election=election.to_json(), + fedmsgshim.publish( + NewElectionV1( + body=dict( + agent=flask.g.fas_user.username, + election=election.to_json(), + ) ) - )) + ) flask.flash('Election "%s" added' % election.alias) - return flask.redirect(flask.url_for( - 'admin_view_election', election_alias=election.alias)) + return flask.redirect( + flask.url_for("admin_view_election", election_alias=election.alias) + ) return flask.render_template( - 'admin/election_form.html', - form=form, - submit_text='Create election') + "admin/election_form.html", form=form, submit_text="Create election" + ) -@APP.route('/admin//', methods=('GET', 'POST')) +@APP.route("/admin//", methods=("GET", "POST")) @election_admin_required def admin_view_election(election_alias): election = models.Election.get(SESSION, alias=election_alias) if not election: flask.abort(404) - if flask.request.method == 'GET': + if flask.request.method == "GET": form = forms.ElectionForm(election.id, obj=election) else: form = forms.ElectionForm(election.id) @@ -152,20 +152,17 @@ def admin_view_election(election_alias): else: form.max_votes.data = None - form.candidates_are_fasusers.data = int( - form.candidates_are_fasusers.data) + form.candidates_are_fasusers.data = int(form.candidates_are_fasusers.data) form.populate_obj(election) # Fix start_date and end_date to use datetime election.start_date = datetime.combine(election.start_date, time()) - election.end_date = datetime.combine(election.end_date, - time(23, 59, 59)) + election.end_date = datetime.combine(election.end_date, time(23, 59, 59)) SESSION.add(election) admin_groups = set(election.admin_groups_list) - new_groups = set( - [grp.strip() for grp in form.admin_grp.data.split(',')]) + new_groups = set([grp.strip() for grp in form.admin_grp.data.split(",")]) # Add the new admin groups for admin_grp in new_groups.difference(admin_groups): @@ -178,14 +175,15 @@ def admin_view_election(election_alias): # Remove the admin groups that were removed with this edition for admin_grp in admin_groups.difference(new_groups): admingrp = models.ElectionAdminGroup.by_election_id_and_name( - SESSION, election.id, admin_grp) + SESSION, election.id, admin_grp + ) SESSION.delete(admingrp) legal_voters = set(election.legal_voters_list) new_lgl_voters_groups = set( - [grp.strip() for grp in form.lgl_voters.data.split(',') - if grp.strip()]) + [grp.strip() for grp in form.lgl_voters.data.split(",") if grp.strip()] + ) # Add the new legal voter groups for lgl_grp in new_lgl_voters_groups.difference(legal_voters): @@ -198,30 +196,36 @@ def admin_view_election(election_alias): # Remove the legal voter groups that were removed with this edition for lgl_grp in legal_voters.difference(new_lgl_voters_groups): admingrp = models.LegalVoter.by_election_id_and_name( - SESSION, election.id, lgl_grp) + SESSION, election.id, lgl_grp + ) SESSION.delete(admingrp) SESSION.commit() - fedmsgshim.publish(EditElectionV1(body=dict( - agent=flask.g.fas_user.username, - election=election.to_json(), + fedmsgshim.publish( + EditElectionV1( + body=dict( + agent=flask.g.fas_user.username, + election=election.to_json(), + ) ) - )) + ) flask.flash('Election "%s" saved' % election.alias) - return flask.redirect(flask.url_for( - 'admin_view_election', election_alias=election.alias)) + return flask.redirect( + flask.url_for("admin_view_election", election_alias=election.alias) + ) - form.admin_grp.data = ', '.join(election.admin_groups_list) - form.lgl_voters.data = ', '.join(election.legal_voters_list) + form.admin_grp.data = ", ".join(election.admin_groups_list) + form.lgl_voters.data = ", ".join(election.legal_voters_list) return flask.render_template( - 'admin/view_election.html', + "admin/view_election.html", election=election, form=form, - submit_text='Edit election') + submit_text="Edit election", + ) -@APP.route('/admin//candidates/new', methods=('GET', 'POST')) +@APP.route("/admin//candidates/new", methods=("GET", "POST")) @election_admin_required def admin_add_candidate(election_alias): election = models.Election.get(SESSION, alias=election_alias) @@ -234,21 +238,18 @@ def admin_add_candidate(election_alias): fas_name = None if election.candidates_are_fasusers: # pragma: no cover try: - if APP.config.get('FASJSON'): - user = ACCOUNTS.get_user( - username=form.name.data).result + if APP.config.get("FASJSON"): + user = ACCOUNTS.get_user(username=form.name.data).result fas_name = f"{user['givenname']} {user['surname']}" else: - fas_name = ACCOUNTS.person_by_username( - form.name.data)['human_name'] + fas_name = ACCOUNTS.person_by_username(form.name.data)["human_name"] except (KeyError, AuthError, APIError): flask.flash( - 'User `%s` does not have a FAS account.' - % form.name.data, 'error') + "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)) + flask.url_for("admin_add_candidate", election_alias=election_alias) + ) candidate = models.Candidate( election=election, @@ -260,23 +261,25 @@ def admin_add_candidate(election_alias): SESSION.add(candidate) SESSION.commit() flask.flash('Candidate "%s" saved' % candidate.name) - fedmsgshim.publish(NewCandidateV1(body=dict( - agent=flask.g.fas_user.username, - election=candidate.election.to_json(), - candidate=candidate.to_json(), + fedmsgshim.publish( + NewCandidateV1( + body=dict( + agent=flask.g.fas_user.username, + election=candidate.election.to_json(), + candidate=candidate.to_json(), + ) ) - )) - return flask.redirect(flask.url_for( - 'admin_view_election', election_alias=election.alias)) + ) + return flask.redirect( + flask.url_for("admin_view_election", election_alias=election.alias) + ) return flask.render_template( - 'admin/candidate.html', - form=form, - submit_text='Add candidate') + "admin/candidate.html", form=form, submit_text="Add candidate" + ) -@APP.route('/admin//candidates/new/multi', - methods=('GET', 'POST')) +@APP.route("/admin//candidates/new/multi", methods=("GET", "POST")) @election_admin_required def admin_add_multi_candidate(election_alias): election = models.Election.get(SESSION, alias=election_alias) @@ -293,29 +296,29 @@ def admin_add_multi_candidate(election_alias): fas_name = None if election.candidates_are_fasusers: # pragma: no cover try: - if APP.config.get('FASJSON'): - user = ACCOUNTS.get_user( - username=candidate[0]).result + if APP.config.get("FASJSON"): + user = ACCOUNTS.get_user(username=candidate[0]).result fas_name = f"{user['givenname']} {user['surname']}" else: - fas_name = ACCOUNTS.person_by_username( - candidate[0])['human_name'] + fas_name = ACCOUNTS.person_by_username(candidate[0])[ + "human_name" + ] except (KeyError, AuthError, APIError): SESSION.rollback() flask.flash( - 'User `%s` does not have a FAS account.' - % candidate[0], 'error') + "User `%s` does not have a FAS account." % candidate[0], "error" + ) return flask.redirect( flask.url_for( - 'admin_add_candidate', - election_alias=election_alias)) + "admin_add_candidate", election_alias=election_alias + ) + ) # No url if len(candidate) == 1: cand = models.Candidate( - election=election, - name=candidate[0], - fas_name=fas_name) + election=election, name=candidate[0], fas_name=fas_name + ) SESSION.add(cand) candidates_name.append(cand.name) # With url @@ -324,32 +327,38 @@ def admin_add_multi_candidate(election_alias): election=election, name=candidate[0], url=candidate[1], - fas_name=fas_name) + fas_name=fas_name, + ) SESSION.add(cand) candidates_name.append(cand.name) else: flask.flash("There was an issue!") continue - fedmsgshim.publish(NewCandidateV1(body=dict( - agent=flask.g.fas_user.username, - election=cand.election.to_json(), - candidate=cand.to_json(), + fedmsgshim.publish( + NewCandidateV1( + body=dict( + agent=flask.g.fas_user.username, + election=cand.election.to_json(), + candidate=cand.to_json(), + ) ) - )) + ) SESSION.commit() - flask.flash('Added %s candidates' % len(candidates_name)) - return flask.redirect(flask.url_for( - 'admin_view_election', election_alias=election.alias)) + flask.flash("Added %s candidates" % len(candidates_name)) + return flask.redirect( + flask.url_for("admin_view_election", election_alias=election.alias) + ) return flask.render_template( - 'admin/candidate_multi.html', - form=form, - submit_text='Add candidates') + "admin/candidate_multi.html", form=form, submit_text="Add candidates" + ) -@APP.route('/admin//candidates//edit', - methods=('GET', 'POST')) +@APP.route( + "/admin//candidates//edit", + methods=("GET", "POST"), +) @election_admin_required def admin_edit_candidate(election_alias, candidate_id): election = models.Election.get(SESSION, alias=election_alias) @@ -367,42 +376,50 @@ def admin_edit_candidate(election_alias, candidate_id): if election.candidates_are_fasusers: # pragma: no cover try: - if APP.config.get('FASJSON'): - user = ACCOUNTS.get_user( - username=candidate.name).result + if APP.config.get("FASJSON"): + user = ACCOUNTS.get_user(username=candidate.name).result candidate.fas_name = f"{user['givenname']} {user['surname']}" else: - candidate.fas_name = ACCOUNTS.person_by_username( - candidate.name)['human_name'] + candidate.fas_name = ACCOUNTS.person_by_username(candidate.name)[ + "human_name" + ] except (KeyError, AuthError, APIError): SESSION.rollback() flask.flash( - 'User `%s` does not have a FAS account.' - % candidate.name, 'error') - return flask.redirect(flask.url_for( - 'admin_edit_candidate', - election_alias=election_alias, - candidate_id=candidate_id)) + "User `%s` does not have a FAS account." % candidate.name, "error" + ) + return flask.redirect( + flask.url_for( + "admin_edit_candidate", + election_alias=election_alias, + candidate_id=candidate_id, + ) + ) SESSION.commit() flask.flash('Candidate "%s" saved' % candidate.name) - fedmsgshim.publish(EditCandidateV1(body=dict( - agent=flask.g.fas_user.username, - election=candidate.election.to_json(), - candidate=candidate.to_json(), + fedmsgshim.publish( + EditCandidateV1( + body=dict( + agent=flask.g.fas_user.username, + election=candidate.election.to_json(), + candidate=candidate.to_json(), + ) ) - )) - return flask.redirect(flask.url_for( - 'admin_view_election', election_alias=election.alias)) + ) + return flask.redirect( + flask.url_for("admin_view_election", election_alias=election.alias) + ) return flask.render_template( - 'admin/candidate.html', - form=form, - submit_text='Edit candidate') + "admin/candidate.html", form=form, submit_text="Edit candidate" + ) -@APP.route('/admin//candidates//delete', - methods=('GET', 'POST')) +@APP.route( + "/admin//candidates//delete", + methods=("GET", "POST"), +) @election_admin_required def admin_delete_candidate(election_alias, candidate_id): election = models.Election.get(SESSION, alias=election_alias) @@ -421,24 +438,28 @@ def admin_delete_candidate(election_alias, candidate_id): SESSION.delete(candidate) SESSION.commit() flask.flash('Candidate "%s" deleted' % candidate_name) - fedmsgshim.publish(DeleteCandidateV1(body=dict( - agent=flask.g.fas_user.username, - election=candidate.election.to_json(), - candidate=candidate.to_json(), + fedmsgshim.publish( + DeleteCandidateV1( + body=dict( + agent=flask.g.fas_user.username, + election=candidate.election.to_json(), + candidate=candidate.to_json(), + ) ) - )) + ) except SQLAlchemyError as err: SESSION.rollback() - APP.logger.debug('Could not delete candidate') + APP.logger.debug("Could not delete candidate") APP.logger.exception(err) flask.flash( - 'Could not delete this candidate. Is it already part of an ' - 'election?', 'error' + "Could not delete this candidate. Is it already part of an " + "election?", + "error", ) - return flask.redirect(flask.url_for( - 'admin_view_election', election_alias=election.alias)) + return flask.redirect( + flask.url_for("admin_view_election", election_alias=election.alias) + ) return flask.render_template( - 'admin/delete_candidate.html', - form=form, - candidate=candidate) + "admin/delete_candidate.html", form=form, candidate=candidate + ) diff --git a/fedora_elections/default_config.py b/fedora_elections/default_config.py index 73b86c8..60ce759 100644 --- a/fedora_elections/default_config.py +++ b/fedora_elections/default_config.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -''' +""" Fedora elections default configuration. -''' +""" import os from datetime import timedelta from fedora_elections.mail_logging import MSG_FORMAT, ContextInjector @@ -10,35 +10,40 @@ from fedora_elections.mail_logging import MSG_FORMAT, ContextInjector # Set the time after which the session expires PERMANENT_SESSION_LIFETIME = timedelta(hours=1) -FEDORA_ELECTIONS_ADMIN_GROUP = 'elections' +FEDORA_ELECTIONS_ADMIN_GROUP = "elections" # url to the database server: -DB_URL = 'sqlite:////var/tmp/elections_dev.sqlite' +DB_URL = "sqlite:////var/tmp/elections_dev.sqlite" # You will want to change this for your install -SECRET_KEY = 'change me' +SECRET_KEY = "change me" FASJSON = False -FAS_BASE_URL = 'https://admin.stg.fedoraproject.org/accounts/' -FAS_USERNAME = '' -FAS_PASSWORD = '' +FAS_BASE_URL = "https://admin.stg.fedoraproject.org/accounts/" +FAS_USERNAME = "" +FAS_PASSWORD = "" FAS_CHECK_CERT = False -OIDC_CLIENT_SECRETS = os.path.join(os.path.dirname( - os.path.abspath(__file__)), '..', 'client_secrets.json') -OIDC_SCOPES = ['openid', 'email', 'profile', 'https://id.fedoraproject.org/scope/groups', 'https://id.fedoraproject.org/scope/agreements'] -OIDC_OPENID_REALM = 'http://localhost:5005/oidc_callback' +OIDC_CLIENT_SECRETS = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "..", "client_secrets.json" +) +OIDC_SCOPES = [ + "openid", + "email", + "profile", + "https://id.fedoraproject.org/scope/groups", + "https://id.fedoraproject.org/scope/agreements", +] +OIDC_OPENID_REALM = "http://localhost:5005/oidc_callback" LOGGING = { "version": 1, "disable_existing_loggers": False, "formatters": { - "standard": { - "format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s" - }, + "standard": {"format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s"}, "email_format": {"format": MSG_FORMAT}, }, "filters": {"myfilter": {"()": ContextInjector}}, @@ -62,10 +67,7 @@ LOGGING = { }, # The root logger configuration; this is a catch-all configuration # that applies to all log messages not handled by a different logger - "root": { - "level": "DEBUG", - "handlers": ["console"] - }, + "root": {"level": "DEBUG", "handlers": ["console"]}, "loggers": { "fedora_elections": { "handlers": ["console"], diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py index a4c98c7..80889ad 100644 --- a/fedora_elections/elections.py +++ b/fedora_elections/elections.py @@ -33,7 +33,12 @@ import flask from fedora_elections import forms from fedora_elections import models from fedora_elections import ( - OIDC, APP, SESSION, is_authenticated, is_admin, is_election_admin, + OIDC, + APP, + SESSION, + is_authenticated, + is_admin, + is_election_admin, safe_redirect_back, ) from fedora_elections.utils import build_name_map @@ -43,51 +48,51 @@ def login_required(f): @wraps(f) def decorated_function(*args, **kwargs): if not is_authenticated(): - return flask.redirect(flask.url_for( - 'auth_login', next=flask.request.url)) + return flask.redirect(flask.url_for("auth_login", next=flask.request.url)) elif not flask.g.fas_user.cla_done: - flask.flash( - 'You must sign the CLA to vote', 'error') + flask.flash("You must sign the CLA to vote", "error") return safe_redirect_back() else: - user_groups = OIDC.user_getfield('groups') + user_groups = OIDC.user_getfield("groups") if len(user_groups) == 0: flask.flash( - 'You need to be in one another group than CLA to vote', - 'error') + "You need to be in one another group than CLA to vote", "error" + ) return safe_redirect_back() return f(*args, **kwargs) + return decorated_function def get_valid_election(election_alias, ended=False): - """ Return the election if it is valid (not pending, not ended). - """ + """Return the election if it is valid (not pending, not ended).""" election = models.Election.get(SESSION, alias=election_alias) if not election: - flask.flash('The election, %s, does not exist.' % election_alias) + flask.flash("The election, %s, does not exist." % election_alias) return safe_redirect_back() - if election.status == 'Pending': - flask.flash('Voting has not yet started, sorry.') + if election.status == "Pending": + flask.flash("Voting has not yet started, sorry.") return safe_redirect_back() - elif not ended and election.status in ('Ended', 'Embargoed'): - return flask.redirect(flask.url_for( - 'about_election', election_alias=election.alias)) + elif not ended and election.status in ("Ended", "Embargoed"): + return flask.redirect( + flask.url_for("about_election", election_alias=election.alias) + ) - elif ended and election.status == 'In progress': + elif ended and election.status == "In progress": flask.flash( - 'Sorry but this election is in progress, and you may not see its ' - 'results yet.') + "Sorry but this election is in progress, and you may not see its " + "results yet." + ) return safe_redirect_back() return election -@APP.route('/vote/', methods=['GET', 'POST']) +@APP.route("/vote/", methods=["GET", "POST"]) @login_required def vote(election_alias): election = get_valid_election(election_alias) @@ -96,44 +101,49 @@ def vote(election_alias): return election if election.legal_voters_list: - user_groups = OIDC.user_getfield('groups') - if len(set(user_groups).intersection( - set(election.legal_voters_list))) == 0: + user_groups = OIDC.user_getfield("groups") + if len(set(user_groups).intersection(set(election.legal_voters_list))) == 0: flask.flash( - 'You are not among the groups that are allowed to vote ' - 'for this election', 'error') + "You are not among the groups that are allowed to vote " + "for this election", + "error", + ) return safe_redirect_back() votes = models.Vote.of_user_on_election( - SESSION, flask.g.fas_user.username, election.id, count=True) + SESSION, flask.g.fas_user.username, election.id, count=True + ) revote = True if votes > 0 else False - if election.voting_type.startswith('range'): + if election.voting_type.startswith("range"): return vote_range(election, revote) - elif election.voting_type == 'simple': + elif election.voting_type == "simple": return vote_simple(election, revote) - elif election.voting_type == 'select': + elif election.voting_type == "select": return vote_select(election, revote) - elif election.voting_type == 'irc': + elif election.voting_type == "irc": return vote_irc(election, revote) else: # pragma: no cover - flask.flash( - 'Unknown election voting type: %s' % election.voting_type) + flask.flash("Unknown election voting type: %s" % election.voting_type) return safe_redirect_back() -@APP.route('/results//text') +@APP.route("/results//text") def election_results_text(election_alias): election = get_valid_election(election_alias, ended=True) if not isinstance(election, models.Election): # pragma: no cover return election - if not (is_authenticated() and (is_admin(flask.g.fas_user) - or is_election_admin(flask.g.fas_user, election.id))): - flask.flash( - "The text results are only available to the admins", "error") + if not ( + is_authenticated() + and ( + is_admin(flask.g.fas_user) + or is_election_admin(flask.g.fas_user, election.id) + ) + ): + flask.flash("The text results are only available to the admins", "error") return safe_redirect_back() usernamemap = build_name_map(election) @@ -141,153 +151,158 @@ def election_results_text(election_alias): stats = models.Vote.get_election_stats(SESSION, election.id) return flask.render_template( - 'results_text.html', + "results_text.html", election=election, usernamemap=usernamemap, stats=stats, candidates=sorted( - election.candidates, key=lambda x: x.vote_count, reverse=True) + election.candidates, key=lambda x: x.vote_count, reverse=True + ), ) def vote_range(election, revote): votes = models.Vote.of_user_on_election( - SESSION, flask.g.fas_user.username, election.id) + SESSION, flask.g.fas_user.username, election.id + ) num_candidates = election.candidates.count() - next_action = 'confirm' + next_action = "confirm" max_selection = num_candidates if election.max_votes: max_selection = election.max_votes form = forms.get_range_voting_form( - candidates=election.candidates, - max_range=max_selection) + candidates=election.candidates, max_range=max_selection + ) if form.validate_on_submit(): - if form.action.data == 'submit': + if form.action.data == "submit": candidates = [ candidate for candidate in form - if candidate - and candidate.short_name not in ['csrf_token', 'action'] + if candidate and candidate.short_name not in ["csrf_token", "action"] ] process_vote(candidates, election, votes, revote) say_thank_you(election) return safe_redirect_back() - if form.action.data == 'preview': + if form.action.data == "preview": flask.flash("Please confirm your vote!") - next_action = 'vote' + next_action = "vote" usernamemap = build_name_map(election) return flask.render_template( - 'vote_range.html', + "vote_range.html", election=election, form=form, num_candidates=num_candidates, max_range=max_selection, usernamemap=usernamemap, - nextaction=next_action) + nextaction=next_action, + ) def vote_select(election, revote): votes = models.Vote.of_user_on_election( - SESSION, flask.g.fas_user.username, election.id) + SESSION, flask.g.fas_user.username, election.id + ) num_candidates = election.candidates.count() cand_name = {} for candidate in election.candidates: cand_name[candidate.name] = candidate.id - next_action = 'confirm' + next_action = "confirm" max_selection = num_candidates if election.max_votes: max_selection = election.max_votes form = forms.get_select_voting_form( - candidates=election.candidates, - max_selection=max_selection) + candidates=election.candidates, max_selection=max_selection + ) if form.validate_on_submit(): cnt = [ candidate for candidate in form - if candidate.data - and candidate.short_name not in ['csrf_token', 'action'] + if candidate.data and candidate.short_name not in ["csrf_token", "action"] ] if len(cnt) > max_selection: - flask.flash('Too many candidates submitted', 'error') + flask.flash("Too many candidates submitted", "error") else: - if form.action.data == 'submit': + if form.action.data == "submit": candidates = [ candidate for candidate in form if candidate - and candidate.short_name not in ['csrf_token', 'action'] + and candidate.short_name not in ["csrf_token", "action"] ] process_vote(candidates, election, votes, revote, cand_name) say_thank_you(election) return safe_redirect_back() - if form.action.data == 'preview': + if form.action.data == "preview": flask.flash("Please confirm your vote!") - next_action = 'vote' + next_action = "vote" usernamemap = build_name_map(election) return flask.render_template( - 'vote_simple.html', + "vote_simple.html", election=election, form=form, num_candidates=num_candidates, max_selection=max_selection, usernamemap=usernamemap, - nextaction=next_action) + nextaction=next_action, + ) def vote_simple(election, revote): votes = models.Vote.of_user_on_election( - SESSION, flask.g.fas_user.username, election.id) + SESSION, flask.g.fas_user.username, election.id + ) num_candidates = election.candidates.count() - next_action = 'confirm' + next_action = "confirm" form = forms.get_simple_voting_form( - candidates=election.candidates, - fasusers=election.candidates_are_fasusers) + candidates=election.candidates, fasusers=election.candidates_are_fasusers + ) if form.validate_on_submit(): - if form.action.data == 'submit': + if form.action.data == "submit": candidates = [ candidate for candidate in form - if candidate - and candidate.short_name not in ['csrf_token', 'action'] + if candidate and candidate.short_name not in ["csrf_token", "action"] ] process_vote(candidates, election, votes, revote, value=1) say_thank_you(election) return safe_redirect_back() - if form.action.data == 'preview': + if form.action.data == "preview": flask.flash("Please confirm your vote!") - next_action = 'vote' + next_action = "vote" return flask.render_template( - 'vote_simple.html', + "vote_simple.html", election=election, form=form, num_candidates=num_candidates, - nextaction=next_action) + nextaction=next_action, + ) def vote_irc(election, revote): votes = models.Vote.of_user_on_election( - SESSION, flask.g.fas_user.username, election.id) + SESSION, flask.g.fas_user.username, election.id + ) cand_name = {} for candidate in election.candidates: @@ -295,39 +310,38 @@ def vote_irc(election, revote): num_candidates = election.candidates.count() - next_action = 'confirm' + next_action = "confirm" form = forms.get_irc_voting_form( - candidates=election.candidates, - fasusers=election.candidates_are_fasusers) + candidates=election.candidates, fasusers=election.candidates_are_fasusers + ) if form.validate_on_submit(): - if form.action.data == 'submit': + if form.action.data == "submit": candidates = [ candidate for candidate in form - if candidate - and candidate.short_name not in ['csrf_token', 'action'] + if candidate and candidate.short_name not in ["csrf_token", "action"] ] process_vote(candidates, election, votes, revote, cand_name) say_thank_you(election) return safe_redirect_back() - if form.action.data == 'preview': + if form.action.data == "preview": flask.flash("Please confirm your vote!") - next_action = 'vote' + next_action = "vote" return flask.render_template( - 'vote_simple.html', + "vote_simple.html", election=election, form=form, num_candidates=num_candidates, - nextaction=next_action) + nextaction=next_action, + ) -def process_vote( - candidates, election, votes, revote, cand_name=None, value=None): +def process_vote(candidates, election, votes, revote, cand_name=None, value=None): for index in range(len(candidates)): candidate = candidates[index] - if revote and (index+1 <= len(votes)): + if revote and (index + 1 <= len(votes)): vote = votes[index] if value is not None: vote.candidate_id = candidate.data @@ -356,6 +370,10 @@ def process_vote( def say_thank_you(election): thank_you = "Your vote has been recorded. Thank you!" if election.url_badge: - thank_you = thank_you + '
Claim your I Voted badge.' + thank_you = ( + thank_you + + '
Claim your I Voted badge.' + ) flask.flash(thank_you) diff --git a/fedora_elections/fedmsgshim.py b/fedora_elections/fedmsgshim.py index 8d8eed0..105a93b 100644 --- a/fedora_elections/fedmsgshim.py +++ b/fedora_elections/fedmsgshim.py @@ -16,13 +16,11 @@ _log = logging.getLogger(__name__) def publish(message): # pragma: no cover - _log.debug('Publishing a message for %r: %s', message.topic, message.body) + _log.debug("Publishing a message for %r: %s", message.topic, message.body) try: fedora_messaging.api.publish(message) _log.debug("Sent to fedora_messaging") except PublishReturned as e: - _log.exception( - 'Fedora Messaging broker rejected message %s: %s', - message.id, e) + _log.exception("Fedora Messaging broker rejected message %s: %s", message.id, e) except ConnectionException as e: - _log.exception('Error sending message %s: %s', message.id, e) + _log.exception("Error sending message %s: %s", message.id, e) diff --git a/fedora_elections/forms.py b/fedora_elections/forms.py index 0c927cd..0d1e87f 100644 --- a/fedora_elections/forms.py +++ b/fedora_elections/forms.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals, absolute_import import flask import wtforms + try: from flask_wtf import FlaskForm except ImportError: @@ -17,76 +18,83 @@ from fasjson_client.errors import APIError class ElectionForm(FlaskForm): shortdesc = wtforms.TextField( - 'Summary', [ - wtforms.validators.Required(), - wtforms.validators.Length(max=150)]) + "Summary", [wtforms.validators.Required(), wtforms.validators.Length(max=150)] + ) alias = wtforms.TextField( - 'Alias', [ + "Alias", + [ wtforms.validators.Required(), wtforms.validators.Length(max=100), wtforms.validators.Regexp( - '[a-z0-9_-]+', - message=('Alias may only contain lower case letters, numbers, ' - 'hyphens and underscores.')), - ]) + "[a-z0-9_-]+", + message=( + "Alias may only contain lower case letters, numbers, " + "hyphens and underscores." + ), + ), + ], + ) - description = wtforms.TextAreaField( - 'Description', [ - wtforms.validators.Required()]) + description = wtforms.TextAreaField("Description", [wtforms.validators.Required()]) voting_type = wtforms.SelectField( - 'Type', + "Type", choices=[ - ('range', 'Range Voting'), - ('simple', 'Simple Voting (choose one candidate in the list)'), - ('range_simple', 'Simplified Range Voting (max is set below)'), - ('select', 'Select Voting (checkboxes for each candidate, ' - 'maximum number of votes set below)'), - ('irc', '+1/0/-1 voting'), + ("range", "Range Voting"), + ("simple", "Simple Voting (choose one candidate in the list)"), + ("range_simple", "Simplified Range Voting (max is set below)"), + ( + "select", + "Select Voting (checkboxes for each candidate, " + "maximum number of votes set below)", + ), + ("irc", "+1/0/-1 voting"), ], - default='range') + default="range", + ) max_votes = wtforms.TextField( - 'Maximum Range/Votes', - [wtforms.validators.optional()]) + "Maximum Range/Votes", [wtforms.validators.optional()] + ) url = wtforms.TextField( - 'URL', [ + "URL", + [ wtforms.validators.Required(), wtforms.validators.URL(), - wtforms.validators.Length(max=250)]) + wtforms.validators.Length(max=250), + ], + ) - start_date = wtforms.DateField( - 'Start date', [ - wtforms.validators.Required()]) + start_date = wtforms.DateField("Start date", [wtforms.validators.Required()]) - end_date = wtforms.DateField( - 'End date', [ - wtforms.validators.Required()]) + end_date = wtforms.DateField("End date", [wtforms.validators.Required()]) seats_elected = wtforms.IntegerField( - 'Number elected', [ - wtforms.validators.Required(), - wtforms.validators.NumberRange(min=1)], - default=1) + "Number elected", + [wtforms.validators.Required(), wtforms.validators.NumberRange(min=1)], + default=1, + ) - candidates_are_fasusers = wtforms.BooleanField( - 'Candidates are FAS users?') + candidates_are_fasusers = wtforms.BooleanField("Candidates are FAS users?") - embargoed = wtforms.BooleanField('Embargo results?', default=True) + embargoed = wtforms.BooleanField("Embargo results?", default=True) url_badge = wtforms.TextField( - 'Badge URL (optional)', [ + "Badge URL (optional)", + [ wtforms.validators.Optional(), wtforms.validators.URL(), - wtforms.validators.Length(max=250)]) + wtforms.validators.Length(max=250), + ], + ) lgl_voters = wtforms.TextField( - 'Legal voters groups', [wtforms.validators.optional()]) + "Legal voters groups", [wtforms.validators.optional()] + ) - admin_grp = wtforms.TextField( - 'Admin groups', [wtforms.validators.optional()]) + admin_grp = wtforms.TextField("Admin groups", [wtforms.validators.optional()]) def __init__(form, election_id=None, *args, **kwargs): super(ElectionForm, form).__init__(*args, **kwargs) @@ -97,32 +105,33 @@ class ElectionForm(FlaskForm): if check: if not (form._election_id and form._election_id == check[0].id): raise wtforms.ValidationError( - 'There is already another election with this summary.') + "There is already another election with this summary." + ) def validate_alias(form, field): - if form.alias.data == 'new': - raise wtforms.ValidationError(flask.Markup( - 'The alias cannot be new.')) + if form.alias.data == "new": + raise wtforms.ValidationError( + flask.Markup("The alias cannot be new.") + ) check = Election.search(SESSION, alias=form.alias.data) if check: if not (form._election_id and form._election_id == check[0].id): raise wtforms.ValidationError( - 'There is already another election with this alias.') + "There is already another election with this alias." + ) def validate_end_date(form, field): if form.end_date.data <= form.start_date.data: - raise wtforms.ValidationError( - 'End date must be later than start date.') + raise wtforms.ValidationError("End date must be later than start date.") class CandidateForm(FlaskForm): - name = wtforms.TextField('Name', [wtforms.validators.Required()]) - url = wtforms.TextField('URL', [wtforms.validators.Length(max=250)]) + name = wtforms.TextField("Name", [wtforms.validators.Required()]) + url = wtforms.TextField("URL", [wtforms.validators.Length(max=250)]) class MultiCandidateForm(FlaskForm): - candidate = wtforms.TextField( - 'Candidates', [wtforms.validators.Required()]) + candidate = wtforms.TextField("Candidates", [wtforms.validators.Required()]) class ConfirmationForm(FlaskForm): @@ -136,10 +145,12 @@ def get_range_voting_form(candidates, max_range): for candidate in candidates: title = candidate.fas_name or candidate.name if candidate.url: - title = '%s [Info]' % (title, candidate.url) + title = ( + '%s [Info]' + % (title, candidate.url) + ) field = wtforms.SelectField( - title, - choices=[(str(item), item) for item in range(max_range + 1)] + title, choices=[(str(item), item) for item in range(max_range + 1)] ) setattr(RangeVoting, str(candidate.id), field) @@ -156,23 +167,21 @@ def get_simple_voting_form(candidates, fasusers): if fasusers: # pragma: no cover # We can't cover FAS integration try: - if APP.config.get('FASJSON'): - user = ACCOUNTS.get_user( - username=candidate.name).result + if APP.config.get("FASJSON"): + user = ACCOUNTS.get_user(username=candidate.name).result title = f"{user['givenname']} {user['surname']}" else: - title = ACCOUNTS.person_by_username( - candidate.name)['human_name'] + title = ACCOUNTS.person_by_username(candidate.name)["human_name"] except (KeyError, AuthError, APIError) as err: APP.logger.debug(err) if candidate.url: - title = '%s [Info]' % (title, candidate.url) + title = ( + '%s [Info]' + % (title, candidate.url) + ) titles.append((str(candidate.id), title)) - field = wtforms.RadioField( - 'Candidates', - choices=titles - ) - setattr(SimpleVoting, 'candidate', field) + field = wtforms.RadioField("Candidates", choices=titles) + setattr(SimpleVoting, "candidate", field) return SimpleVoting() @@ -183,8 +192,7 @@ def get_irc_voting_form(candidates, fasusers): for candidate in candidates: field = wtforms.SelectField( - candidate.name, - choices=[('0', 0), ('1', 1), ('-1', -1)] + candidate.name, choices=[("0", 0), ("1", 1), ("-1", -1)] ) setattr(IrcVoting, candidate.name, field) @@ -198,7 +206,10 @@ def get_select_voting_form(candidates, max_selection): for candidate in candidates: title = candidate.fas_name or candidate.name if candidate.url: - title = '%s [Info]' % (title, candidate.url) + title = ( + '%s [Info]' + % (title, candidate.url) + ) field = wtforms.BooleanField( title, ) diff --git a/fedora_elections/mail_logging.py b/fedora_elections/mail_logging.py index c990b0e..b1fdac1 100644 --- a/fedora_elections/mail_logging.py +++ b/fedora_elections/mail_logging.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" Mail handler for logging. -''' +""" from __future__ import unicode_literals, absolute_import import logging @@ -43,7 +43,7 @@ except (OSError, ImportError): class ContextInjector(logging.Filter): - """ Logging filter that adds context to log records. + """Logging filter that adds context to log records. Filters are typically used to "filter" log records. They declare a filter method that can return True or False. Only records with 'True' will @@ -72,7 +72,7 @@ class ContextInjector(logging.Filter): record.host = current_hostname record.proc = current_process - record.pid = '-' + record.pid = "-" if not isinstance(current_process, str): record.pid = current_process.pid record.proc_name = current_process.name @@ -83,9 +83,9 @@ class ContextInjector(logging.Filter): @staticmethod def format_callstack(): for i, frame in enumerate(f[0] for f in inspect.stack()): - if '__name__' not in frame.f_globals: + if "__name__" not in frame.f_globals: continue - modname = frame.f_globals['__name__'].split('.')[0] + modname = frame.f_globals["__name__"].split(".")[0] if modname != "logging": break @@ -137,13 +137,10 @@ Callstack that lead to the logging statement def get_mail_handler(smtp_server, mail_admin): - """ Set up the handler sending emails for big exception - """ + """Set up the handler sending emails for big exception""" mail_handler = logging.handlers.SMTPHandler( - smtp_server, - 'nobody@fedoraproject.org', - mail_admin, - 'elections error') + smtp_server, "nobody@fedoraproject.org", mail_admin, "elections error" + ) mail_handler.setFormatter(logging.Formatter(MSG_FORMAT)) mail_handler.setLevel(logging.ERROR) mail_handler.addFilter(ContextInjector()) diff --git a/fedora_elections/models.py b/fedora_elections/models.py index 703cc3d..0c933b2 100644 --- a/fedora_elections/models.py +++ b/fedora_elections/models.py @@ -16,7 +16,7 @@ BASE = declarative_base() def create_tables(db_url, alembic_ini=None, debug=False): - """ Create the tables in the database using the information from the + """Create the tables in the database using the information from the url obtained. :arg db_url, URL used to connect to the database. The URL contains @@ -33,13 +33,14 @@ def create_tables(db_url, alembic_ini=None, debug=False): engine = create_engine(db_url, echo=debug) BASE.metadata.create_all(engine) # engine.execute(collection_package_create_view(driver=engine.driver)) - if db_url.startswith('sqlite:'): # pragma: no cover + if db_url.startswith("sqlite:"): # pragma: no cover # Ignore the warning about con_record # pylint: disable=W0613 def _fk_pragma_on_connect(dbapi_con, con_record): - ''' Tries to enforce referential constraints on sqlite. ''' - dbapi_con.execute('pragma foreign_keys=ON') - sa.event.listen(engine, 'connect', _fk_pragma_on_connect) + """ Tries to enforce referential constraints on sqlite. """ + dbapi_con.execute("pragma foreign_keys=ON") + + sa.event.listen(engine, "connect", _fk_pragma_on_connect) if alembic_ini is not None: # pragma: no cover # then, load the Alembic configuration and generate the @@ -49,6 +50,7 @@ def create_tables(db_url, alembic_ini=None, debug=False): # pylint: disable=F0401 from alembic.config import Config from alembic import command + alembic_cfg = Config(alembic_ini) command.stamp(alembic_cfg, "head") @@ -57,7 +59,7 @@ def create_tables(db_url, alembic_ini=None, debug=False): def create_session(db_url, debug=False, pool_recycle=3600): - """ Create the Session object to use to query the database. + """Create the Session object to use to query the database. :arg db_url: URL used to connect to the database. The URL contains information with regards to the database engine, the host to connect @@ -68,14 +70,13 @@ def create_session(db_url, debug=False, pool_recycle=3600): :return a Session that can be used to query the database. """ - engine = sa.create_engine( - db_url, echo=debug, pool_recycle=pool_recycle) + engine = sa.create_engine(db_url, echo=debug, pool_recycle=pool_recycle) scopedsession = scoped_session(sessionmaker(bind=engine)) return scopedsession class Election(BASE): - __tablename__ = 'elections' + __tablename__ = "elections" id = sa.Column(sa.Integer, primary_key=True) shortdesc = sa.Column(sa.Unicode(150), unique=True, nullable=False) @@ -86,22 +87,21 @@ class Election(BASE): end_date = sa.Column(sa.DateTime, nullable=False) seats_elected = sa.Column(sa.Integer, nullable=False, default=1) embargoed = sa.Column(sa.Integer, nullable=False, default=0) - voting_type = sa.Column(sa.Unicode(100), nullable=False, default=u'range') + voting_type = sa.Column(sa.Unicode(100), nullable=False, default="range") url_badge = sa.Column(sa.Unicode(250), nullable=True) max_votes = sa.Column(sa.Integer, nullable=True) - candidates_are_fasusers = sa.Column( - sa.Integer, nullable=False, default=0) + candidates_are_fasusers = sa.Column(sa.Integer, nullable=False, default=0) fas_user = sa.Column(sa.Unicode(50), nullable=False) def to_json(self): - ''' Return a json representation of this object. ''' + """ Return a json representation of this object. """ return dict( shortdesc=self.shortdesc, alias=self.alias, description=self.description, url=self.url, - start_date=self.start_date.strftime('%Y-%m-%d %H:%M'), - end_date=self.end_date.strftime('%Y-%m-%d %H:%M'), + start_date=self.start_date.strftime("%Y-%m-%d %H:%M"), + end_date=self.end_date.strftime("%Y-%m-%d %H:%M"), embargoed=self.embargoed, voting_type=self.voting_type, ) @@ -118,25 +118,23 @@ class Election(BASE): def status(self): now = datetime.utcnow() if now.date() < self.start_date.date(): - return 'Pending' + return "Pending" else: if now.date() <= self.end_date.date(): - return 'In progress' + return "In progress" else: if self.embargoed: - return 'Embargoed' + return "Embargoed" else: - return 'Ended' + return "Ended" @property def locked(self): return datetime.utcnow() >= self.start_date @classmethod - def search(cls, session, alias=None, shortdesc=None, - fas_user=None): - """ Search the election and filter based on the arguments passed. - """ + def search(cls, session, alias=None, shortdesc=None, fas_user=None): + """Search the election and filter based on the arguments passed.""" query = session.query(cls) if alias is not None: @@ -161,110 +159,94 @@ class Election(BASE): @classmethod def get_older_election(cls, session, limit): - """ Return all the election which end_date if older than the + """Return all the election which end_date if older than the provided limit. """ - query = session.query( - cls - ).filter( - cls.end_date < limit - ).order_by( - sa.desc(cls.start_date) + query = ( + session.query(cls) + .filter(cls.end_date < limit) + .order_by(sa.desc(cls.start_date)) ) return query.all() @classmethod def get_open_election(cls, session, limit): - """ Return all the election which start_date is lower and the + """Return all the election which start_date is lower and the end_date if greater or equal to the provided limit. """ - query = session.query( - cls - ).filter( - cls.start_date < limit - ).filter( - cls.end_date >= limit - ).order_by( - sa.desc(cls.start_date) + query = ( + session.query(cls) + .filter(cls.start_date < limit) + .filter(cls.end_date >= limit) + .order_by(sa.desc(cls.start_date)) ) return query.all() @classmethod def get_next_election(cls, session, limit): - """ Return all the future elections whose start_date is greater than + """Return all the future elections whose start_date is greater than the provided limit. """ - query = session.query( - cls - ).filter( - cls.start_date > limit - ).order_by( - sa.desc(cls.start_date) + query = ( + session.query(cls) + .filter(cls.start_date > limit) + .order_by(sa.desc(cls.start_date)) ) return query.all() class ElectionAdminGroup(BASE): - __tablename__ = 'electionadmins' + __tablename__ = "electionadmins" id = sa.Column(sa.Integer, primary_key=True) election_id = sa.Column( sa.Integer, - sa.ForeignKey('elections.id', ondelete='CASCADE', onupdate='CASCADE'), - nullable=False) + sa.ForeignKey("elections.id", ondelete="CASCADE", onupdate="CASCADE"), + nullable=False, + ) group_name = sa.Column(sa.Unicode(150), nullable=False) - election = relationship( - 'Election', backref=backref('admin_groups', lazy='dynamic')) + election = relationship("Election", backref=backref("admin_groups", lazy="dynamic")) @classmethod def by_election_id(cls, session, election_id): - """ Return all the ElectionAdminGroup having a specific election_id. - """ - return session.query( - cls - ).filter( - cls.election_id == election_id - ).all() + """Return all the ElectionAdminGroup having a specific election_id.""" + return session.query(cls).filter(cls.election_id == election_id).all() @classmethod def by_election_id_and_name(cls, session, election_id, group_name): - """ Return the ElectionAdminGroup having a specific election_id + """Return the ElectionAdminGroup having a specific election_id and group_name. """ - return session.query( - cls - ).filter( - cls.election_id == election_id - ).filter( - cls.group_name == group_name - ).first() + return ( + session.query(cls) + .filter(cls.election_id == election_id) + .filter(cls.group_name == group_name) + .first() + ) class Candidate(BASE): - __tablename__ = 'candidates' + __tablename__ = "candidates" id = sa.Column(sa.Integer, primary_key=True) election_id = sa.Column( sa.Integer, - sa.ForeignKey( - 'elections.id', - ondelete='RESTRICT', - onupdate='CASCADE'), - nullable=False) + sa.ForeignKey("elections.id", ondelete="RESTRICT", onupdate="CASCADE"), + nullable=False, + ) # FAS username if candidates_are_fasusers name = sa.Column(sa.Unicode(150), nullable=False) fas_name = sa.Column(sa.Unicode(150), nullable=True) url = sa.Column(sa.Unicode(250)) - election = relationship( - 'Election', backref=backref('candidates', lazy='dynamic')) + election = relationship("Election", backref=backref("candidates", lazy="dynamic")) def to_json(self): - ''' Return a json representation of this object. ''' + """ Return a json representation of this object. """ return dict( name=self.name, fas_name=self.fas_name, @@ -285,74 +267,68 @@ class Candidate(BASE): class LegalVoter(BASE): - __tablename__ = 'legalvoters' + __tablename__ = "legalvoters" id = sa.Column(sa.Integer, primary_key=True) election_id = sa.Column( sa.Integer, - sa.ForeignKey('elections.id', ondelete='RESTRICT', onupdate='CASCADE'), - nullable=False) + sa.ForeignKey("elections.id", ondelete="RESTRICT", onupdate="CASCADE"), + nullable=False, + ) group_name = sa.Column(sa.Unicode(150), nullable=False) - election = relationship( - 'Election', backref=backref('legal_voters', lazy='dynamic')) + election = relationship("Election", backref=backref("legal_voters", lazy="dynamic")) # special names: # "cla + one" = cla_done + 1 non-cla group @classmethod def by_election_id_and_name(cls, session, election_id, group_name): - """ Return the ElectionAdminGroup having a specific election_id + """Return the ElectionAdminGroup having a specific election_id and group_name. """ - return session.query( - cls - ).filter( - cls.election_id == election_id - ).filter( - cls.group_name == group_name - ).first() + return ( + session.query(cls) + .filter(cls.election_id == election_id) + .filter(cls.group_name == group_name) + .first() + ) class Vote(BASE): - __tablename__ = 'votes' + __tablename__ = "votes" - __table_args__ = (sa.UniqueConstraint('election_id', 'voter', - 'candidate_id', - name='eid_voter_cid'), {}) + __table_args__ = ( + sa.UniqueConstraint( + "election_id", "voter", "candidate_id", name="eid_voter_cid" + ), + {}, + ) id = sa.Column(sa.Integer, primary_key=True) - election_id = sa.Column(sa.Integer, sa.ForeignKey('elections.id'), - nullable=False) + election_id = sa.Column(sa.Integer, sa.ForeignKey("elections.id"), nullable=False) voter = sa.Column(sa.Unicode(150), nullable=False) timestamp = sa.Column(sa.DateTime, nullable=False, default=safunc.now()) candidate_id = sa.Column( sa.Integer, - sa.ForeignKey( - 'candidates.id', - ondelete='RESTRICT', - onupdate='CASCADE'), - nullable=False) + sa.ForeignKey("candidates.id", ondelete="RESTRICT", onupdate="CASCADE"), + nullable=False, + ) value = sa.Column(sa.Integer, nullable=False) - election = relationship( - 'Election', backref=backref('votes', lazy='dynamic')) - candidate = relationship( - 'Candidate', backref=backref('votes', lazy='dynamic')) + election = relationship("Election", backref=backref("votes", lazy="dynamic")) + candidate = relationship("Candidate", backref=backref("votes", lazy="dynamic")) @classmethod def of_user_on_election(cls, session, user, election_id, count=False): - """ Return the votes of a user on a specific election. + """Return the votes of a user on a specific election. If count if True, then return the number of votes instead of the actual votes. """ - query = session.query( - cls - ).filter( - cls.election_id == election_id - ).filter( - cls.voter == user - ).order_by( - cls.candidate_id + query = ( + session.query(cls) + .filter(cls.election_id == election_id) + .filter(cls.voter == user) + .order_by(cls.candidate_id) ) if count: @@ -362,7 +338,7 @@ class Vote(BASE): @classmethod def get_election_stats(cls, session, election_id): - """ Return a dictionnary containing some statistics about the + """Return a dictionnary containing some statistics about the specified elections. (Number of voters, number of votes per candidates, total number of votes) @@ -370,83 +346,76 @@ class Vote(BASE): stats = {} - n_voters = session.query( - sa.func.distinct(cls.voter) - ).filter( - cls.election_id == election_id - ).count() - stats['n_voters'] = n_voters - - n_votes = session.query( - cls - ).filter( - cls.election_id == election_id - ).filter( - cls.value > 0 - ).count() - stats['n_votes'] = n_votes - - election = session.query( - Election - ).filter( - Election.id == election_id - ).first() + n_voters = ( + session.query(sa.func.distinct(cls.voter)) + .filter(cls.election_id == election_id) + .count() + ) + stats["n_voters"] = n_voters + + n_votes = ( + session.query(cls) + .filter(cls.election_id == election_id) + .filter(cls.value > 0) + .count() + ) + stats["n_votes"] = n_votes + + election = session.query(Election).filter(Election.id == election_id).first() candidate_voters = {} cnt = 0 for cand in election.candidates: cnt += 1 - n_voters = session.query( - sa.func.distinct(cls.voter) - ).filter( - cls.election_id == election_id - ).filter( - cls.candidate_id == cand.id - ).filter( - cls.value > 0 - ).count() + n_voters = ( + session.query(sa.func.distinct(cls.voter)) + .filter(cls.election_id == election_id) + .filter(cls.candidate_id == cand.id) + .filter(cls.value > 0) + .count() + ) candidate_voters[cand.name] = n_voters - stats['candidate_voters'] = candidate_voters - stats['n_candidates'] = cnt + stats["candidate_voters"] = candidate_voters + stats["n_candidates"] = cnt - stats['max_vote'] = 1 - if election.voting_type == 'select' \ - or election.voting_type.startswith('range'): - stats['max_vote'] = cnt + stats["max_vote"] = 1 + if election.voting_type == "select" or election.voting_type.startswith("range"): + stats["max_vote"] = cnt if election.max_votes: - stats['max_vote'] = election.max_votes - - dates = election = session.query( - Vote.timestamp - ).filter( - Vote.election_id == election_id - ).group_by( - Vote.voter, - Vote.timestamp - ).all() - - stats['vote_timestamps'] = [ - date[0].strftime('%d-%m-%Y') - for date in dates - ] + stats["max_vote"] = election.max_votes + + dates = election = ( + session.query(Vote.timestamp) + .filter(Vote.election_id == election_id) + .group_by(Vote.voter, Vote.timestamp) + .all() + ) + + stats["vote_timestamps"] = [date[0].strftime("%d-%m-%Y") for date in dates] return stats def get_groups(session): - """ Return the list of groups of interest. + """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()] + 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 diff --git a/fedora_elections/proxy.py b/fedora_elections/proxy.py index e53890f..1261793 100644 --- a/fedora_elections/proxy.py +++ b/fedora_elections/proxy.py @@ -19,17 +19,17 @@ # of Red Hat, Inc. # -''' +""" Makes elections an application behind a reverse proxy and thus ensure the redirects are using ``https``. Source: http://flask.pocoo.org/snippets/35/ by Peter Hansen -''' +""" from __future__ import unicode_literals, absolute_import class ReverseProxied(object): - '''Wrap the application in this middleware and configure the + """Wrap the application in this middleware and configure the front-end server to add these headers, to let you quietly bind this to a URL other than / and to an HTTP scheme that is different than what is used locally. @@ -44,23 +44,24 @@ class ReverseProxied(object): } :param app: the WSGI application - ''' + """ + def __init__(self, app): self.app = app def __call__(self, environ, start_response): - script_name = environ.get('HTTP_X_SCRIPT_NAME', '') + script_name = environ.get("HTTP_X_SCRIPT_NAME", "") if script_name: - environ['SCRIPT_NAME'] = script_name - path_info = environ['PATH_INFO'] + environ["SCRIPT_NAME"] = script_name + path_info = environ["PATH_INFO"] if path_info.startswith(script_name): - environ['PATH_INFO'] = path_info[len(script_name):] + environ["PATH_INFO"] = path_info[len(script_name) :] - server = environ.get('HTTP_X_FORWARDED_HOST', '') + server = environ.get("HTTP_X_FORWARDED_HOST", "") if server: - environ['HTTP_HOST'] = server + environ["HTTP_HOST"] = server - scheme = environ.get('HTTP_X_SCHEME', '') + scheme = environ.get("HTTP_X_SCHEME", "") if scheme: - environ['wsgi.url_scheme'] = scheme + environ["wsgi.url_scheme"] = scheme return self.app(environ, start_response) diff --git a/fedora_elections/utils.py b/fedora_elections/utils.py index 0d50999..4af36c0 100644 --- a/fedora_elections/utils.py +++ b/fedora_elections/utils.py @@ -7,7 +7,9 @@ def build_name_map(election): if not election.candidates_are_fasusers: return {} - return dict([ - (str(candidate.id), candidate.fas_name or candidate.name) - for candidate in election.candidates - ]) + return dict( + [ + (str(candidate.id), candidate.fas_name or candidate.name) + for candidate in election.candidates + ] + ) diff --git a/runserver.py b/runserver.py index 54cbbea..1ca04d6 100644 --- a/runserver.py +++ b/runserver.py @@ -1,7 +1,7 @@ #!/usr/bin/env python2 # These two lines are needed to run on EL6 -__requires__ = ['SQLAlchemy >= 0.8', 'jinja2 >= 2.4'] +__requires__ = ["SQLAlchemy >= 0.8", "jinja2 >= 2.4"] import pkg_resources import argparse @@ -9,32 +9,42 @@ import sys import os -parser = argparse.ArgumentParser( - description='Run the Fedora election app') +parser = argparse.ArgumentParser(description="Run the Fedora election app") parser.add_argument( - '--config', '-c', dest='config', - help='Configuration file to use for packages.') + "--config", "-c", dest="config", help="Configuration file to use for packages." +) parser.add_argument( - '--debug', dest='debug', action='store_true', + "--debug", + dest="debug", + action="store_true", default=False, - help='Expand the level of data returned.') + help="Expand the level of data returned.", +) parser.add_argument( - '--profile', dest='profile', action='store_true', + "--profile", + dest="profile", + action="store_true", default=False, - help='Profile the application.') + help="Profile the application.", +) parser.add_argument( - '--port', '-p', default=5005, - help='Port for the flask application.') + "--port", "-p", default=5005, help="Port for the flask application." +) parser.add_argument( - '--cert', '-s', default=None, - help='Filename of SSL cert for the flask application.') + "--cert", "-s", default=None, help="Filename of SSL cert for the flask application." +) parser.add_argument( - '--key', '-k', default=None, - help='Filename of the SSL key for the flask application.') + "--key", + "-k", + default=None, + help="Filename of the SSL key for the flask application.", +) parser.add_argument( - '--host', default="127.0.0.1", - help='Hostname to listen on. When set to 0.0.0.0 the server is available \ - externally. Defaults to 127.0.0.1 making the it only visable on localhost') + "--host", + default="127.0.0.1", + help="Hostname to listen on. When set to 0.0.0.0 the server is available \ + externally. Defaults to 127.0.0.1 making the it only visable on localhost", +) args = parser.parse_args() @@ -42,15 +52,16 @@ from fedora_elections import APP if args.profile: from werkzeug.contrib.profiler import ProfilerMiddleware - APP.config['PROFILE'] = True + + APP.config["PROFILE"] = True APP.wsgi_app = ProfilerMiddleware(APP.wsgi_app, restrictions=[30]) if args.config: config = args.config - if not config.startswith('/'): + if not config.startswith("/"): here = os.path.join(os.path.dirname(os.path.abspath(__file__))) config = os.path.join(here, config) - os.environ['FEDORA_ELECTIONS_CONFIG'] = config + os.environ["FEDORA_ELECTIONS_CONFIG"] = config APP.debug = True if args.cert and args.key: diff --git a/setup.py b/setup.py index c9e8a12..bc93f0c 100644 --- a/setup.py +++ b/setup.py @@ -8,27 +8,33 @@ import os import re from setuptools import setup -versionfile = os.path.join( - os.path.dirname(__file__), 'fedora_elections', '__init__.py') +versionfile = os.path.join(os.path.dirname(__file__), "fedora_elections", "__init__.py") # Thanks to SQLAlchemy: # https://github.com/zzzeek/sqlalchemy/blob/master/setup.py#L104 with open(versionfile) as stream: - __version__ = re.compile( - r".*__version__ = '(.*?)'", re.S - ).match(stream.read()).group(1) + __version__ = ( + re.compile(r".*__version__ = \"(.*?)\"", re.S).match(stream.read()).group(1) + ) setup( - name='fedora-elections', + name="fedora-elections", version=__version__, - author='Frank Chiulli', - author_email='fchiulli@fedoraproject.org', - packages=['fedora_elections'], + author="Frank Chiulli", + author_email="fchiulli@fedoraproject.org", + packages=["fedora_elections"], include_package_data=True, install_requires=[ - 'Flask', 'SQLAlchemy>=0.7', 'python-fedora', 'kitchen', - 'python-openid', 'python-openid-teams', 'python-openid-cla', - 'Flask-wtf', 'wtforms', 'fedora-elections-messages', + "Flask", + "SQLAlchemy>=0.7", + "python-fedora", + "kitchen", + "python-openid", + "python-openid-teams", + "python-openid-cla", + "Flask-wtf", + "wtforms", + "fedora-elections-messages", ], test_suite="tests", ) diff --git a/tests/__init__.py b/tests/__init__.py index 49b1449..5e8d93e 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -22,7 +22,7 @@ """ from __future__ import print_function -__requires__ = ['SQLAlchemy >= 0.7'] +__requires__ = ["SQLAlchemy >= 0.7"] import pkg_resources import logging @@ -40,8 +40,7 @@ from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import scoped_session -sys.path.insert(0, os.path.join(os.path.dirname( - os.path.abspath(__file__)), '..')) +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) import fedora_elections import fedora_elections.admin @@ -50,16 +49,17 @@ import fedora_elections.forms from fedora_elections import models -DB_PATH = 'sqlite:///:memory:' -FAITOUT_URL = 'http://faitout.fedorainfracloud.org/' +DB_PATH = "sqlite:///:memory:" +FAITOUT_URL = "http://faitout.fedorainfracloud.org/" -if os.environ.get('BUILD_ID'): +if os.environ.get("BUILD_ID"): try: import requests - req = requests.get('%s/new' % FAITOUT_URL) + + req = requests.get("%s/new" % FAITOUT_URL) if req.status_code == 200: DB_PATH = req.text - print('Using faitout at: %s' % DB_PATH) + print("Using faitout at: %s" % DB_PATH) except: pass @@ -75,6 +75,7 @@ def user_set(APP, user, oidc_id_token=None): # flask.ext.fas_openid.FAS which otherwise kills our effort to set a # flask.g.fas_user. from flask import appcontext_pushed, g + APP.before_request_funcs[None] = [] def handler(sender, **kwargs): @@ -88,7 +89,7 @@ def user_set(APP, user, oidc_id_token=None): class Modeltests(unittest.TestCase): """ Model tests. """ - def __init__(self, method_name='runTest'): + def __init__(self, method_name="runTest"): """ Constructor. """ unittest.TestCase.__init__(self, method_name) self.session = None @@ -104,22 +105,23 @@ class Modeltests(unittest.TestCase): self.session.close() if os.path.exists(DB_PATH): os.unlink(DB_PATH) - if DB_PATH.startswith('postgres'): - if 'localhost' in DB_PATH: + if DB_PATH.startswith("postgres"): + if "localhost" in DB_PATH: models.drop_tables(DB_PATH, self.session.bind) else: - db_name = DB_PATH.rsplit('/', 1)[1] - requests.get('%s/clean/%s' % (FAITOUT_URL, db_name)) + db_name = DB_PATH.rsplit("/", 1)[1] + requests.get("%s/clean/%s" % (FAITOUT_URL, db_name)) class ModelFlasktests(Modeltests): """ Model flask application tests. """ def setup_db(self): - """ Add a calendar and some meetings so that we can play with - something. """ + """Add a calendar and some meetings so that we can play with + something.""" from tests.test_vote import Votetests - votes = Votetests('test_init_vote') + + votes = Votetests("test_init_vote") votes.session = self.session votes.test_init_vote() @@ -127,9 +129,8 @@ class ModelFlasktests(Modeltests): """ Set up the environnment, ran before every tests. """ super(ModelFlasktests, self).setUp() - fedora_elections.APP.config['TESTING'] = True - fedora_elections.APP.config[ - 'FEDORA_ELECTIONS_ADMIN_GROUP'] = 'elections' + fedora_elections.APP.config["TESTING"] = True + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"] = "elections" fedora_elections.APP.debug = True fedora_elections.APP.logger.handlers = [] fedora_elections.APP.logger.setLevel(logging.CRITICAL) @@ -144,7 +145,8 @@ class ModelFlasktests(Modeltests): def get_wtforms_version(self): """Returns the wtforms version as a tuple.""" import wtforms - wtforms_v = wtforms.__version__.split('.') + + wtforms_v = wtforms.__version__.split(".") for idx, val in enumerate(wtforms_v): try: val = int(val) @@ -153,35 +155,38 @@ class ModelFlasktests(Modeltests): wtforms_v[idx] = val return tuple(wtforms_v) - def get_csrf(self, url='/admin/new', output=None): + def get_csrf(self, url="/admin/new", output=None): """Retrieve a CSRF token from given URL.""" if output is None: output = self.app.get(url) self.assertEqual(output.status_code, 200) - return output.get_data(as_text=True).split( - 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + return ( + output.get_data(as_text=True) + .split('name="csrf_token" type="hidden" value="')[1] + .split('">')[0] + ) class FakeGroup(object): - """ Fake object used to make the FakeUser object closer to the + """Fake object used to make the FakeUser object closer to the expectations. """ def __init__(self, name): - """ Constructor. + """Constructor. :arg name: the name given to the name attribute of this object. """ self.name = name - self.group_type = 'cla' + self.group_type = "cla" # pylint: disable=R0903 class FakeUser(object): """ Fake user used to test the fedocallib library. """ - def __init__(self, groups=[], username='username', cla_done=True): - """ Constructor. + def __init__(self, groups=[], username="username", cla_done=True): + """Constructor. :arg groups: list of the groups in which this fake user is supposed to be. """ @@ -190,11 +195,9 @@ class FakeUser(object): self.groups = groups self.username = username self.name = username - self.approved_memberships = [ - FakeGroup('packager'), - FakeGroup('design-team')] + self.approved_memberships = [FakeGroup("packager"), FakeGroup("design-team")] self.dic = {} - self.dic['timezone'] = 'Europe/Paris' + self.dic["timezone"] = "Europe/Paris" self.cla_done = cla_done self.email = "test@example.com" @@ -202,6 +205,6 @@ class FakeUser(object): return self.dic[key] -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(Modeltests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/tests/test_candidate.py b/tests/test_candidate.py index 1b07da5..a5a6363 100644 --- a/tests/test_candidate.py +++ b/tests/test_candidate.py @@ -20,7 +20,7 @@ fedora_elections.model.Candidate test script """ -__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4'] +__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] import pkg_resources import unittest @@ -30,8 +30,7 @@ import os from datetime import time from datetime import timedelta -sys.path.insert(0, os.path.join(os.path.dirname( - os.path.abspath(__file__)), '..')) +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) from fedora_elections import models from tests import Modeltests, TODAY @@ -46,7 +45,7 @@ class Candidatetests(Modeltests): def test_init_candidate(self): """ Test the Candidate init function. """ - elections = Electiontests('test_init_election') + elections = Electiontests("test_init_election") elections.session = self.session elections.test_init_election() @@ -56,8 +55,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:1 election_id=1, - name='Toshio', - url='https://fedoraproject.org/wiki/User:Toshio', + name="Toshio", + url="https://fedoraproject.org/wiki/User:Toshio", ) self.session.add(obj) self.session.commit() @@ -65,8 +64,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:2 election_id=1, - name='Kevin', - url='https://fedoraproject.org/wiki/User:Kevin', + name="Kevin", + url="https://fedoraproject.org/wiki/User:Kevin", ) self.session.add(obj) self.session.commit() @@ -74,8 +73,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:3 election_id=1, - name='Ralph', - url='https://fedoraproject.org/wiki/User:Ralph', + name="Ralph", + url="https://fedoraproject.org/wiki/User:Ralph", ) self.session.add(obj) self.session.commit() @@ -87,8 +86,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:4 election_id=3, - name='Toshio', - url='https://fedoraproject.org/wiki/User:Toshio', + name="Toshio", + url="https://fedoraproject.org/wiki/User:Toshio", ) self.session.add(obj) self.session.commit() @@ -96,8 +95,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:5 election_id=3, - name='Kevin', - url='https://fedoraproject.org/wiki/User:Kevin', + name="Kevin", + url="https://fedoraproject.org/wiki/User:Kevin", ) self.session.add(obj) self.session.commit() @@ -105,8 +104,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:6 election_id=3, - name='Ralph', - url='https://fedoraproject.org/wiki/User:Ralph', + name="Ralph", + url="https://fedoraproject.org/wiki/User:Ralph", ) self.session.add(obj) self.session.commit() @@ -118,8 +117,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:7 election_id=5, - name='Toshio', - url='https://fedoraproject.org/wiki/User:Toshio', + name="Toshio", + url="https://fedoraproject.org/wiki/User:Toshio", ) self.session.add(obj) self.session.commit() @@ -127,8 +126,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:8 election_id=5, - name='Kevin', - url='https://fedoraproject.org/wiki/User:Kevin', + name="Kevin", + url="https://fedoraproject.org/wiki/User:Kevin", ) self.session.add(obj) self.session.commit() @@ -136,8 +135,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:9 election_id=5, - name='Ralph', - url='https://fedoraproject.org/wiki/User:Ralph', + name="Ralph", + url="https://fedoraproject.org/wiki/User:Ralph", ) self.session.add(obj) self.session.commit() @@ -149,8 +148,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:10 election_id=4, - name='Toshio', - url='https://fedoraproject.org/wiki/User:Toshio', + name="Toshio", + url="https://fedoraproject.org/wiki/User:Toshio", ) self.session.add(obj) self.session.commit() @@ -158,8 +157,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:11 election_id=4, - name='Kevin', - url='https://fedoraproject.org/wiki/User:Kevin', + name="Kevin", + url="https://fedoraproject.org/wiki/User:Kevin", ) self.session.add(obj) self.session.commit() @@ -171,8 +170,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:12 election_id=6, - name='Toshio', - url='https://fedoraproject.org/wiki/User:Toshio', + name="Toshio", + url="https://fedoraproject.org/wiki/User:Toshio", ) self.session.add(obj) self.session.commit() @@ -180,8 +179,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:13 election_id=6, - name='Kevin', - url='https://fedoraproject.org/wiki/User:Kevin', + name="Kevin", + url="https://fedoraproject.org/wiki/User:Kevin", ) self.session.add(obj) self.session.commit() @@ -193,8 +192,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:14 election_id=7, - name='Toshio', - url='https://fedoraproject.org/wiki/User:Toshio', + name="Toshio", + url="https://fedoraproject.org/wiki/User:Toshio", ) self.session.add(obj) self.session.commit() @@ -202,8 +201,8 @@ class Candidatetests(Modeltests): obj = models.Candidate( # id:15 election_id=7, - name='Kevin', - url='https://fedoraproject.org/wiki/User:Kevin', + name="Kevin", + url="https://fedoraproject.org/wiki/User:Kevin", ) self.session.add(obj) self.session.commit() @@ -216,20 +215,20 @@ class Candidatetests(Modeltests): self.assertEqual( obj.to_json(), { - 'name': 'Ralph', - 'url': 'https://fedoraproject.org/wiki/User:Ralph', - 'fas_name': None, - } + "name": "Ralph", + "url": "https://fedoraproject.org/wiki/User:Ralph", + "fas_name": None, + }, ) obj = models.Candidate.get(self.session, 2) self.assertEqual( obj.to_json(), { - 'name': 'Kevin', - 'url': 'https://fedoraproject.org/wiki/User:Kevin', - 'fas_name': None, - } + "name": "Kevin", + "url": "https://fedoraproject.org/wiki/User:Kevin", + "fas_name": None, + }, ) def test_vote_count(self): @@ -243,6 +242,6 @@ class Candidatetests(Modeltests): self.assertEqual(obj.vote_count, 0) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(Candidatetests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/tests/test_election.py b/tests/test_election.py index b33bf86..1417644 100644 --- a/tests/test_election.py +++ b/tests/test_election.py @@ -20,7 +20,7 @@ fedora_elections.model.Election test script """ -__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4'] +__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] import pkg_resources import unittest @@ -30,8 +30,7 @@ import os from datetime import time from datetime import timedelta -sys.path.insert(0, os.path.join(os.path.dirname( - os.path.abspath(__file__)), '..')) +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) from fedora_elections import models from tests import Modeltests, TODAY @@ -47,17 +46,17 @@ class Electiontests(Modeltests): """ Test the Election init function. """ # Election finished - result open obj = models.Election( # id:1 - shortdesc='test election shortdesc', - alias='test_election', - description='test election description', - url='https://fedoraproject.org', + shortdesc="test election shortdesc", + alias="test_election", + description="test election description", + url="https://fedoraproject.org", start_date=TODAY - timedelta(days=10), end_date=TODAY - timedelta(days=8), seats_elected=1, embargoed=0, - voting_type='range', + voting_type="range", candidates_are_fasusers=0, - fas_user='ralph', + fas_user="ralph", ) self.session.add(obj) self.session.commit() @@ -65,17 +64,17 @@ class Electiontests(Modeltests): # Election finished - result embargoed obj = models.Election( # id:2 - shortdesc='test election 2 shortdesc', - alias='test_election2', - description='test election 2 description', - url='https://fedoraproject.org', + shortdesc="test election 2 shortdesc", + alias="test_election2", + description="test election 2 description", + url="https://fedoraproject.org", start_date=TODAY - timedelta(days=7), end_date=TODAY - timedelta(days=5), seats_elected=1, embargoed=1, - voting_type='range', + voting_type="range", candidates_are_fasusers=0, - fas_user='kevin', + fas_user="kevin", ) self.session.add(obj) self.session.commit() @@ -84,7 +83,7 @@ class Electiontests(Modeltests): # Add an AdminGroup to election #2 admin = models.ElectionAdminGroup( election=obj, - group_name='testers', + group_name="testers", ) self.session.add(admin) self.session.commit() @@ -92,18 +91,18 @@ class Electiontests(Modeltests): # Election open obj = models.Election( # id:3 - shortdesc='test election 3 shortdesc', - alias='test_election3', - description='test election 3 description', - url='https://fedoraproject.org', + shortdesc="test election 3 shortdesc", + alias="test_election3", + description="test election 3 description", + url="https://fedoraproject.org", start_date=TODAY - timedelta(days=2), end_date=TODAY + timedelta(days=2), seats_elected=1, embargoed=1, - voting_type='range', + voting_type="range", candidates_are_fasusers=0, max_votes=2, - fas_user='pingou', + fas_user="pingou", ) self.session.add(obj) self.session.commit() @@ -112,7 +111,7 @@ class Electiontests(Modeltests): # Add a LegalVoter group to election #3 voters = models.LegalVoter( election=obj, - group_name='voters', + group_name="voters", ) self.session.add(voters) self.session.commit() @@ -120,17 +119,17 @@ class Electiontests(Modeltests): # Election created but not open obj = models.Election( # id:4 - shortdesc='test election 4 shortdesc', - alias='test_election4', - description='test election 4 description', - url='https://fedoraproject.org', + shortdesc="test election 4 shortdesc", + alias="test_election4", + description="test election 4 description", + url="https://fedoraproject.org", start_date=TODAY + timedelta(days=3), end_date=TODAY + timedelta(days=6), seats_elected=1, embargoed=1, - voting_type='range', + voting_type="range", candidates_are_fasusers=0, - fas_user='skvidal', + fas_user="skvidal", ) self.session.add(obj) self.session.commit() @@ -138,17 +137,17 @@ class Electiontests(Modeltests): # Election - simple voting - Open obj = models.Election( # id:5 - shortdesc='test election 5 shortdesc', - alias='test_election5', - description='test election 5 description', - url='https://fedoraproject.org', + shortdesc="test election 5 shortdesc", + alias="test_election5", + description="test election 5 description", + url="https://fedoraproject.org", start_date=TODAY - timedelta(days=1), end_date=TODAY + timedelta(days=3), seats_elected=1, embargoed=1, - voting_type='simple', + voting_type="simple", candidates_are_fasusers=0, - fas_user='skvidal', + fas_user="skvidal", ) self.session.add(obj) self.session.commit() @@ -156,36 +155,36 @@ class Electiontests(Modeltests): # 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', + 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', + voting_type="select", candidates_are_fasusers=0, max_votes=1, - fas_user='skvidal', + fas_user="skvidal", ) self.session.add(obj) self.session.commit() self.assertNotEqual(obj, None) # Election - IRC voting - Open obj = models.Election( # id:7 - shortdesc='test election 7 shortdesc', - alias='test_election7', - description='test election 7 description', - url='https://fedoraproject.org', + shortdesc="test election 7 shortdesc", + alias="test_election7", + description="test election 7 description", + url="https://fedoraproject.org", start_date=TODAY - timedelta(days=1), end_date=TODAY + timedelta(days=3), seats_elected=1, embargoed=1, - voting_type='irc', + voting_type="irc", candidates_are_fasusers=0, max_votes=1, - fas_user='nerdsville', + fas_user="nerdsville", ) self.session.add(obj) self.session.commit() @@ -194,84 +193,84 @@ class Electiontests(Modeltests): def test_get_election(self): """ Test the Election.get function. """ self.test_init_election() - obj = models.Election.get(self.session, 'test_election') + obj = models.Election.get(self.session, "test_election") self.assertNotEqual(obj, None) self.assertEqual(obj.id, 1) def test_status_election(self): """ Test the Election.status function. """ self.test_init_election() - obj = models.Election.get(self.session, 'test_election') + obj = models.Election.get(self.session, "test_election") self.assertNotEqual(obj, None) - self.assertEqual(obj.status, 'Ended') + self.assertEqual(obj.status, "Ended") - obj = models.Election.get(self.session, 'test_election2') + obj = models.Election.get(self.session, "test_election2") self.assertNotEqual(obj, None) - self.assertEqual(obj.status, 'Embargoed') + self.assertEqual(obj.status, "Embargoed") - obj = models.Election.get(self.session, 'test_election3') + obj = models.Election.get(self.session, "test_election3") self.assertNotEqual(obj, None) - self.assertEqual(obj.status, 'In progress') + self.assertEqual(obj.status, "In progress") - obj = models.Election.get(self.session, 'test_election4') + obj = models.Election.get(self.session, "test_election4") self.assertNotEqual(obj, None) - self.assertEqual(obj.status, 'Pending') + self.assertEqual(obj.status, "Pending") def test_locked_election(self): """ Test the Election.locked function. """ self.test_init_election() - obj = models.Election.get(self.session, 'test_election') + obj = models.Election.get(self.session, "test_election") self.assertNotEqual(obj, None) self.assertTrue(obj.locked) - obj = models.Election.get(self.session, 'test_election2') + obj = models.Election.get(self.session, "test_election2") self.assertNotEqual(obj, None) self.assertTrue(obj.locked) - obj = models.Election.get(self.session, 'test_election3') + obj = models.Election.get(self.session, "test_election3") self.assertNotEqual(obj, None) self.assertTrue(obj.locked) - obj = models.Election.get(self.session, 'test_election4') + obj = models.Election.get(self.session, "test_election4") self.assertNotEqual(obj, None) self.assertFalse(obj.locked) def test_search_election(self): """ Test the Election.search function. """ self.test_init_election() - obj = models.Election.search(self.session, alias='test_election') + obj = models.Election.search(self.session, alias="test_election") self.assertNotEqual(obj, None) self.assertNotEqual(obj, []) self.assertEqual(len(obj), 1) - self.assertEqual(obj[0].shortdesc, 'test election shortdesc') + self.assertEqual(obj[0].shortdesc, "test election shortdesc") obj = models.Election.search( - self.session, shortdesc='test election 2 shortdesc') + self.session, shortdesc="test election 2 shortdesc" + ) self.assertNotEqual(obj, None) self.assertNotEqual(obj, []) self.assertEqual(len(obj), 1) - self.assertEqual(obj[0].description, 'test election 2 description') + self.assertEqual(obj[0].description, "test election 2 description") - obj = models.Election.search( - self.session, fas_user='skvidal') + obj = models.Election.search(self.session, fas_user="skvidal") self.assertNotEqual(obj, None) self.assertNotEqual(obj, []) 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') + 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), 7) - 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') - self.assertEqual(obj[3].description, 'test election 7 description') - self.assertEqual(obj[4].description, 'test election 3 description') - self.assertEqual(obj[5].description, 'test election 2 description') - self.assertEqual(obj[6].description, 'test election description') + 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") + self.assertEqual(obj[3].description, "test election 7 description") + self.assertEqual(obj[4].description, "test election 3 description") + self.assertEqual(obj[5].description, "test election 2 description") + self.assertEqual(obj[6].description, "test election description") def test_get_older_election(self): """ Test the Election.get_older_election function. """ @@ -280,8 +279,8 @@ class Electiontests(Modeltests): self.assertNotEqual(obj, None) self.assertNotEqual(obj, []) self.assertEqual(len(obj), 2) - self.assertEqual(obj[0].shortdesc, 'test election 2 shortdesc') - self.assertEqual(obj[1].shortdesc, 'test election shortdesc') + self.assertEqual(obj[0].shortdesc, "test election 2 shortdesc") + self.assertEqual(obj[1].shortdesc, "test election shortdesc") def test_get_open_election(self): """ Test the Election.get_open_election function. """ @@ -290,10 +289,10 @@ class Electiontests(Modeltests): self.assertNotEqual(obj, None) self.assertNotEqual(obj, []) self.assertEqual(len(obj), 4) - self.assertEqual(obj[0].shortdesc, 'test election 5 shortdesc') - self.assertEqual(obj[1].shortdesc, 'test election 6 shortdesc') - self.assertEqual(obj[2].shortdesc, 'test election 7 shortdesc') - self.assertEqual(obj[3].shortdesc, 'test election 3 shortdesc') + self.assertEqual(obj[0].shortdesc, "test election 5 shortdesc") + self.assertEqual(obj[1].shortdesc, "test election 6 shortdesc") + self.assertEqual(obj[2].shortdesc, "test election 7 shortdesc") + self.assertEqual(obj[3].shortdesc, "test election 3 shortdesc") def test_get_next_election(self): """ Test the Election.get_next_election function. """ @@ -302,29 +301,27 @@ class Electiontests(Modeltests): self.assertNotEqual(obj, None) self.assertNotEqual(obj, []) self.assertEqual(len(obj), 1) - self.assertEqual(obj[0].shortdesc, 'test election 4 shortdesc') + self.assertEqual(obj[0].shortdesc, "test election 4 shortdesc") def test_to_json(self): """ Test the Election.to_json function. """ self.test_init_election() - obj = models.Election.get(self.session, 'test_election') + obj = models.Election.get(self.session, "test_election") self.assertEqual( obj.to_json(), { - 'description': 'test election description', - 'end_date': ( - TODAY - timedelta(days=8)).strftime('%Y-%m-%d %H:%M'), - 'url': 'https://fedoraproject.org', - 'embargoed': 0, - 'alias': 'test_election', - 'shortdesc': 'test election shortdesc', - 'voting_type': 'range', - 'start_date': ( - TODAY - timedelta(days=10)).strftime('%Y-%m-%d %H:%M'), - } + "description": "test election description", + "end_date": (TODAY - timedelta(days=8)).strftime("%Y-%m-%d %H:%M"), + "url": "https://fedoraproject.org", + "embargoed": 0, + "alias": "test_election", + "shortdesc": "test election shortdesc", + "voting_type": "range", + "start_date": (TODAY - timedelta(days=10)).strftime("%Y-%m-%d %H:%M"), + }, ) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(Electiontests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/tests/test_flask.py b/tests/test_flask.py index 0645662..74909e4 100644 --- a/tests/test_flask.py +++ b/tests/test_flask.py @@ -20,7 +20,7 @@ fedora_elections.model.Election test script """ -__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4'] +__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] import pkg_resources import unittest @@ -33,8 +33,7 @@ from datetime import timedelta import flask from mock import patch, MagicMock -sys.path.insert(0, os.path.join(os.path.dirname( - os.path.abspath(__file__)), '..')) +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) import fedora_elections from tests import ModelFlasktests, FakeUser, user_set @@ -46,276 +45,261 @@ class Flasktests(ModelFlasktests): def test_is_safe_url(self): """ Test the is_safe_url function. """ - app = flask.Flask('elections') + 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/')) + 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('/') + output = self.app.get("/") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertIn('Fedora elections', output_text) - self.assertNotIn('

Current elections

', output_text) - self.assertNotIn('

Next', output_text) - self.assertNotIn('

Last', output_text) + self.assertIn("Fedora elections", output_text) + self.assertNotIn("

Current elections

", output_text) + self.assertNotIn("

Next", output_text) + self.assertNotIn("

Last", output_text) self.assertIn('Log In', output_text) - user = FakeUser([], username='pingou') + user = FakeUser([], username="pingou") with user_set(fedora_elections.APP, user): - output = self.app.get('/', follow_redirects=True) + output = self.app.get("/", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertIn('Fedora elections', output_text) + self.assertIn("Fedora elections", output_text) self.assertIn( - 'log out', - output_text) + 'log out', output_text + ) def test_index_filled(self): """ Test the index function. """ self.setup_db() - output = self.app.get('/') + output = self.app.get("/") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('

Elections' in output_text) - self.assertTrue('

Open elections

' in output_text) - self.assertTrue('Upcoming elections' in output_text) + self.assertTrue("

Elections" in output_text) + self.assertTrue("

Open elections

" in output_text) + self.assertTrue("Upcoming elections" in output_text) self.assertTrue('Log In' in output_text) - user = FakeUser([], username='pingou') + user = FakeUser([], username="pingou") with user_set(fedora_elections.APP, user): - output = self.app.get('/') + output = self.app.get("/") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('

Elections' in output_text) - self.assertTrue('

Open elections

' in output_text) - self.assertTrue('Upcoming elections' in output_text) - self.assertTrue('Elections" in output_text) + self.assertTrue("

Open elections

" in output_text) + self.assertTrue("Upcoming elections" in output_text) self.assertTrue( - '
log out' in output_text) - self.assertEqual(output_text.count('Vote now!'), 4) + 'log out' in output_text + ) + self.assertEqual(output_text.count("Vote now!"), 4) - user = FakeUser([], username='toshio') + user = FakeUser([], username="toshio") with user_set(fedora_elections.APP, user): - output = self.app.get('/') + output = self.app.get("/") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('

Elections' in output_text) - self.assertTrue('

Open elections

' in output_text) - self.assertTrue('Upcoming elections' in output_text) + self.assertTrue("

Elections" in output_text) + self.assertTrue("

Open elections

" in output_text) + self.assertTrue("Upcoming elections" in output_text) self.assertTrue( - 'log out' in output_text) + 'log out' in output_text + ) def test_is_admin(self): """ Test the is_admin function. """ - app = flask.Flask('fedora_elections') + app = flask.Flask("fedora_elections") with app.test_request_context(): flask.g.fas_user = None self.assertFalse(fedora_elections.is_admin(flask.g.fas_user)) - flask.g.oidc_id_token = 'foobar' + flask.g.oidc_id_token = "foobar" with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['foobar'])): + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["foobar"]), + ): flask.g.fas_user = FakeUser() self.assertFalse(fedora_elections.is_admin(flask.g.fas_user)) with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): flask.g.fas_user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP']) + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"] + ) self.assertTrue( - fedora_elections.is_admin(flask.g.fas_user, ['elections'])) + fedora_elections.is_admin(flask.g.fas_user, ["elections"]) + ) with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['sysadmin-main'])): - - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'] = [ - 'sysadmin-main', 'sysadmin-elections'] - flask.g.fas_user = FakeUser(['sysadmin-main']) + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["sysadmin-main"]), + ): + + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"] = [ + "sysadmin-main", + "sysadmin-elections", + ] + flask.g.fas_user = FakeUser(["sysadmin-main"]) self.assertTrue( - fedora_elections.is_admin(flask.g.fas_user, ['sysadmin-main'])) + fedora_elections.is_admin(flask.g.fas_user, ["sysadmin-main"]) + ) def test_is_election_admin(self): """ Test the is_election_admin function. """ - app = flask.Flask('fedora_elections') + app = flask.Flask("fedora_elections") with app.test_request_context(): flask.g.fas_user = None - self.assertFalse( - fedora_elections.is_election_admin( - flask.g.fas_user, 1) - ) + self.assertFalse(fedora_elections.is_election_admin(flask.g.fas_user, 1)) - flask.g.oidc_id_token = 'foobar' + flask.g.oidc_id_token = "foobar" flask.g.fas_user = FakeUser() - self.assertFalse( - fedora_elections.is_election_admin( - flask.g.fas_user, 1) - ) + self.assertFalse(fedora_elections.is_election_admin(flask.g.fas_user, 1)) with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): flask.g.fas_user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP']) - self.assertTrue(fedora_elections.is_election_admin( - flask.g.fas_user, 1)) + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"] + ) + self.assertTrue(fedora_elections.is_election_admin(flask.g.fas_user, 1)) self.setup_db() with app.test_request_context(): - flask.g.fas_user = FakeUser('testers') - flask.g.oidc_id_token = 'foobar' + flask.g.fas_user = FakeUser("testers") + flask.g.oidc_id_token = "foobar" # This is user is not an admin for election #1 with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['foobar'])): + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["foobar"]), + ): self.assertFalse( - fedora_elections.is_election_admin( - flask.g.fas_user, 1) + fedora_elections.is_election_admin(flask.g.fas_user, 1) ) # This is user is an admin for election #2 - self.assertTrue( - fedora_elections.is_election_admin( - flask.g.fas_user, 2) - ) + self.assertTrue(fedora_elections.is_election_admin(flask.g.fas_user, 2)) def test_is_safe_url(self): """ Test the is_safe_url function. """ - app = flask.Flask('fedora_elections') + app = flask.Flask("fedora_elections") with app.test_request_context(): - self.assertFalse( - fedora_elections.is_safe_url('https://google.fr')) - self.assertTrue( - fedora_elections.is_safe_url('/admin/')) + self.assertFalse(fedora_elections.is_safe_url("https://google.fr")) + self.assertTrue(fedora_elections.is_safe_url("/admin/")) def test_auth_login(self): """ Test the auth_login function. """ - app = flask.Flask('fedora_elections') + app = flask.Flask("fedora_elections") with app.test_request_context(): - flask.g.fas_user = FakeUser(['gitr2spec']) - output = self.app.get('/login') + flask.g.fas_user = FakeUser(["gitr2spec"]) + output = self.app.get("/login") self.assertEqual(output.status_code, 302) output_text = output.get_data(as_text=True) self.assertIn( - 'https://iddev.fedorainfracloud.org/openidc/Authorization?', - output_text) + "https://iddev.fedorainfracloud.org/openidc/Authorization?", output_text + ) - output = self.app.get('/login?next=http://localhost/') + output = self.app.get("/login?next=http://localhost/") self.assertEqual(output.status_code, 302) output_text = output.get_data(as_text=True) self.assertIn( - 'https://iddev.fedorainfracloud.org/openidc/Authorization?', - output_text) + "https://iddev.fedorainfracloud.org/openidc/Authorization?", output_text + ) # self.setup_db() # user = FakeUser([], username='pingou') # with user_set(fedora_elections.APP, user): - # output = self.app.get('/login', follow_redirects=True) - # self.assertEqual(output.status_code, 200) - # self.assertTrue('Fedora elections' in output.data) + # output = self.app.get('/login', follow_redirects=True) + # self.assertEqual(output.status_code, 200) + # self.assertTrue('Fedora elections' in output.data) def test_auth_logout(self): """ Test the auth_logout function. """ - user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP']) + user = FakeUser(fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"]) with user_set(fedora_elections.APP, user): - output = self.app.get('/logout', follow_redirects=True) + output = self.app.get("/logout", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('Fedora elections' in output_text) - self.assertTrue( - 'You have been logged out' - in output_text) + self.assertTrue("Fedora elections" in output_text) + self.assertTrue("You have been logged out" in output_text) user = None with user_set(fedora_elections.APP, user): - output = self.app.get('/logout', follow_redirects=True) + output = self.app.get("/logout", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('Fedora elections' in output_text) - self.assertFalse( - 'You have been logged out' - in output_text) + self.assertTrue("Fedora elections" in output_text) + self.assertFalse("You have been logged out" in output_text) def test_about_election(self): """ Test the about_election function. """ self.setup_db() - #the blah election doesnt exist, so check if - #we get the redirect http code 302. - output = self.app.get('/about/blah') + # the blah election doesnt exist, so check if + # we get the redirect http code 302. + output = self.app.get("/about/blah") self.assertEqual(output.status_code, 302) - #the blah election doesnt exist, so check if - #we get redirected to the main page. - output = self.app.get('/about/blah', follow_redirects=True) + # the blah election doesnt exist, so check if + # we get redirected to the main page. + output = self.app.get("/about/blah", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'The election, blah, does not exist.' - in output_text) - self.assertTrue('

Elections' in output_text) - self.assertTrue('

Open elections

' in output_text) - self.assertTrue('Upcoming elections' in output_text) + self.assertTrue("The election, blah, does not exist." in output_text) + self.assertTrue("

Elections" in output_text) + self.assertTrue("

Open elections

" in output_text) + self.assertTrue("Upcoming elections" in output_text) - #test_election does exist, so check if it shows + # test_election does exist, so check if it shows # with the correct candidates - output = self.app.get('/about/test_election') + output = self.app.get("/about/test_election") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) + self.assertTrue("Election Information" in output_text) self.assertTrue( - 'Election Information' in output_text) + '' in output_text + ) self.assertTrue( - '' - in output_text) - self.assertTrue( - '' - in output_text) + '' in output_text + ) self.assertTrue('Log In' in output_text) def test_archived_election(self): """ Test the archived_elections function. """ - output = self.app.get('/archives') + output = self.app.get("/archives") self.assertEqual(output.status_code, 302) - output = self.app.get('/archives', follow_redirects=True) + output = self.app.get("/archives", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'There are no archived elections.' - in output_text) - self.assertTrue('Fedora elections' in output_text) - self.assertTrue('

Elections' in output_text) + self.assertTrue("There are no archived elections." in output_text) + self.assertTrue("Fedora elections" in output_text) + self.assertTrue("

Elections" in output_text) self.setup_db() - output = self.app.get('/archives') + output = self.app.get("/archives") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('Fedora elections' in output_text) - self.assertTrue( - 'test election 2 shortdesc' in output_text) - self.assertTrue( - 'test election shortdesc' in output_text) + self.assertTrue("Fedora elections" in output_text) + self.assertTrue("test election 2 shortdesc" in output_text) + self.assertTrue("test election shortdesc" in output_text) self.assertEqual(output_text.count('href="/about/'), 2) self.assertTrue('Log In' in output_text) @@ -323,39 +307,42 @@ class Flasktests(ModelFlasktests): """ Test the open_elections function. """ self.setup_db() - output = self.app.get('/') + output = self.app.get("/") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('

Elections' in output_text) - self.assertTrue('

Open elections

' in output_text) - self.assertTrue('Upcoming elections' in output_text) + self.assertTrue("

Elections" in output_text) + self.assertTrue("

Open elections

" in output_text) + self.assertTrue("Upcoming elections" in output_text) self.assertTrue('href="/vote/' in output_text) self.assertTrue('Log In' in output_text) - user = FakeUser([], username='pingou') + user = FakeUser([], username="pingou") with user_set(fedora_elections.APP, user): - output = self.app.get('/') + output = self.app.get("/") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('

Elections' in output_text) - self.assertTrue('

Open elections

' in output_text) - self.assertTrue('Upcoming elections' in output_text) + self.assertTrue("

Elections" in output_text) + self.assertTrue("

Open elections

" in output_text) + self.assertTrue("Upcoming elections" in output_text) self.assertTrue('href="/vote/' in output_text) self.assertTrue( - 'log out' in output_text) - self.assertEqual(output_text.count('Vote now!'), 4) + 'log out' in output_text + ) + self.assertEqual(output_text.count("Vote now!"), 4) - user = FakeUser([], username='toshio') + user = FakeUser([], username="toshio") with user_set(fedora_elections.APP, user): - output = self.app.get('/') + output = self.app.get("/") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('

Elections' in output_text) - self.assertTrue('

Open elections

' in output_text) - self.assertTrue('Upcoming elections' in output_text) + self.assertTrue("

Elections" in output_text) + self.assertTrue("

Open elections

" in output_text) + self.assertTrue("Upcoming elections" in output_text) self.assertTrue( - 'log out' in output_text) + 'log out' in output_text + ) + -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(Flasktests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/tests/test_flask_admin.py b/tests/test_flask_admin.py index 4cc0feb..d77a6ca 100644 --- a/tests/test_flask_admin.py +++ b/tests/test_flask_admin.py @@ -20,7 +20,7 @@ fedora_elections.admin test script """ -__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4'] +__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] import pkg_resources import logging @@ -35,11 +35,14 @@ import flask from mock import patch, MagicMock from fedora_messaging.testing import mock_sends from fedora_elections_messages import ( - NewElectionV1, EditElectionV1, NewCandidateV1, EditCandidateV1, DeleteCandidateV1, + NewElectionV1, + EditElectionV1, + NewCandidateV1, + EditCandidateV1, + DeleteCandidateV1, ) -sys.path.insert(0, os.path.join(os.path.dirname( - os.path.abspath(__file__)), '..')) +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 @@ -52,41 +55,49 @@ class FlaskAdmintests(ModelFlasktests): def test_admin_view_election(self): """ Test the admin_view_election function. """ user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'], - username='toshio') + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"], + username="toshio", + ) - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/election_test/') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/election_test/") self.assertEqual(output.status_code, 404) self.setup_db() - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/test_election/') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/test_election/") output_text = output.get_data(as_text=True) self.assertEqual(output.status_code, 200) - self.assertTrue('Candidates 3' in output_text) + self.assertTrue( + 'Candidates 3' + in output_text + ) def test_admin_no_cla(self): """ Test the admin_new_election function. """ self.setup_db() user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'], - username='toshio') + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"], + username="toshio", + ) user.cla_done = False - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/new') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/new") self.assertEqual(output.status_code, 403) def test_admin_new_election(self): @@ -94,1062 +105,1223 @@ class FlaskAdmintests(ModelFlasktests): self.setup_db() user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'], - username='toshio') + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"], + username="toshio", + ) - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/new') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/new") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - '

Create new election

' in output_text) + self.assertTrue("

Create new election

" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" required type="text" ', output_text) + 'name="shortdesc" required type="text" ', + output_text, + ) else: self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" type="text" ', output_text) + 'name="shortdesc" type="text" ', + output_text, + ) # No csrf provided data = { - 'alias': 'new_election', - 'shortdesc': 'new election shortdesc', - 'description': 'new election description', - 'voting_type': 'simple', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY + timedelta(days=2), - 'end_date': TODAY + timedelta(days=4), - 'seats_elected': '2', - 'candidates_are_fasusers': False, - 'embargoed': True, + "alias": "new_election", + "shortdesc": "new election shortdesc", + "description": "new election description", + "voting_type": "simple", + "url": "https://fedoraproject.org", + "start_date": TODAY + timedelta(days=2), + "end_date": TODAY + timedelta(days=4), + "seats_elected": "2", + "candidates_are_fasusers": False, + "embargoed": True, } - output = self.app.post('/admin/new', data=data) + output = self.app.post("/admin/new", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - '

Create new election

' in output_text) + self.assertTrue("

Create new election

" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" required type="text" ', output_text) + 'name="shortdesc" required type="text" ', + output_text, + ) else: self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" type="text" ', output_text) + 'name="shortdesc" type="text" ', + output_text, + ) csrf_token = self.get_csrf(output=output) # Description missing data = { - 'alias': 'new_election', - 'shortdesc': 'new election shortdesc', - 'voting_type': 'simple', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY + timedelta(days=2), - 'end_date': TODAY + timedelta(days=4), - 'seats_elected': '2', - 'candidates_are_fasusers': False, - 'embargoed': True, - 'csrf_token': csrf_token, + "alias": "new_election", + "shortdesc": "new election shortdesc", + "voting_type": "simple", + "url": "https://fedoraproject.org", + "start_date": TODAY + timedelta(days=2), + "end_date": TODAY + timedelta(days=4), + "seats_elected": "2", + "candidates_are_fasusers": False, + "embargoed": True, + "csrf_token": csrf_token, } - output = self.app.post('/admin/new', data=data) + output = self.app.post("/admin/new", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - '

Create new election

' in output_text) + self.assertTrue("

Create new election

" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" required type="text" ', output_text) + 'name="shortdesc" required type="text" ', + output_text, + ) else: self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" type="text" ', output_text) + 'name="shortdesc" type="text" ', + output_text, + ) self.assertTrue( '' - in output_text) + in output_text + ) # Invalid alias data = { - 'alias': 'new', - 'shortdesc': 'new election shortdesc', - 'description': 'new election description', - 'voting_type': 'simple', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY + timedelta(days=2), - 'end_date': TODAY + timedelta(days=4), - 'seats_elected': 2, - 'candidates_are_fasusers': False, - 'embargoed': True, - 'csrf_token': csrf_token, + "alias": "new", + "shortdesc": "new election shortdesc", + "description": "new election description", + "voting_type": "simple", + "url": "https://fedoraproject.org", + "start_date": TODAY + timedelta(days=2), + "end_date": TODAY + timedelta(days=4), + "seats_elected": 2, + "candidates_are_fasusers": False, + "embargoed": True, + "csrf_token": csrf_token, } - output = self.app.post('/admin/new', data=data) + output = self.app.post("/admin/new", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - '

Create new election

' in output_text) + self.assertTrue("

Create new election

" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" required type="text" ', output_text) + 'name="shortdesc" required type="text" ', + output_text, + ) else: self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" type="text" ', output_text) + 'name="shortdesc" type="text" ', + output_text, + ) self.assertTrue( '' - in output_text) + in output_text + ) # Invalid: end_date earlier than start_date data = { - 'alias': 'new_election', - 'shortdesc': 'new election shortdesc', - 'description': 'new election description', - 'voting_type': 'simple', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY + timedelta(days=6), - 'end_date': TODAY + timedelta(days=4), - 'seats_elected': 2, - 'candidates_are_fasusers': False, - 'embargoed': True, - 'csrf_token': csrf_token, + "alias": "new_election", + "shortdesc": "new election shortdesc", + "description": "new election description", + "voting_type": "simple", + "url": "https://fedoraproject.org", + "start_date": TODAY + timedelta(days=6), + "end_date": TODAY + timedelta(days=4), + "seats_elected": 2, + "candidates_are_fasusers": False, + "embargoed": True, + "csrf_token": csrf_token, } - output = self.app.post('/admin/new', data=data) + output = self.app.post("/admin/new", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - '

Create new election

' in output_text) + self.assertTrue("

Create new election

" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" required type="text" ', output_text) + 'name="shortdesc" required type="text" ', + output_text, + ) else: self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" type="text" ', output_text) + 'name="shortdesc" type="text" ', + output_text, + ) self.assertTrue( 'class="form-control-feedback">End date must be later than start date.' - in output_text) + in output_text + ) # Invalid: alias already taken data = { - 'alias': 'test_election', - 'shortdesc': 'new election shortdesc', - 'description': 'new election description', - 'voting_type': 'simple', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY + timedelta(days=6), - 'end_date': TODAY + timedelta(days=4), - 'seats_elected': 2, - 'candidates_are_fasusers': False, - 'embargoed': True, - 'csrf_token': csrf_token, + "alias": "test_election", + "shortdesc": "new election shortdesc", + "description": "new election description", + "voting_type": "simple", + "url": "https://fedoraproject.org", + "start_date": TODAY + timedelta(days=6), + "end_date": TODAY + timedelta(days=4), + "seats_elected": 2, + "candidates_are_fasusers": False, + "embargoed": True, + "csrf_token": csrf_token, } - output = self.app.post('/admin/new', data=data) + output = self.app.post("/admin/new", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - '

Create new election

' in output_text) + self.assertTrue("

Create new election

" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" required type="text" ', output_text) + 'name="shortdesc" required type="text" ', + output_text, + ) else: self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" type="text" ', output_text) + 'name="shortdesc" type="text" ', + output_text, + ) self.assertTrue( '' in output_text) + "this alias." in output_text + ) # Invalid: shortdesc already taken data = { - 'alias': 'new_election', - 'shortdesc': 'test election shortdesc', - 'description': 'new election description', - 'voting_type': 'simple', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY + timedelta(days=6), - 'end_date': TODAY + timedelta(days=4), - 'seats_elected': 2, - 'candidates_are_fasusers': False, - 'embargoed': True, - 'csrf_token': csrf_token, + "alias": "new_election", + "shortdesc": "test election shortdesc", + "description": "new election description", + "voting_type": "simple", + "url": "https://fedoraproject.org", + "start_date": TODAY + timedelta(days=6), + "end_date": TODAY + timedelta(days=4), + "seats_elected": 2, + "candidates_are_fasusers": False, + "embargoed": True, + "csrf_token": csrf_token, } - output = self.app.post('/admin/new', data=data) + output = self.app.post("/admin/new", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - '

Create new election

' in output_text) + self.assertTrue("

Create new election

" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" required type="text" ', output_text) + 'name="shortdesc" required type="text" ', + output_text, + ) else: self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" type="text" ', output_text) + 'name="shortdesc" type="text" ', + output_text, + ) self.assertTrue( '' in output_text) + "this summary." in output_text + ) # All good - max_votes is ignored as it is not a integer data = { - 'alias': 'new_election', - 'shortdesc': 'new election shortdesc', - 'description': 'new election description', - 'voting_type': 'simple', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY + timedelta(days=2), - 'end_date': TODAY + timedelta(days=4), - 'seats_elected': 2, - 'candidates_are_fasusers': False, - 'embargoed': True, - 'admin_grp': 'testers, sysadmin-main,,', - 'lgl_voters': 'testers, packager,,', - 'max_votes': 'wrong', - 'csrf_token': csrf_token, + "alias": "new_election", + "shortdesc": "new election shortdesc", + "description": "new election description", + "voting_type": "simple", + "url": "https://fedoraproject.org", + "start_date": TODAY + timedelta(days=2), + "end_date": TODAY + timedelta(days=4), + "seats_elected": 2, + "candidates_are_fasusers": False, + "embargoed": True, + "admin_grp": "testers, sysadmin-main,,", + "lgl_voters": "testers, packager,,", + "max_votes": "wrong", + "csrf_token": csrf_token, } with mock_sends(NewElectionV1): output = self.app.post( - '/admin/new', data=data, follow_redirects=True) + "/admin/new", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'Election "new_election" added' - in output_text) - self.assertTrue( - 'There are no candidates.' in output_text) + self.assertTrue('Election "new_election" added' in output_text) + self.assertTrue("There are no candidates." in output_text) self.assertIn( 'input class="form-control" id="admin_grp" ' 'name="admin_grp" type="text" ' - 'value="sysadmin-main, testers">', output_text) + 'value="sysadmin-main, testers">', + output_text, + ) self.assertIn( 'input class="form-control" id="lgl_voters" ' 'name="lgl_voters" type="text" ' - 'value="packager, testers">', output_text) + 'value="packager, testers">', + output_text, + ) self.assertIn( 'input class="form-control" id="max_votes" ' 'name="max_votes" type="text" ' - 'value="">', output_text) + 'value="">', + output_text, + ) # All good - max_votes is ignored as it is not a integer data = { - 'alias': 'new_election2', - 'shortdesc': 'new election2 shortdesc', - 'description': 'new election2 description', - 'voting_type': 'simple', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY + timedelta(days=2), - 'end_date': TODAY + timedelta(days=4), - 'seats_elected': 2, - 'candidates_are_fasusers': False, - 'embargoed': True, - 'admin_grp': 'testers, , sysadmin-main,,', - 'lgl_voters': 'testers, packager,,,', - 'csrf_token': csrf_token, + "alias": "new_election2", + "shortdesc": "new election2 shortdesc", + "description": "new election2 description", + "voting_type": "simple", + "url": "https://fedoraproject.org", + "start_date": TODAY + timedelta(days=2), + "end_date": TODAY + timedelta(days=4), + "seats_elected": 2, + "candidates_are_fasusers": False, + "embargoed": True, + "admin_grp": "testers, , sysadmin-main,,", + "lgl_voters": "testers, packager,,,", + "csrf_token": csrf_token, } with mock_sends(NewElectionV1): output = self.app.post( - '/admin/new', data=data, follow_redirects=True) + "/admin/new", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'Election "new_election2" added' - in output_text) - self.assertTrue( - 'There are no candidates.' in output_text) + self.assertTrue('Election "new_election2" added' in output_text) + self.assertTrue("There are no candidates." in output_text) self.assertIn( 'input class="form-control" id="admin_grp" ' 'name="admin_grp" type="text" ' - 'value="sysadmin-main, testers">', output_text) + 'value="sysadmin-main, testers">', + output_text, + ) self.assertIn( 'input class="form-control" id="lgl_voters" ' 'name="lgl_voters" type="text" ' - 'value="packager, testers">', output_text) + 'value="packager, testers">', + output_text, + ) self.assertIn( 'input class="form-control" id="max_votes" ' 'name="max_votes" type="text" ' - 'value="">', output_text) + 'value="">', + output_text, + ) def test_admin_edit_election(self): """ Test the admin_edit_election function. """ user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'], - username='toshio') + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"], + username="toshio", + ) - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/test_election/') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/test_election/") self.assertEqual(output.status_code, 404) self.setup_db() - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/test_election/') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/test_election/") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'Election Details' in output_text) + self.assertTrue("Election Details" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" required type="text" ', output_text) + 'name="shortdesc" required type="text" ', + output_text, + ) else: self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" type="text" ', output_text) + 'name="shortdesc" type="text" ', + output_text, + ) data = { - 'alias': 'test_election', - 'shortdesc': 'test election shortdesc', - 'description': 'test election description', - 'voting_type': 'simple', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY - timedelta(days=10), - 'end_date': TODAY - timedelta(days=8), - 'seats_elected': '2', - 'candidates_are_fasusers': False, - 'embargoed': False, + "alias": "test_election", + "shortdesc": "test election shortdesc", + "description": "test election description", + "voting_type": "simple", + "url": "https://fedoraproject.org", + "start_date": TODAY - timedelta(days=10), + "end_date": TODAY - timedelta(days=8), + "seats_elected": "2", + "candidates_are_fasusers": False, + "embargoed": False, } - output = self.app.post('/admin/test_election/', data=data) + output = self.app.post("/admin/test_election/", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'Election Details' in output_text) + self.assertTrue("Election Details" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" required type="text" ', output_text) + 'name="shortdesc" required type="text" ', + output_text, + ) else: self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" type="text" ', output_text) + 'name="shortdesc" type="text" ', + output_text, + ) csrf_token = self.get_csrf() data = { - 'alias': 'test_election', - 'voting_type': 'simple', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY - timedelta(days=10), - 'end_date': TODAY - timedelta(days=8), - 'seats_elected': '2', - 'candidates_are_fasusers': False, - 'embargoed': False, - 'csrf_token': csrf_token, + "alias": "test_election", + "voting_type": "simple", + "url": "https://fedoraproject.org", + "start_date": TODAY - timedelta(days=10), + "end_date": TODAY - timedelta(days=8), + "seats_elected": "2", + "candidates_are_fasusers": False, + "embargoed": False, + "csrf_token": csrf_token, } - output = self.app.post( - '/admin/test_election/', data=data) + output = self.app.post("/admin/test_election/", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'Election Details' in output_text) + self.assertTrue("Election Details" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" required type="text" ', output_text) + 'name="shortdesc" required type="text" ', + output_text, + ) else: self.assertIn( 'input class="form-control" id="shortdesc" ' - 'name="shortdesc" type="text" ', output_text) + 'name="shortdesc" type="text" ', + output_text, + ) self.assertIn( '', - output_text) + output_text, + ) # Check election before edit - output = self.app.get('/admin/test_election/') + output = self.app.get("/admin/test_election/") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('Candidates 3' in output_text) + self.assertTrue( + 'Candidates 3' + in output_text + ) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" required type="text" ' - 'value="1">', output_text) + 'value="1">', + output_text, + ) else: self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" type="text" ' - 'value="1">', output_text) + 'value="1">', + output_text, + ) data = { - 'alias': 'test_election', - 'shortdesc': 'test election shortdesc', - 'description': 'test election description', - 'voting_type': 'simple', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY - timedelta(days=10), - 'end_date': TODAY - timedelta(days=8), - 'seats_elected': '2', - 'candidates_are_fasusers': False, - 'embargoed': False, - 'max_votes': 'wrong', - 'csrf_token': csrf_token, + "alias": "test_election", + "shortdesc": "test election shortdesc", + "description": "test election description", + "voting_type": "simple", + "url": "https://fedoraproject.org", + "start_date": TODAY - timedelta(days=10), + "end_date": TODAY - timedelta(days=8), + "seats_elected": "2", + "candidates_are_fasusers": False, + "embargoed": False, + "max_votes": "wrong", + "csrf_token": csrf_token, } with mock_sends(EditElectionV1): output = self.app.post( - '/admin/test_election/', data=data, follow_redirects=True) + "/admin/test_election/", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'Election "test_election" saved' - in output_text) + self.assertTrue('Election "test_election" saved' in output_text) # We edited the seats_elected from 1 to 2 if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" required type="text" ' - 'value="2">', output_text) + 'value="2">', + output_text, + ) else: self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" type="text" ' - 'value="2">', output_text) - self.assertTrue('Candidates 3' in output_text) + 'value="2">', + output_text, + ) + self.assertTrue( + 'Candidates 3' + in output_text + ) def test_admin_edit_election_admin_groups(self): - """ Test the admin_edit_election function when editing admin groups. - """ + """Test the admin_edit_election function when editing admin groups.""" user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'], - username='toshio') + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"], + username="toshio", + ) - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/test_election/edit') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/test_election/edit") self.assertEqual(output.status_code, 404) self.setup_db() - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/test_election2/') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/test_election2/") self.assertEqual(output.status_code, 200) csrf_token = self.get_csrf(output=output) # Edit Admin Group # Check election before edit - output = self.app.get('/admin/test_election2/') + output = self.app.get("/admin/test_election2/") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" required type="text" ' - 'value="1">', output_text) + 'value="1">', + output_text, + ) else: self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" type="text" ' - 'value="1">', output_text) + 'value="1">', + output_text, + ) self.assertTrue('Candidates = (2, 2): self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" required type="text" ' - 'value="2">', output_text) + 'value="2">', + output_text, + ) else: self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" type="text" ' - 'value="2">', output_text) + 'value="2">', + output_text, + ) # We edited the admin groups self.assertIn( 'input class="form-control" id="admin_grp" ' 'name="admin_grp" type="text" ' - 'value="sysadmin-main, testers">', output_text) + 'value="sysadmin-main, testers">', + output_text, + ) # Remove an existing group: testers data = { - 'alias': 'test_election2', - 'shortdesc': 'test election 2 shortdesc', - 'description': 'test election 2 description', - 'voting_type': 'range', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY - timedelta(days=7), - 'end_date': TODAY - timedelta(days=5), - 'seats_elected': '2', - 'candidates_are_fasusers': False, - 'embargoed': False, - 'admin_grp': 'sysadmin-main', - 'csrf_token': csrf_token, + "alias": "test_election2", + "shortdesc": "test election 2 shortdesc", + "description": "test election 2 description", + "voting_type": "range", + "url": "https://fedoraproject.org", + "start_date": TODAY - timedelta(days=7), + "end_date": TODAY - timedelta(days=5), + "seats_elected": "2", + "candidates_are_fasusers": False, + "embargoed": False, + "admin_grp": "sysadmin-main", + "csrf_token": csrf_token, } with mock_sends(EditElectionV1): output = self.app.post( - '/admin/test_election2/', data=data, follow_redirects=True) + "/admin/test_election2/", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'Election "test_election2" saved' - in output_text) + self.assertTrue('Election "test_election2" saved' in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" required type="text" ' - 'value="2">', output_text) + 'value="2">', + output_text, + ) else: self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" type="text" ' - 'value="2">', output_text) + 'value="2">', + output_text, + ) # We edited the admin groups self.assertIn( 'input class="form-control" id="admin_grp" ' 'name="admin_grp" type="text" ' - 'value="sysadmin-main">', output_text) + 'value="sysadmin-main">', + output_text, + ) def test_admin_edit_election_legal_voters(self): - """ Test the admin_edit_election function when editing legal voters. - """ + """Test the admin_edit_election function when editing legal voters.""" user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'], - username='toshio') + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"], + username="toshio", + ) - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/test_election/edit') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/test_election/edit") self.assertEqual(output.status_code, 404) self.setup_db() - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/test_election3/') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/test_election3/") self.assertEqual(output.status_code, 200) csrf_token = self.get_csrf(output=output) # Edit LegalVoter Group # Check election before edit - output = self.app.get('/admin/test_election3/') + output = self.app.get("/admin/test_election3/") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="seats_elected" ' - 'name="seats_elected" required type="text"', output_text) + 'name="seats_elected" required type="text"', + output_text, + ) else: self.assertIn( 'input class="form-control" id="seats_elected" ' - 'name="seats_elected" type="text"', output_text) - self.assertTrue('Candidates ' - in output_text) + in output_text + ) self.assertIn( 'input class="form-control" id="lgl_voters" ' 'name="lgl_voters" type="text" value="voters">', - output_text) + output_text, + ) # Add a new admin group: sysadmin-main data = { - 'alias': 'test_election3', - 'shortdesc': 'test election 3 shortdesc', - 'description': 'test election 3 description', - 'voting_type': 'range', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY - timedelta(days=2), - 'end_date': TODAY + timedelta(days=3), - 'seats_elected': '1', - 'candidates_are_fasusers': False, - 'embargoed': False, - 'lgl_voters': 'voters, sysadmin-main', - 'csrf_token': csrf_token, + "alias": "test_election3", + "shortdesc": "test election 3 shortdesc", + "description": "test election 3 description", + "voting_type": "range", + "url": "https://fedoraproject.org", + "start_date": TODAY - timedelta(days=2), + "end_date": TODAY + timedelta(days=3), + "seats_elected": "1", + "candidates_are_fasusers": False, + "embargoed": False, + "lgl_voters": "voters, sysadmin-main", + "csrf_token": csrf_token, } with mock_sends(EditElectionV1): output = self.app.post( - '/admin/test_election3/', data=data, follow_redirects=True) + "/admin/test_election3/", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'Election "test_election3" saved' - in output_text) + self.assertTrue('Election "test_election3" saved' in output_text) # We edited the legal_voters self.assertIn( 'input class="form-control" id="lgl_voters" ' 'name="lgl_voters" type="text" ' - 'value="sysadmin-main, voters">', output_text) + 'value="sysadmin-main, voters">', + output_text, + ) # Remove an existing group: voters data = { - 'alias': 'test_election3', - 'shortdesc': 'test election 3 shortdesc', - 'description': 'test election 3 description', - 'voting_type': 'range', - 'url': 'https://fedoraproject.org', - 'start_date': TODAY - timedelta(days=2), - 'end_date': TODAY + timedelta(days=3), - 'seats_elected': '1', - 'candidates_are_fasusers': False, - 'embargoed': False, - 'lgl_voters': 'sysadmin-main', - 'csrf_token': csrf_token, + "alias": "test_election3", + "shortdesc": "test election 3 shortdesc", + "description": "test election 3 description", + "voting_type": "range", + "url": "https://fedoraproject.org", + "start_date": TODAY - timedelta(days=2), + "end_date": TODAY + timedelta(days=3), + "seats_elected": "1", + "candidates_are_fasusers": False, + "embargoed": False, + "lgl_voters": "sysadmin-main", + "csrf_token": csrf_token, } with mock_sends(EditElectionV1): output = self.app.post( - '/admin/test_election3/', data=data, follow_redirects=True) + "/admin/test_election3/", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'Election "test_election3" saved' - in output_text) + self.assertTrue('Election "test_election3" saved' in output_text) # We edited the legal_voters self.assertIn( 'input class="form-control" id="lgl_voters" ' 'name="lgl_voters" type="text" ' - 'value="sysadmin-main">', output_text) + 'value="sysadmin-main">', + output_text, + ) def test_admin_add_candidate(self): """ Test the admin_add_candidate function. """ user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'], - username='toshio') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"], + username="toshio", + ) + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/test_election/candidates/new') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/test_election/candidates/new") self.assertEqual(output.status_code, 404) self.setup_db() - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/test_election/candidates/new') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/test_election/candidates/new") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('Add candidate' in output_text) + self.assertTrue("Add candidate" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="name" name="name" ' - 'required type="text"', output_text) + 'required type="text"', + output_text, + ) else: self.assertIn( 'input class="form-control" id="name" name="name" ' - 'type="text"', output_text) + 'type="text"', + output_text, + ) data = { - 'name': 'pingou', - 'url': '', + "name": "pingou", + "url": "", } - output = self.app.post( - '/admin/test_election/candidates/new', data=data) + output = self.app.post("/admin/test_election/candidates/new", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('Add candidate' in output_text) + self.assertTrue("Add candidate" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="name" name="name" ' - 'required type="text"', output_text) + 'required type="text"', + output_text, + ) else: self.assertIn( 'input class="form-control" id="name" name="name" ' - 'type="text"', output_text) + 'type="text"', + output_text, + ) csrf_token = self.get_csrf(output=output) data = { - 'name': '', - 'url': '', - 'csrf_token': csrf_token, + "name": "", + "url": "", + "csrf_token": csrf_token, } - output = self.app.post( - '/admin/test_election/candidates/new', data=data) + output = self.app.post("/admin/test_election/candidates/new", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('Add candidate' in output_text) + self.assertTrue("Add candidate" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="name" name="name" ' - 'required type="text"', output_text) + 'required type="text"', + output_text, + ) else: self.assertIn( 'input class="form-control" id="name" name="name" ' - 'type="text"', output_text) + 'type="text"', + output_text, + ) self.assertTrue( '' - in output_text) + in output_text + ) data = { - 'name': 'pingou', - 'url': '', - 'csrf_token': csrf_token, + "name": "pingou", + "url": "", + "csrf_token": csrf_token, } with mock_sends(NewCandidateV1): output = self.app.post( - '/admin/test_election/candidates/new', data=data, - follow_redirects=True) + "/admin/test_election/candidates/new", + data=data, + follow_redirects=True, + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) + self.assertTrue('Candidate "pingou" saved' in output_text) self.assertTrue( - 'Candidate "pingou" saved' - in output_text) - self.assertTrue('Candidates 4' in output_text) + 'Candidates 4' + in output_text + ) def test_admin_add_multi_candidate(self): """ Test the admin_add_multi_candidate function. """ user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'], - username='toshio') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"], + username="toshio", + ) + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/test_election/candidates/new/multi') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/test_election/candidates/new/multi") self.assertEqual(output.status_code, 404) self.setup_db() - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/test_election/candidates/new/multi') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/test_election/candidates/new/multi") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('Add candidates' in output_text) + self.assertTrue("Add candidates" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="candidate" ' - 'name="candidate" required type="text"', output_text) + 'name="candidate" required type="text"', + output_text, + ) else: self.assertIn( 'input class="form-control" id="candidate" ' - 'name="candidate" type="text"', output_text) + 'name="candidate" type="text"', + output_text, + ) data = { - 'candidate': 'pingou', + "candidate": "pingou", } output = self.app.post( - '/admin/test_election/candidates/new/multi', data=data) + "/admin/test_election/candidates/new/multi", data=data + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('Add candidates' in output_text) + self.assertTrue("Add candidates" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="candidate" ' - 'name="candidate" required type="text"', output_text) + 'name="candidate" required type="text"', + output_text, + ) else: self.assertIn( 'input class="form-control" id="candidate" ' - 'name="candidate" type="text"', output_text) + 'name="candidate" type="text"', + output_text, + ) csrf_token = self.get_csrf(output=output) data = { - 'candidate': '', - 'csrf_token': csrf_token, + "candidate": "", + "csrf_token": csrf_token, } output = self.app.post( - '/admin/test_election/candidates/new/multi', data=data) + "/admin/test_election/candidates/new/multi", data=data + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('Add candidates' in output_text) + self.assertTrue("Add candidates" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="candidate" ' - 'name="candidate" required type="text"', output_text) + 'name="candidate" required type="text"', + output_text, + ) else: self.assertIn( 'input class="form-control" id="candidate" ' - 'name="candidate" type="text"', output_text) + 'name="candidate" type="text"', + output_text, + ) self.assertTrue( '' - in output_text) + in output_text + ) data = { - 'candidate': 'pingou|patrick!https://fedoraproject.org|' - 'shaiton!https://fedoraproject.org!test|sochotni', - 'csrf_token': csrf_token, + "candidate": "pingou|patrick!https://fedoraproject.org|" + "shaiton!https://fedoraproject.org!test|sochotni", + "csrf_token": csrf_token, } with mock_sends(NewCandidateV1, NewCandidateV1, NewCandidateV1): output = self.app.post( - '/admin/test_election/candidates/new/multi', data=data, - follow_redirects=True) + "/admin/test_election/candidates/new/multi", + data=data, + follow_redirects=True, + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) + self.assertTrue("Added 3 candidates" in output_text) self.assertTrue( - 'Added 3 candidates' - in output_text) - self.assertTrue('Candidates 6' in output_text) + 'Candidates 6' + in output_text + ) def test_admin_edit_candidate(self): """ Test the admin_edit_candidate function. """ user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'], - username='toshio') + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"], + username="toshio", + ) self.setup_db() # Election does not exist - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/test/candidates/1/edit') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/test/candidates/1/edit") self.assertEqual(output.status_code, 404) # Candidate does not exist - output = self.app.get('/admin/test_election/candidates/100/edit') + output = self.app.get("/admin/test_election/candidates/100/edit") self.assertEqual(output.status_code, 404) # Candidate not in election - output = self.app.get('/admin/test_election/candidates/5/edit') + output = self.app.get("/admin/test_election/candidates/5/edit") self.assertEqual(output.status_code, 404) - output = self.app.get('/admin/test_election/candidates/1/edit') + output = self.app.get("/admin/test_election/candidates/1/edit") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('Edit candidate' in output_text) + self.assertTrue("Edit candidate" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="name" name="name" ' - 'required type="text"', output_text) + 'required type="text"', + output_text, + ) else: self.assertIn( 'input class="form-control" id="name" name="name" ' - 'type="text"', output_text) + 'type="text"', + output_text, + ) data = { - 'name': 'Toshio Kuratomi', - 'url': 'https://fedoraproject.org/wiki/User:Toshio', + "name": "Toshio Kuratomi", + "url": "https://fedoraproject.org/wiki/User:Toshio", } - self.assertTrue('Edit candidate' in output_text) + self.assertTrue("Edit candidate" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="name" name="name" ' - 'required type="text"', output_text) + 'required type="text"', + output_text, + ) else: self.assertIn( 'input class="form-control" id="name" name="name" ' - 'type="text"', output_text) + 'type="text"', + output_text, + ) csrf_token = self.get_csrf(output=output) data = { - 'name': '', - 'csrf_token': csrf_token, + "name": "", + "csrf_token": csrf_token, } output = self.app.post( - '/admin/test_election/candidates/1/edit', data=data) + "/admin/test_election/candidates/1/edit", data=data + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('Edit candidate' in output_text) + self.assertTrue("Edit candidate" in output_text) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="name" name="name" ' - 'required type="text"', output_text) + 'required type="text"', + output_text, + ) else: self.assertIn( 'input class="form-control" id="name" name="name" ' - 'type="text"', output_text) + 'type="text"', + output_text, + ) self.assertTrue( '' - in output_text) + in output_text + ) # Check election before edit - output = self.app.get('/admin/test_election/') + output = self.app.get("/admin/test_election/") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('Candidates 3' in output_text) + self.assertTrue( + 'Candidates 3' + in output_text + ) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" required type="text" value="1"', - output_text) + output_text, + ) else: self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" type="text" value="1"', - output_text) + output_text, + ) self.assertTrue('
Toshio' in output_text) data = { - 'name': 'Toshio Kuratomi', - 'url': 'https://fedoraproject.org/wiki/User:Toshio', - 'csrf_token': csrf_token, + "name": "Toshio Kuratomi", + "url": "https://fedoraproject.org/wiki/User:Toshio", + "csrf_token": csrf_token, } with mock_sends(EditCandidateV1): output = self.app.post( - '/admin/test_election/candidates/1/edit', data=data, - follow_redirects=True) + "/admin/test_election/candidates/1/edit", + data=data, + follow_redirects=True, + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) + self.assertTrue('Candidate "Toshio Kuratomi" saved' in output_text) self.assertTrue( - 'Candidate "Toshio Kuratomi" saved' - in output_text) - self.assertTrue('Candidates 3' in output_text) + 'Candidates 3' + in output_text + ) self.assertTrue('
Toshio' in output_text) def test_admin_delete_candidate(self): """ Test the admin_delete_candidate function. """ user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'], - username='toshio') + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"], + username="toshio", + ) self.setup_db() # Election does not exist - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get('/admin/test/candidates/1/delete') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/admin/test/candidates/1/delete") self.assertEqual(output.status_code, 404) # Candidate does not exist - output = self.app.get('/admin/test_election/candidates/100/delete') + output = self.app.get("/admin/test_election/candidates/100/delete") self.assertEqual(output.status_code, 404) # Candidate not in election - output = self.app.get('/admin/test_election/candidates/5/delete') + output = self.app.get("/admin/test_election/candidates/5/delete") self.assertEqual(output.status_code, 404) - output = self.app.get('/admin/test_election/candidates/1/delete') + output = self.app.get("/admin/test_election/candidates/1/delete") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue('

Delete candidate

' in output_text) + self.assertTrue("

Delete candidate

" in output_text) self.assertTrue( 'p>Are you sure you want to delete candidate "Toshio"?Delete candidate' in output_text) + self.assertTrue("

Delete candidate

" in output_text) self.assertTrue( 'p>Are you sure you want to delete candidate "Toshio"?test election shortdesc' in output_text) + self.assertTrue("

test election shortdesc

" in output_text) self.assertTrue( - 'Could not delete this candidate. Is it ' - 'already part of an election?' in output_text) + "Could not delete this candidate. Is it " + "already part of an election?" in output_text + ) # Check election before edit - output = self.app.get('/admin/test_election4/') + output = self.app.get("/admin/test_election4/") output_text = output.get_data(as_text=True) - self.assertTrue('Candidates 2' in output_text) + self.assertTrue( + 'Candidates 2' + in output_text + ) if self.get_wtforms_version() >= (2, 2): self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" required type="text" value="1"', - output_text) + output_text, + ) else: self.assertIn( 'input class="form-control" id="seats_elected" ' 'name="seats_elected" type="text" value="1"', - output_text) + output_text, + ) self.assertTrue('
Toshio' in output_text) - self.assertTrue( - 'value="test election 4 shortdesc">' in output_text) + self.assertTrue('value="test election 4 shortdesc">' in output_text) # Delete one candidate data = { - 'csrf_token': csrf_token, + "csrf_token": csrf_token, } with mock_sends(DeleteCandidateV1): output = self.app.post( - '/admin/test_election4/candidates/10/delete', data=data, - follow_redirects=True) + "/admin/test_election4/candidates/10/delete", + data=data, + follow_redirects=True, + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) + self.assertTrue('Candidate "Toshio" deleted' in output_text) + self.assertTrue('value="test election 4 shortdesc">' in output_text) self.assertTrue( - 'Candidate "Toshio" deleted' - in output_text) - self.assertTrue( - 'value="test election 4 shortdesc">' in output_text) - self.assertTrue('Candidates 1' in output_text) + 'Candidates 1' + in output_text + ) self.assertFalse('
Toshio' in output_text) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(FlaskAdmintests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/tests/test_flask_elections.py b/tests/test_flask_elections.py index 09e99cc..f51e9b2 100644 --- a/tests/test_flask_elections.py +++ b/tests/test_flask_elections.py @@ -20,7 +20,7 @@ fedora_elections.elections test script """ -__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4'] +__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] import pkg_resources import logging @@ -34,8 +34,7 @@ from datetime import timedelta import flask from mock import patch, MagicMock -sys.path.insert(0, os.path.join(os.path.dirname( - os.path.abspath(__file__)), '..')) +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 @@ -47,249 +46,243 @@ class FlaskElectionstests(ModelFlasktests): def test_vote_empty(self): """ Test the vote function without data. """ - output = self.app.get('/vote/test_election') + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) output_text = output.get_data(as_text=True) self.assertIn( - '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election', - output_text) + "/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election", output_text + ) - user = FakeUser(['packager'], username='pingou') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["packager"], username="pingou") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['packager'])): - output = self.app.get('/vote/test_election') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["packager"]), + ): + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) - output = self.app.get('/vote/test_election', follow_redirects=True) + output = self.app.get("/vote/test_election", follow_redirects=True) output_text = output.get_data(as_text=True) self.assertTrue( - 'The election, test_election, does not exist.' - in output_text) + "The election, test_election, does not exist." in output_text + ) def test_vote(self): """ Test the vote function. """ - output = self.app.get('/vote/test_election') + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) output_text = output.get_data(as_text=True) self.assertIn( - '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election', - output_text) + "/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election", output_text + ) self.setup_db() - user = FakeUser([], username='pingou', cla_done=False) + user = FakeUser([], username="pingou", cla_done=False) with user_set(fedora_elections.APP, user): - output = self.app.get('/vote/test_election') + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) - output = self.app.get( - '/vote/test_election', follow_redirects=True) + output = self.app.get("/vote/test_election", follow_redirects=True) output_text = output.get_data(as_text=True) - self.assertTrue( - 'You must sign the CLA to vote' - in output_text) + self.assertTrue("You must sign the CLA to vote" in output_text) - user = FakeUser([], username='pingou') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser([], username="pingou") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=[])): + "fedora_elections.OIDC.user_getfield", MagicMock(return_value=[]) + ): - output = self.app.get('/vote/test_election') + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) - output = self.app.get( - '/vote/test_election', follow_redirects=True) + output = self.app.get("/vote/test_election", follow_redirects=True) output_text = output.get_data(as_text=True) self.assertTrue( - 'You need to be in one another group than ' - 'CLA to vote' in output_text) + "You need to be in one another group than " + "CLA to vote" in output_text + ) - user = FakeUser(['packager'], username='pingou') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["packager"], username="pingou") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['packager'])): + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["packager"]), + ): - output = self.app.get('/vote/test_election3') + output = self.app.get("/vote/test_election3") self.assertEqual(output.status_code, 302) # Election closed and results open - output = self.app.get( - '/vote/test_election3', follow_redirects=True) + output = self.app.get("/vote/test_election3", follow_redirects=True) output_text = output.get_data(as_text=True) self.assertTrue( - 'You are not among the groups that are ' - 'allowed to vote for this election' in output_text) + "You are not among the groups that are " + "allowed to vote for this election" in output_text + ) - user = FakeUser(['voters'], username='pingou') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["voters"], username="pingou") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['voters'])): + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["voters"]), + ): - output = self.app.get('/vote/test_election') + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) # Election closed and results open - output = self.app.get( - '/vote/test_election', follow_redirects=True) + output = self.app.get("/vote/test_election", follow_redirects=True) output_text = output.get_data(as_text=True) self.assertTrue( 'Election Closed' - in output_text) + in output_text + ) # Election closed and results are embargoed - output = self.app.get( - '/vote/test_election2', follow_redirects=True) + output = self.app.get("/vote/test_election2", follow_redirects=True) output_text = output.get_data(as_text=True) self.assertTrue( 'Election Closed' - in output_text) + in output_text + ) # Election still pending - output = self.app.get( - '/vote/test_election4', follow_redirects=True) + output = self.app.get("/vote/test_election4", follow_redirects=True) output_text = output.get_data(as_text=True) - self.assertTrue( - 'Voting has not yet started, sorry.' - in output_text) + self.assertTrue("Voting has not yet started, sorry." in output_text) # Election in progress - output = self.app.get('/vote/test_election3') + output = self.app.get("/vote/test_election3") output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 3 shortdesc' in output_text) + self.assertTrue("test election 3 shortdesc" in output_text) self.assertTrue( '' - in output_text) + in output_text + ) # Election in progress - output = self.app.get('/vote/test_election5') + output = self.app.get("/vote/test_election5") output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 5 shortdesc' in output_text) + self.assertTrue("test election 5 shortdesc" in output_text) self.assertTrue( '' - in output_text) + in output_text + ) def test_election_results(self): """ Test the election_results function - the preview part. """ - output = self.app.get( - '/about/test_election', follow_redirects=True) + output = self.app.get("/about/test_election", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'The election, test_election, does not exist.' - in output_text) + self.assertTrue("The election, test_election, does not exist." in output_text) self.setup_db() - output = self.app.get('/about/test_election') + output = self.app.get("/about/test_election") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( 'Votes' - in output_text) - self.assertTrue( - '

Some statistics about this election

' - in output_text) + in output_text + ) + self.assertTrue("

Some statistics about this election

" in output_text) - output = self.app.get( - '/about/test_election2', follow_redirects=True) + output = self.app.get("/about/test_election2", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'The results for this election cannot be viewed because they are ' - in output_text) + "The results for this election cannot be viewed because they are " + in output_text + ) - user = FakeUser(['packager'], username='toshio') + user = FakeUser(["packager"], username="toshio") with user_set(fedora_elections.APP, user): - output = self.app.get( - '/about/test_election2', follow_redirects=True) + output = self.app.get("/about/test_election2", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'The results for this election cannot be viewed because they are ' - in output_text) + "The results for this election cannot be viewed because they are " + in output_text + ) user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'], - username='toshio') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"], + username="toshio", + ) + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): - output = self.app.get( - '/about/test_election2', follow_redirects=True) + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): + output = self.app.get("/about/test_election2", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'You are only seeing these results because you are an admin.' - in output_text) + "You are only seeing these results because you are an admin." + in output_text + ) self.assertTrue( - 'The results for this election are currently embargoed ' - in output_text) + "The results for this election are currently embargoed " + in output_text + ) self.assertTrue( 'Votes' - in output_text) + in output_text + ) self.assertTrue( - '

Some statistics about this election

' - in output_text) + "

Some statistics about this election

" in output_text + ) - user = FakeUser(['gitr2spec'], username='kevin') + user = FakeUser(["gitr2spec"], username="kevin") with user_set(fedora_elections.APP, user): - output = self.app.get( - '/about/test_election3', follow_redirects=True) + output = self.app.get("/about/test_election3", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'Election Open' - in output_text) + 'Election Open' in output_text + ) def test_election_results_text(self): """ Test the election_results_text function - the preview part. """ - output = self.app.get( - '/results/test_election/text', follow_redirects=True) + output = self.app.get("/results/test_election/text", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'The election, test_election, does not exist.' - in output_text) + self.assertTrue("The election, test_election, does not exist." in output_text) self.setup_db() - output = self.app.get( - '/results/test_election/text', follow_redirects=True) + output = self.app.get("/results/test_election/text", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'The text results are only available to the ' - 'admins' in output_text) + "The text results are only available to the " "admins" in output_text + ) - user = FakeUser(['packager'], username='toshio') + user = FakeUser(["packager"], username="toshio") with user_set(fedora_elections.APP, user): - output = self.app.get( - '/results/test_election2/text', follow_redirects=True) + output = self.app.get("/results/test_election2/text", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'The text results are only available to the ' - 'admins' in output_text) - self.assertTrue('

Elections' in output_text) + "The text results are only available to the " "admins" in output_text + ) + self.assertTrue("

Elections" in output_text) user = FakeUser( - fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'], - username='toshio') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + fedora_elections.APP.config["FEDORA_ELECTIONS_ADMIN_GROUP"], + username="toshio", + ) + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['elections'])): + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["elections"]), + ): output = self.app.get( - '/results/test_election/text', follow_redirects=True) + "/results/test_election/text", follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) exp = """ @@ -332,7 +325,8 @@ candidates for running this elections! self.assertEqual(output_text, exp) output = self.app.get( - '/results/test_election2/text', follow_redirects=True) + "/results/test_election2/text", follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) exp = """ @@ -370,18 +364,18 @@ candidates for running this elections! self.assertEqual(output_text, exp) - user = FakeUser(['gitr2spec'], username='kevin') + user = FakeUser(["gitr2spec"], username="kevin") with user_set(fedora_elections.APP, user): - output = self.app.get( - '/results/test_election3/text', follow_redirects=True) + output = self.app.get("/results/test_election3/text", follow_redirects=True) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'Sorry but this election is in progress,' - ' and you may not see its results yet.' in output_text) - self.assertTrue('Open elections' in output_text) + "Sorry but this election is in progress," + " and you may not see its results yet." in output_text + ) + self.assertTrue("Open elections" in output_text) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(FlaskElectionstests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/tests/test_flask_irc.py b/tests/test_flask_irc.py index 628ace6..c4b8c3e 100644 --- a/tests/test_flask_irc.py +++ b/tests/test_flask_irc.py @@ -20,7 +20,7 @@ fedora_elections.elections test script """ -__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4'] +__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] import pkg_resources import logging @@ -34,8 +34,7 @@ from datetime import timedelta import flask from mock import patch, MagicMock -sys.path.insert(0, os.path.join(os.path.dirname( - os.path.abspath(__file__)), '..')) +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 @@ -47,163 +46,168 @@ class FlaskIrcElectionstests(ModelFlasktests): def test_vote_irc(self): """ Test the vote_irc function - the preview part. """ - output = self.app.get('/vote/test_election') + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) output_text = output.get_data(as_text=True) self.assertIn( - '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election', - output_text) + "/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election", output_text + ) self.setup_db() - user = FakeUser(['packager'], username='nerdsville') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["packager"], username="nerdsville") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['packager'])): - output = self.app.get('/vote/test_election7') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["packager"]), + ): + output = self.app.get("/vote/test_election7") output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 7 shortdesc' in output_text) + self.assertTrue("test election 7 shortdesc" in output_text) self.assertTrue( '' - in output_text) + in output_text + ) csrf_token = output_text.split( - 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + 'name="csrf_token" type="hidden" value="' + )[1].split('">')[0] # Invalid vote: No candidate data = { - 'action': 'preview', + "action": "preview", } - output = self.app.post('/vote/test_election7', data=data) + output = self.app.post("/vote/test_election7", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 7 shortdesc' in output_text) + self.assertTrue("test election 7 shortdesc" in output_text) # Valid input data = { - 'Kevin': -1, - 'Toshio': '0', - 'action': 'preview', - 'csrf_token': csrf_token, + "Kevin": -1, + "Toshio": "0", + "action": "preview", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election7', data=data) + output = self.app.post("/vote/test_election7", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 7 shortdesc' in output_text) + self.assertTrue("test election 7 shortdesc" in output_text) self.assertTrue( '' - in output_text) - self.assertTrue( - 'Please confirm your vote!' - in output_text) + in output_text + ) + self.assertTrue("Please confirm your vote!" in output_text) def test_vote_irc_process(self): """ Test the vote_irc function - the voting part. """ - output = self.app.get('/vote/test_election') + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) output_text = output.get_data(as_text=True) self.assertIn( - '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election', - output_text) + "/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election", output_text + ) self.setup_db() - user = FakeUser(['packager'], username='pingou') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["packager"], username="pingou") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['packager'])): + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["packager"]), + ): # Invalid candidate id - no csrf data = { - 'candidate': 1, - 'action': 'submit', + "candidate": 1, + "action": "submit", } output = self.app.post( - '/vote/test_election7', data=data, - follow_redirects=True) + "/vote/test_election7", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) csrf_token = output_text.split( - 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + 'name="csrf_token" type="hidden" value="' + )[1].split('">')[0] # Valid input data = { - 'Toshio': '0', - 'Kevin': '1', - 'action': 'submit', - 'csrf_token': csrf_token, + "Toshio": "0", + "Kevin": "1", + "action": "submit", + "csrf_token": csrf_token, } output = self.app.post( - '/vote/test_election7', data=data, - follow_redirects=True) + "/vote/test_election7", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'Your vote has been recorded. Thank you!' - in output_text) - self.assertTrue('Open elections' in output_text) + "Your vote has been recorded. Thank you!" in output_text + ) + self.assertTrue("Open elections" in output_text) def test_vote_irc_revote(self): """ Test the vote_irc function - the re-voting part. """ - #First we need to vote + # First we need to vote self.setup_db() - user = FakeUser(['voters'], username='nerdsville') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["voters"], username="nerdsville") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['packager'])): - retrieve_csrf = self.app.post('/vote/test_election7') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["packager"]), + ): + retrieve_csrf = self.app.post("/vote/test_election7") output_text = retrieve_csrf.get_data(as_text=True) csrf_token = output_text.split( - 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + 'name="csrf_token" type="hidden" value="' + )[1].split('">')[0] # Valid input data = { - 'Kevin': -1, - 'Toshio': 1, - 'action': 'submit', - 'csrf_token': csrf_token, + "Kevin": -1, + "Toshio": 1, + "action": "submit", + "csrf_token": csrf_token, } - self.app.post('/vote/test_election7', data=data, follow_redirects=True) + self.app.post("/vote/test_election7", data=data, follow_redirects=True) vote = fedora_elections.models.Vote - votes = vote.of_user_on_election(self.session, "nerdsville", '7') + votes = vote.of_user_on_election(self.session, "nerdsville", "7") self.assertEqual(votes[0].value, 1) self.assertEqual(votes[1].value, -1) - #Let's not do repetition of what is tested above we aren't testing the - #functionality of voting as that has already been asserted + # Let's not do repetition of what is tested above we aren't testing the + # functionality of voting as that has already been asserted - #Next, we need to try revoting + # Next, we need to try revoting newdata = { - 'Kevin': 1, - 'Toshio': -1, - 'action': 'submit', - 'csrf_token': csrf_token, + "Kevin": 1, + "Toshio": -1, + "action": "submit", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election7', data=newdata, follow_redirects=True) - #Next, we need to check if the vote has been recorded + output = self.app.post( + "/vote/test_election7", data=newdata, follow_redirects=True + ) + # Next, we need to check if the vote has been recorded self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'Your vote has been recorded. Thank you!' - in output_text) - self.assertTrue('Open elections' in output_text) + "Your vote has been recorded. Thank you!" in output_text + ) + self.assertTrue("Open elections" in output_text) vote = fedora_elections.models.Vote - votes = vote.of_user_on_election(self.session, "nerdsville", '7') + votes = vote.of_user_on_election(self.session, "nerdsville", "7") self.assertEqual(votes[0].value, -1) self.assertEqual(votes[1].value, 1) - #If we haven't failed yet, HOORAY! + # If we haven't failed yet, HOORAY! -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(FlaskIrcElectionstests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/tests/test_flask_range_voting.py b/tests/test_flask_range_voting.py index b1592c8..48fb0dd 100644 --- a/tests/test_flask_range_voting.py +++ b/tests/test_flask_range_voting.py @@ -20,7 +20,7 @@ fedora_elections.elections test script """ -__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4'] +__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] import pkg_resources import logging @@ -34,8 +34,7 @@ from datetime import timedelta import flask from mock import patch, MagicMock -sys.path.insert(0, os.path.join(os.path.dirname( - os.path.abspath(__file__)), '..')) +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 @@ -47,326 +46,366 @@ class FlaskRangeElectionstests(ModelFlasktests): def test_vote_range(self): """ Test the vote_range function - the preview part. """ - output = self.app.get('/vote/test_election') + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) output_text = output.get_data(as_text=True) self.assertIn( - '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election', - output_text) + "/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election", output_text + ) self.setup_db() - user = FakeUser(['voters'], username='pingou') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["voters"], username="pingou") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['voters'])): - output = self.app.get('/vote/test_election3') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["voters"]), + ): + output = self.app.get("/vote/test_election3") output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 3 shortdesc' in output_text) + self.assertTrue("test election 3 shortdesc" in output_text) self.assertTrue( '' - in output_text) + in output_text + ) # Invalid candidate id data = { - 'Toshio': 1, - 'kevin': 3, - 'Ralph': 2, - 'action': 'preview', + "Toshio": 1, + "kevin": 3, + "Ralph": 2, + "action": "preview", } - output = self.app.post('/vote/test_election3', data=data) + output = self.app.post("/vote/test_election3", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertEqual( - output_text.count(''), - 3) + output_text.count( + '' + ), + 3, + ) csrf_token = output_text.split( - 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + '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, + "Toshio": 1, + "Kevin": 3, + "Ralph": 2, + "action": "preview", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election3', data=data) + output = self.app.post("/vote/test_election3", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertEqual( - output_text.count(''), - 3) + output_text.count( + '' + ), + 3, + ) # Invalid vote: too low data = { - '9': -1, - '6': 0, - '5': 2, - 'action': 'preview', - 'csrf_token': csrf_token, + "9": -1, + "6": 0, + "5": 2, + "action": "preview", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election3', data=data) + output = self.app.post("/vote/test_election3", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 3 shortdesc' in output_text) + self.assertTrue("test election 3 shortdesc" in output_text) self.assertTrue( '' - in output_text) + in output_text + ) self.assertEqual( - output_text.count(''), - 1) + output_text.count( + '' + ), + 1, + ) # Invalid vote: 2 are too high data = { - '9': 5, - '6': 3, - '5': 2, - 'action': 'preview', - 'csrf_token': csrf_token, + "9": 5, + "6": 3, + "5": 2, + "action": "preview", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election3', data=data) + output = self.app.post("/vote/test_election3", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 3 shortdesc' in output_text) + self.assertTrue("test election 3 shortdesc" in output_text) self.assertTrue( '' - in output_text) + in output_text + ) self.assertEqual( - output_text.count(''), - 2) + output_text.count( + '' + ), + 2, + ) # Invalid vote: Not numeric data = { - '9': 'a', - '6': 0, - '5': 2, - 'action': 'preview', - 'csrf_token': csrf_token, + "9": "a", + "6": 0, + "5": 2, + "action": "preview", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election3', data=data) + output = self.app.post("/vote/test_election3", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 3 shortdesc' in output_text) + self.assertTrue("test election 3 shortdesc" in output_text) self.assertTrue( '' - in output_text) + in output_text + ) self.assertEqual( - output_text.count(''), - 1) + output_text.count( + '' + ), + 1, + ) # Valid input data = { - '4': 1, - '6': 0, - '5': 2, - 'action': 'preview', - 'csrf_token': csrf_token, + "4": 1, + "6": 0, + "5": 2, + "action": "preview", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election3', data=data) + output = self.app.post("/vote/test_election3", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 3 shortdesc' in output_text) + self.assertTrue("test election 3 shortdesc" in output_text) self.assertTrue( '' - in output_text) + in output_text + ) def test_vote_range_process(self): """ Test the vote_range function - the voting part. """ - output = self.app.get('/vote/test_election') + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) output_text = output.get_data(as_text=True) self.assertIn( - '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election', - output_text) + "/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election", output_text + ) self.setup_db() - user = FakeUser(['voters'], username='pingou') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["voters"], username="pingou") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['voters'])): + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["voters"]), + ): # No csrf token provided data = { - 'Toshio': 1, - 'Kevin': 3, - 'Ralph': 2, - 'action': 'submit', + "Toshio": 1, + "Kevin": 3, + "Ralph": 2, + "action": "submit", } - output = self.app.post('/vote/test_election3', data=data) + output = self.app.post("/vote/test_election3", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertEqual( - output_text.count(''), - 3) + output_text.count( + '' + ), + 3, + ) csrf_token = output_text.split( - 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + 'name="csrf_token" type="hidden" value="' + )[1].split('">')[0] # Invalid vote: invalid username data = { - 'Toshio': 1, - 'Kevin': 3, - 'Ralph': 2, - 'action': 'submit', + "Toshio": 1, + "Kevin": 3, + "Ralph": 2, + "action": "submit", } - output = self.app.post('/vote/test_election3', data=data) + output = self.app.post("/vote/test_election3", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertEqual( - output_text.count(''), - 3) + output_text.count( + '' + ), + 3, + ) # Invalid vote: too low data = { - '4': -1, - '5': 0, - '6': 2, - 'action': 'submit', - 'csrf_token': csrf_token, + "4": -1, + "5": 0, + "6": 2, + "action": "submit", + "csrf_token": csrf_token, } - output = self.app.post( - '/vote/test_election3', data=data) + output = self.app.post("/vote/test_election3", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertEqual( - output_text.count(''), - 1) + output_text.count( + '' + ), + 1, + ) # Invalid vote: 2 are too high data = { - '4': 5, - '5': 3, - '6': 2, - 'action': 'submit', - 'csrf_token': csrf_token, + "4": 5, + "5": 3, + "6": 2, + "action": "submit", + "csrf_token": csrf_token, } output = self.app.post( - '/vote/test_election3', data=data, follow_redirects=True) + "/vote/test_election3", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertEqual( - output_text.count(''), - 2) + output_text.count( + '' + ), + 2, + ) # Invalid vote: Not numeric data = { - '4': 'a', - '5': 0, - '6': 2, - 'action': 'submit', - 'csrf_token': csrf_token, + "4": "a", + "5": 0, + "6": 2, + "action": "submit", + "csrf_token": csrf_token, } output = self.app.post( - '/vote/test_election3', data=data, follow_redirects=True) + "/vote/test_election3", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertEqual( - output_text.count(''), - 1) + output_text.count( + '' + ), + 1, + ) # Valid input data = { - '4': 1, - '5': 0, - '6': 2, - 'action': 'submit', - 'csrf_token': csrf_token, + "4": 1, + "5": 0, + "6": 2, + "action": "submit", + "csrf_token": csrf_token, } output = self.app.post( - '/vote/test_election3', data=data, follow_redirects=True) + "/vote/test_election3", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'Your vote has been recorded. Thank you!' - in output_text) - self.assertTrue('Open elections' in output_text) + "Your vote has been recorded. Thank you!" in output_text + ) + self.assertTrue("Open elections" in output_text) def test_vote_range_revote(self): """ Test the vote_range function - the re-voting part. """ - #First we need to vote + # First we need to vote self.setup_db() - user = FakeUser(['voters'], username='nerdsville') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["voters"], username="nerdsville") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['voters'])): - retrieve_csrf = self.app.post('/vote/test_election3') - csrf_token = retrieve_csrf.get_data(as_text=True).split( - 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["voters"]), + ): + retrieve_csrf = self.app.post("/vote/test_election3") + csrf_token = ( + retrieve_csrf.get_data(as_text=True) + .split('name="csrf_token" type="hidden" value="')[1] + .split('">')[0] + ) data = { - '4': 1, - '5': 0, - '6': 2, - 'action': 'submit', - 'csrf_token': csrf_token, + "4": 1, + "5": 0, + "6": 2, + "action": "submit", + "csrf_token": csrf_token, } - self.app.post('/vote/test_election3', data=data, follow_redirects=True) + self.app.post("/vote/test_election3", data=data, follow_redirects=True) vote = fedora_elections.models.Vote - votes = vote.of_user_on_election(self.session, "nerdsville", '3') + votes = vote.of_user_on_election(self.session, "nerdsville", "3") self.assertEqual(votes[0].value, 1) self.assertEqual(votes[1].value, 0) self.assertEqual(votes[2].value, 2) - #Let's not do repetition of what is tested above we aren't testing the - #functionality of voting as that has already been asserted + # Let's not do repetition of what is tested above we aren't testing the + # functionality of voting as that has already been asserted obj = fedora_elections.models.Candidate( # id:16 election_id=3, - name='Josh', - url='https://fedoraproject.org/wiki/User:Nerdsville', + name="Josh", + url="https://fedoraproject.org/wiki/User:Nerdsville", ) self.session.add(obj) self.session.commit() - - #Next, we need to try revoting + # Next, we need to try revoting newdata = { - '4': 2, - '5': 1, - '6': 1, - '16': 0, - 'action': 'submit', - 'csrf_token': csrf_token, + "4": 2, + "5": 1, + "6": 1, + "16": 0, + "action": "submit", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election3', data=newdata, follow_redirects=True) - #Next, we need to check if the vote has been recorded + output = self.app.post( + "/vote/test_election3", data=newdata, follow_redirects=True + ) + # Next, we need to check if the vote has been recorded self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'Your vote has been recorded. Thank you!' - in output_text) - self.assertTrue('Open elections' in output_text) + "Your vote has been recorded. Thank you!" in output_text + ) + self.assertTrue("Open elections" in output_text) vote = fedora_elections.models.Vote - votes = vote.of_user_on_election(self.session, "nerdsville", '3') + votes = vote.of_user_on_election(self.session, "nerdsville", "3") self.assertEqual(votes[0].value, 2) self.assertEqual(votes[1].value, 1) self.assertEqual(votes[2].value, 1) self.assertEqual(votes[3].value, 0) - #If we haven't failed yet, HOORAY! + # If we haven't failed yet, HOORAY! -if __name__ == '__main__': - SUITE = unittest.TestLoader().loadTestsFromTestCase( - FlaskRangeElectionstests) +if __name__ == "__main__": + SUITE = unittest.TestLoader().loadTestsFromTestCase(FlaskRangeElectionstests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/tests/test_flask_select_voting.py b/tests/test_flask_select_voting.py index 1dc268a..1d3b635 100644 --- a/tests/test_flask_select_voting.py +++ b/tests/test_flask_select_voting.py @@ -20,7 +20,7 @@ fedora_elections.elections test script """ -__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4'] +__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] import pkg_resources import logging @@ -34,8 +34,7 @@ from datetime import timedelta import flask from mock import patch, MagicMock -sys.path.insert(0, os.path.join(os.path.dirname( - os.path.abspath(__file__)), '..')) +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 @@ -47,180 +46,184 @@ class FlaskSimpleElectionstests(ModelFlasktests): def test_vote_select(self): """ Test the vote_select function - the preview part. """ - output = self.app.get('/vote/test_election') + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) output_text = output.get_data(as_text=True) self.assertIn( - '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election', - output_text) + "/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election", output_text + ) self.setup_db() - user = FakeUser(['packager'], username='pingou') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["packager"], username="pingou") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['packager'])): - output = self.app.get('/vote/test_election6') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["packager"]), + ): + output = self.app.get("/vote/test_election6") output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 6 shortdesc' in output_text) + self.assertTrue("test election 6 shortdesc" in output_text) self.assertTrue( '' - in output_text) + in output_text + ) csrf_token = output_text.split( - 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + 'name="csrf_token" type="hidden" value="' + )[1].split('">')[0] # Invalid vote: No candidate data = { - 'action': 'preview', + "action": "preview", } - output = self.app.post('/vote/test_election6', data=data) + output = self.app.post("/vote/test_election6", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 6 shortdesc' in output_text) + self.assertTrue("test election 6 shortdesc" in output_text) # Invalid vote: Too many candidates data = { - 'Kevin': True, - 'Toshio': True, - 'action': 'preview', - 'csrf_token': csrf_token, + "Kevin": True, + "Toshio": True, + "action": "preview", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election6', data=data) + output = self.app.post("/vote/test_election6", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 6 shortdesc' in output_text) + self.assertTrue("test election 6 shortdesc" in output_text) self.assertTrue( '' - in output_text) - self.assertTrue( - 'Too many candidates submitted' - in output_text) + in output_text + ) + self.assertTrue("Too many candidates submitted" in output_text) # Valid input data = { - 'Kevin': True, - 'action': 'preview', - 'csrf_token': csrf_token, + "Kevin": True, + "action": "preview", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election6', data=data) + output = self.app.post("/vote/test_election6", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 6 shortdesc' in output_text) + self.assertTrue("test election 6 shortdesc" in output_text) self.assertTrue( '' - in output_text) - self.assertTrue( - 'Please confirm your vote!' - in output_text) + in output_text + ) + self.assertTrue("Please confirm your vote!" in output_text) def test_vote_select_process(self): """ Test the vote_select function - the voting part. """ - output = self.app.get('/vote/test_election') + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) output_text = output.get_data(as_text=True) self.assertIn( - '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election', - output_text) + "/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election", output_text + ) self.setup_db() - user = FakeUser(['packager'], username='pingou') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["packager"], username="pingou") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['packager'])): + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["packager"]), + ): # Invalid candidate id - no csrf data = { - 'candidate': 1, - 'action': 'submit', + "candidate": 1, + "action": "submit", } output = self.app.post( - '/vote/test_election6', data=data, - follow_redirects=True) + "/vote/test_election6", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) csrf_token = output_text.split( - 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + 'name="csrf_token" type="hidden" value="' + )[1].split('">')[0] # Valid input data = { - 'Toshio': True, - 'action': 'submit', - 'csrf_token': csrf_token, + "Toshio": True, + "action": "submit", + "csrf_token": csrf_token, } output = self.app.post( - '/vote/test_election6', data=data, - follow_redirects=True) + "/vote/test_election6", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'Your vote has been recorded. Thank you!' - in output_text) - self.assertTrue('Open elections' in output_text) + "Your vote has been recorded. Thank you!" in output_text + ) + self.assertTrue("Open elections" in output_text) def test_vote_select_revote(self): """ Test the vote_select function - the re-voting part. """ - #First we need to vote + # First we need to vote self.setup_db() - user = FakeUser(['voters'], username='nerdsville') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["voters"], username="nerdsville") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['voters'])): - retrieve_csrf = self.app.post('/vote/test_election6') - csrf_token = retrieve_csrf.get_data(as_text=True).split( - 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["voters"]), + ): + retrieve_csrf = self.app.post("/vote/test_election6") + csrf_token = ( + retrieve_csrf.get_data(as_text=True) + .split('name="csrf_token" type="hidden" value="')[1] + .split('">')[0] + ) # Valid input data = { - 'Kevin': True, - 'action': 'submit', - 'csrf_token': csrf_token, + "Kevin": True, + "action": "submit", + "csrf_token": csrf_token, } - self.app.post('/vote/test_election6', data=data, follow_redirects=True) + self.app.post("/vote/test_election6", data=data, follow_redirects=True) vote = fedora_elections.models.Vote - votes = vote.of_user_on_election(self.session, "nerdsville", '6') + votes = vote.of_user_on_election(self.session, "nerdsville", "6") self.assertEqual(votes[0].candidate.name, "Toshio") self.assertEqual(votes[0].value, 0) self.assertEqual(votes[1].candidate.name, "Kevin") self.assertEqual(votes[1].value, 1) - #Next, we need to try revoting + # Next, we need to try revoting newdata = { - 'Toshio': True, - 'action': 'submit', - 'csrf_token': csrf_token, + "Toshio": True, + "action": "submit", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election6', data=newdata, follow_redirects=True) - #Next, we need to check if the vote has been recorded + output = self.app.post( + "/vote/test_election6", data=newdata, follow_redirects=True + ) + # Next, we need to check if the vote has been recorded self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'Your vote has been recorded. Thank you!' - in output_text) - self.assertTrue('Open elections' in output_text) + "Your vote has been recorded. Thank you!" in output_text + ) + self.assertTrue("Open elections" in output_text) vote = fedora_elections.models.Vote - votes = vote.of_user_on_election(self.session, "nerdsville", '6') + votes = vote.of_user_on_election(self.session, "nerdsville", "6") self.assertEqual(votes[0].value, 1) self.assertEqual(votes[1].value, 0) - #If we haven't failed yet, HOORAY! + # If we haven't failed yet, HOORAY! -if __name__ == '__main__': - SUITE = unittest.TestLoader().loadTestsFromTestCase( - FlaskSimpleElectionstests) +if __name__ == "__main__": + SUITE = unittest.TestLoader().loadTestsFromTestCase(FlaskSimpleElectionstests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/tests/test_flask_simple_voting.py b/tests/test_flask_simple_voting.py index ade65bd..ecaf486 100644 --- a/tests/test_flask_simple_voting.py +++ b/tests/test_flask_simple_voting.py @@ -20,7 +20,7 @@ fedora_elections.elections test script """ -__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4'] +__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] import pkg_resources import logging @@ -34,8 +34,7 @@ from datetime import timedelta import flask from mock import patch, MagicMock -sys.path.insert(0, os.path.join(os.path.dirname( - os.path.abspath(__file__)), '..')) +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 @@ -47,239 +46,241 @@ class FlaskSimpleElectionstests(ModelFlasktests): def test_vote_simple(self): """ Test the vote_simple function - the preview part. """ - output = self.app.get('/vote/test_election') + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) output_text = output.get_data(as_text=True) self.assertIn( - '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election', - output_text) + "/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election", output_text + ) self.setup_db() - user = FakeUser(['packager'], username='pingou') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["packager"], username="pingou") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['voters'])): - output = self.app.get('/vote/test_election5') + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["voters"]), + ): + output = self.app.get("/vote/test_election5") output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 5 shortdesc' in output_text) + self.assertTrue("test election 5 shortdesc" in output_text) self.assertTrue( '' - in output_text) + in output_text + ) # Invalid vote: No candidate data = { - 'action': 'preview', + "action": "preview", } - output = self.app.post('/vote/test_election5', data=data) + output = self.app.post("/vote/test_election5", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 5 shortdesc' in output_text) - self.assertTrue( - 'Preview your vote' - in output_text) + self.assertTrue("test election 5 shortdesc" in output_text) + self.assertTrue("Preview your vote" in output_text) self.assertTrue( '' - in output_text) + in output_text + ) csrf_token = output_text.split( - 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + 'name="csrf_token" type="hidden" value="' + )[1].split('">')[0] # Invalid vote: No candidate data = { - 'action': 'preview', - 'csrf_token': csrf_token, + "action": "preview", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election5', data=data) + output = self.app.post("/vote/test_election5", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 5 shortdesc' in output_text) - self.assertTrue( - 'Preview your vote' - in output_text) + self.assertTrue("test election 5 shortdesc" in output_text) + self.assertTrue("Preview your vote" in output_text) self.assertTrue( '' - in output_text) + in output_text + ) # Invalid vote: Not numeric data = { - 'candidate': 'a', - 'action': 'preview', - 'csrf_token': csrf_token, + "candidate": "a", + "action": "preview", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election5', data=data) + output = self.app.post("/vote/test_election5", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 5 shortdesc' in output_text) + self.assertTrue("test election 5 shortdesc" in output_text) self.assertTrue( '' - in output_text) - + in output_text + ) # Valid input data = { - 'candidate': 7, - 'action': 'preview', - 'csrf_token': csrf_token, + "candidate": 7, + "action": "preview", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election5', data=data) + output = self.app.post("/vote/test_election5", data=data) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) - self.assertTrue( - 'test election 5 shortdesc' in output_text) + self.assertTrue("test election 5 shortdesc" in output_text) self.assertTrue( '' - in output_text) - self.assertTrue( - 'Please confirm your vote!' - in output_text) + in output_text + ) + self.assertTrue("Please confirm your vote!" in output_text) def test_vote_simple_process(self): """ Test the vote_simple function - the voting part. """ - output = self.app.get('/vote/test_election') + output = self.app.get("/vote/test_election") self.assertEqual(output.status_code, 302) output_text = output.get_data(as_text=True) self.assertIn( - '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election', - output_text) + "/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election", output_text + ) self.setup_db() - user = FakeUser(['packager'], username='pingou') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["packager"], username="pingou") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['voters'])): + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["voters"]), + ): # Invalid candidate id - no csrf data = { - 'candidate': 1, - 'action': 'submit', + "candidate": 1, + "action": "submit", } output = self.app.post( - '/vote/test_election5', data=data, - follow_redirects=True) + "/vote/test_election5", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) csrf_token = output_text.split( - 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + 'name="csrf_token" type="hidden" value="' + )[1].split('">')[0] # Invalid candidate id data = { - 'candidate': 1, - 'action': 'submit', - 'csrf_token': csrf_token, + "candidate": 1, + "action": "submit", + "csrf_token": csrf_token, } output = self.app.post( - '/vote/test_election5', data=data, - follow_redirects=True) + "/vote/test_election5", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) # Invalid vote: too low data = { - 'candidate': -1, - 'action': 'submit', - 'csrf_token': csrf_token, + "candidate": -1, + "action": "submit", + "csrf_token": csrf_token, } output = self.app.post( - '/vote/test_election5', data=data, - follow_redirects=True) + "/vote/test_election5", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) # Invalid vote: Not numeric data = { - 'candidate': 'a', - 'action': 'submit', - 'csrf_token': csrf_token, + "candidate": "a", + "action": "submit", + "csrf_token": csrf_token, } output = self.app.post( - '/vote/test_election5', data=data, - follow_redirects=True) + "/vote/test_election5", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) # Valid input data = { - 'candidate': 8, - 'action': 'submit', - 'csrf_token': csrf_token, + "candidate": 8, + "action": "submit", + "csrf_token": csrf_token, } output = self.app.post( - '/vote/test_election5', data=data, - follow_redirects=True) + "/vote/test_election5", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'Your vote has been recorded. Thank you!' - in output_text) - self.assertTrue('Open elections' in output_text) + "Your vote has been recorded. Thank you!" in output_text + ) + self.assertTrue("Open elections" in output_text) def test_vote_simple_revote(self): """ Test the vote_simple function - the re-voting part. """ - #First we need to vote + # First we need to vote self.setup_db() - user = FakeUser(['voters'], username='nerdsville') - with user_set(fedora_elections.APP, user, oidc_id_token='foobar'): + user = FakeUser(["voters"], username="nerdsville") + with user_set(fedora_elections.APP, user, oidc_id_token="foobar"): with patch( - 'fedora_elections.OIDC.user_getfield', - MagicMock(return_value=['voters'])): - retrieve_csrf = self.app.post('/vote/test_election5') - csrf_token = retrieve_csrf.get_data(as_text=True).split( - 'name="csrf_token" type="hidden" value="')[1].split('">')[0] + "fedora_elections.OIDC.user_getfield", + MagicMock(return_value=["voters"]), + ): + retrieve_csrf = self.app.post("/vote/test_election5") + csrf_token = ( + retrieve_csrf.get_data(as_text=True) + .split('name="csrf_token" type="hidden" value="')[1] + .split('">')[0] + ) # Valid input data = { - 'candidate': 8, - 'action': 'submit', - 'csrf_token': csrf_token, + "candidate": 8, + "action": "submit", + "csrf_token": csrf_token, } - self.app.post('/vote/test_election5', data=data, follow_redirects=True) + self.app.post("/vote/test_election5", data=data, follow_redirects=True) vote = fedora_elections.models.Vote - votes = vote.of_user_on_election(self.session, "nerdsville", '5') + votes = vote.of_user_on_election(self.session, "nerdsville", "5") self.assertEqual(votes[0].candidate_id, 8) - #Let's not do repetition of what is tested above we aren't testing the - #functionality of voting as that has already been asserted + # Let's not do repetition of what is tested above we aren't testing the + # functionality of voting as that has already been asserted - #Next, we need to try revoting + # Next, we need to try revoting # Valid input newdata = { - 'candidate': 9, - 'action': 'submit', - 'csrf_token': csrf_token, + "candidate": 9, + "action": "submit", + "csrf_token": csrf_token, } - output = self.app.post('/vote/test_election5', data=newdata, follow_redirects=True) - #Next, we need to check if the vote has been recorded + output = self.app.post( + "/vote/test_election5", data=newdata, follow_redirects=True + ) + # Next, we need to check if the vote has been recorded self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertTrue( - 'Your vote has been recorded. Thank you!' - in output_text) - self.assertTrue('Open elections' in output_text) + "Your vote has been recorded. Thank you!" in output_text + ) + self.assertTrue("Open elections" in output_text) vote = fedora_elections.models.Vote - votes = vote.of_user_on_election(self.session, "nerdsville", '5') + votes = vote.of_user_on_election(self.session, "nerdsville", "5") self.assertEqual(votes[0].candidate_id, 9) - #If we haven't failed yet, HOORAY! + # If we haven't failed yet, HOORAY! -if __name__ == '__main__': - SUITE = unittest.TestLoader().loadTestsFromTestCase( - FlaskSimpleElectionstests) +if __name__ == "__main__": + SUITE = unittest.TestLoader().loadTestsFromTestCase(FlaskSimpleElectionstests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/tests/test_vote.py b/tests/test_vote.py index 1f9adac..63a01b5 100644 --- a/tests/test_vote.py +++ b/tests/test_vote.py @@ -20,7 +20,7 @@ fedora_elections.model.Vote test script """ -__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4'] +__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] import pkg_resources import unittest @@ -30,8 +30,7 @@ import os from datetime import time from datetime import timedelta -sys.path.insert(0, os.path.join(os.path.dirname( - os.path.abspath(__file__)), '..')) +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) from fedora_elections import models from tests import Modeltests, TODAY @@ -46,15 +45,15 @@ class Votetests(Modeltests): def test_init_vote(self): """ Test the Vote init function. """ - candidates = Candidatetests('test_init_candidate') + candidates = Candidatetests("test_init_candidate") candidates.session = self.session candidates.test_init_candidate() obj = models.Vote( # id:1 election_id=1, - voter='toshio', + voter="toshio", candidate_id=1, - value='3', + value="3", ) self.session.add(obj) self.session.commit() @@ -62,9 +61,9 @@ class Votetests(Modeltests): obj = models.Vote( # id:2 election_id=1, - voter='toshio', + voter="toshio", candidate_id=2, - value='3', + value="3", ) self.session.add(obj) self.session.commit() @@ -72,9 +71,9 @@ class Votetests(Modeltests): obj = models.Vote( # id:3 election_id=1, - voter='toshio', + voter="toshio", candidate_id=3, - value='3', + value="3", ) self.session.add(obj) self.session.commit() @@ -82,7 +81,7 @@ class Votetests(Modeltests): obj = models.Vote( # id:4 election_id=1, - voter='ralph', + voter="ralph", candidate_id=2, value=2, ) @@ -92,7 +91,7 @@ class Votetests(Modeltests): obj = models.Vote( # id:5 election_id=1, - voter='ralph', + voter="ralph", candidate_id=3, value=1, ) @@ -104,9 +103,9 @@ class Votetests(Modeltests): obj = models.Vote( # id:1 election_id=3, - voter='toshio', + voter="toshio", candidate_id=1, - value='3', + value="3", ) self.session.add(obj) self.session.commit() @@ -114,9 +113,9 @@ class Votetests(Modeltests): obj = models.Vote( # id:2 election_id=3, - voter='toshio', + voter="toshio", candidate_id=2, - value='3', + value="3", ) self.session.add(obj) self.session.commit() @@ -124,9 +123,9 @@ class Votetests(Modeltests): obj = models.Vote( # id:4 election_id=3, - voter='toshio', + voter="toshio", candidate_id=3, - value='3', + value="3", ) self.session.add(obj) self.session.commit() @@ -136,9 +135,9 @@ class Votetests(Modeltests): obj = models.Vote( # id:1 election_id=5, - voter='toshio', + voter="toshio", candidate_id=7, - value='1', + value="1", ) self.session.add(obj) self.session.commit() @@ -146,9 +145,9 @@ class Votetests(Modeltests): obj = models.Vote( # id:2 election_id=5, - voter='toshio', + voter="toshio", candidate_id=8, - value='1', + value="1", ) self.session.add(obj) self.session.commit() @@ -156,9 +155,9 @@ class Votetests(Modeltests): obj = models.Vote( # id:4 election_id=5, - voter='kevin', + voter="kevin", candidate_id=9, - value='1', + value="1", ) self.session.add(obj) self.session.commit() @@ -168,9 +167,9 @@ class Votetests(Modeltests): obj = models.Vote( # id:1 election_id=6, - voter='toshio', + voter="toshio", candidate_id=12, - value='1', + value="1", ) self.session.add(obj) self.session.commit() @@ -180,9 +179,9 @@ class Votetests(Modeltests): obj = models.Vote( # id:1 election_id=7, - voter='toshio', + voter="toshio", candidate_id=12, - value='1', + value="1", ) self.session.add(obj) self.session.commit() @@ -205,34 +204,29 @@ class Votetests(Modeltests): """ Test the Vote.of_user_on_election function. """ self.test_init_vote() - obj = models.Vote.of_user_on_election( - self.session, 'toshio', 1, count=True) + obj = models.Vote.of_user_on_election(self.session, "toshio", 1, count=True) self.assertEqual(obj, 3) - obj = models.Vote.of_user_on_election( - self.session, 'toshio', 1, count=False) + obj = models.Vote.of_user_on_election(self.session, "toshio", 1, count=False) self.assertEqual(len(obj), 3) - self.assertEqual(obj[0].voter, 'toshio') - self.assertEqual(obj[0].candidate.name, 'Toshio') - self.assertEqual(obj[1].voter, 'toshio') - self.assertEqual(obj[1].candidate.name, 'Kevin') - self.assertEqual(obj[2].voter, 'toshio') - self.assertEqual(obj[2].candidate.name, 'Ralph') + self.assertEqual(obj[0].voter, "toshio") + self.assertEqual(obj[0].candidate.name, "Toshio") + self.assertEqual(obj[1].voter, "toshio") + self.assertEqual(obj[1].candidate.name, "Kevin") + self.assertEqual(obj[2].voter, "toshio") + self.assertEqual(obj[2].candidate.name, "Ralph") def test_get_election_stats(self): """ Test the get_election_stats function. """ self.test_init_vote() obj = models.Vote.get_election_stats(self.session, 1) - self.assertEqual(obj['n_voters'], 2) - self.assertEqual(obj['n_votes'], 5) - self.assertEqual( - obj['candidate_voters'], - {'Toshio': 1, 'Ralph': 2, 'Kevin': 2} - ) - self.assertEqual(obj['n_candidates'], 3) + self.assertEqual(obj["n_voters"], 2) + self.assertEqual(obj["n_votes"], 5) + self.assertEqual(obj["candidate_voters"], {"Toshio": 1, "Ralph": 2, "Kevin": 2}) + self.assertEqual(obj["n_candidates"], 3) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(Votetests) unittest.TextTestRunner(verbosity=2).run(SUITE) From 403abe6b34cb4ae496a2489b3689b5782ed7d62b Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Apr 08 2021 19:47:28 +0000 Subject: [PATCH 5/6] Add code linting with flake8 and flake8-import-order Signed-off-by: Pierre-Yves Chibon --- diff --git a/tox.ini b/tox.ini index a88b890..f81f122 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py36,py37,py38,diff-cover,bandit,format +envlist = py36,py37,py38,diff-cover,bandit,format,lint skipsdist = True [testenv] @@ -22,6 +22,12 @@ deps = commands = diff-cover coverage.xml --compare-branch=origin/develop --fail-under=100 +[testenv:lint] +deps = + flake8 + flake8-import-order +commands = + flake8 {posargs} [testenv:format] deps = black From a381ca2cbc6172c3374f9292ff2bf5df0325ac92 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Apr 08 2021 19:47:28 +0000 Subject: [PATCH 6/6] Fix code styling to make flake8 and flake8-import-order happy Signed-off-by: Pierre-Yves Chibon --- diff --git a/alembic/env.py b/alembic/env.py index 8298c0a..2c17253 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -1,7 +1,10 @@ from __future__ import with_statement + +from logging.config import fileConfig + from alembic import context + from sqlalchemy import create_engine, pool -from logging.config import fileConfig # this is the Alembic Config object, which provides # access to the values within the .ini file in use. @@ -11,8 +14,8 @@ config = context.config # This line sets up loggers basically. fileConfig(config.config_file_name) -import fedora_elections -import fedora_elections.models +import fedora_elections # noqa:E402 +import fedora_elections.models # noqa:E402 # add your model's MetaData object here # for 'autogenerate' support diff --git a/alembic/versions/2b8f5a6f10a4_store_fas_name_locally.py b/alembic/versions/2b8f5a6f10a4_store_fas_name_locally.py index 56c8773..142b2c8 100644 --- a/alembic/versions/2b8f5a6f10a4_store_fas_name_locally.py +++ b/alembic/versions/2b8f5a6f10a4_store_fas_name_locally.py @@ -5,14 +5,14 @@ Revises: d07c5ef2d03 Create Date: 2016-01-21 16:53:38.956503 """ +from alembic import op + +import sqlalchemy as sa # revision identifiers, used by Alembic. revision = "2b8f5a6f10a4" down_revision = "d07c5ef2d03" -from alembic import op -import sqlalchemy as sa - def upgrade(): """ Add the fas_name column to the candidates table. """ diff --git a/alembic/versions/5ecdd55b4af4_add_badge_support_to_elections.py b/alembic/versions/5ecdd55b4af4_add_badge_support_to_elections.py index d933a18..88c44a0 100644 --- a/alembic/versions/5ecdd55b4af4_add_badge_support_to_elections.py +++ b/alembic/versions/5ecdd55b4af4_add_badge_support_to_elections.py @@ -5,14 +5,14 @@ Revises: 2b8f5a6f10a4 Create Date: 2019-03-18 12:21:59.536380 """ +from alembic import op + +import sqlalchemy as sa # revision identifiers, used by Alembic. revision = "5ecdd55b4af4" down_revision = "2b8f5a6f10a4" -from alembic import op -import sqlalchemy as sa - def upgrade(): """ Add the url_badge column to the Elections table. """ diff --git a/alembic/versions/d07c5ef2d03_add_max_votes_to_ele.py b/alembic/versions/d07c5ef2d03_add_max_votes_to_ele.py index 44aa1af..b624f1e 100644 --- a/alembic/versions/d07c5ef2d03_add_max_votes_to_ele.py +++ b/alembic/versions/d07c5ef2d03_add_max_votes_to_ele.py @@ -6,14 +6,14 @@ Revises: None Create Date: 2014-05-26 16:33:50.812050 """ +from alembic import op + +import sqlalchemy as sa # revision identifiers, used by Alembic. revision = "d07c5ef2d03" down_revision = None -from alembic import op -import sqlalchemy as sa - def upgrade(): """ Add the max_votes column to the Elections table. """ diff --git a/createdb.py b/createdb.py index 27f1fff..8c0463e 100644 --- a/createdb.py +++ b/createdb.py @@ -1,8 +1,3 @@ -import __main__ - -__main__.__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] -import pkg_resources - from fedora_elections import APP from fedora_elections.models import create_tables diff --git a/fedora_elections/__init__.py b/fedora_elections/__init__.py index 8c82ab0..bcc94c3 100644 --- a/fedora_elections/__init__.py +++ b/fedora_elections/__init__.py @@ -23,33 +23,32 @@ # Frank Chiulli # Pierre-Yves Chibon # -from __future__ import unicode_literals, absolute_import __version__ = "2.9" -import logging # noqa -import os # noqa -import sys # noqa -import urllib # noqa -import hashlib # noqa -import arrow # noqa - - +import hashlib +import logging +import os from datetime import datetime, time, timedelta # noqa -from functools import wraps # noqa -from six.moves.urllib.parse import urlparse, urljoin, urlencode # noqa -import flask # noqa -import munch # noqa -import six # noqa +import arrow from fasjson_client import Client -from fedora.client import AuthError, AppError # noqa -from fedora.client.fas2 import AccountSystem # noqa -from flask_oidc import OpenIDConnect # noqa -import fedora_elections.fedmsgshim # noqa -import fedora_elections.proxy # noqa +from fedora.client.fas2 import AccountSystem + +import fedora_elections.fedmsgshim +import fedora_elections.proxy + +import flask + +from flask_oidc import OpenIDConnect + +import munch + +import six +from six.moves.urllib.parse import urlencode, urljoin, urlparse + APP = flask.Flask(__name__) APP.config.from_object("fedora_elections.default_config") diff --git a/fedora_elections/admin.py b/fedora_elections/admin.py index f54d3cd..062ac9a 100644 --- a/fedora_elections/admin.py +++ b/fedora_elections/admin.py @@ -23,27 +23,31 @@ # Frank Chiulli # Pierre-Yves Chibon # -from __future__ import unicode_literals, absolute_import from datetime import datetime, time from functools import wraps -import flask -from sqlalchemy.exc import SQLAlchemyError +from fasjson_client.errors import APIError + from fedora.client import AuthError + +from fedora_elections import ACCOUNTS, APP, SESSION, is_admin, is_authenticated +from fedora_elections import fedmsgshim +from fedora_elections import forms +from fedora_elections import models + from fedora_elections_messages import ( - NewElectionV1, + DeleteCandidateV1, + EditCandidateV1, EditElectionV1, NewCandidateV1, - EditCandidateV1, - DeleteCandidateV1, + NewElectionV1, ) -from fedora_elections import fedmsgshim -from fedora_elections import forms -from fedora_elections import models -from fedora_elections import APP, SESSION, ACCOUNTS, is_authenticated, is_admin -from fasjson_client.errors import APIError + +import flask + +from sqlalchemy.exc import SQLAlchemyError def election_admin_required(f): diff --git a/fedora_elections/default_config.py b/fedora_elections/default_config.py index 60ce759..438ba25 100644 --- a/fedora_elections/default_config.py +++ b/fedora_elections/default_config.py @@ -5,7 +5,8 @@ Fedora elections default configuration. """ import os from datetime import timedelta -from fedora_elections.mail_logging import MSG_FORMAT, ContextInjector + +from fedora_elections.mail_logging import ContextInjector, MSG_FORMAT # Set the time after which the session expires PERMANENT_SESSION_LIFETIME = timedelta(hours=1) diff --git a/fedora_elections/elections.py b/fedora_elections/elections.py index 80889ad..84d984a 100644 --- a/fedora_elections/elections.py +++ b/fedora_elections/elections.py @@ -23,26 +23,25 @@ # Frank Chiulli # Pierre-Yves Chibon # -from __future__ import unicode_literals, absolute_import from datetime import datetime from functools import wraps -import flask - -from fedora_elections import forms -from fedora_elections import models from fedora_elections import ( - OIDC, APP, + OIDC, SESSION, - is_authenticated, is_admin, + is_authenticated, is_election_admin, safe_redirect_back, ) +from fedora_elections import forms +from fedora_elections import models from fedora_elections.utils import build_name_map +import flask + def login_required(f): @wraps(f) diff --git a/fedora_elections/fedmsgshim.py b/fedora_elections/fedmsgshim.py index 105a93b..48cbbb9 100644 --- a/fedora_elections/fedmsgshim.py +++ b/fedora_elections/fedmsgshim.py @@ -4,12 +4,10 @@ :Author: Pierre-Yves Chibon """ -from __future__ import unicode_literals, absolute_import - import logging import fedora_messaging.api -from fedora_messaging.exceptions import PublishReturned, ConnectionException +from fedora_messaging.exceptions import ConnectionException, PublishReturned _log = logging.getLogger(__name__) diff --git a/fedora_elections/forms.py b/fedora_elections/forms.py index 0d1e87f..4cd3640 100644 --- a/fedora_elections/forms.py +++ b/fedora_elections/forms.py @@ -1,19 +1,20 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals, absolute_import + +from fasjson_client.errors import APIError + +from fedora.client import AuthError + +from fedora_elections import ACCOUNTS, APP, SESSION +from fedora_elections.models import Election import flask -import wtforms try: from flask_wtf import FlaskForm except ImportError: from flask_wtf import Form as FlaskForm - -from fedora.client import AuthError -from fedora_elections import SESSION, ACCOUNTS, APP -from fedora_elections.models import Election -from fasjson_client.errors import APIError +import wtforms class ElectionForm(FlaskForm): diff --git a/fedora_elections/mail_logging.py b/fedora_elections/mail_logging.py index b1fdac1..4542cd6 100644 --- a/fedora_elections/mail_logging.py +++ b/fedora_elections/mail_logging.py @@ -22,12 +22,9 @@ """ Mail handler for logging. """ -from __future__ import unicode_literals, absolute_import - +import inspect import logging import logging.handlers - -import inspect import os import socket import traceback diff --git a/fedora_elections/models.py b/fedora_elections/models.py index 0c933b2..87503b1 100644 --- a/fedora_elections/models.py +++ b/fedora_elections/models.py @@ -1,16 +1,14 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals, absolute_import - from datetime import datetime import sqlalchemy as sa from sqlalchemy import create_engine from sqlalchemy import func as safunc from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import sessionmaker -from sqlalchemy.orm import scoped_session -from sqlalchemy.orm import relationship from sqlalchemy.orm import backref +from sqlalchemy.orm import relationship +from sqlalchemy.orm import scoped_session +from sqlalchemy.orm import sessionmaker BASE = declarative_base() diff --git a/fedora_elections/proxy.py b/fedora_elections/proxy.py index 1261793..8839a58 100644 --- a/fedora_elections/proxy.py +++ b/fedora_elections/proxy.py @@ -25,7 +25,6 @@ redirects are using ``https``. Source: http://flask.pocoo.org/snippets/35/ by Peter Hansen """ -from __future__ import unicode_literals, absolute_import class ReverseProxied(object): diff --git a/fedora_elections/utils.py b/fedora_elections/utils.py index 4af36c0..a9e2284 100644 --- a/fedora_elections/utils.py +++ b/fedora_elections/utils.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals, absolute_import def build_name_map(election): diff --git a/runserver.py b/runserver.py index 1ca04d6..7ce737f 100644 --- a/runserver.py +++ b/runserver.py @@ -1,13 +1,10 @@ #!/usr/bin/env python2 -# These two lines are needed to run on EL6 -__requires__ = ["SQLAlchemy >= 0.8", "jinja2 >= 2.4"] -import pkg_resources - import argparse -import sys import os +from fedora_elections import APP + parser = argparse.ArgumentParser(description="Run the Fedora election app") parser.add_argument( @@ -48,8 +45,6 @@ parser.add_argument( args = parser.parse_args() -from fedora_elections import APP - if args.profile: from werkzeug.contrib.profiler import ProfilerMiddleware diff --git a/setup.py b/setup.py index bc93f0c..f38b669 100644 --- a/setup.py +++ b/setup.py @@ -6,6 +6,7 @@ Setup script import os import re + from setuptools import setup versionfile = os.path.join(os.path.dirname(__file__), "fedora_elections", "__init__.py") diff --git a/tests/__init__.py b/tests/__init__.py index 5e8d93e..dcfb2f5 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -20,33 +20,22 @@ fedora_elections test script """ -from __future__ import print_function - -__requires__ = ["SQLAlchemy >= 0.7"] -import pkg_resources - import logging -import unittest -import sys import os - -from datetime import date -from datetime import timedelta -from functools import wraps - -import six +import sys +import unittest from contextlib import contextmanager -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker -from sqlalchemy.orm import scoped_session +from datetime import date sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) -import fedora_elections -import fedora_elections.admin -import fedora_elections.elections -import fedora_elections.forms -from fedora_elections import models +import fedora_elections # noqa: E402 +import fedora_elections.admin # noqa:E402 +import fedora_elections.elections # noqa:E402 +import fedora_elections.forms # noqa:E402 +from fedora_elections import models # noqa:E402 + +import six # noqa:E402 DB_PATH = "sqlite:///:memory:" @@ -60,7 +49,7 @@ if os.environ.get("BUILD_ID"): if req.status_code == 200: DB_PATH = req.text print("Using faitout at: %s" % DB_PATH) - except: + except Exception: pass diff --git a/tests/test_candidate.py b/tests/test_candidate.py index a5a6363..13aeea9 100644 --- a/tests/test_candidate.py +++ b/tests/test_candidate.py @@ -20,21 +20,17 @@ fedora_elections.model.Candidate test script """ -__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] -import pkg_resources -import unittest -import sys import os - -from datetime import time -from datetime import timedelta +import sys +import unittest sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) -from fedora_elections import models -from tests import Modeltests, TODAY -from tests.test_election import Electiontests +from fedora_elections import models # noqa:E402 + +from tests import Modeltests # noqa: E402 +from tests.test_election import Electiontests # noqa:E402 # pylint: disable=R0904 diff --git a/tests/test_election.py b/tests/test_election.py index 1417644..831b80e 100644 --- a/tests/test_election.py +++ b/tests/test_election.py @@ -20,20 +20,15 @@ fedora_elections.model.Election test script """ -__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] -import pkg_resources - -import unittest -import sys import os - -from datetime import time +import sys +import unittest from datetime import timedelta sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) -from fedora_elections import models -from tests import Modeltests, TODAY +from fedora_elections import models # noqa:E402 +from tests import Modeltests, TODAY # noqa:E402 # pylint: disable=R0904 diff --git a/tests/test_flask.py b/tests/test_flask.py index 74909e4..f524f84 100644 --- a/tests/test_flask.py +++ b/tests/test_flask.py @@ -20,23 +20,18 @@ fedora_elections.model.Election test script """ -__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] -import pkg_resources - -import unittest -import sys import os - -from datetime import time -from datetime import timedelta +import sys +import unittest import flask -from mock import patch, MagicMock + +from mock import MagicMock, patch sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) -import fedora_elections -from tests import ModelFlasktests, FakeUser, user_set +import fedora_elections # noqa:E402 +from tests import ModelFlasktests, FakeUser, user_set # noqa:E402 # pylint: disable=R0904 @@ -53,6 +48,8 @@ class Flasktests(ModelFlasktests): 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/")) + self.assertFalse(fedora_elections.is_safe_url("https://google.fr")) + self.assertTrue(fedora_elections.is_safe_url("/admin/")) def test_index_empty(self): """ Test the index function. """ @@ -195,13 +192,6 @@ class Flasktests(ModelFlasktests): # This is user is an admin for election #2 self.assertTrue(fedora_elections.is_election_admin(flask.g.fas_user, 2)) - def test_is_safe_url(self): - """ Test the is_safe_url function. """ - app = flask.Flask("fedora_elections") - with app.test_request_context(): - self.assertFalse(fedora_elections.is_safe_url("https://google.fr")) - self.assertTrue(fedora_elections.is_safe_url("/admin/")) - def test_auth_login(self): """ Test the auth_login function. """ app = flask.Flask("fedora_elections") diff --git a/tests/test_flask_admin.py b/tests/test_flask_admin.py index d77a6ca..d4d9c53 100644 --- a/tests/test_flask_admin.py +++ b/tests/test_flask_admin.py @@ -20,32 +20,27 @@ fedora_elections.admin test script """ -__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] -import pkg_resources - -import logging -import unittest -import sys import os - -from datetime import time +import sys +import unittest from datetime import timedelta -import flask -from mock import patch, MagicMock -from fedora_messaging.testing import mock_sends from fedora_elections_messages import ( - NewElectionV1, + DeleteCandidateV1, + EditCandidateV1, EditElectionV1, NewCandidateV1, - EditCandidateV1, - DeleteCandidateV1, + NewElectionV1, ) +from fedora_messaging.testing import mock_sends + +from mock import MagicMock, patch + 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 +import fedora_elections # noqa:E402 +from tests import ModelFlasktests, TODAY, FakeUser, user_set # noqa:E402 # pylint: disable=R0904 @@ -784,8 +779,8 @@ class FlaskAdmintests(ModelFlasktests): ) self.assertTrue('Candidates ' - in output_text + '' in output_text ) self.assertIn( 'input class="form-control" id="lgl_voters" ' diff --git a/tests/test_flask_elections.py b/tests/test_flask_elections.py index f51e9b2..caced31 100644 --- a/tests/test_flask_elections.py +++ b/tests/test_flask_elections.py @@ -20,24 +20,16 @@ fedora_elections.elections test script """ -__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] -import pkg_resources - -import logging -import unittest -import sys import os +import sys +import unittest -from datetime import time -from datetime import timedelta - -import flask -from mock import patch, MagicMock +from mock import MagicMock, patch 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 +import fedora_elections # noqa:E402 +from tests import ModelFlasktests, FakeUser, user_set # noqa:E402 # pylint: disable=R0904 diff --git a/tests/test_flask_irc.py b/tests/test_flask_irc.py index c4b8c3e..e2bcd75 100644 --- a/tests/test_flask_irc.py +++ b/tests/test_flask_irc.py @@ -20,24 +20,16 @@ fedora_elections.elections test script """ -__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] -import pkg_resources - -import logging -import unittest -import sys import os +import sys +import unittest -from datetime import time -from datetime import timedelta - -import flask -from mock import patch, MagicMock +from mock import MagicMock, patch 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 +import fedora_elections # noqa:E402 +from tests import ModelFlasktests, FakeUser, user_set # noqa:E402 # pylint: disable=R0904 diff --git a/tests/test_flask_range_voting.py b/tests/test_flask_range_voting.py index 48fb0dd..4c20ace 100644 --- a/tests/test_flask_range_voting.py +++ b/tests/test_flask_range_voting.py @@ -20,24 +20,16 @@ fedora_elections.elections test script """ -__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] -import pkg_resources - -import logging -import unittest -import sys import os +import sys +import unittest -from datetime import time -from datetime import timedelta - -import flask -from mock import patch, MagicMock +from mock import MagicMock, patch 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 +import fedora_elections # noqa:E402 +from tests import ModelFlasktests, FakeUser, user_set # noqa:E402 # pylint: disable=R0904 diff --git a/tests/test_flask_select_voting.py b/tests/test_flask_select_voting.py index 1d3b635..7df0b27 100644 --- a/tests/test_flask_select_voting.py +++ b/tests/test_flask_select_voting.py @@ -20,24 +20,17 @@ fedora_elections.elections test script """ -__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] -import pkg_resources -import logging -import unittest -import sys import os +import sys +import unittest -from datetime import time -from datetime import timedelta - -import flask -from mock import patch, MagicMock +from mock import MagicMock, patch 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 +import fedora_elections # noqa:E402 +from tests import ModelFlasktests, FakeUser, user_set # noqa:E402 # pylint: disable=R0904 diff --git a/tests/test_flask_simple_voting.py b/tests/test_flask_simple_voting.py index ecaf486..38745ad 100644 --- a/tests/test_flask_simple_voting.py +++ b/tests/test_flask_simple_voting.py @@ -20,24 +20,17 @@ fedora_elections.elections test script """ -__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] -import pkg_resources -import logging -import unittest -import sys import os +import sys +import unittest -from datetime import time -from datetime import timedelta - -import flask -from mock import patch, MagicMock +from mock import MagicMock, patch 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 +import fedora_elections # noqa:E402 +from tests import ModelFlasktests, FakeUser, user_set # noqa:E402 # pylint: disable=R0904 diff --git a/tests/test_vote.py b/tests/test_vote.py index 63a01b5..60002e2 100644 --- a/tests/test_vote.py +++ b/tests/test_vote.py @@ -20,21 +20,15 @@ fedora_elections.model.Vote test script """ -__requires__ = ["SQLAlchemy >= 0.7", "jinja2 >= 2.4"] -import pkg_resources - -import unittest -import sys import os - -from datetime import time -from datetime import timedelta +import sys +import unittest sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) -from fedora_elections import models -from tests import Modeltests, TODAY -from tests.test_candidate import Candidatetests +from fedora_elections import models # noqa:E402 +from tests import Modeltests # noqa:E402 +from tests.test_candidate import Candidatetests # noqa:E402 # pylint: disable=R0904