#2 Allow updating rejected candidates
Opened 5 years ago by pingou. Modified 5 years ago

@@ -0,0 +1,43 @@ 

+ """Add allow_updating field

+ 

+ Revision ID: 9262dc2af69d

+ Revises: 7db0e24a2a85

+ Create Date: 2017-04-11 13:50:35.179230

+ 

+ """

+ 

+ from alembic import op

+ import sqlalchemy as sa

+ 

+ # revision identifiers, used by Alembic.

+ revision = '9262dc2af69d'

+ down_revision = '7db0e24a2a85'

+ 

+ 

+ def upgrade():

+     """ Add the allows_updating field to the Elections table. """

+     op.add_column(

+         'Elections',

+         sa.Column(

+             'allows_updating',

+             sa.Boolean, default=True, nullable=True)

+     )

+ 

+     try:

+         ins = "UPDATE \"Elections\" SET "\

+             "allows_updating=True;"

+         op.execute(ins)

+     except Exception, err:

+         print 'ERROR', err

+ 

+     ## Enforce the nullable=False

+     op.alter_column(

+         'Elections',

+         column_name='allows_updating',

+         nullable=False,

+         existing_nullable=True,)

+ 

+ 

+ def downgrade():

+     ''' Drop the columns allows_updating from the Elections table. '''

+     op.drop_column('Elections', 'allows_updating')

file modified
+2
@@ -88,6 +88,7 @@ 

                  election_n_choice=form.election_n_choice.data,

                  user_n_candidates=form.user_n_candidates.data,

                  election_badge_link=form.election_badge_link.data,

+                 allows_updating=form.allows_updating.data,

                  user=flask.g.fas_user.username,

              )

              SESSION.commit()
@@ -136,6 +137,7 @@ 

                  election_n_choice=form.election_n_choice.data,

                  user_n_candidates=form.user_n_candidates.data,

                  election_badge_link=form.election_badge_link.data,

+                 allows_updating=form.allows_updating.data,

                  user=flask.g.fas_user.username,

              )

  

file modified
+2
@@ -122,6 +122,7 @@ 

          'Number of candidate an user can upload',

          [wtf.validators.Required(), is_number])

      generate_cache = wtf.BooleanField('Generate cache')

