def validate_title(title): title_len = len(title) if not title_len: raise ValidationError(_("You have to enter thread title.")) if title_len < settings.thread_title_length_min: message = ungettext( "Thread title should be at least %(limit_value)s character long (it has %(show_value)s).", "Thread title should be at least %(limit_value)s characters long (it has %(show_value)s).", settings.thread_title_length_min) raise ValidationError(message % { 'limit_value': settings.thread_title_length_min, 'show_value': title_len }) if title_len > settings.thread_title_length_max: message = ungettext( "Thread title cannot be longer than %(limit_value)s character (it has %(show_value)s).", "Thread title cannot be longer than %(limit_value)s characters (it has %(show_value)s).", settings.thread_title_length_max) raise ValidationError(message % { 'limit_value': settings.thread_title_length_max, 'show_value': title_len }) error_not_sluggable = _("Thread title should contain alpha-numeric characters.") error_slug_too_long = _("Thread title is too long.") validate_sluggable(error_not_sluggable, error_slug_too_long)(title) return title
def validate_title(title): title_len = len(title) if not title_len: raise ValidationError(_("You have to enter thread title.")) if title_len < settings.thread_title_length_min: message = ungettext( "Thread title should be at least %(limit_value)s character long (it has %(show_value)s).", "Thread title should be at least %(limit_value)s characters long (it has %(show_value)s).", settings.thread_title_length_min) raise ValidationError( message % { 'limit_value': settings.thread_title_length_min, 'show_value': title_len }) if title_len > settings.thread_title_length_max: message = ungettext( "Thread title cannot be longer than %(limit_value)s character (it has %(show_value)s).", "Thread title cannot be longer than %(limit_value)s characters (it has %(show_value)s).", settings.thread_title_length_max) raise ValidationError( message % { 'limit_value': settings.thread_title_length_max, 'show_value': title_len }) error_not_sluggable = _( "Thread title should contain alpha-numeric characters.") error_slug_too_long = _("Thread title is too long.") validate_sluggable(error_not_sluggable, error_slug_too_long)(title) return title
def validate_title(title): title_len = len(title) if not title_len: raise ValidationError(_("Enter thread title.")) if title_len < settings.thread_title_length_min: message = ungettext( "Thread title should be at least %(limit)s character long.", "Thread title should be at least %(limit)s characters long.", settings.thread_title_length_min) message = message % {'limit': settings.thread_title_length_min} raise ValidationError(message) if title_len > settings.thread_title_length_max: message = ungettext( "Thread title can't be longer than %(limit)s character.", "Thread title can't be longer than %(limit)s characters.", settings.thread_title_length_max,) message = message % {'limit': settings.thread_title_length_max} raise ValidationError(message) error_not_sluggable = _("Thread title should contain " "alpha-numeric characters.") error_slug_too_long = _("Thread title is too long.") slug_validator = validate_sluggable(error_not_sluggable, error_slug_too_long) slug_validator(title) return title
def validate_title(title): title_len = len(title) if not title_len: raise ValidationError(_("Enter thread title.")) if title_len < settings.thread_title_length_min: message = ungettext( "Thread title should be at least %(limit)s character long.", "Thread title should be at least %(limit)s characters long.", settings.thread_title_length_min) message = message % {'limit': settings.thread_title_length_min} raise ValidationError(message) if title_len > settings.thread_title_length_max: message = ungettext( "Thread title can't be longer than %(limit)s character.", "Thread title can't be longer than %(limit)s characters.", settings.thread_title_length_max, ) message = message % {'limit': settings.thread_title_length_max} raise ValidationError(message) error_not_sluggable = _("Thread title should contain " "alpha-numeric characters.") error_slug_too_long = _("Thread title is too long.") slug_validator = validate_sluggable(error_not_sluggable, error_slug_too_long) slug_validator(title) return title
class RankForm(forms.ModelForm): name = forms.CharField( label=_("Name"), validators=[validate_sluggable()], help_text=_('Short and descriptive name of all users with this rank. ' '"The Team" or "Game Masters" are good examples.')) title = forms.CharField( label=_("User title"), required=False, help_text=_('Optional, singular version of rank name displayed by ' 'user names. For example "GM" or "Dev".')) description = forms.CharField( label=_("Description"), max_length=2048, required=False, widget=forms.Textarea(attrs={'rows': 3}), help_text=_("Optional description explaining function or status of " "members distincted with this rank.")) roles = forms.ModelMultipleChoiceField( label=_("User roles"), queryset=Role.objects.order_by('name'), required=False, widget=forms.CheckboxSelectMultiple, help_text=_('Rank can give additional roles to users with it.')) css_class = forms.CharField( label=_("CSS class"), required=False, help_text=_("Optional css class added to content belonging to this " "rank owner.")) is_tab = forms.BooleanField( label=_("Give rank dedicated tab on users list"), required=False, help_text=_("Selecting this option will make users with this rank " "easily discoverable by others trough dedicated page on " "forum users list.")) is_on_index = forms.BooleanField( label=_("Show users online on forum index"), required=False, help_text=_("Selecting this option will make forum inform other " "users of their availability by displaying them on forum " "index page.")) class Meta: model = Rank fields = [ 'name', 'description', 'css_class', 'title', 'roles', 'is_tab', 'is_on_index', ] def clean(self): data = super(RankForm, self).clean() self.instance.set_name(data.get('name')) return data
def test_error_messages_set(self): """custom error messages are set and used""" error_short = "I'm short custom error!" error_long = "I'm long custom error!" validator = validate_sluggable(error_short, error_long) self.assertEqual(validator.error_short, error_short) self.assertEqual(validator.error_long, error_long)
def test_faulty_input_validation(self): """invalid values raise errors""" validator = validate_sluggable() with self.assertRaises(ValidationError): validator('!#@! !@#@') with self.assertRaises(ValidationError): validator('!#@! !@#@ 1234567890 1234567890 1234567890 1234567890' '1234567890 1234567890 1234567890 1234567890 1234567890' '1234567890 1234567890 1234567890 1234567890 1234567890' '1234567890 1234567890 1234567890 1234567890 1234567890' '1234567890 1234567890 1234567890 1234567890 1234567890')
class LabelForm(forms.ModelForm): name = forms.CharField(label=_("Label name"), validators=[validate_sluggable()]) css_class = forms.CharField( label=_("CSS class"), required=False, help_text=_("Optional CSS clas used to style this label.")) forums = AdminForumMultipleChoiceField( label=_('Forums'), required=False, widget=forms.CheckboxSelectMultiple(), help_text=_('Select forums this label will be available in.')) class Meta: model = Label fields = ['name', 'css_class', 'forums'] def clean_name(self): data = self.cleaned_data['name'] self.instance.set_name(data) return data
class RankForm(forms.ModelForm): name = forms.CharField( label=_("Name"), validators=[validate_sluggable()], help_text=_('Short and descriptive name of all users with this rank. ' '"The Team" or "Game Masters" are good examples.')) title = forms.CharField( label=_("User title"), required=False, help_text=_( 'Optional, singular version of rank name displayed by user names. ' 'For example "GM" or "Dev".')) description = forms.CharField( label=_("Description"), max_length=2048, required=False, widget=forms.Textarea(attrs={'rows': 3}), help_text=_("Optional description explaining function or status of " "members distincted with this rank.")) roles = forms.ModelMultipleChoiceField( label=_("User roles"), widget=forms.CheckboxSelectMultiple, queryset=Role.objects.order_by('name'), required=False, help_text=_("Rank can give additional roles to users with it.")) css_class = forms.CharField( label=_("CSS class"), required=False, help_text=_( "Optional css class added to content belonging to this rank owner." )) is_tab = forms.BooleanField( label=_("Give rank dedicated tab on users list"), required=False, help_text=_("Selecting this option will make users with this rank " "easily discoverable by others trough dedicated page on " "forum users list.")) class Meta: model = Rank fields = [ 'name', 'description', 'css_class', 'title', 'roles', 'is_tab', ] def clean_name(self): data = self.cleaned_data['name'] self.instance.set_name(data) unique_qs = Rank.objects.filter(slug=self.instance.slug) if self.instance.pk: unique_qs = unique_qs.exclude(pk=self.instance.pk) if unique_qs.exists(): raise forms.ValidationError( _("This name collides with other rank.")) return data
class CategoryFormBase(forms.ModelForm): name = forms.CharField(label=_("Name"), validators=[validate_sluggable()]) description = forms.CharField( label=_("Description"), max_length=2048, required=False, widget=forms.Textarea(attrs={'rows': 3}), help_text=_( "Optional description explaining category intented purpose.")) css_class = forms.CharField( label=_("CSS class"), required=False, help_text=_("Optional CSS class used to customize this category " "appearance from templates.")) is_closed = YesNoSwitch( label=_("Closed category"), required=False, help_text=_("Only members with valid permissions can post in " "closed categories.")) css_class = forms.CharField( label=_("CSS class"), required=False, help_text=_("Optional CSS class used to customize this category " "appearance from templates.")) prune_started_after = forms.IntegerField( label=_("Thread age"), min_value=0, help_text=_("Prune thread if number of days since its creation is " "greater than specified. Enter 0 to disable this " "pruning criteria.")) prune_replied_after = forms.IntegerField( label=_("Last reply"), min_value=0, help_text=_("Prune thread if number of days since last reply is " "greater than specified. Enter 0 to disable this " "pruning criteria.")) class Meta: model = Category fields = [ 'name', 'description', 'css_class', 'is_closed', 'prune_started_after', 'prune_replied_after', 'archive_pruned_in', ] def clean_copy_permissions(self): data = self.cleaned_data['copy_permissions'] if data and data.pk == self.instance.pk: message = _( "Permissions cannot be copied from category into itself.") raise forms.ValidationError(message) return data def clean_archive_pruned_in(self): data = self.cleaned_data['archive_pruned_in'] if data and data.pk == self.instance.pk: message = _("Category cannot act as archive for itself.") raise forms.ValidationError(message) return data def clean(self): data = super(CategoryFormBase, self).clean() self.instance.set_name(data.get('name')) return data
def test_valid_input_validation(self): """valid values don't raise errors""" validator = validate_sluggable() validator('Bob') validator('Lorem ipsum123!')
class ForumFormBase(forms.ModelForm): role = forms.ChoiceField(label=_("Type"), choices=FORUM_ROLES) name = forms.CharField(label=_("Name"), validators=[validate_sluggable()]) description = forms.CharField( label=_("Description"), max_length=2048, required=False, widget=forms.Textarea(attrs={'rows': 3}), help_text=_("Optional description explaining forum intented " "purpose.")) redirect_url = forms.URLField( label=_("Redirect URL"), validators=[validate_sluggable()], help_text=_('If forum type is redirect, enter here its URL.'), required=False) css_class = forms.CharField( label=_("CSS class"), required=False, help_text=_("Optional CSS class used to customize this forum " "appearance from templates.")) is_closed = forms.YesNoSwitch( label=_("Closed forum"), required=False, help_text=_("Only members with valid permissions can post in " "closed forums.")) css_class = forms.CharField( label=_("CSS class"), required=False, help_text=_("Optional CSS class used to customize this forum " "appearance from templates.")) prune_started_after = forms.IntegerField( label=_("Thread age"), min_value=0, help_text=_("Prune thread if number of days since its creation is " "greater than specified. Enter 0 to disable this " "pruning criteria.")) prune_replied_after = forms.IntegerField( label=_("Last reply"), min_value=0, help_text=_("Prune thread if number of days since last reply is " "greater than specified. Enter 0 to disable this " "pruning criteria.")) class Meta: model = Forum fields = [ 'role', 'name', 'description', 'redirect_url', 'css_class', 'is_closed', 'prune_started_after', 'prune_replied_after', 'archive_pruned_in', ] def clean_copy_permissions(self): data = self.cleaned_data['copy_permissions'] if data and data.pk == self.instance.pk: message = _("Permissions cannot be copied from forum into itself.") raise forms.ValidationError(message) return data def clean_archive_pruned_in(self): data = self.cleaned_data['archive_pruned_in'] if data and data.pk == self.instance.pk: message = _("Forum cannot act as archive for itself.") raise forms.ValidationError(message) return data def clean(self): data = super(ForumFormBase, self).clean() self.instance.set_name(data.get('name')) if data['role'] != 'category': if not data['new_parent'].level: message = _("Only categories can have no parent category.") raise forms.ValidationError(message) if data['role'] == 'redirect': if not data.get('redirect_url'): message = _("This forum is redirect, yet you haven't " "specified URL to which it should redirect " "after click.") raise forms.ValidationError(message) return data