Merge pull request #695 from normanjaeckel/RemoveOfSupporters

Fixed #130: New config var for removal of supports when a motion is edit...
This commit is contained in:
Oskar Hahn 2013-06-02 08:21:33 -07:00
commit 6b2dd7d358
4 changed files with 81 additions and 10 deletions

View File

@ -395,6 +395,12 @@ class Motion(SlideMixin, models.Model):
else: else:
raise WorkflowError('You can not unsupport a motion in state %s.' % self.state.name) raise WorkflowError('You can not unsupport a motion in state %s.' % self.state.name)
def clear_supporters(self):
"""
Deletes all supporters of this motion.
"""
MotionSupporter.objects.filter(motion=self).delete()
def create_poll(self): def create_poll(self):
""" """
Create a new poll for this motion. Create a new poll for this motion.
@ -469,7 +475,7 @@ class Motion(SlideMixin, models.Model):
The dictonary contains the following actions. The dictonary contains the following actions.
* edit * update / edit
* delete * delete
* create_poll * create_poll
* support * support
@ -478,9 +484,11 @@ class Motion(SlideMixin, models.Model):
* reset_state * reset_state
""" """
actions = { actions = {
'edit': ((self.is_submitter(person) and 'update': ((self.is_submitter(person) and
self.state.allow_submitter_edit) or self.state.allow_submitter_edit) or
person.has_perm('motion.can_manage_motion')), person.has_perm('motion.can_manage_motion')),
'delete': person.has_perm('motion.can_manage_motion'),
'create_poll': (person.has_perm('motion.can_manage_motion') and 'create_poll': (person.has_perm('motion.can_manage_motion') and
self.state.allow_create_poll), self.state.allow_create_poll),
@ -491,14 +499,14 @@ class Motion(SlideMixin, models.Model):
not self.is_supporter(person)), not self.is_supporter(person)),
'unsupport': (self.state.allow_support and 'unsupport': (self.state.allow_support and
not self.is_submitter(person) and
self.is_supporter(person)), self.is_supporter(person)),
'change_state': person.has_perm('motion.can_manage_motion'), 'change_state': person.has_perm('motion.can_manage_motion'),
} 'reset_state': person.has_perm('motion.can_manage_motion')}
actions['delete'] = actions['edit'] # TODO: Only if the motion has no number
actions['reset_state'] = actions['change_state'] actions['edit'] = actions['update']
return actions return actions
def write_log(self, message_list, person=None): def write_log(self, message_list, person=None):

View File