+     allows_updating = wtf.BooleanField('Allows updating rejected candidate')

  

      def __init__(self, *args, **kwargs):

          ''' Calls the default constructor and fill in additional information.
@@ -140,6 +141,7 @@ 

              self.election_n_choice.data = election.election_n_choice

              self.submission_date_start.data = election.submission_date_start

              self.user_n_candidates.data = election.user_n_candidates

+             self.allows_updating.data = election.allows_updating

  

  

  class AddCandidateForm(BaseForm):

file modified
+7 -2
@@ -152,7 +152,7 @@ 

  def add_election(session, election_name, election_folder, election_year,

                   election_date_start, election_date_end,

                   submission_date_start, submission_date_end,

-                  election_n_choice, user_n_candidates,

+                  election_n_choice, user_n_candidates, allows_updating=True,

                   election_badge_link=None, user=None):

      """ Add a new election to the database.

  
@@ -183,6 +183,7 @@ 

          election_n_choice=election_n_choice,

          user_n_candidates=user_n_candidates,

          election_badge_link=election_badge_link,

+         allows_updating=allows_updating,

      )

      session.add(election)

      session.flush()
@@ -201,7 +202,7 @@ 

  def edit_election(session, election, election_name, election_folder,

                    election_year, election_date_start, election_date_end,

                    submission_date_start, submission_date_end,

-                   election_n_choice, user_n_candidates,

+                   election_n_choice, user_n_candidates, allows_updating=True,

                    election_badge_link=None, user=None):

      """ Edit an election of the database.

  
@@ -263,6 +264,10 @@ 

          election.user_n_candidates = user_n_candidates

          edited.append('Number of candidates per user')

  

+     if election.allows_updating != allows_updating:

+         election.allows_updating = allows_updating

+         edited.append('Election allows updating')

+ 

      if edited:

          session.add(election)

          session.flush()

file modified
+1
@@ -101,6 +101,7 @@ 

      submission_date_start = sa.Column(sa.Date, nullable=False)

      submission_date_end = sa.Column(sa.Date, nullable=False)

      user_n_candidates = sa.Column(sa.Integer, nullable=True)

+     allows_updating = sa.Column(sa.Boolean, nullable=False, default=True)

  

      date_created = sa.Column(sa.DateTime, nullable=False,

                               default=sa.func.current_timestamp())

@@ -21,6 +21,7 @@ 

      {{ render_field_in_row(form.election_badge_link) }}

      {{ render_field_in_row(form.election_n_choice) }}

      {{ render_field_in_row(form.user_n_candidates) }}

+     {{ render_field_in_row(form.allows_updating) }}

  </table>

  <input type="submit" class="submit positive button" value="Edit">

  <input type="button" value="Cancel" class="button" onclick="history.back();">

@@ -21,6 +21,7 @@ 

      {{ render_field_in_row(form.election_badge_link) }}

      {{ render_field_in_row(form.election_n_choice) }}

      {{ render_field_in_row(form.user_n_candidates) }}

+     {{ render_field_in_row(form.allows_updating) }}

      {{ render_field_in_row(form.generate_cache) }}

  </table>

  <input type="submit" class="submit positive button" value="Create">

@@ -76,10 +76,14 @@ 

          </td>

          <td>{{ candidate.approved_motif }} </td>

          <td>

-             {% if candidate.election.submission_open %}

+             {% if candidate.election.submission_open

+                   and candidate.election.allows_updating %}

              <a href="{{ url_for('update_candidate', cand_id=candidate.id) }}">

                  Update

              </a>

+             {% elif candidate.election.submission_open

+                     and not candidate.election.allows_updating %}

+             Your submission cannot be updated

              {% else %}

              Submission are closed

              {% endif %}

file modified
+5
@@ -494,6 +494,11 @@ 

              'You are not the person that submitted this candidate, you may '

              'not update it', 'error')

          return flask.redirect(flask.url_for('elections_list'))

+     elif not candidate.election.allows_updating:

+         flask.flash(

+             'This election does not allow rejected candidate to be updated',

+             'error')

+         return flask.redirect(flask.url_for('elections_list'))

  

      form = nuancier.forms.AddCandidateForm(obj=candidate)

      if form.validate_on_submit():

file modified
+50
@@ -2005,6 +2005,56 @@ 

  

              self.assertFalse(os.path.exists(upload_path))

  

+     def test_update_candidate_not_allowed(self):

+         """ Test the update_candidate function. """

+ 

+         create_elections(self.session)

+         create_candidates(self.session)

+         approve_candidate(self.session)

+         deny_candidate(self.session)

+ 

+         upload_path = os.path.join(PICTURE_FOLDER, 'F21')

+ 

+         user = FakeFasUser()

+         user.cla_done = True

+         with user_set(nuancier.APP, user):

+             # Election does not allow updating submissions

+             election = nuancierlib.get_election(self.session, 3)

+             election.allows_updating = False

+             self.session.add(election)

+             self.session.commit()

+ 

+             output = self.app.get('/contribution/6/update',

+                                   follow_redirects=True)

+             self.assertEqual(output.status_code, 200)

+             self.assertIn(

+                 '<li class="error">This election does not allow rejected '

+                 'candidate to be updated</li>', output.data)

+ 

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

+             csrf_token = output.data.split(

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

+ 

+             with open(FILE_OK) as stream:

+                 data = {

+                     'candidate_name': 'name',

+                     'candidate_author': 'pingou',

+                     'candidate_file': stream,

+                     'candidate_license': 'CC-BY-SA',

+                     'csrf_token': csrf_token,

+                 }

+ 

+                 output = self.app.post('/contribution/6/update', data=data,

+                                        follow_redirects=True)

+                 self.assertEqual(output.status_code, 200)

+                 self.assertIn(

+                     '<li class="error">This election does not allow rejected '

+                     'candidate to be updated</li>', output.data)

+                 self.assertTrue('<h1>Elections</h1>' in output.data)

+ 

+         self.assertFalse(os.path.exists(upload_path))

+ 

+ 

      def test_contribute_max_upload(self):

          """ Test the contribute function when the user has already submitted

          a number of candidates.