def setUp(self): self.admin = User(username='******') self.admin.save() self.anonym = User(username='******') self.anonym.save() self.app1 = Motion(submitter=self.admin) self.app1.save()
def test_set_identifier_allready_set(self): """ If the motion already has a identifier, the method does nothing. """ motion = Motion(identifier='My test identifier') motion.set_identifier() self.assertEqual(motion.identifier, 'My test identifier')
def test_set_identifier_manually(self): """ If the config is set to manually, the method does nothing. """ config['motion_identifier'] = 'manually' motion = Motion() motion.set_identifier() # If the identifier should be set manually, the method does nothing self.assertIsNone(motion.identifier)
def test_set_identifier_amendment(self): """ If the motion is an amendment, the identifier is the identifier from the parent + a suffix. """ config['motion_amendments_enabled'] = True self.motion.identifier = 'Parent identifier' self.motion.save() motion = Motion(parent=self.motion) motion.set_identifier() self.assertEqual(motion.identifier, 'Parent identifier A 1')
def test_version_data(self): motion = Motion() self.assertEqual(motion.title, '') with self.assertRaises(AttributeError): self._title motion.title = 'title' self.assertEqual(motion._title, 'title') motion.text = 'text' self.assertEqual(motion._text, 'text') motion.reason = 'reason' self.assertEqual(motion._reason, 'reason')
def test_set_identifier_second_amendment(self): """ If a motion has already an amendment, the second motion gets another identifier. """ config['motion_amendments_enabled'] = True self.motion.identifier = 'Parent identifier' self.motion.save() Motion.objects.create(title='Amendment1', parent=self.motion) motion = Motion(parent=self.motion) motion.set_identifier() self.assertEqual(motion.identifier, 'Parent identifier A 2')
class MotionTest(TestCase): def setUp(self): self.admin = User(username='******') self.admin.save() self.anonym = User(username='******') self.anonym.save() self.app1 = Motion(submitter=self.admin) self.app1.save() def refresh(self): self.app1 = Motion.objects.get(pk=self.app1.id) def testVersion(self): self.assertTrue(self.app1.versions.exists()) self.assertEqual(self.app1.last_version, self.app1.versions[0]) self.assertEqual(self.app1.creation_time, self.app1.last_version.time) self.app1.title = "app1" self.app1.save() self.refresh() self.assertEqual(self.app1.versions.count(), 2) self.assertEqual(self.app1.last_version, self.app1.versions[1])
def test_do_not_create_new_version_when_permit_old_version(self): motion = Motion() motion.title = 'foo' motion.text = 'bar' motion.save() first_version = motion.get_last_version() motion = Motion.objects.get(pk=motion.pk) motion.title = 'New Title' motion.save(use_version=motion.get_new_version()) new_version = motion.get_last_version() self.assertEqual(motion.versions.count(), 2) motion.active_version = new_version motion.save() self.assertEqual(motion.versions.count(), 2) motion.active_version = first_version motion.save(use_version=False) self.assertEqual(motion.versions.count(), 2)
def motion_import(request): if request.method == 'POST': form = MotionImportForm(request.POST, request.FILES) if form.is_valid(): import_permitted = form.cleaned_data['import_permitted'] try: # check for valid encoding (will raise UnicodeDecodeError if not) request.FILES['csvfile'].read().decode('utf-8') request.FILES['csvfile'].seek(0) users_generated = 0 motions_generated = 0 motions_modified = 0 groups_assigned = 0 groups_generated = 0 with transaction.commit_on_success(): dialect = csv.Sniffer().sniff(request.FILES['csvfile'].readline()) dialect = csv_ext.patchup(dialect) request.FILES['csvfile'].seek(0) for (lno, line) in enumerate(csv.reader(request.FILES['csvfile'], dialect=dialect)): # basic input verification if lno < 1: continue try: (number, title, text, reason, first_name, last_name, is_group) = line[:7] if is_group.strip().lower() in ['y', 'j', 't', 'yes', 'ja', 'true', '1', 1]: is_group = True else: is_group = False except ValueError: messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1)) continue form = MotionForm({'title': title, 'text': text, 'reason': reason}) if not form.is_valid(): messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1)) continue if number: try: number = abs(long(number)) if number < 1: messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1)) continue except ValueError: messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1)) continue if is_group: # fetch existing groups or issue an error message try: user = Group.objects.get(name=last_name) if user.group_as_person == False: messages.error(request, _('Ignoring line %d because the assigned group may not act as a person.') % (lno + 1)) continue else: user = get_person(user.person_id) groups_assigned += 1 except Group.DoesNotExist: group = Group() group.group_as_person = True group.description = _('Created by motion import.') group.name = last_name group.save() groups_generated += 1 user = get_person(group.person_id) else: # fetch existing users or create new users as needed try: user = User.objects.get(first_name=first_name, last_name=last_name) except User.DoesNotExist: user = None if user is None: if not first_name or not last_name: messages.error(request, _('Ignoring line %d because it contains an incomplete first / last name pair.') % (lno + 1)) continue user = User() user.last_name = last_name user.first_name = first_name user.username = gen_username(first_name, last_name) user.structure_level = '' user.committee = '' user.gender = '' user.type = '' user.default_password = gen_password() user.save() user.reset_password() users_generated += 1 # create / modify the motion motion = None if number: try: motion = Motion.objects.get(number=number) motions_modified += 1 except Motion.DoesNotExist: motion = None if motion is None: motion = Motion(submitter=user) if number: motion.number = number motions_generated += 1 motion.title = form.cleaned_data['title'] motion.text = form.cleaned_data['text'] motion.reason = form.cleaned_data['reason'] if import_permitted: motion.status = 'per' motion.save(user, trivial_change=True) if motions_generated: messages.success(request, ungettext('%d motion was successfully imported.', '%d motions were successfully imported.', motions_generated) % motions_generated) if motions_modified: messages.success(request, ungettext('%d motion was successfully modified.', '%d motions were successfully modified.', motions_modified) % motions_modified) if users_generated: messages.success(request, ungettext('%d new user was added.', '%d new users were added.', users_generated) % users_generated) if groups_generated: messages.success(request, ungettext('%d new group was added.', '%d new groups were added.', groups_generated) % groups_generated) if groups_assigned: messages.success(request, ungettext('%d group assigned to motions.', '%d groups assigned to motions.', groups_assigned) % groups_assigned) return redirect(reverse('motion_overview')) except csv.Error: messages.error(request, _('Import aborted because of severe errors in the input file.')) except UnicodeDecodeError: messages.error(request, _('Import file has wrong character encoding, only UTF-8 is supported!')) else: messages.error(request, _('Please check the form for errors.')) else: messages.warning(request, _("Attention: Existing motions will be modified if you import new motions with the same number.")) messages.warning(request, _("Attention: Importing an motions without a number multiple times will create duplicates.")) form = MotionImportForm() return { 'form': form, }
def edit(request, motion_id=None): """ View a form to edit or create a motion. """ if request.user.has_perm('motion.can_manage_motion'): is_manager = True else: is_manager = False if not is_manager \ and not request.user.has_perm('motion.can_create_motion'): messages.error(request, _("You have not the necessary rights to create or edit motions.")) return redirect(reverse('motion_overview')) if motion_id is not None: motion = Motion.objects.get(id=motion_id) if not 'edit' in motion.get_allowed_actions(request.user): messages.error(request, _("You can not edit this motion.")) return redirect(reverse('motion_view', args=[motion.id])) actions = motion.get_allowed_actions(user=request.user) else: motion = None actions = None formclass = MotionFormTrivialChanges \ if config['motion_allow_trivial_change'] and motion_id \ else MotionForm managerformclass = MotionManagerFormSupporter \ if config['motion_min_supporters'] \ else MotionManagerForm if request.method == 'POST': dataform = formclass(request.POST, prefix="data") valid = dataform.is_valid() if is_manager: managerform = managerformclass(request.POST, instance=motion, prefix="manager") valid = valid and managerform.is_valid() else: managerform = None if valid: if is_manager: motion = managerform.save(commit=False) elif motion_id is None: motion = Motion(submitter=request.user) motion.title = dataform.cleaned_data['title'] motion.text = dataform.cleaned_data['text'] motion.reason = dataform.cleaned_data['reason'] try: trivial_change = config['motion_allow_trivial_change'] \ and dataform.cleaned_data['trivial_change'] except KeyError: trivial_change = False motion.save(request.user, trivial_change=trivial_change) if is_manager: try: new_supporters = set(managerform.cleaned_data['supporter']) except KeyError: # The managerform has no field for the supporters pass else: old_supporters = set(motion.supporters) # add new supporters for supporter in new_supporters.difference(old_supporters): motion.support(supporter) # remove old supporters for supporter in old_supporters.difference(new_supporters): motion.unsupport(supporter) if motion_id is None: messages.success(request, _('New motion was successfully created.')) else: messages.success(request, _('Motion was successfully modified.')) if not 'apply' in request.POST: return redirect(reverse('motion_view', args=[motion.id])) if motion_id is None: return redirect(reverse('motion_edit', args=[motion.id])) else: messages.error(request, _('Please check the form for errors.')) else: if motion_id is None: initial = {'text': config['motion_preamble']} else: if motion.status == "pub" and motion.supporters: if request.user.has_perm('motion.can_manage_motion'): messages.warning(request, _("Attention: Do you really want to edit this motion? The supporters will <b>not</b> be removed automatically because you can manage motions. Please check if the supports are valid after your changing!")) else: messages.warning(request, _("Attention: Do you really want to edit this motion? All <b>%s</b> supporters will be removed! Try to convince the supporters again.") % motion.count_supporters() ) initial = {'title': motion.title, 'text': motion.text, 'reason': motion.reason} dataform = formclass(initial=initial, prefix="data") if is_manager: if motion_id is None: initial = {'submitter': request.user.person_id} else: initial = {'submitter': motion.submitter.person_id, 'supporter': [supporter.person_id for supporter in motion.supporters]} managerform = managerformclass(initial=initial, instance=motion, prefix="manager") else: managerform = None return { 'form': dataform, 'managerform': managerform, 'motion': motion, 'actions': actions, }
def motion_import(request): if request.method == 'POST': form = MotionImportForm(request.POST, request.FILES) if form.is_valid(): import_permitted = form.cleaned_data['import_permitted'] try: # check for valid encoding (will raise UnicodeDecodeError if not) request.FILES['csvfile'].read().decode('utf-8') request.FILES['csvfile'].seek(0) users_generated = 0 motions_generated = 0 motions_modified = 0 groups_assigned = 0 groups_generated = 0 with transaction.commit_on_success(): dialect = csv.Sniffer().sniff( request.FILES['csvfile'].readline()) dialect = csv_ext.patchup(dialect) request.FILES['csvfile'].seek(0) for (lno, line) in enumerate( csv.reader(request.FILES['csvfile'], dialect=dialect)): # basic input verification if lno < 1: continue try: (number, title, text, reason, first_name, last_name, is_group) = line[:7] if is_group.strip().lower() in [ 'y', 'j', 't', 'yes', 'ja', 'true', '1', 1 ]: is_group = True else: is_group = False except ValueError: messages.error( request, _('Ignoring malformed line %d in import file.') % (lno + 1)) continue form = MotionForm({ 'title': title, 'text': text, 'reason': reason }) if not form.is_valid(): messages.error( request, _('Ignoring malformed line %d in import file.') % (lno + 1)) continue if number: try: number = abs(long(number)) if number < 1: messages.error( request, _('Ignoring malformed line %d in import file.' ) % (lno + 1)) continue except ValueError: messages.error( request, _('Ignoring malformed line %d in import file.' ) % (lno + 1)) continue if is_group: # fetch existing groups or issue an error message try: user = Group.objects.get(name=last_name) if user.group_as_person == False: messages.error( request, _('Ignoring line %d because the assigned group may not act as a person.' ) % (lno + 1)) continue else: user = get_person(user.person_id) groups_assigned += 1 except Group.DoesNotExist: group = Group() group.group_as_person = True group.description = _( 'Created by motion import.') group.name = last_name group.save() groups_generated += 1 user = get_person(group.person_id) else: # fetch existing users or create new users as needed try: user = User.objects.get(first_name=first_name, last_name=last_name) except User.DoesNotExist: user = None if user is None: if not first_name or not last_name: messages.error( request, _('Ignoring line %d because it contains an incomplete first / last name pair.' ) % (lno + 1)) continue user = User() user.last_name = last_name user.first_name = first_name user.username = gen_username( first_name, last_name) user.structure_level = '' user.committee = '' user.gender = '' user.type = '' user.default_password = gen_password() user.save() user.reset_password() users_generated += 1 # create / modify the motion motion = None if number: try: motion = Motion.objects.get(number=number) motions_modified += 1 except Motion.DoesNotExist: motion = None if motion is None: motion = Motion(submitter=user) if number: motion.number = number motions_generated += 1 motion.title = form.cleaned_data['title'] motion.text = form.cleaned_data['text'] motion.reason = form.cleaned_data['reason'] if import_permitted: motion.status = 'per' motion.save(user, trivial_change=True) if motions_generated: messages.success( request, ungettext('%d motion was successfully imported.', '%d motions were successfully imported.', motions_generated) % motions_generated) if motions_modified: messages.success( request, ungettext('%d motion was successfully modified.', '%d motions were successfully modified.', motions_modified) % motions_modified) if users_generated: messages.success( request, ungettext('%d new user was added.', '%d new users were added.', users_generated) % users_generated) if groups_generated: messages.success( request, ungettext('%d new group was added.', '%d new groups were added.', groups_generated) % groups_generated) if groups_assigned: messages.success( request, ungettext('%d group assigned to motions.', '%d groups assigned to motions.', groups_assigned) % groups_assigned) return redirect(reverse('motion_overview')) except csv.Error: messages.error( request, _('Import aborted because of severe errors in the input file.' )) except UnicodeDecodeError: messages.error( request, _('Import file has wrong character encoding, only UTF-8 is supported!' )) else: messages.error(request, _('Please check the form for errors.')) else: messages.warning( request, _("Attention: Existing motions will be modified if you import new motions with the same number." )) messages.warning( request, _("Attention: Importing an motions without a number multiple times will create duplicates." )) form = MotionImportForm() return { 'form': form, }
def edit(request, motion_id=None): """ View a form to edit or create a motion. """ if request.user.has_perm('motion.can_manage_motion'): is_manager = True else: is_manager = False if not is_manager \ and not request.user.has_perm('motion.can_create_motion'): messages.error( request, _("You have not the necessary rights to create or edit motions.")) return redirect(reverse('motion_overview')) if motion_id is not None: motion = Motion.objects.get(id=motion_id) if not 'edit' in motion.get_allowed_actions(request.user): messages.error(request, _("You can not edit this motion.")) return redirect(reverse('motion_view', args=[motion.id])) actions = motion.get_allowed_actions(user=request.user) else: motion = None actions = None formclass = MotionFormTrivialChanges \ if config['motion_allow_trivial_change'] and motion_id \ else MotionForm managerformclass = MotionManagerFormSupporter \ if config['motion_min_supporters'] \ else MotionManagerForm if request.method == 'POST': dataform = formclass(request.POST, prefix="data") valid = dataform.is_valid() if is_manager: managerform = managerformclass(request.POST, instance=motion, prefix="manager") valid = valid and managerform.is_valid() else: managerform = None if valid: if is_manager: motion = managerform.save(commit=False) elif motion_id is None: motion = Motion(submitter=request.user) motion.title = dataform.cleaned_data['title'] motion.text = dataform.cleaned_data['text'] motion.reason = dataform.cleaned_data['reason'] try: trivial_change = config['motion_allow_trivial_change'] \ and dataform.cleaned_data['trivial_change'] except KeyError: trivial_change = False motion.save(request.user, trivial_change=trivial_change) if is_manager: try: new_supporters = set(managerform.cleaned_data['supporter']) except KeyError: # The managerform has no field for the supporters pass else: old_supporters = set(motion.supporters) # add new supporters for supporter in new_supporters.difference(old_supporters): motion.support(supporter) # remove old supporters for supporter in old_supporters.difference(new_supporters): motion.unsupport(supporter) if motion_id is None: messages.success(request, _('New motion was successfully created.')) else: messages.success(request, _('Motion was successfully modified.')) if not 'apply' in request.POST: return redirect(reverse('motion_view', args=[motion.id])) if motion_id is None: return redirect(reverse('motion_edit', args=[motion.id])) else: messages.error(request, _('Please check the form for errors.')) else: if motion_id is None: initial = {'text': config['motion_preamble']} else: if motion.status == "pub" and motion.supporters: if request.user.has_perm('motion.can_manage_motion'): messages.warning( request, _("Attention: Do you really want to edit this motion? The supporters will <b>not</b> be removed automatically because you can manage motions. Please check if the supports are valid after your changing!" )) else: messages.warning( request, _("Attention: Do you really want to edit this motion? All <b>%s</b> supporters will be removed! Try to convince the supporters again." ) % motion.count_supporters()) initial = { 'title': motion.title, 'text': motion.text, 'reason': motion.reason } dataform = formclass(initial=initial, prefix="data") if is_manager: if motion_id is None: initial = {'submitter': request.user.person_id} else: initial = { 'submitter': motion.submitter.person_id, 'supporter': [supporter.person_id for supporter in motion.supporters] } managerform = managerformclass(initial=initial, instance=motion, prefix="manager") else: managerform = None return { 'form': dataform, 'managerform': managerform, 'motion': motion, 'actions': actions, }