@ -42,6 +42,12 @@ def setup_motion_config_page(sender, **kwargs):
min_value=0, min_value=0,
max_value=8, max_value=8,
help_text=ugettext_lazy('Choose 0 to disable the supporting system'))) help_text=ugettext_lazy('Choose 0 to disable the supporting system')))
motion_remove_supporters = ConfigVariable(
name='motion_remove_supporters',
default_value=False,
form_field=forms.BooleanField(
label=ugettext_lazy('Supporters of a motion will be removed if a submitter edits his motion in early state.'),
required=False))
motion_preamble = ConfigVariable( motion_preamble = ConfigVariable(
name='motion_preamble', name='motion_preamble',
default_value=_('The assembly may decide,'), default_value=_('The assembly may decide,'),
@ -114,6 +120,7 @@ def setup_motion_config_page(sender, **kwargs):
weight=30, weight=30,
variables=(motion_stop_submitting, variables=(motion_stop_submitting,
motion_min_supporters, motion_min_supporters,
motion_remove_supporters,
motion_preamble, motion_preamble,
motion_pdf_ballot_papers_selection, motion_pdf_ballot_papers_selection,
motion_pdf_ballot_papers_number, motion_pdf_ballot_papers_number,

View File

@ -209,7 +209,7 @@ class MotionUpdateView(MotionMixin, UpdateView):
def has_permission(self, request, *args, **kwargs): def has_permission(self, request, *args, **kwargs):
"""Check, if the request.user has the permission to edit the motion.""" """Check, if the request.user has the permission to edit the motion."""
return self.get_object().get_allowed_actions(request.user)['edit'] return self.get_object().get_allowed_actions(request.user)['update']
def form_valid(self, form): def form_valid(self, form):
"""Write a log message, if the form is valid.""" """Write a log message, if the form is valid."""
@ -217,6 +217,18 @@ class MotionUpdateView(MotionMixin, UpdateView):
self.object.write_log([ugettext_noop('Motion updated')], self.request.user) self.object.write_log([ugettext_noop('Motion updated')], self.request.user)
return value return value
def manipulate_object(self, *args, **kwargs):
"""
Removes the supporters if config option is True and supporting is still
available in the state.
"""
return_value = super(MotionUpdateView, self).manipulate_object(*args, **kwargs)
if (config['motion_remove_supporters'] and self.object.state.allow_support and
not self.request.user.has_perm('motion.can_manage_motion')):
self.object.clear_supporters()
self.object.write_log([ugettext_noop('All supporters removed')], self.request.user)
return return_value
motion_edit = MotionUpdateView.as_view() motion_edit = MotionUpdateView.as_view()

View File

@ -232,6 +232,50 @@ class TestMotionUpdateView(MotionViewTestCase):
self.assertRedirects(response, '/motion/1/') self.assertRedirects(response, '/motion/1/')
self.assertEqual(Motion.objects.get(pk=self.motion1.pk).state.workflow.pk, 2) self.assertEqual(Motion.objects.get(pk=self.motion1.pk).state.workflow.pk, 2)
def test_remove_supporters(self):
# Setup a new motion with one supporter
config['motion_min_supporters'] = 1
motion = Motion.objects.create(title='cuoPhoX4Baifoxoothi3', text='zee7xei3taediR9loote')
response = self.staff_client.get('/motion/%s/' % motion.id)
self.assertNotContains(response, 'aengeing3quair3fieGi')
motion.support(self.registered)
self.registered.last_name = 'aengeing3quair3fieGi'
self.registered.save()
response = self.staff_client.get('/motion/%s/' % motion.id)
self.assertContains(response, 'aengeing3quair3fieGi')
# Check editing by submitter
response = self.delegate_client.post(
'/motion/%s/edit/' % motion.id,
{'title': 'oori4KiaghaeSeuzaim2',
'text': 'eequei1Tee1aegeNgee0',
'submitter': self.delegate.person_id})
self.assertEqual(response.status_code, 403)
motion.add_submitter(self.delegate)
# Edit three times, without removal of supporters, with removal and in another state
for i in range(3):
if i == 1:
config['motion_remove_supporters'] = True
response = self.delegate_client.post(
'/motion/%s/edit/' % motion.id,
{'title': 'iezae8reevaT6phiesoa',
'text': 'Lohjuu1aebewiu2or3oh'})
self.assertRedirects(response, '/motion/%s/' % motion.id)
if i == 0 or i == 2:
self.assertTrue(self.registered in Motion.objects.get(pk=motion.pk).supporters)
else:
self.assertFalse(self.registered in Motion.objects.get(pk=motion.pk).supporters)
# Preparing the comming (third) run
motion = Motion.objects.get(pk=motion.pk)
motion.support(self.registered)
motion.state = State.objects.create(
name='not_support',
workflow=self.motion1.state.workflow,
allow_submitter_edit=True,
allow_support=False)
motion.save()
class TestMotionDeleteView(MotionViewTestCase): class TestMotionDeleteView(MotionViewTestCase):
def test_get(self): def test_get(self):
@ -247,7 +291,7 @@ class TestMotionDeleteView(MotionViewTestCase):
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 403)
motion = Motion.objects.get(pk=2).add_submitter(self.delegate) motion = Motion.objects.get(pk=2).add_submitter(self.delegate)
response = self.delegate_client.post('/motion/2/del/', {}) response = self.delegate_client.post('/motion/2/del/', {})
self.assertRedirects(response, '/motion/') self.assertEqual(response.status_code, 403)
class TestVersionPermitView(MotionViewTestCase): class TestVersionPermitView(MotionViewTestCase):