#60 Add support for requesting an 'I Voted' badge.
Closed 5 years ago by bcotton. Opened 5 years ago by bcotton.
bcotton/elections add_voted_badge  into  master

file added
+1
@@ -0,0 +1,1 @@ 

+ fedoraInfraTox { }

file modified
+1
@@ -7,3 +7,4 @@ 

  .coverage

  alembic.ini

  .vagrant/

+ .tox/

file modified
+31 -4
@@ -43,7 +43,7 @@ 

  [vagrant@localhost ~]$ pushd /vagrant/; ./runserver.py --host "0.0.0.0";

  ```

  

- Once that is running, go to [localhost:5002](http://localhost:5002/) in your

+ Once that is running, go to [localhost:5005](http://localhost:5005/) in your

  browser to see your running Fedora Elections test instance.

  

  ### A note about fonts
@@ -116,6 +116,32 @@ 

  python createdb.py

  ```

  

+ ### Register the application using openid-connect

+ 

+ Run:

+ 

+ ```

+ oidc-register https://iddev.fedorainfracloud.org/ http://localhost:5005/oidc_callback

+ ```

+ 

+ Copy the corresponding ``client_secrets.json`` in the sources:

+ 

+ ```

+ cp client_secrets.json fedora_elections/client_secrets.json

+ ```

+ 

+ ### Create a local configuration file

+ 

+ Run:

+ 

+ ```

+ cat > config <<EOL

+ OIDC_ID_TOKEN_COOKIE_SECURE = False

+ OIDC_REQUIRE_VERIFIED_EMAIL = False

+ EOL

+ ```

+ 

+ 

  ### Starting the app

  

  There are 2 ways to start the application:
@@ -127,10 +153,10 @@ 

  

  This is useful for a quick development instance, when you don't have to worry

  about security yet. Do not run this in production. The server will start on

- http://127.0.0.1:5000.

+ http://127.0.0.1:5005.

  

  ```

- ./runserver

+ ./runserver.py -c config

  ```

  

  #### With Apache
@@ -151,7 +177,8 @@ 

  adjust the `.wsgi` file in `/var/www` to point to the `fedora_elections`

  directory.

  

- Place the configuration file in `/etc/fedora-elections/fedora-elections.cfg`.

+ Place the configuration file in `/etc/fedora-elections/fedora-elections.cfg`

+ and adjust it as you wish.

  

  ```

  sudo mkdir -p /etc/fedora-elections/

@@ -0,0 +1,27 @@ 

+ """Add badge support to elections

+ 

+ Revision ID: 5ecdd55b4af4

+ Revises: 2b8f5a6f10a4

+ Create Date: 2019-03-18 12:21:59.536380

+ 

+ """

+ 

+ # 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. """

+     op.add_column(

+         'elections',

+         sa.Column('url_badge', sa.Unicde(250), nullable=True)

+     )

+ 

+ 

+ def downgrade():

+     """ Drop the url_badge column from the Elections table. """

+     op.drop_column('elections', 'url_badge')

file modified
+41 -10
@@ -39,10 +39,11 @@ 

  from urlparse import urlparse, urljoin  # noqa

  

  import flask  # noqa

+ import munch  # noqa

  

  from fedora.client import AuthError, AppError  # noqa

  from fedora.client.fas2 import AccountSystem  # noqa

- from flask_fas_openid import FAS  # noqa

+ from flask_oidc import OpenIDConnect  # noqa

  

  import fedora_elections.fedmsgshim  # noqa

  import fedora_elections.mail_logging  # noqa
@@ -54,7 +55,7 @@ 

      APP.config.from_envvar('FEDORA_ELECTIONS_CONFIG')

  

  # set up FAS

- FAS = FAS(APP)

+ OIDC = OpenIDConnect(APP, credentials_store=flask.session)

  

  # Set up the logging

  if not APP.debug:
@@ -106,12 +107,22 @@ 

          ref_url.netloc == test_url.netloc

  

  

- def is_admin(user):

+ def is_admin(user, user_groups=None):

      ''' Is the user an elections admin.

      '''

+     if not user_groups:

+         user_groups = []

+ 

      if not user:

          return False

-     if not user.cla_done or len(user.groups) < 1:

+     if not user.cla_done:

+         return False

+ 

+     user_groups = []

+     if is_authenticated() and OIDC.user_loggedin:

+         user_groups = OIDC.user_getfield('groups')

+ 

+     if len(user_groups) < 1:

          return False

  

      admins = APP.config['FEDORA_ELECTIONS_ADMIN_GROUP']
@@ -120,7 +131,7 @@ 

      else:

          admins = set(admins)

  

-     return len(set(user.groups).intersection(admins)) > 0

+     return len(set(user_groups).intersection(admins)) > 0

  

  

  def is_election_admin(user, election_id):
@@ -163,7 +174,7 @@ 

      template).

      '''

      user = None

-     if hasattr(flask.g, 'fas_user'):

+     if is_authenticated() and OIDC.user_loggedin:

          user = flask.g.fas_user

      return dict(is_admin=is_admin(user),

                  version=__version__)
@@ -195,10 +206,25 @@ 

  

  # pylint: disable=W0613

  @APP.before_request

- def set_session():

+ def set_session():  # pragma: no-cover

      """ Set the flask session as permanent. """

      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': \

+                     'http://admin.fedoraproject.org/accounts/cla/done' \

+                     in (OIDC.user_getfield('cla') or []),

+             })

+         flask.g.fas_user = flask.session.fas_user

+     else:

+         flask.session.fas_user = None

+         flask.g.fas_user = None

+ 

  

  # pylint: disable=W0613

  @APP.teardown_request
@@ -272,7 +298,10 @@ 

          stats=stats,

          voted=voted,

          evolution_label=evolution_label,

-         evolution_data=evolution_data)

+         evolution_data=evolution_data,

+         candidates=sorted(

+             election.candidates, key=lambda x: x.vote_count, reverse=True),

+     )

  

  

  @APP.route('/archives')
@@ -291,6 +320,7 @@ 

  

  

  @APP.route('/login', methods=('GET', 'POST'))

+ @OIDC.require_login

  def auth_login():

      next_url = None

      if 'next' in flask.request.args:
@@ -307,14 +337,15 @@ 

          if isinstance(groups, basestring):

              groups = [groups]

          groups.extend(models.get_groups(SESSION))

-         return FAS.login(return_url=next_url, groups=groups)

+         return flask.redirect(next_url)

  

  

  @APP.route('/logout')

  def auth_logout():

      if hasattr(flask.g, 'fas_user') and flask.g.fas_user is not None:

-         FAS.logout()

+         OIDC.logout()

          flask.g.fas_user = None

+         flask.session.fas_user = None

          flask.flash('You have been logged out')

      return safe_redirect_back()

  

file modified
+7 -3
@@ -74,6 +74,7 @@ 

              end_date=form.end_date.data,

              seats_elected=form.seats_elected.data,

              embargoed=int(form.embargoed.data),

+             url_badge=form.url_badge.data,

              voting_type=form.voting_type.data,

              max_votes=form.max_votes.data,

              candidates_are_fasusers=int(form.candidates_are_fasusers.data),
@@ -115,7 +116,6 @@ 

          )

  

          flask.flash('Election "%s" added' % election.alias)

-         fedmsgshim.publish(topic="election.new", msg=election)

          return flask.redirect(flask.url_for(

              'admin_view_election', election_alias=election.alias))

      return flask.render_template(
@@ -130,7 +130,11 @@ 

      election = models.Election.get(SESSION, alias=election_alias)

      if not election:

          flask.abort(404)

-     form = forms.ElectionForm(election.id, obj=election)

+     if flask.request.method == 'GET':

+         form = forms.ElectionForm(election.id, obj=election)

+     else:

+         form = forms.ElectionForm(election.id)

+ 

      if form.validate_on_submit():

          form.embargoed.data = int(form.embargoed.data)

          if form.max_votes.data:
@@ -410,7 +414,7 @@ 

                      candidate=candidate.to_json(),

                  )

              )

-         except SQLAlchemyError, err:

+         except SQLAlchemyError as err:

              SESSION.rollback()

              APP.logger.debug('Could not delete candidate')

              APP.logger.exception(err)

@@ -3,7 +3,7 @@ 

  '''

  Fedora elections default configuration.

  '''

- 

+ import os

  from datetime import timedelta

  

  # Set the time after which the session expires
@@ -22,3 +22,9 @@ 

  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', 'fedora']

+ OIDC_OPENID_REALM = 'http://localhost:5005/oidc_callback'

file modified
+24 -11
@@ -32,7 +32,7 @@ 

  from fedora_elections import forms

  from fedora_elections import models

  from fedora_elections import (

-     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
@@ -48,11 +48,13 @@ 

              flask.flash(

                  'You must sign the CLA to vote', 'error')

              return safe_redirect_back()

-         elif len(flask.g.fas_user.groups) == 0:

-             flask.flash(

-                 'You need to be in one another group than CLA to vote',

-                 'error')

-             return safe_redirect_back()

+         else:

+             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')

+                 return safe_redirect_back()

  

          return f(*args, **kwargs)

      return decorated_function
@@ -93,7 +95,8 @@ 

          return election

  

      if election.legal_voters_list:

-         if len(set(flask.g.fas_user.groups).intersection(

+         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 '
@@ -141,6 +144,8 @@ 

          election=election,

          usernamemap=usernamemap,

          stats=stats,

+         candidates=sorted(

+             election.candidates, key=lambda x: x.vote_count, reverse=True)

      )

  

  
@@ -168,7 +173,7 @@ 

                  and candidate.short_name not in ['csrf_token', 'action']

              ]

              process_vote(candidates, election, votes, revote)

-             flask.flash("Your vote has been recorded.  Thank you!")

+             say_thank_you(election)

              return safe_redirect_back()

  

          if form.action.data == 'preview':
@@ -224,7 +229,7 @@ 

                      and candidate.short_name not in ['csrf_token', 'action']

                  ]

                  process_vote(candidates, election, votes, revote, cand_name)

-                 flask.flash("Your vote has been recorded.  Thank you!")

+                 say_thank_you(election)

                  return safe_redirect_back()

  

              if form.action.data == 'preview':
@@ -264,7 +269,7 @@ 

                  and candidate.short_name not in ['csrf_token', 'action']

              ]

              process_vote(candidates, election, votes, revote, value=1)

-             flask.flash("Your vote has been recorded.  Thank you!")

+             say_thank_you(election)

              return safe_redirect_back()

  

          if form.action.data == 'preview':
@@ -302,7 +307,7 @@ 

                  and candidate.short_name not in ['csrf_token', 'action']

              ]

              process_vote(candidates, election, votes, revote, cand_name)

-             flask.flash("Your vote has been recorded.  Thank you!")

+             say_thank_you(election)

              return safe_redirect_back()

  

          if form.action.data == 'preview':
@@ -345,3 +350,11 @@ 

              )

              SESSION.add(new_vote)

          SESSION.commit()

+ 

+ 

+ def say_thank_you(election):

+     thank_you = "Your vote has been recorded.  Thank you!"

+     if election.url_badge:

+         thank_you = thank_you + '<br><a href="' + \

+             election.url_badge + '" target=_new>Claim your I Voted badge</a>.'

+     flask.flash(thank_you)

@@ -13,5 +13,5 @@ 

      try:

          import fedmsg

          fedmsg.publish(*args, **kwargs)

-     except Exception, e:

+     except Exception as e:

          warnings.warn(str(e))

file modified
+7 -1
@@ -74,6 +74,12 @@ 

  

      embargoed = wtforms.BooleanField('Embargo results?', default=True)

  

+     url_badge = wtforms.TextField(

+         'Badge URL (optional)', [

+             wtforms.validators.Optional(),

+             wtforms.validators.URL(),

+             wtforms.validators.Length(max=250)])

+ 

      lgl_voters = wtforms.TextField(

          'Legal voters groups', [wtforms.validators.optional()])

  
@@ -150,7 +156,7 @@ 

              try:

                  title = \

                      FAS2.person_by_username(candidate.name)['human_name']

-             except (KeyError, AuthError), err:

+             except (KeyError, AuthError) as err:

                  APP.logger.debug(err)

          if candidate.url:

              title = '%s <a href="%s">[Info]</a>' % (title, candidate.url)

@@ -86,6 +86,7 @@ 

      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')

+     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)

@@ -112,6 +112,7 @@ 

            {{ render_bootstrap_textfield_in_row(form.seats_elected) }}

            {{ render_bootstrap_checkbox_in_row(form.candidates_are_fasusers) }}

            {{ render_bootstrap_checkbox_in_row(form.embargoed) }}

+           {{ render_bootstrap_textfield_in_row(form.url_badge) }}

            {{ render_bootstrap_textfield_in_row(form.lgl_voters, after="FAS groups allowed to vote on this election (CLA-done is always required)") }}

            {{ render_bootstrap_textfield_in_row(form.admin_grp, after="FAS groups allowed to view the result despite the embargo") }}

        </fieldset>

@@ -107,41 +107,44 @@ 

      {% endif %}

      <h3> Results </h3>

      <table id="results" class="table">

-         <thead>

-           <tr>

-               <th class="stretch-cell nowrap">Candidate</th>

-               <th class="nowrap" title="Number of votes received">Votes</th>

-               {% if stats['candidate_voters'] %}

-               <th class="nowrap">Voters per candidate</th>

-               <th class="nowrap">Average votes per candidate</th>

-               {% endif %}

-           </tr>

+       <thead>

+         <tr>

+           <th class="stretch-cell nowrap">Candidate</th>

+           <th class="nowrap" title="Number of votes received">Votes</th>

+           {% if stats['candidate_voters'] %}

+           <th class="nowrap">Voters per candidate</th>

+           <th class="nowrap">Average votes per candidate</th>

+           {% endif %}

+         </tr>

        </thead>

  

-       {% for candidate in election.candidates|sort(attribute='vote_count', reverse=True) %}

-       {% if loop.index <= election.seats_elected %}

-       {# If we are below the number of user that will be selected, get the number

-       of votes and the flag to False#}

-       {% set flag = False %}

-       {% set votes = candidate.vote_count %}

-       {% elif loop.index > election.seats_elected and votes > candidate.vote_count and not flag %}

-       {# if we are above the number of user that will be selected (seats

-       available), check if the number of votes for this candidate is lower than

-       the number of votes for the last candidate and if the Flag is False

-       So this takes care of the case where there are 10 seats elected and the 11th

-       candidate has the same score as the 10th one.

-       In this case we would end up with one more person that the number of seats

-       available and we'll need to either find a way to select one over the other

-       or deal with having one more candidate accepted #}

-       {% set flag = True %}

-       {% set lastrow = True %}

-       {% else %}

-       {# we are above the number of seats available, the number of votes is below

-       that of the last candidate above selected and the Flag is True which means

-       we already passed the condition above #}

-       {% set lastrow = False %}

-       {% endif %}

-       <tr class="{% if lastrow == True %}firstout{% endif %} {{ loop.cycle('row_odd', 'row_even') }}">

+       {%- set lastrow = [0] -%}

+       {%- set flag = [0] -%}

+       {% for candidate in candidates %}

+         {% if loop.index <= election.seats_elected %}

+           {# If we are below the number of user that will be selected, get the number

+           of votes and the flag to False#}

+           {%- set _ = flag.append(0) -%}

+         {%- elif loop.index > election.seats_elected

+           and candidates[loop.index -2].vote_count > candidate.vote_count

+           and flag[-1] == 0 -%}

+           {# if we are above the number of user that will be selected (seats

+             available), check if the number of votes for this candidate is lower than

+             the number of votes for the last candidate and if the Flag is False

+             So this takes care of the case where there are 10 seats elected and the 11th

+             candidate has the same score as the 10th one.

+             In this case we would end up with one more person that the number of seats

+             available and we'll need to either find a way to select one over the other

+             or deal with having one more candidate accepted #}

+          {%- set _ = lastrow.append(1) -%}

+          {%- set _ = flag.append(1) -%}

+         {% else %}

+           {# we are above the number of seats available, the number of votes is below

+             that of the last candidate above selected and the Flag is True which means

+             we already passed the condition above #}

+           {% set _ = lastrow.append(0) -%}

+         {% endif %}

+       <tr class="{% if lastrow[-1] == 1 %}firstout{% endif %} {{ loop.cycle('row_odd', 'row_even') }}">

            <td>

              {% if candidate.url %}

                <a href="{{ candidate.url }}">
@@ -154,7 +157,7 @@ 

              {% if candidate.url %}

                </a>

              {% endif %}

-             {% if not flag %}

+             {% if flag[-1] == 0 %}

              <span class="label label-success">Elected</span>

              {% endif %}

            </td>

@@ -21,14 +21,17 @@ 

  The results for the elections are as follows:

  

    # votes |  name

- - --------+----------------------{%

- for candidate in election.candidates|sort(attribute='vote_count', reverse=True) -%}

+ - --------+----------------------

+ {%- set lastrow = [0] -%}

+ {%- set flag = [0] -%}

+ {%- for candidate in candidates -%}

    {% if loop.index <= election.seats_elected -%}

-         {# If we are below the number of user that will be selected,

+         {# If we are below the number of user that will be selected

            get the number of votes and the flag to False -#}

-     {% set flag = False -%}

-     {% set votes = candidate.vote_count -%}

-   {%- elif loop.index > election.seats_elected and votes > candidate.vote_count and not flag -%}

+     {%- set _ = flag.append(0) -%}

+   {%- elif loop.index > election.seats_elected

+         and candidates[loop.index -2].vote_count > candidate.vote_count

+         and flag[-1] == 0 -%}

      {# if we are above the number of user that will be selected (seats

        available), check if the number of votes for this candidate is lower

        than the number of votes for the last candidate and if the Flag is
@@ -38,14 +41,17 @@ 

        In this case we would end up with one more person that the number of

        seats available and we'll need to either find a way to select one

        over the other or deal with having one more candidate accepted -#}

-     {% set flag = True -%}

-     {% set lastrow = True -%}

+     {%- set _ = lastrow.append(1) -%}

+     {%- set _ = flag.append(1) -%}

    {%- else -%}

      {# we are above the number of seats available, the number of votes is

        below that of the last candidate above selected and the Flag is True

        which means we already passed the condition above -#}

-     {% set lastrow = False -%} {%- endif %}{% if lastrow == True %}

- - --------+---------------------- {%- endif %}

+     {% set _ = lastrow.append(0) -%}

+   {%- endif -%}

+   {%- if lastrow[-1] == 1 %}

+ - --------+----------------------

+   {%- endif %}

  {{ candidate.vote_count | rjust(8) }}  | {% if election.candidates_are_fasusers -%}

        {{ usernamemap[candidate.id] }} {%- else -%} {{candidate.name}}

      {%- endif %}

file modified
+1 -3
@@ -1,12 +1,10 @@ 

  # Used for when working from a virtualenv.

  # Use this file by running "$ pip install -r requirements.txt"

  Flask>=0.10

+ flask-oidc

  Flask-wtf

  kitchen

  python-fedora

- python-openid

- python-openid-cla

- python-openid-teams

  SQLAlchemy

  wtforms

  arrow

file modified
+1 -1
@@ -23,7 +23,7 @@ 

      default=False,

      help='Profile the application.')

  parser.add_argument(

-     '--port', '-p', default=5000,

+     '--port', '-p', default=5005,

      help='Port for the flask application.')

  parser.add_argument(

      '--host', default="127.0.0.1",

file modified
+1
@@ -1,4 +1,5 @@ 

  #!/bin/bash

  

+ FEDORA_ELECTIONS_CONFIG=`pwd`/tests/config \

  PYTHONPATH=fedora_elections ./nosetests \

  --with-coverage --cover-erase --cover-package=fedora_elections $*

file modified
+11 -5
@@ -4,13 +4,19 @@ 

  Setup script

  """

  

- # These two lines are needed to run on EL6

- __requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']

- import pkg_resources

+ import os

+ import re

+ from setuptools import setup

  

- from fedora_elections import __version__

+ versionfile = os.path.join(

+     os.path.dirname(__file__), 'fedora_elections', '__init__.py')

  

- from setuptools import setup

+ # 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)

  

  setup(

      name='fedora-elections',

file modified
+25 -2
@@ -20,6 +20,7 @@ 

  

   fedora_elections test script

  """

+ from __future__ import print_function

  

  __requires__ = ['SQLAlchemy >= 0.7']

  import pkg_resources
@@ -57,7 +58,7 @@ 

          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

  
@@ -66,7 +67,7 @@ 

  

  

  @contextmanager

- def user_set(APP, user):

+ def user_set(APP, user, oidc_id_token=None):

      """ Set the provided user as fas_user in the provided application."""

  

      # Hack used to remove the before_request function set by
@@ -77,6 +78,7 @@ 

  

      def handler(sender, **kwargs):

          g.fas_user = user

+         g.oidc_id_token = oidc_id_token

  

      with appcontext_pushed.connected_to(handler, APP):

          yield
@@ -138,6 +140,27 @@ 

  

          self.app = fedora_elections.APP.test_client()

  

+     def get_wtforms_version(self):

+         """Returns the wtforms version as a tuple."""

+         import wtforms

+         wtforms_v = wtforms.__version__.split('.')

+         for idx, val in enumerate(wtforms_v):

+             try:

+                 val = int(val)

+             except ValueError:

+                 pass

+             wtforms_v[idx] = val

+         return tuple(wtforms_v)

+ 

+     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]

+ 

  

  class FakeGroup(object):

      """ Fake object used to make the FakeUser object closer to the

@@ -0,0 +1,12 @@ 

+ {

+ 	"web": {

+ 		"redirect_uris": ["http://localhost:5005/oidc_callback"],

+ 		"token_uri": "https://iddev.fedorainfracloud.org/openidc/Token",

+ 		"auth_uri": "https://iddev.fedorainfracloud.org/openidc/Authorization",

+ 		"client_id": "client_id",

+ 		"client_secret": "client_secret",

+ 		"userinfo_uri": "https://iddev.fedorainfracloud.org/openidc/UserInfo",

+ 		"token_introspection_uri": "https://iddev.fedorainfracloud.org/openidc/TokenInfo",

+ 		"issuer": "https://iddev.fedorainfracloud.org/openidc/"

+ 	}

+ }

file added
+4
@@ -0,0 +1,4 @@ 

+ import os

+ 

+ OIDC_CLIENT_SECRETS = os.path.join(os.path.dirname(

+     os.path.abspath(__file__)), 'client_secrets.json')

file modified
+64 -33
@@ -31,6 +31,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__)), '..'))
@@ -117,18 +118,31 @@ 

              flask.g.fas_user = None

              self.assertFalse(fedora_elections.is_admin(flask.g.fas_user))

  

-             flask.g.fas_user = FakeUser()

-             self.assertFalse(fedora_elections.is_admin(flask.g.fas_user))

+             flask.g.oidc_id_token = 'foobar'

+ 

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['foobar'])):

+                 flask.g.fas_user = FakeUser()

+                 self.assertFalse(fedora_elections.is_admin(flask.g.fas_user))

  

-             flask.g.fas_user = FakeUser(

-                 fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'])

-             self.assertTrue(fedora_elections.is_admin(flask.g.fas_user))

+             with patch(

+                     '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_admin(flask.g.fas_user, ['elections']))

  

-             fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'] = [

-                 'sysadmin-main', 'sysadmin-elections']

-             flask.g.fas_user = FakeUser(

-                 fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'])

-             self.assertTrue(fedora_elections.is_admin(flask.g.fas_user))

+             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'])

+                 self.assertTrue(

+                     fedora_elections.is_admin(flask.g.fas_user, ['sysadmin-main']))

  

      def test_is_election_admin(self):

          """ Test the is_election_admin function. """
@@ -140,31 +154,42 @@ 

                  fedora_elections.is_election_admin(

                      flask.g.fas_user, 1)

              )

+ 

+             flask.g.oidc_id_token = 'foobar'

+ 

              flask.g.fas_user = FakeUser()

              self.assertFalse(

                  fedora_elections.is_election_admin(

                      flask.g.fas_user, 1)

              )

-             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))

+             with patch(

+                     '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))

  

          self.setup_db()

  

          with app.test_request_context():

              flask.g.fas_user = FakeUser('testers')

-             # This is user is not an admin for election #1

-             self.assertFalse(

-                 fedora_elections.is_election_admin(

-                     flask.g.fas_user, 1)

-             )

+             flask.g.oidc_id_token = 'foobar'

  

-             # This is user is an admin for election #2

-             self.assertTrue(

-                 fedora_elections.is_election_admin(

-                     flask.g.fas_user, 2)

-             )

+             # This is user is not an admin for election #1

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['foobar'])):

+                 self.assertFalse(

+                     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)

+                 )

  

      def test_is_safe_url(self):

          """ Test the is_safe_url function. """
@@ -182,17 +207,23 @@ 

          with app.test_request_context():

              flask.g.fas_user = FakeUser(['gitr2spec'])

              output = self.app.get('/login')

-             self.assertEqual(output.status_code, 200)

+             self.assertEqual(output.status_code, 302)

+             self.assertIn(

+                 'https://iddev.fedorainfracloud.org/openidc/Authorization?',

+                 output.data)

  

              output = self.app.get('/login?next=http://localhost/')

-             self.assertEqual(output.status_code, 200)

- 

-         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('<title>Fedora elections</title>' in output.data)

+             self.assertEqual(output.status_code, 302)

+             self.assertIn(

+                 'https://iddev.fedorainfracloud.org/openidc/Authorization?',

+                 output.data)

+ 

+         # 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('<title>Fedora elections</title>' in output.data)

  

      def test_auth_logout(self):

          """ Test the auth_logout function. """

file modified
+967 -736
@@ -32,6 +32,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__)), '..'))
@@ -49,17 +50,39 @@ 

          user = FakeUser(

              fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'],

              username='toshio')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/election_test/')

-             self.assertEqual(output.status_code, 404)

  

+         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/')

+                 self.assertEqual(output.status_code, 404)

+ 

+         self.setup_db()

+ 

+         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/')

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

+ 

+     def test_admin_no_cla(self):

+         """ Test the admin_new_election function. """

          self.setup_db()

  

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/')

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

+         user = FakeUser(

+             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 patch(

+                     '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):

          """ Test the admin_new_election function. """
@@ -68,339 +91,421 @@ 

          user = FakeUser(

              fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'],

              username='toshio')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/new')

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="shortdesc" name="shortdesc" type="text"'

-                 in output.data)

- 

-             # 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,

-             }

- 

-             output = self.app.post('/admin/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="shortdesc" name="shortdesc" type="text"'

-                 in output.data)

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             # 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,

-             }

- 

-             output = self.app.post('/admin/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="shortdesc" name="shortdesc" type="text"'

-                 in output.data)

-             self.assertTrue(

-                 '<div class="form-control-feedback">This field is required.</div>'

-                 in output.data)

- 

-             # 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,

-             }

- 

-             output = self.app.post('/admin/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="shortdesc" name="shortdesc" type="text"'

-                 in output.data)

-             self.assertTrue(

-                 '<div class="form-control-feedback">The alias cannot be <code>new</code>.</div>'

-                 in output.data)

- 

-             # 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,

-             }

- 

-             output = self.app.post('/admin/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="shortdesc" name="shortdesc" type="text"'

-                 in output.data)

-             self.assertTrue(

-                 'class="form-control-feedback">End date must be later than start date.</div>'

-                 in output.data)

- 

-             # 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,

-             }

- 

-             output = self.app.post('/admin/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="shortdesc" name="shortdesc" type="text"'

-                 in output.data)

-             self.assertTrue(

-                 '<div class="form-control-feedback">There is already another election with '

-                 'this alias.</div>' in output.data)

- 

-             # 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,

-             }

- 

-             output = self.app.post('/admin/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<h2>Create new election</h2>' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="shortdesc" name="shortdesc" type="text"'

-                 in output.data)

-             self.assertTrue(

-                 '<div class="form-control-feedback">There is already another election with '

-                 'this summary.</div>' in output.data)

- 

-             # 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,

-             }

- 

-             output = self.app.post(

-                 '/admin/new', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election "new_election" added'

-                 in output.data)

-             self.assertTrue(

-                 'There are no candidates.' in output.data)

-             self.assertTrue(

-                 '<input class="form-control" id="admin_grp" name="admin_grp" type="text" value="sysadmin-main, testers">'

-                 in output.data)

-             self.assertTrue(

-                 '<input class="form-control" id="lgl_voters" name="lgl_voters" type="text" value="packager, testers">'

-                 in output.data)

-             self.assertTrue(

-                 '<input class="form-control" id="max_votes" name="max_votes" type="text" value="">'

-                 in output.data)

- 

-             # 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,

-             }

- 

-             output = self.app.post(

-                 '/admin/new', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election "new_election2" added'

-                 in output.data)

-             self.assertTrue(

-                 'There are no candidates.' in output.data)

-             self.assertTrue(

-                 '<input class="form-control" id="admin_grp" name="admin_grp" type="text" value="sysadmin-main, testers">'

-                 in output.data)

-             self.assertTrue(

-                 '<input class="form-control" id="lgl_voters" name="lgl_voters" type="text" value="packager, testers">'

-                 in output.data)

-             self.assertTrue(

-                 '<input class="form-control" id="max_votes" name="max_votes" type="text" value="">'

-                 in output.data)

+ 

+         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')

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+ 

+                 # 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,

+                 }

+ 

+                 output = self.app.post('/admin/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+ 

+                 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,

+                 }

+ 

+                 output = self.app.post('/admin/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+                 self.assertTrue(

+                     '<div class="form-control-feedback">This field is required.</div>'

+                     in output.data)

+ 

+                 # 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,

+                 }

+ 

+                 output = self.app.post('/admin/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+                 self.assertTrue(

+                     '<div class="form-control-feedback">The alias cannot be <code>new</code>.</div>'

+                     in output.data)

+ 

+                 # 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,

+                 }

+ 

+                 output = self.app.post('/admin/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+                 self.assertTrue(

+                     'class="form-control-feedback">End date must be later than start date.</div>'

+                     in output.data)

+ 

+                 # 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,

+                 }

+ 

+                 output = self.app.post('/admin/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+                 self.assertTrue(

+                     '<div class="form-control-feedback">There is already another election with '

+                     'this alias.</div>' in output.data)

+ 

+                 # 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,

+                 }

+ 

+                 output = self.app.post('/admin/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     '<h2>Create new election</h2>' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+                 self.assertTrue(

+                     '<div class="form-control-feedback">There is already another election with '

+                     'this summary.</div>' in output.data)

+ 

+                 # 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,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/new', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election "new_election" added'

+                     in output.data)

+                 self.assertTrue(

+                     'There are no candidates.' in output.data)

+                 self.assertIn(

+                     'input class="form-control" id="admin_grp" '

+                     'name="admin_grp" type="text" '

+                     'value="sysadmin-main, testers">', output.data)

+                 self.assertIn(

+                     'input class="form-control" id="lgl_voters" '

+                     'name="lgl_voters" type="text" '

+                     'value="packager, testers">', output.data)

+                 self.assertIn(

+                     'input class="form-control" id="max_votes" '

+                     'name="max_votes" type="text" '

+                     'value="">', output.data)

+ 

+                 # 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,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/new', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election "new_election2" added'

+                     in output.data)

+                 self.assertTrue(

+                     'There are no candidates.' in output.data)

+                 self.assertIn(

+                     'input class="form-control" id="admin_grp" '

+                     'name="admin_grp" type="text" '

+                     'value="sysadmin-main, testers">', output.data)

+                 self.assertIn(

+                     'input class="form-control" id="lgl_voters" '

+                     'name="lgl_voters" type="text" '

+                     'value="packager, testers">', output.data)

+                 self.assertIn(

+                     'input class="form-control" id="max_votes" '

+                     'name="max_votes" type="text" '

+                     'value="">', output.data)

  

      def test_admin_edit_election(self):

          """ Test the admin_edit_election function. """

          user = FakeUser(

              fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'],

              username='toshio')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/')

-             self.assertEqual(output.status_code, 404)

+ 

+         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/')

+                 self.assertEqual(output.status_code, 404)

  

          self.setup_db()

  

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/')

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election Details' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="shortdesc" name="shortdesc" type="text"'

-                 in output.data)

- 

-             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,

-             }

- 

-             output = self.app.post('/admin/test_election/', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election Details' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="shortdesc" name="shortdesc" type="text"'

-                 in output.data)

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             data = {

-                 'alias': 'test_election',

-                 'shortdesc': 'test election shortdesc',

-                 '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)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election Details' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="shortdesc" name="shortdesc" type="text"'

-                 in output.data)

-             self.assertTrue(

-                 '<div class="form-control-feedback">This field is required.</div>'

-                 in output.data)

- 

-             # Check election before edit

-             output = self.app.get('/admin/test_election/')

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

-             self.assertTrue('<input class="form-control" id="seats_elected" name="seats_elected" type="text" value="1">' in output.data)

- 

-             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,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election/', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election "test_election" saved'

-                 in output.data)

-             # We edited the seats_elected from 1 to 2

-             self.assertTrue(

-                 '<input class="form-control" id="seats_elected" name="seats_elected" type="text" value="2">' in output.data)

-             self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

+         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/')

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election Details' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+ 

+                 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,

+                 }

+ 

+                 output = self.app.post('/admin/test_election/', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election Details' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+ 

+                 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,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election/', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election Details' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" required type="text" ', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="shortdesc" '

+                         'name="shortdesc" type="text" ', output.data)

+                 self.assertIn(

+                     '<div class="form-control-feedback">This field is required.</div>',

+                     output.data)

+ 

+                 # Check election before edit

+                 output = self.app.get('/admin/test_election/')

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

+                 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.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" type="text" '

+                         'value="1">', output.data)

+ 

+                 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,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election/', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election "test_election" saved'

+                     in output.data)

+                 # 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.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" type="text" '

+                         'value="2">', output.data)

+                 self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

  

      def test_admin_edit_election_admin_groups(self):

          """ Test the admin_edit_election function when editing admin groups.
@@ -408,84 +513,116 @@ 

          user = FakeUser(

              fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'],

              username='toshio')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/edit')

-             self.assertEqual(output.status_code, 404)

+ 

+         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')

+                 self.assertEqual(output.status_code, 404)

  

          self.setup_db()

  

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election2/')

-             self.assertEqual(output.status_code, 200)

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             # Edit Admin Group

- 

-             # Check election before edit

-             output = self.app.get('/admin/test_election2/')

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<input class="form-control" id="seats_elected" name="seats_elected" type="text" value="1">' in output.data)

-             self.assertTrue('Candidates <span class="label' in output.data)

- 

-             # Add a new admin group: sysadmin-main

-             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': 'testers, sysadmin-main',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election2/', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election "test_election2" saved'

-                 in output.data)

-             self.assertTrue(

-                 '<input class="form-control" id="seats_elected" name="seats_elected" type="text" value="2">' in output.data)

-             # We edited the admin groups

-             self.assertTrue(

-                 '<input class="form-control" id="admin_grp" name="admin_grp" type="text" value="sysadmin-main, testers">'

-                 in output.data)

- 

-             # 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,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election2/', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election "test_election2" saved'

-                 in output.data)

-             self.assertTrue(

-                 '<input class="form-control" id="seats_elected" name="seats_elected" type="text" value="2">' in output.data)

-             # We edited the admin groups

-             self.assertTrue(

-                 '<input class="form-control" id="admin_grp" name="admin_grp" type="text" value="sysadmin-main">'

-                 in output.data)

+         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/')

+                 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/')

+                 self.assertEqual(output.status_code, 200)

+                 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.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" type="text" '

+                         'value="1">', output.data)

+                 self.assertTrue('Candidates <span class="label' in output.data)

+ 

+                 # Add a new admin group: sysadmin-main

+                 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': 'testers, sysadmin-main',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election2/', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election "test_election2" saved'

+                     in output.data)

+                 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.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" type="text" '

+                         'value="2">', output.data)

+                 # We edited the admin groups

+                 self.assertIn(

+                     'input class="form-control" id="admin_grp" '

+                     'name="admin_grp" type="text" '

+                     'value="sysadmin-main, testers">', output.data)

+ 

+                 # 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,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election2/', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election "test_election2" saved'

+                     in output.data)

+                 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.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" type="text" '

+                         'value="2">', output.data)

+                 # We edited the admin groups

+                 self.assertIn(

+                     'input class="form-control" id="admin_grp" '

+                     'name="admin_grp" type="text" '

+                     'value="sysadmin-main">', output.data)

  

      def test_admin_edit_election_legal_voters(self):

          """ Test the admin_edit_election function when editing legal voters.
@@ -493,215 +630,275 @@ 

          user = FakeUser(

              fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'],

              username='toshio')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/edit')

-             self.assertEqual(output.status_code, 404)

+ 

+         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')

+                 self.assertEqual(output.status_code, 404)

  

          self.setup_db()

  

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election3/')

-             self.assertEqual(output.status_code, 200)

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

-             # Edit LegalVoter Group

- 

-             # Check election before edit

-             output = self.app.get('/admin/test_election3/')

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 '<input class="form-control" id="seats_elected" name="seats_elected" type="text" value="1">'

-                 in output.data)

-             self.assertTrue('Candidates <span class="label'

-                 in output.data)

-             self.assertTrue(

-                 '<input class="form-control" id="admin_grp" name="admin_grp" type="text" value="">'

-                 in output.data)

-             self.assertTrue('<input class="form-control" id="lgl_voters" name="lgl_voters" type="text" value="voters">'

-                 in output.data)

- 

-             # 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,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election3/', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election "test_election3" saved'

-                 in output.data)

-             # We edited the legal_voters

-             self.assertTrue('<input class="form-control" id="lgl_voters" name="lgl_voters" type="text" value="sysadmin-main, voters">'

-                 in output.data)

- 

-             # 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,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election3/', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Election "test_election3" saved'

-                 in output.data)

-             # We edited the legal_voters

-             self.assertTrue('<input class="form-control" id="lgl_voters" name="lgl_voters" type="text" value="sysadmin-main">'

-                 in output.data)

+         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/')

+                 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/')

+                 self.assertEqual(output.status_code, 200)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" required type="text"', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" type="text"', output.data)

+                 self.assertTrue('Candidates <span class="label'

+                     in output.data)

+                 self.assertTrue(

+                     '<input class="form-control" id="admin_grp" name="admin_grp" type="text" value="">'

+                     in output.data)

+                 self.assertIn(

+                     'input class="form-control" id="lgl_voters" '

+                     'name="lgl_voters" type="text" value="voters">',

+                     output.data)

+ 

+                 # 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,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election3/', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election "test_election3" saved'

+                     in output.data)

+                 # We edited the legal_voters

+                 self.assertIn(

+                     'input class="form-control" id="lgl_voters" '

+                     'name="lgl_voters" type="text" '

+                     'value="sysadmin-main, voters">', output.data)

+ 

+                 # 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,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election3/', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Election "test_election3" saved'

+                     in output.data)

+                 # We edited the legal_voters

+                 self.assertIn(

+                     'input class="form-control" id="lgl_voters" '

+                     'name="lgl_voters" type="text" '

+                     'value="sysadmin-main">', output.data)

  

      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):

-             output = self.app.get('/admin/test_election/candidates/new')

-             self.assertEqual(output.status_code, 404)

+         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')

+                 self.assertEqual(output.status_code, 404)

  

          self.setup_db()

  

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/candidates/new')

-             self.assertEqual(output.status_code, 200)

- 

-             self.assertTrue('Add candidate' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="name" name="name" type="text"' in output.data)

- 

-             data = {

-                 'name': 'pingou',

-                 'url': '',

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election/candidates/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue('Add candidate' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="name" name="name" type="text"' in output.data)

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             data = {

-                 'name': '',

-                 'url': '',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election/candidates/new', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue('Add candidate' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="name" name="name" type="text"' in output.data)

-             self.assertTrue(

-                 '<div class="form-control-feedback">This field is required.</div>'

-                 in output.data)

- 

-             data = {

-                 'name': 'pingou',

-                 'url': '',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election/candidates/new', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Candidate "pingou" saved'

-                 in output.data)

-             self.assertTrue('Candidates <span class="label label-pill label-default">4</span>' in output.data)

+         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')

+                 self.assertEqual(output.status_code, 200)

+ 

+                 self.assertTrue('Add candidate' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="name" name="name" '

+                         'required type="text"', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="name" name="name" '

+                         'type="text"', output.data)

+ 

+                 data = {

+                     'name': 'pingou',

+                     'url': '',

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election/candidates/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue('Add candidate' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="name" name="name" '

+                         'required type="text"', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="name" name="name" '

+                         'type="text"', output.data)

+ 

+                 csrf_token = self.get_csrf(output=output)

+ 

+                 data = {

+                     'name': '',

+                     'url': '',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election/candidates/new', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue('Add candidate' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="name" name="name" '

+                         'required type="text"', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="name" name="name" '

+                         'type="text"', output.data)

+                 self.assertTrue(

+                     '<div class="form-control-feedback">This field is required.</div>'

+                     in output.data)

+ 

+                 data = {

+                     'name': 'pingou',

+                     'url': '',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election/candidates/new', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Candidate "pingou" saved'

+                     in output.data)

+                 self.assertTrue('Candidates <span class="label label-pill label-default">4</span>' in output.data)

  

      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):

-             output = self.app.get('/admin/test_election/candidates/new/multi')

-             self.assertEqual(output.status_code, 404)

+         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')

+                 self.assertEqual(output.status_code, 404)

  

          self.setup_db()

  

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/candidates/new/multi')

-             self.assertEqual(output.status_code, 200)

- 

-             self.assertTrue('Add candidates' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="candidate" name="candidate" type="text"'

-                 in output.data)

- 

-             data = {

-                 'candidate': 'pingou',

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election/candidates/new/multi', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue('Add candidates' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="candidate" name="candidate" type="text"'

-                 in output.data)

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             data = {

-                 'candidate': '',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election/candidates/new/multi', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue('Add candidates' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="candidate" name="candidate" type="text"'

-                 in output.data)

-             self.assertTrue(

-                 '<div class="form-control-feedback">This field is required.</div>'

-                 in output.data)

- 

-             data = {

-                 'candidate': 'pingou|patrick!https://fedoraproject.org|'

-                 'shaiton!https://fedoraproject.org!test|sochotni',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election/candidates/new/multi', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Added 3 candidates'

-                 in output.data)

-             self.assertTrue('Candidates <span class="label label-pill label-default">6</span>' in output.data)

+         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')

+                 self.assertEqual(output.status_code, 200)

+ 

+                 self.assertTrue('Add candidates' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="candidate" '

+                         'name="candidate" required type="text"', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="candidate" '

+                         'name="candidate" type="text"', output.data)

+ 

+                 data = {

+                     'candidate': 'pingou',

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election/candidates/new/multi', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue('Add candidates' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="candidate" '

+                         'name="candidate" required type="text"', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="candidate" '

+                         'name="candidate" type="text"', output.data)

+ 

+                 csrf_token = self.get_csrf(output=output)

+ 

+                 data = {

+                     'candidate': '',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election/candidates/new/multi', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue('Add candidates' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="candidate" '

+                         'name="candidate" required type="text"', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="candidate" '

+                         'name="candidate" type="text"', output.data)

+                 self.assertTrue(

+                     '<div class="form-control-feedback">This field is required.</div>'

+                     in output.data)

+ 

+                 data = {

+                     'candidate': 'pingou|patrick!https://fedoraproject.org|'

+                     'shaiton!https://fedoraproject.org!test|sochotni',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election/candidates/new/multi', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Added 3 candidates'

+                     in output.data)

+                 self.assertTrue('Candidates <span class="label label-pill label-default">6</span>' in output.data)

  

      def test_admin_edit_candidate(self):

          """ Test the admin_edit_candidate function. """
@@ -712,77 +909,103 @@ 

          self.setup_db()

  

          # Election does not exist

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test/candidates/1/edit')

-             self.assertEqual(output.status_code, 404)

- 

-         # Candidate does not exist

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/candidates/100/edit')

-             self.assertEqual(output.status_code, 404)

- 

-         # Candidate not in election

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/candidates/5/edit')

-             self.assertEqual(output.status_code, 404)

- 

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/candidates/1/edit')

-             self.assertEqual(output.status_code, 200)

- 

-             self.assertTrue('Edit candidate' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="name" name="name" type="text"' in output.data)

- 

-             data = {

-                 'name': 'Toshio Kuratomi',

-                 'url': 'https://fedoraproject.org/wiki/User:Toshio',

-             }

- 

-             self.assertTrue('Edit candidate' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="name" name="name" type="text"' in output.data)

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             data = {

-                 'name': '',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election/candidates/1/edit', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue('Edit candidate' in output.data)

-             self.assertTrue(

-                 'input class="form-control" id="name" name="name" type="text"' in output.data)

-             self.assertTrue(

-                 '<div class="form-control-feedback">This field is required.</div>'

-                 in output.data)

- 

-             # Check election before edit

-             output = self.app.get('/admin/test_election/')

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

-             self.assertTrue('<input class="form-control" id="seats_elected" name="seats_elected" type="text" value="1">' in output.data)

-             self.assertTrue('<div class="list-group-item">Toshio' in output.data)

- 

-             data = {

-                 'name': 'Toshio Kuratomi',

-                 'url': 'https://fedoraproject.org/wiki/User:Toshio',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election/candidates/1/edit', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Candidate "Toshio Kuratomi" saved'

-                 in output.data)

-             self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

-             self.assertTrue('<div class="list-group-item">Toshio' in output.data)

+         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')

+                 self.assertEqual(output.status_code, 404)

+ 

+                 # Candidate does not exist

+                 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')

+                 self.assertEqual(output.status_code, 404)

+ 

+                 output = self.app.get('/admin/test_election/candidates/1/edit')

+                 self.assertEqual(output.status_code, 200)

+ 

+                 self.assertTrue('Edit candidate' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="name" name="name" '

+                         'required type="text"', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="name" name="name" '

+                         'type="text"', output.data)

+ 

+                 data = {

+                     'name': 'Toshio Kuratomi',

+                     'url': 'https://fedoraproject.org/wiki/User:Toshio',

+                 }

+ 

+                 self.assertTrue('Edit candidate' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="name" name="name" '

+                         'required type="text"', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="name" name="name" '

+                         'type="text"', output.data)

+ 

+                 csrf_token = self.get_csrf(output=output)

+ 

+                 data = {

+                     'name': '',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election/candidates/1/edit', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue('Edit candidate' in output.data)

+                 if self.get_wtforms_version() >= (2, 2):

+                     self.assertIn(

+                         'input class="form-control" id="name" name="name" '

+                         'required type="text"', output.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="name" name="name" '

+                         'type="text"', output.data)

+                 self.assertTrue(

+                     '<div class="form-control-feedback">This field is required.</div>'

+                     in output.data)

+ 

+                 # Check election before edit

+                 output = self.app.get('/admin/test_election/')

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

+                 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.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" type="text" value="1"',

+                         output.data)

+                 self.assertTrue('<div class="list-group-item">Toshio' in output.data)

+ 

+                 data = {

+                     'name': 'Toshio Kuratomi',

+                     'url': 'https://fedoraproject.org/wiki/User:Toshio',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election/candidates/1/edit', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Candidate "Toshio Kuratomi" saved'

+                     in output.data)

+                 self.assertTrue('Candidates <span class="label label-pill label-default">3</span>' in output.data)

+                 self.assertTrue('<div class="list-group-item">Toshio' in output.data)

  

      def test_admin_delete_candidate(self):

          """ Test the admin_delete_candidate function. """
@@ -793,77 +1016,85 @@ 

          self.setup_db()

  

          # Election does not exist

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test/candidates/1/delete')

-             self.assertEqual(output.status_code, 404)

- 

-         # Candidate does not exist

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/candidates/100/delete')

-             self.assertEqual(output.status_code, 404)

- 

-         # Candidate not in election

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/candidates/5/delete')

-             self.assertEqual(output.status_code, 404)

- 

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/admin/test_election/candidates/1/delete')

-             self.assertEqual(output.status_code, 200)

- 

-             self.assertTrue('<h2>Delete candidate</h2>' in output.data)

-             self.assertTrue(

-                 'p>Are you sure you want to delete candidate "Toshio"?</p'

-                 in output.data)

- 

-             output = self.app.post('/admin/test_election/candidates/1/delete')

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue('<h2>Delete candidate</h2>' in output.data)

-             self.assertTrue(

-                 'p>Are you sure you want to delete candidate "Toshio"?</p'

-                 in output.data)

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             # Try to delete while there are votes link to this candidates

-             data = {

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election/candidates/1/delete', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue('<h2>test election shortdesc</h2>' in output.data)

-             self.assertTrue(

-                 'Could not delete this candidate. Is it '

-                 'already part of an election?' in output.data)

- 

-             # Check election before edit

-             output = self.app.get('/admin/test_election4/')

-             self.assertTrue('Candidates <span class="label label-pill label-default">2</span>' in output.data)

-             self.assertTrue('<input class="form-control" id="seats_elected" name="seats_elected" type="text" value="1">' in output.data)

-             self.assertTrue('<div class="list-group-item">Toshio' in output.data)

-             self.assertTrue(

-                 'value="test election 4 shortdesc">' in output.data)

- 

-             # Delete one candidate

-             data = {

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/admin/test_election4/candidates/10/delete', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Candidate "Toshio" deleted'

-                 in output.data)

-             self.assertTrue(

-                 'value="test election 4 shortdesc">' in output.data)

-             self.assertTrue('Candidates <span class="label label-pill label-default">1</span>' in output.data)

-             self.assertFalse('<div class="list-group-item">Toshio' in output.data)

+         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')

+                 self.assertEqual(output.status_code, 404)

+ 

+                 # Candidate does not exist

+                 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')

+                 self.assertEqual(output.status_code, 404)

+ 

+                 output = self.app.get('/admin/test_election/candidates/1/delete')

+                 self.assertEqual(output.status_code, 200)

+ 

+                 self.assertTrue('<h2>Delete candidate</h2>' in output.data)

+                 self.assertTrue(

+                     'p>Are you sure you want to delete candidate "Toshio"?</p'

+                     in output.data)

+ 

+                 output = self.app.post('/admin/test_election/candidates/1/delete')

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue('<h2>Delete candidate</h2>' in output.data)

+                 self.assertTrue(

+                     'p>Are you sure you want to delete candidate "Toshio"?</p'

+                     in output.data)

+ 

+                 csrf_token = self.get_csrf(output=output)

+ 

+                 # Try to delete while there are votes link to this candidates

+                 data = {

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election/candidates/1/delete', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue('<h2>test election shortdesc</h2>' in output.data)

+                 self.assertTrue(

+                     'Could not delete this candidate. Is it '

+                     'already part of an election?' in output.data)

+ 

+                 # Check election before edit

+                 output = self.app.get('/admin/test_election4/')

+                 self.assertTrue('Candidates <span class="label label-pill label-default">2</span>' in output.data)

+                 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.data)

+                 else:

+                     self.assertIn(

+                         'input class="form-control" id="seats_elected" '

+                         'name="seats_elected" type="text" value="1"',

+                         output.data)

+                 self.assertTrue('<div class="list-group-item">Toshio' in output.data)

+                 self.assertTrue(

+                     'value="test election 4 shortdesc">' in output.data)

+ 

+                 # Delete one candidate

+                 data = {

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/admin/test_election4/candidates/10/delete', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Candidate "Toshio" deleted'

+                     in output.data)

+                 self.assertTrue(

+                     'value="test election 4 shortdesc">' in output.data)

+                 self.assertTrue('Candidates <span class="label label-pill label-default">1</span>' in output.data)

+                 self.assertFalse('<div class="list-group-item">Toshio' in output.data)

  

  

  if __name__ == '__main__':

file modified
+121 -104
@@ -32,6 +32,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__)), '..'))
@@ -48,30 +49,30 @@ 

          """ Test the vote function without data. """

          output = self.app.get('/vote/test_election')

          self.assertEqual(output.status_code, 302)

- 

-         output = self.app.get('/vote/test_election', follow_redirects=True)

-         self.assertEqual(output.status_code, 200)

-         self.assertTrue(

-             '<title>OpenID transaction in progress</title>' in output.data

-             or 'discoveryfailure' in output.data)

+         self.assertIn(

+             '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election',

+             output.data)

  

          user = FakeUser(['packager'], username='pingou')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get('/vote/test_election')

-             self.assertEqual(output.status_code, 302)

- 

-             output = self.app.get('/vote/test_election', follow_redirects=True)

-             self.assertTrue(

-                 'The election, test_election, does not exist.'

-                 in output.data)

+         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')

+                 self.assertEqual(output.status_code, 302)

+ 

+                 output = self.app.get('/vote/test_election', follow_redirects=True)

+                 self.assertTrue(

+                     'The election, test_election, does not exist.'

+                     in output.data)

  

      def test_vote(self):

          """ Test the vote function. """

-         output = self.app.get('/vote/test_election', follow_redirects=True)

-         self.assertEqual(output.status_code, 200)

-         self.assertTrue(

-             '<title>OpenID transaction in progress</title>' in output.data

-             or 'discoveryfailure' in output.data)

+         output = self.app.get('/vote/test_election')

+         self.assertEqual(output.status_code, 302)

+         self.assertIn(

+             '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election',

+             output.data)

  

          self.setup_db()

  
@@ -88,72 +89,81 @@ 

                  in output.data)

  

          user = FakeUser([], username='pingou')

-         with user_set(fedora_elections.APP, user):

+         with user_set(fedora_elections.APP, user, oidc_id_token='foobar'):

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=[])):

  

-             output = self.app.get('/vote/test_election')

-             self.assertEqual(output.status_code, 302)

+                 output = self.app.get('/vote/test_election')

+                 self.assertEqual(output.status_code, 302)

  

-             output = self.app.get(

-                 '/vote/test_election', follow_redirects=True)

-             self.assertTrue(

-                 'You need to be in one another group than '

-                 'CLA to vote' in output.data)

+                 output = self.app.get(

+                     '/vote/test_election', follow_redirects=True)

+                 self.assertTrue(

+                     'You need to be in one another group than '

+                     'CLA to vote' in output.data)

  

          user = FakeUser(['packager'], username='pingou')

-         with user_set(fedora_elections.APP, user):

+         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_election3')

-             self.assertEqual(output.status_code, 302)

+                 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)

-             self.assertTrue(

-                 'You are not among the groups that are '

-                 'allowed to vote for this election' in output.data)

+                 # Election closed and results open

+                 output = self.app.get(

+                     '/vote/test_election3', follow_redirects=True)

+                 self.assertTrue(

+                     'You are not among the groups that are '

+                     'allowed to vote for this election' in output.data)

  

          user = FakeUser(['voters'], username='pingou')

-         with user_set(fedora_elections.APP, user):

- 

-             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)

-             self.assertTrue(

-                 '<span class="label label-danger">Election Closed</span>'

-                 in output.data)

- 

-             # Election closed and results are embargoed

-             output = self.app.get(

-                 '/vote/test_election2', follow_redirects=True)

-             self.assertTrue(

-                 '<span class="label label-danger">Election Closed</span>'

-                 in output.data)

- 

-             # Election still pending

-             output = self.app.get(

-                 '/vote/test_election4', follow_redirects=True)

-             self.assertTrue(

-                 'Voting has not yet started, sorry.'

-                 in output.data)

- 

-             # Election in progress

-             output = self.app.get('/vote/test_election3')

-             self.assertTrue(

-                 'test election 3 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="preview" />'

-                 in output.data)

- 

-             # Election in progress

-             output = self.app.get('/vote/test_election5')

-             self.assertTrue(

-                 'test election 5 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="preview" />'

-                 in output.data)

+         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_election')

+                 self.assertEqual(output.status_code, 302)

+ 

+                 # Election closed and results open

+                 output = self.app.get(

+                     '/vote/test_election', follow_redirects=True)

+                 self.assertTrue(

+                     '<span class="label label-danger">Election Closed</span>'

+                     in output.data)

+ 

+                 # Election closed and results are embargoed

+                 output = self.app.get(

+                     '/vote/test_election2', follow_redirects=True)

+                 self.assertTrue(

+                     '<span class="label label-danger">Election Closed</span>'

+                     in output.data)

+ 

+                 # Election still pending

+                 output = self.app.get(

+                     '/vote/test_election4', follow_redirects=True)

+                 self.assertTrue(

+                     'Voting has not yet started, sorry.'

+                     in output.data)

+ 

+                 # Election in progress

+                 output = self.app.get('/vote/test_election3')

+                 self.assertTrue(

+                     'test election 3 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="preview" />'

+                     in output.data)

+ 

+                 # Election in progress

+                 output = self.app.get('/vote/test_election5')

+                 self.assertTrue(

+                     'test election 5 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="preview" />'

+                     in output.data)

  

      def test_election_results(self):

          """ Test the election_results function - the preview part. """
@@ -194,22 +204,25 @@ 

          user = FakeUser(

              fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'],

              username='toshio')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get(

-                 '/about/test_election2', follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'You are only seeing these results because you are an admin.'

-                 in output.data)

-             self.assertTrue(

-                 'The results for this election are currently embargoed '

-                 in output.data)

-             self.assertTrue(

-                 '<th class="nowrap" title="Number of votes received">Votes</th>'

-                 in output.data)

-             self.assertTrue(

-                 '<h3>Some statistics about this election</h3>'

-                 in output.data)

+         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)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'You are only seeing these results because you are an admin.'

+                     in output.data)

+                 self.assertTrue(

+                     'The results for this election are currently embargoed '

+                     in output.data)

+                 self.assertTrue(

+                     '<th class="nowrap" title="Number of votes received">Votes</th>'

+                     in output.data)

+                 self.assertTrue(

+                     '<h3>Some statistics about this election</h3>'

+                     in output.data)

  

          user = FakeUser(['gitr2spec'], username='kevin')

          with user_set(fedora_elections.APP, user):
@@ -251,11 +264,14 @@ 

          user = FakeUser(

              fedora_elections.APP.config['FEDORA_ELECTIONS_ADMIN_GROUP'],

              username='toshio')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get(

-                 '/results/test_election/text', follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             exp = """<!DOCTYPE html>

+         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(

+                     '/results/test_election/text', follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 exp = """<!DOCTYPE html>

  

  <html xmlns="http://www.w3.org/1999/xhtml">

    <head>
@@ -291,12 +307,13 @@ 

  

  </body>

  </html>"""

-             self.assertEqual(output.data, exp)

+                 print(output.data)

+                 self.assertEqual(output.data, exp)

  

-             output = self.app.get(

-                 '/results/test_election2/text', follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             exp = """<!DOCTYPE html>

+                 output = self.app.get(

+                     '/results/test_election2/text', follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 exp = """<!DOCTYPE html>

  

  <html xmlns="http://www.w3.org/1999/xhtml">

    <head>
@@ -329,7 +346,7 @@ 

  </body>

  </html>"""

  

-             self.assertEqual(output.data, exp)

+                 self.assertEqual(output.data, exp)

  

          user = FakeUser(['gitr2spec'], username='kevin')

          with user_set(fedora_elections.APP, user):

file modified
+130 -122
@@ -32,6 +32,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__)), '..'))
@@ -46,100 +47,104 @@ 

  

      def test_vote_irc(self):

          """ Test the vote_irc function - the preview part. """

-         output = self.app.get(

-             '/vote/test_election', follow_redirects=True)

-         self.assertEqual(output.status_code, 200)

-         self.assertTrue(

-             '<title>OpenID transaction in progress</title>' in output.data

-             or 'discoveryfailure' in output.data)

+         output = self.app.get('/vote/test_election')

+         self.assertEqual(output.status_code, 302)

+         self.assertIn(

+             '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election',

+             output.data)

  

          self.setup_db()

  

          user = FakeUser(['packager'], username='nerdsville')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get(

-                 '/vote/test_election7')

-             self.assertTrue(

-                 'test election 7 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="preview" />'

-                 in output.data)

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             # Invalid vote: No candidate

-             data = {

-                 'action': 'preview',

-             }

- 

-             output = self.app.post('/vote/test_election7', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'test election 7 shortdesc' in output.data)

- 

-             # Valid input

-             data = {

-                 'Kevin': -1,

-                 'Toshio': '0',

-                 'action': 'preview',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/vote/test_election7', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'test election 7 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="submit" />'

-                 in output.data)

-             self.assertTrue(

-                 'Please confirm your vote!'

-                 in output.data)

+         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')

+                 self.assertTrue(

+                     'test election 7 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="preview" />'

+                     in output.data)

+ 

+                 csrf_token = output.data.split(

+                     'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+ 

+                 # Invalid vote: No candidate

+                 data = {

+                     'action': 'preview',

+                 }

+ 

+                 output = self.app.post('/vote/test_election7', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'test election 7 shortdesc' in output.data)

+ 

+                 # Valid input

+                 data = {

+                     'Kevin': -1,

+                     'Toshio': '0',

+                     'action': 'preview',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/vote/test_election7', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'test election 7 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="submit" />'

+                     in output.data)

+                 self.assertTrue(

+                     'Please confirm your vote!'

+                     in output.data)

  

      def test_vote_irc_process(self):

          """ Test the vote_irc function - the voting part. """

-         output = self.app.get(

-             '/vote/test_election', follow_redirects=True)

-         self.assertEqual(output.status_code, 200)

-         self.assertTrue(

-             '<title>OpenID transaction in progress</title>' in output.data

-             or 'discoveryfailure' in output.data)

+         output = self.app.get('/vote/test_election')

+         self.assertEqual(output.status_code, 302)

+         self.assertIn(

+             '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election',

+             output.data)

  

          self.setup_db()

  

          user = FakeUser(['packager'], username='pingou')

-         with user_set(fedora_elections.APP, user):

-             # Invalid candidate id - no csrf

-             data = {

-                 'candidate': 1,

-                 'action': 'submit',

-             }

- 

-             output = self.app.post(

-                 '/vote/test_election7', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             # Valid input

-             data = {

-                 'Toshio': '0',

-                 'Kevin': '1',

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/vote/test_election7', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Your vote has been recorded.  Thank you!'

-                 in output.data)

-             self.assertTrue('Open elections' in output.data)

+         with user_set(fedora_elections.APP, user, oidc_id_token='foobar'):

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['packager'])):

+                 # Invalid candidate id - no csrf

+                 data = {

+                     'candidate': 1,

+                     'action': 'submit',

+                 }

+ 

+                 output = self.app.post(

+                     '/vote/test_election7', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+ 

+                 csrf_token = output.data.split(

+                     'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+ 

+                 # Valid input

+                 data = {

+                     'Toshio': '0',

+                     'Kevin': '1',

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/vote/test_election7', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Your vote has been recorded.  Thank you!'

+                     in output.data)

+                 self.assertTrue('Open elections' in output.data)

  

      def test_vote_irc_revote(self):

          """ Test the vote_irc function - the re-voting part. """
@@ -147,45 +152,48 @@ 

          self.setup_db()

  

          user = FakeUser(['voters'], username='nerdsville')

-         with user_set(fedora_elections.APP, user):

-             retrieve_csrf = self.app.post('/vote/test_election7')

-             csrf_token = retrieve_csrf.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

-             # Valid input

-             data = {

-                 'Kevin': -1,

-                 'Toshio': 1,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

-             self.app.post('/vote/test_election7', data=data, follow_redirects=True)

-             vote = fedora_elections.models.Vote

-             votes = vote.of_user_on_election(self.session, "nerdsville", '7')

-             self.assertEqual(votes[0].value, 1)

-             self.assertEqual(votes[1].value, -1)

-         #Let's not do repetition of what is tested above we aren't testing the

-         #functionality of voting as that has already been asserted

- 

-         #Next, we need to try revoting

-             newdata = {

-                 'Kevin': 1,

-                 'Toshio': -1,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

-             output = self.app.post('/vote/test_election7', data=newdata, follow_redirects=True)

-         #Next, we need to check if the vote has been recorded

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Your vote has been recorded.  Thank you!'

-                 in output.data)

-             self.assertTrue('Open elections' in output.data)

-             vote = fedora_elections.models.Vote

-             votes = vote.of_user_on_election(self.session, "nerdsville", '7')

-             self.assertEqual(votes[0].value, -1)

-             self.assertEqual(votes[1].value, 1)

- 

-         #If we haven't failed yet, HOORAY!

+         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')

+                 csrf_token = retrieve_csrf.data.split(

+                     'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+                 # Valid input

+                 data = {

+                     'Kevin': -1,

+                     'Toshio': 1,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+                 self.app.post('/vote/test_election7', data=data, follow_redirects=True)

+                 vote = fedora_elections.models.Vote

+                 votes = vote.of_user_on_election(self.session, "nerdsville", '7')

+                 self.assertEqual(votes[0].value, 1)

+                 self.assertEqual(votes[1].value, -1)

+             #Let's not do repetition of what is tested above we aren't testing the

+             #functionality of voting as that has already been asserted

+ 

+             #Next, we need to try revoting

+                 newdata = {

+                     'Kevin': 1,

+                     'Toshio': -1,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+                 output = self.app.post('/vote/test_election7', data=newdata, follow_redirects=True)

+             #Next, we need to check if the vote has been recorded

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Your vote has been recorded.  Thank you!'

+                     in output.data)

+                 self.assertTrue('Open elections' in output.data)

+                 vote = fedora_elections.models.Vote

+                 votes = vote.of_user_on_election(self.session, "nerdsville", '7')

+                 self.assertEqual(votes[0].value, -1)

+                 self.assertEqual(votes[1].value, 1)

+ 

+             #If we haven't failed yet, HOORAY!

  

  if __name__ == '__main__':

      SUITE = unittest.TestLoader().loadTestsFromTestCase(FlaskIrcElectionstests)

file modified
+285 -277
@@ -32,6 +32,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__)), '..'))
@@ -46,242 +47,246 @@ 

  

      def test_vote_range(self):

          """ Test the vote_range function - the preview part. """

-         output = self.app.get(

-             '/vote/test_election', follow_redirects=True)

-         self.assertEqual(output.status_code, 200)

-         self.assertTrue(

-             '<title>OpenID transaction in progress</title>' in output.data

-             or 'discoveryfailure' in output.data)

+         output = self.app.get('/vote/test_election')

+         self.assertEqual(output.status_code, 302)

+         self.assertIn(

+             '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election',

+             output.data)

  

          self.setup_db()

  

          user = FakeUser(['voters'], username='pingou')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get(

-                 '/vote/test_election3')

-             self.assertTrue(

-                 'test election 3 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="preview" />'

-                 in output.data)

- 

-             # Invalid candidate id

-             data = {

-                 'Toshio': 1,

-                 'kevin': 3,

-                 'Ralph': 2,

-                 'action': 'preview',

-             }

- 

-             output = self.app.post('/vote/test_election3', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertEqual(

-                 output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

-                 3)

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             # Invalid candidate id

-             data = {

-                 'Toshio': 1,

-                 'Kevin': 3,

-                 'Ralph': 2,

-                 'action': 'preview',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/vote/test_election3', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertEqual(

-                 output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

-                 3)

- 

-             # Invalid vote: too low

-             data = {

-                 '9': -1,

-                 '6': 0,

-                 '5': 2,

-                 'action': 'preview',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/vote/test_election3', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'test election 3 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="preview" />'

-                 in output.data)

-             self.assertEqual(

-                 output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

-                 1)

- 

-             # Invalid vote: 2 are too high

-             data = {

-                 '9': 5,

-                 '6': 3,

-                 '5': 2,

-                 'action': 'preview',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/vote/test_election3', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'test election 3 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="preview" />'

-                 in output.data)

-             self.assertEqual(

-                 output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

-                 2)

- 

-             # Invalid vote: Not numeric

-             data = {

-                 '9': 'a',

-                 '6': 0,

-                 '5': 2,

-                 'action': 'preview',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/vote/test_election3', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'test election 3 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="preview" />'

-                 in output.data)

-             self.assertEqual(

-                 output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

-                 1)

- 

-             # Valid input

-             data = {

-                 '4': 1,

-                 '6': 0,

-                 '5': 2,

-                 'action': 'preview',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/vote/test_election3', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'test election 3 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="submit" />'

-                 in output.data)

+         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')

+                 self.assertTrue(

+                     'test election 3 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="preview" />'

+                     in output.data)

+ 

+                 # Invalid candidate id

+                 data = {

+                     'Toshio': 1,

+                     'kevin': 3,

+                     'Ralph': 2,

+                     'action': 'preview',

+                 }

+ 

+                 output = self.app.post('/vote/test_election3', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertEqual(

+                     output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

+                     3)

+ 

+                 csrf_token = output.data.split(

+                     'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+ 

+                 # Invalid candidate id

+                 data = {

+                     'Toshio': 1,

+                     'Kevin': 3,

+                     'Ralph': 2,

+                     'action': 'preview',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/vote/test_election3', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertEqual(

+                     output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

+                     3)

+ 

+                 # Invalid vote: too low

+                 data = {

+                     '9': -1,

+                     '6': 0,

+                     '5': 2,

+                     'action': 'preview',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/vote/test_election3', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'test election 3 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="preview" />'

+                     in output.data)

+                 self.assertEqual(

+                     output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

+                     1)

+ 

+                 # Invalid vote: 2 are too high

+                 data = {

+                     '9': 5,

+                     '6': 3,

+                     '5': 2,

+                     'action': 'preview',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/vote/test_election3', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'test election 3 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="preview" />'

+                     in output.data)

+                 self.assertEqual(

+                     output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

+                     2)

+ 

+                 # Invalid vote: Not numeric

+                 data = {

+                     '9': 'a',

+                     '6': 0,

+                     '5': 2,

+                     'action': 'preview',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/vote/test_election3', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'test election 3 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="preview" />'

+                     in output.data)

+                 self.assertEqual(

+                     output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

+                     1)

+ 

+                 # Valid input

+                 data = {

+                     '4': 1,

+                     '6': 0,

+                     '5': 2,

+                     'action': 'preview',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/vote/test_election3', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'test election 3 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="submit" />'

+                     in output.data)

  

      def test_vote_range_process(self):

          """ Test the vote_range function - the voting part. """

-         output = self.app.get(

-             '/vote/test_election', follow_redirects=True)

-         self.assertEqual(output.status_code, 200)

-         self.assertTrue(

-             '<title>OpenID transaction in progress</title>' in output.data

-             or 'discoveryfailure' in output.data)

+         output = self.app.get('/vote/test_election')

+         self.assertEqual(output.status_code, 302)

+         self.assertIn(

+             '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election',

+             output.data)

  

          self.setup_db()

  

          user = FakeUser(['voters'], username='pingou')

-         with user_set(fedora_elections.APP, user):

-             # No csrf token provided

-             data = {

-                 'Toshio': 1,

-                 'Kevin': 3,

-                 'Ralph': 2,

-                 'action': 'submit',

-             }

- 

-             output = self.app.post('/vote/test_election3', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertEqual(

-                 output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

-                 3)

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             # Invalid vote: invalid username

-             data = {

-                 'Toshio': 1,

-                 'Kevin': 3,

-                 'Ralph': 2,

-                 'action': 'submit',

-             }

- 

-             output = self.app.post('/vote/test_election3', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertEqual(

-                 output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

-                 3)

- 

-             # Invalid vote: too low

-             data = {

-                 '4': -1,

-                 '5': 0,

-                 '6': 2,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/vote/test_election3', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertEqual(

-                 output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

-                 1)

- 

-             # Invalid vote: 2 are too high

-             data = {

-                 '4': 5,

-                 '5': 3,

-                 '6': 2,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/vote/test_election3', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertEqual(

-                 output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

-                 2)

- 

-             # Invalid vote: Not numeric

-             data = {

-                 '4': 'a',

-                 '5': 0,

-                 '6': 2,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/vote/test_election3', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertEqual(

-                 output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

-                 1)

- 

-             # Valid input

-             data = {

-                 '4': 1,

-                 '5': 0,

-                 '6': 2,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/vote/test_election3', data=data, follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Your vote has been recorded.  Thank you!'

-                 in output.data)

-             self.assertTrue('Open elections' in output.data)

+         with user_set(fedora_elections.APP, user, oidc_id_token='foobar'):

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['voters'])):

+                 # No csrf token provided

+                 data = {

+                     'Toshio': 1,

+                     'Kevin': 3,

+                     'Ralph': 2,

+                     'action': 'submit',

+                 }

+ 

+                 output = self.app.post('/vote/test_election3', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertEqual(

+                     output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

+                     3)

+ 

+                 csrf_token = output.data.split(

+                     'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+ 

+                 # Invalid vote: invalid username

+                 data = {

+                     'Toshio': 1,

+                     'Kevin': 3,

+                     'Ralph': 2,

+                     'action': 'submit',

+                 }

+ 

+                 output = self.app.post('/vote/test_election3', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertEqual(

+                     output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

+                     3)

+ 

+                 # Invalid vote: too low

+                 data = {

+                     '4': -1,

+                     '5': 0,

+                     '6': 2,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/vote/test_election3', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertEqual(

+                     output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

+                     1)

+ 

+                 # Invalid vote: 2 are too high

+                 data = {

+                     '4': 5,

+                     '5': 3,

+                     '6': 2,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/vote/test_election3', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertEqual(

+                     output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

+                     2)

+ 

+                 # Invalid vote: Not numeric

+                 data = {

+                     '4': 'a',

+                     '5': 0,

+                     '6': 2,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/vote/test_election3', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertEqual(

+                     output.data.count('<div class="form-control-feedback">Not a valid choice</div>'),

+                     1)

+ 

+                 # Valid input

+                 data = {

+                     '4': 1,

+                     '5': 0,

+                     '6': 2,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/vote/test_election3', data=data, follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Your vote has been recorded.  Thank you!'

+                     in output.data)

+                 self.assertTrue('Open elections' in output.data)

  

      def test_vote_range_revote(self):

          """ Test the vote_range function - the re-voting part. """
@@ -289,58 +294,61 @@ 

          self.setup_db()

  

          user = FakeUser(['voters'], username='nerdsville')

-         with user_set(fedora_elections.APP, user):

-             retrieve_csrf = self.app.post('/vote/test_election3')

-             csrf_token = retrieve_csrf.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

-             data = {

-                 '4': 1,

-                 '5': 0,

-                 '6': 2,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

-             self.app.post('/vote/test_election3', data=data, follow_redirects=True)

-             vote = fedora_elections.models.Vote

-             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

- 

-             obj = fedora_elections.models.Candidate(  # id:16

-                 election_id=3,

-                 name='Josh',

-                 url='https://fedoraproject.org/wiki/User:Nerdsville',

-             )

-             self.session.add(obj)

-             self.session.commit()

- 

- 

-         #Next, we need to try revoting

-             newdata = {

-                 '4': 2,

-                 '5': 1,

-                 '6': 1,

-                 '16': 0,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

-             output = self.app.post('/vote/test_election3', data=newdata, follow_redirects=True)

-         #Next, we need to check if the vote has been recorded

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Your vote has been recorded.  Thank you!'

-                 in output.data)

-             self.assertTrue('Open elections' in output.data)

-             vote = fedora_elections.models.Vote

-             votes = vote.of_user_on_election(self.session, "nerdsville", '3')

-             self.assertEqual(votes[0].value, 2)

-             self.assertEqual(votes[1].value, 1)

-             self.assertEqual(votes[2].value, 1)

-             self.assertEqual(votes[3].value, 0)

-         #If we haven't failed yet, HOORAY!

+         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.data.split(

+                     'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+                 data = {

+                     '4': 1,

+                     '5': 0,

+                     '6': 2,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+                 self.app.post('/vote/test_election3', data=data, follow_redirects=True)

+                 vote = fedora_elections.models.Vote

+                 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

+ 

+                 obj = fedora_elections.models.Candidate(  # id:16

+                     election_id=3,

+                     name='Josh',

+                     url='https://fedoraproject.org/wiki/User:Nerdsville',

+                 )

+                 self.session.add(obj)

+                 self.session.commit()

+ 

+ 

+             #Next, we need to try revoting

+                 newdata = {

+                     '4': 2,

+                     '5': 1,

+                     '6': 1,

+                     '16': 0,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+                 output = self.app.post('/vote/test_election3', data=newdata, follow_redirects=True)

+             #Next, we need to check if the vote has been recorded

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Your vote has been recorded.  Thank you!'

+                     in output.data)

+                 self.assertTrue('Open elections' in output.data)

+                 vote = fedora_elections.models.Vote

+                 votes = vote.of_user_on_election(self.session, "nerdsville", '3')

+                 self.assertEqual(votes[0].value, 2)

+                 self.assertEqual(votes[1].value, 1)

+                 self.assertEqual(votes[2].value, 1)

+                 self.assertEqual(votes[3].value, 0)

+             #If we haven't failed yet, HOORAY!

  

  

  if __name__ == '__main__':

file modified
+146 -139
@@ -32,6 +32,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__)), '..'))
@@ -46,117 +47,121 @@ 

  

      def test_vote_select(self):

          """ Test the vote_select function - the preview part. """

-         output = self.app.get(

-             '/vote/test_election', follow_redirects=True)

-         self.assertEqual(output.status_code, 200)

-         self.assertTrue(

-             '<title>OpenID transaction in progress</title>' in output.data

-             or 'discoveryfailure' in output.data)

+         output = self.app.get('/vote/test_election')

+         self.assertEqual(output.status_code, 302)

+         self.assertIn(

+             '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election',

+             output.data)

  

          self.setup_db()

  

          user = FakeUser(['packager'], username='pingou')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get(

-                 '/vote/test_election6')

-             self.assertTrue(

-                 'test election 6 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="preview" />'

-                 in output.data)

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             # Invalid vote: No candidate

-             data = {

-                 'action': 'preview',

-             }

- 

-             output = self.app.post('/vote/test_election6', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'test election 6 shortdesc' in output.data)

- 

-             # Invalid vote: Too many candidates

-             data = {

-                 'Kevin': True,

-                 'Toshio': True,

-                 'action': 'preview',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/vote/test_election6', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'test election 6 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="preview" />'

-                 in output.data)

-             self.assertTrue(

-                 'Too many candidates submitted'

-                 in output.data)

- 

-             # Valid input

-             data = {

-                 'Kevin': True,

-                 'action': 'preview',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/vote/test_election6', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'test election 6 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="submit" />'

-                 in output.data)

-             self.assertTrue(

-                 'Please confirm your vote!'

-                 in output.data)

+         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')

+                 self.assertTrue(

+                     'test election 6 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="preview" />'

+                     in output.data)

+ 

+                 csrf_token = output.data.split(

+                     'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+ 

+                 # Invalid vote: No candidate

+                 data = {

+                     'action': 'preview',

+                 }

+ 

+                 output = self.app.post('/vote/test_election6', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'test election 6 shortdesc' in output.data)

+ 

+                 # Invalid vote: Too many candidates

+                 data = {

+                     'Kevin': True,

+                     'Toshio': True,

+                     'action': 'preview',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/vote/test_election6', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'test election 6 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="preview" />'

+                     in output.data)

+                 self.assertTrue(

+                     'Too many candidates submitted'

+                     in output.data)

+ 

+                 # Valid input

+                 data = {

+                     'Kevin': True,

+                     'action': 'preview',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/vote/test_election6', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'test election 6 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="submit" />'

+                     in output.data)

+                 self.assertTrue(

+                     'Please confirm your vote!'

+                     in output.data)

  

      def test_vote_select_process(self):

          """ Test the vote_select function - the voting part. """

-         output = self.app.get(

-             '/vote/test_election', follow_redirects=True)

-         self.assertEqual(output.status_code, 200)

-         self.assertTrue(

-             '<title>OpenID transaction in progress</title>' in output.data

-             or 'discoveryfailure' in output.data)

+         output = self.app.get('/vote/test_election')

+         self.assertEqual(output.status_code, 302)

+         self.assertIn(

+             '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election',

+             output.data)

  

          self.setup_db()

  

          user = FakeUser(['packager'], username='pingou')

-         with user_set(fedora_elections.APP, user):

-             # Invalid candidate id - no csrf

-             data = {

-                 'candidate': 1,

-                 'action': 'submit',

-             }

- 

-             output = self.app.post(

-                 '/vote/test_election6', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             # Valid input

-             data = {

-                 'Toshio': True,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/vote/test_election6', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Your vote has been recorded.  Thank you!'

-                 in output.data)

-             self.assertTrue('Open elections' in output.data)

+         with user_set(fedora_elections.APP, user, oidc_id_token='foobar'):

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['packager'])):

+                 # Invalid candidate id - no csrf

+                 data = {

+                     'candidate': 1,

+                     'action': 'submit',

+                 }

+ 

+                 output = self.app.post(

+                     '/vote/test_election6', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+ 

+                 csrf_token = output.data.split(

+                     'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+ 

+                 # Valid input

+                 data = {

+                     'Toshio': True,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/vote/test_election6', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Your vote has been recorded.  Thank you!'

+                     in output.data)

+                 self.assertTrue('Open elections' in output.data)

  

      def test_vote_select_revote(self):

          """ Test the vote_select function - the re-voting part. """
@@ -164,45 +169,47 @@ 

          self.setup_db()

  

          user = FakeUser(['voters'], username='nerdsville')

-         with user_set(fedora_elections.APP, user):

-             retrieve_csrf = self.app.post('/vote/test_election6')

-             csrf_token = retrieve_csrf.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             # Valid input

-             data = {

-                 'Kevin': True,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

-             self.app.post('/vote/test_election6', data=data, follow_redirects=True)

-             vote = fedora_elections.models.Vote

-             votes = vote.of_user_on_election(self.session, "nerdsville", '6')

-             self.assertEqual(votes[0].candidate.name, "Toshio")

-             self.assertEqual(votes[0].value, 0)

-             self.assertEqual(votes[1].candidate.name, "Kevin")

-             self.assertEqual(votes[1].value, 1)

- 

-             #Next, we need to try revoting

-             newdata = {

-                 'Toshio': True,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

-             output = self.app.post('/vote/test_election6', data=newdata, follow_redirects=True)

-             #Next, we need to check if the vote has been recorded

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Your vote has been recorded.  Thank you!'

-                 in output.data)

-             self.assertTrue('Open elections' in output.data)

-             vote = fedora_elections.models.Vote

-             votes = vote.of_user_on_election(self.session, "nerdsville", '6')

-             self.assertEqual(votes[0].value, 1)

-             self.assertEqual(votes[1].value, 0)

- 

- 

-         #If we haven't failed yet, HOORAY!

+         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.data.split(

+                     'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+ 

+                 # Valid input

+                 data = {

+                     'Kevin': True,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+                 self.app.post('/vote/test_election6', data=data, follow_redirects=True)

+                 vote = fedora_elections.models.Vote

+                 votes = vote.of_user_on_election(self.session, "nerdsville", '6')

+                 self.assertEqual(votes[0].candidate.name, "Toshio")

+                 self.assertEqual(votes[0].value, 0)

+                 self.assertEqual(votes[1].candidate.name, "Kevin")

+                 self.assertEqual(votes[1].value, 1)

+ 

+                 #Next, we need to try revoting

+                 newdata = {

+                     'Toshio': True,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+                 output = self.app.post('/vote/test_election6', data=newdata, follow_redirects=True)

+                 #Next, we need to check if the vote has been recorded

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Your vote has been recorded.  Thank you!'

+                     in output.data)

+                 self.assertTrue('Open elections' in output.data)

+                 vote = fedora_elections.models.Vote

+                 votes = vote.of_user_on_election(self.session, "nerdsville", '6')

+                 self.assertEqual(votes[0].value, 1)

+                 self.assertEqual(votes[1].value, 0)

+ 

+             #If we haven't failed yet, HOORAY!

  

  

  if __name__ == '__main__':

file modified
+205 -197
@@ -32,6 +32,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__)), '..'))
@@ -46,177 +47,181 @@ 

  

      def test_vote_simple(self):

          """ Test the vote_simple function - the preview part. """

-         output = self.app.get(

-             '/vote/test_election', follow_redirects=True)

-         self.assertEqual(output.status_code, 200)

-         self.assertTrue(

-             '<title>OpenID transaction in progress</title>' in output.data

-             or 'discoveryfailure' in output.data)

+         output = self.app.get('/vote/test_election')

+         self.assertEqual(output.status_code, 302)

+         self.assertIn(

+             '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election',

+             output.data)

  

          self.setup_db()

  

          user = FakeUser(['packager'], username='pingou')

-         with user_set(fedora_elections.APP, user):

-             output = self.app.get(

-                 '/vote/test_election5')

-             self.assertTrue(

-                 'test election 5 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="preview" />'

-                 in output.data)

- 

-             # Invalid vote: No candidate

-             data = {

-                 'action': 'preview',

-             }

- 

-             output = self.app.post('/vote/test_election5', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'test election 5 shortdesc' in output.data)

-             self.assertTrue(

-                 'Preview your vote'

-                 in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="preview" />'

-                 in output.data)

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             # Invalid vote: No candidate

-             data = {

-                 'action': 'preview',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/vote/test_election5', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'test election 5 shortdesc' in output.data)

-             self.assertTrue(

-                 'Preview your vote'

-                 in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="preview" />'

-                 in output.data)

- 

-             # Invalid vote: Not numeric

-             data = {

-                 'candidate': 'a',

-                 'action': 'preview',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/vote/test_election5', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'test election 5 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="preview" />'

-                 in output.data)

- 

- 

-             # Valid input

-             data = {

-                 'candidate': 7,

-                 'action': 'preview',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post('/vote/test_election5', data=data)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'test election 5 shortdesc' in output.data)

-             self.assertTrue(

-                 '<input type="hidden" name="action" value="submit" />'

-                 in output.data)

-             self.assertTrue(

-                 'Please confirm your vote!'

-                 in output.data)

+         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')

+                 self.assertTrue(

+                     'test election 5 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="preview" />'

+                     in output.data)

+ 

+                 # Invalid vote: No candidate

+                 data = {

+                     'action': 'preview',

+                 }

+ 

+                 output = self.app.post('/vote/test_election5', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'test election 5 shortdesc' in output.data)

+                 self.assertTrue(

+                     'Preview your vote'

+                     in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="preview" />'

+                     in output.data)

+ 

+                 csrf_token = output.data.split(

+                     'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+ 

+                 # Invalid vote: No candidate

+                 data = {

+                     'action': 'preview',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/vote/test_election5', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'test election 5 shortdesc' in output.data)

+                 self.assertTrue(

+                     'Preview your vote'

+                     in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="preview" />'

+                     in output.data)

+ 

+                 # Invalid vote: Not numeric

+                 data = {

+                     'candidate': 'a',

+                     'action': 'preview',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/vote/test_election5', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'test election 5 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="preview" />'

+                     in output.data)

+ 

+ 

+                 # Valid input

+                 data = {

+                     'candidate': 7,

+                     'action': 'preview',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/vote/test_election5', data=data)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'test election 5 shortdesc' in output.data)

+                 self.assertTrue(

+                     '<input type="hidden" name="action" value="submit" />'

+                     in output.data)

+                 self.assertTrue(

+                     'Please confirm your vote!'

+                     in output.data)

  

      def test_vote_simple_process(self):

          """ Test the vote_simple function - the voting part. """

-         output = self.app.get(

-             '/vote/test_election', follow_redirects=True)

-         self.assertEqual(output.status_code, 200)

-         self.assertTrue(

-             '<title>OpenID transaction in progress</title>' in output.data

-             or 'discoveryfailure' in output.data)

+         output = self.app.get('/vote/test_election')

+         self.assertEqual(output.status_code, 302)

+         self.assertIn(

+             '/login?next=http%3A%2F%2Flocalhost%2Fvote%2Ftest_election',

+             output.data)

  

          self.setup_db()

  

          user = FakeUser(['packager'], username='pingou')

-         with user_set(fedora_elections.APP, user):

-             # Invalid candidate id - no csrf

-             data = {

-                 'candidate': 1,

-                 'action': 'submit',

-             }

- 

-             output = self.app.post(

-                 '/vote/test_election5', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

- 

- 

-             csrf_token = output.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

- 

-             # Invalid candidate id

-             data = {

-                 'candidate': 1,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/vote/test_election5', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

- 

- 

-             # Invalid vote: too low

-             data = {

-                 'candidate': -1,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/vote/test_election5', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

- 

- 

-             # Invalid vote: Not numeric

-             data = {

-                 'candidate': 'a',

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/vote/test_election5', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

- 

- 

-             # Valid input

-             data = {

-                 'candidate': 8,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

- 

-             output = self.app.post(

-                 '/vote/test_election5', data=data,

-                 follow_redirects=True)

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Your vote has been recorded.  Thank you!'

-                 in output.data)

-             self.assertTrue('Open elections' in output.data)

+         with user_set(fedora_elections.APP, user, oidc_id_token='foobar'):

+             with patch(

+                     'fedora_elections.OIDC.user_getfield',

+                     MagicMock(return_value=['voters'])):

+                 # Invalid candidate id - no csrf

+                 data = {

+                     'candidate': 1,

+                     'action': 'submit',

+                 }

+ 

+                 output = self.app.post(

+                     '/vote/test_election5', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+ 

+ 

+                 csrf_token = output.data.split(

+                     'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+ 

+                 # Invalid candidate id

+                 data = {

+                     'candidate': 1,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/vote/test_election5', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+ 

+ 

+                 # Invalid vote: too low

+                 data = {

+                     'candidate': -1,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/vote/test_election5', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+ 

+ 

+                 # Invalid vote: Not numeric

+                 data = {

+                     'candidate': 'a',

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/vote/test_election5', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+ 

+ 

+                 # Valid input

+                 data = {

+                     'candidate': 8,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post(

+                     '/vote/test_election5', data=data,

+                     follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Your vote has been recorded.  Thank you!'

+                     in output.data)

+                 self.assertTrue('Open elections' in output.data)

  

      def test_vote_simple_revote(self):

          """ Test the vote_simple function - the re-voting part. """
@@ -224,43 +229,46 @@ 

          self.setup_db()

  

          user = FakeUser(['voters'], username='nerdsville')

-         with user_set(fedora_elections.APP, user):

-             retrieve_csrf = self.app.post('/vote/test_election5')

-             csrf_token = retrieve_csrf.data.split(

-                 'name="csrf_token" type="hidden" value="')[1].split('">')[0]

-             # Valid input

-             data = {

-                 'candidate': 8,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

- 

-             self.app.post('/vote/test_election5', data=data, follow_redirects=True)

-             vote = fedora_elections.models.Vote

-             votes = vote.of_user_on_election(self.session, "nerdsville", '5')

-             self.assertEqual(votes[0].candidate_id, 8)

-         #Let's not do repetition of what is tested above we aren't testing the

-         #functionality of voting as that has already been asserted

- 

-         #Next, we need to try revoting

-             # Valid input

-             newdata = {

-                 'candidate': 9,

-                 'action': 'submit',

-                 'csrf_token': csrf_token,

-             }

-             output = self.app.post('/vote/test_election5', data=newdata, follow_redirects=True)

-         #Next, we need to check if the vote has been recorded

-             self.assertEqual(output.status_code, 200)

-             self.assertTrue(

-                 'Your vote has been recorded.  Thank you!'

-                 in output.data)

-             self.assertTrue('Open elections' in output.data)

-             vote = fedora_elections.models.Vote

-             votes = vote.of_user_on_election(self.session, "nerdsville", '5')

-             self.assertEqual(votes[0].candidate_id, 9)

- 

-         #If we haven't failed yet, HOORAY!

+         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.data.split(

+                     'name="csrf_token" type="hidden" value="')[1].split('">')[0]

+                 # Valid input

+                 data = {

+                     'candidate': 8,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 self.app.post('/vote/test_election5', data=data, follow_redirects=True)

+                 vote = fedora_elections.models.Vote

+                 votes = vote.of_user_on_election(self.session, "nerdsville", '5')

+                 self.assertEqual(votes[0].candidate_id, 8)

+             #Let's not do repetition of what is tested above we aren't testing the

+             #functionality of voting as that has already been asserted

+ 

+             #Next, we need to try revoting

+                 # Valid input

+                 newdata = {

+                     'candidate': 9,

+                     'action': 'submit',

+                     'csrf_token': csrf_token,

+                 }

+                 output = self.app.post('/vote/test_election5', data=newdata, follow_redirects=True)

+             #Next, we need to check if the vote has been recorded

+                 self.assertEqual(output.status_code, 200)

+                 self.assertTrue(

+                     'Your vote has been recorded.  Thank you!'

+                     in output.data)

+                 self.assertTrue('Open elections' in output.data)

+                 vote = fedora_elections.models.Vote

+                 votes = vote.of_user_on_election(self.session, "nerdsville", '5')

+                 self.assertEqual(votes[0].candidate_id, 9)

+ 

+             #If we haven't failed yet, HOORAY!

  

  

  if __name__ == '__main__':

file added
+26
@@ -0,0 +1,26 @@ 

+ [tox]

+ envlist = py27,diff-cover

+ skipsdist = True

+ 

+ [testenv]

+ usedevelop = True

+ passenv = HOME

+ deps =

+     -rrequirements.txt

+     mock

+     nose

+    coverage

+ setenv =

+     PYTHONPATH={toxinidir}

+     FEDORA_ELECTIONS_CONFIG={toxinidir}/tests/config

+ commands =

+     nosetests --with-coverage --cover-erase \

+         --cover-package=fedora_elections --cover-xml \

+         {posargs}

+ 

+ [testenv:diff-cover]

+ deps =

+     diff-cover

+ commands =

+     diff-cover coverage.xml --compare-branch=origin/develop --fail-under=100

+ 

Badges will be created to be requestable by URL. This URL will be
provided by the admin. If set, the link will be given to the user after
the ballot is submitted (or re-submitted).

Not sure this works as is, you likely need to pass this to flask.markdown()

We'll need an alembic migration for this

Not sure this works as is, you likely need to pass this to flask.markdown()

Worked for me, though there might be edge cases it doesn't catch.

This change definitely needs alembic migration.

@zlopez @pingou Now that we're between elections, is this something we can get deployed before the F30 elections process starts?

What's involved in doing the alembic migration? Is it something we can get done before the Beta infra freeze or should it wait until after? I'd like to be able to have this before we do F30 voting.

I can take over from you if you like but I'd like the two pending PRs to be reviewed :(

This would allow us to finish deploying elections on openshift in staging, which would allow us to move to production later and gives us an easier workflow to staging and production from git commit :)

@pingou I don't have the skills to provide the review, but I can be annoying to someone until they do it if you need me to.

I ll take the review :-)

Not all elections must have a badge, so we should make this nullable=True :)

I've added the alembic migration in https://pagure.io/elections/c/db28067794018efe9ee4d65826d942c39ef74aba?branch=alembic_migration
Feel free to pull it into your branch.

However, I see the PR is opened against master, we should close it and re-open it against develop (I'll fix pagure to make it the default branch), it seems elections uses the git-flow model.

If we're changing this, what about changing the field name to url_badge ?

If we're changing this, what about changing the field name to url_badge ?

No objections here. I'll make that change and pull in your migration commit and submit a new PR against the right branch.

@bcotton, would you like me to take over the PR to finish it?

@bcotton, would you like me to take over the PR to finish it?

The pesterer has become the pesteree :-)

It's on my list for today, probably within the next hour or so.

rebased onto c49313a

5 years ago

Pull-Request has been closed by bcotton

5 years ago

Thank you, no worries about this, I just had a little time and I know you're busy :)