fields: add validation on comment field (#30618)

This commit is contained in:
Nicolas Roche 2019-09-05 17:35:00 +02:00
parent 822df94654
commit c0a09241c3
3 changed files with 84 additions and 3 deletions

View File

@ -1734,6 +1734,80 @@ def test_form_edit_comment_field(pub):
assert FormDef.get(formdef.id).fields[-1].label == '<div>blah</div>'
def test_form_comment_field_textwidget_validation(pub):
create_superuser(pub)
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
# legacy, ezt syntax in a non-html field will be presented as a textarea
formdef.fields = [fields.CommentField(id='1', type='comment',
label='[if-any toto]hello world[end]')]
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/fields/1/')
# bad {% %} Django template syntax
assert 'WysiwygTextWidget' not in resp.text
resp.form.fields['label'][0].value = '{% if cond %}no endif provided'
resp = resp.form.submit('submit')
assert 'syntax error in Django template: Unclosed tag on line 1' in resp.text
# bad {{ }} Django template syntax
assert 'WysiwygTextWidget' not in resp.text
resp.form.fields['label'][0].value = '{{0+0}}'
resp = resp.form.submit('submit')
assert 'syntax error in Django template: Could not parse' in resp.text
# bad EZT syntax
assert 'WysiwygTextWidget' not in resp.text
resp.form.fields['label'][0].value = '[end]'
resp = resp.form.submit('submit')
assert 'syntax error in ezt template: unmatched [end]' in resp.text
# good syntax
assert 'WysiwygTextWidget' not in resp.text
resp.form.fields['label'][0].value = '{{variable}}'
resp = resp.form.submit('submit')
assert FormDef.get(formdef.id).fields[0].label == '{{variable}}'
def test_form_comment_field_wysiwygtextwidget_validation(pub):
create_superuser(pub)
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [fields.CommentField(id='1', label='a comment field', type='comment')]
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/fields/1/')
assert 'a comment field' in resp.text
# bad {% %} Django template syntax
assert 'WysiwygTextWidget' in resp.text
resp.form.fields['label'][0].value = '{% if cond %}no endif provided'
resp = resp.form.submit('submit')
assert 'syntax error in Django template: Unclosed tag on line 1' in resp.text
# bad {{ }} Django template syntax
assert 'WysiwygTextWidget' in resp.text
resp.form.fields['label'][0].value = '{{0+0}}'
resp = resp.form.submit('submit')
assert 'syntax error in Django template: Could not parse' in resp.text
# bad EZT syntax
assert 'WysiwygTextWidget' in resp.text
resp.form.fields['label'][0].value = '[end]'
resp = resp.form.submit('submit')
assert 'syntax error in ezt template: unmatched [end]' in resp.text
# good syntax
assert 'WysiwygTextWidget' in resp.text
resp.form.fields['label'][0].value = '{{variable}}'
resp = resp.form.submit('submit')
assert FormDef.get(formdef.id).fields[0].label == '{{variable}}'
def test_form_edit_map_field(pub):
create_superuser(pub)
create_role()

View File

@ -719,9 +719,11 @@ class CommentField(Field):
def fill_admin_form(self, form):
if self.label and (self.label[0] != '<' and '[end]' in self.label):
form.add(TextWidget, 'label', title=_('Label'), value=self.label,
validation_function=ComputedExpressionWidget.validate_template,
required=True, cols=70, rows=3, render_br=False)
else:
form.add(WysiwygTextWidget, 'label', title=_('Label'),
validation_function=ComputedExpressionWidget.validate_template,
value=self.get_html_content(), required=True)
form.add(StringWidget, 'extra_css_class', title = _('Extra classes for CSS styling'),
value=self.extra_css_class, size=30, advanced=(not self.extra_css_class))

View File

@ -576,7 +576,7 @@ class TextWidget(quixote.form.TextWidget):
self.validation_function = kwargs.pop('validation_function', None)
super(TextWidget, self).__init__(name, *args, **kwargs)
def _parse(self, request):
def _parse(self, request, use_validation_function=True):
quixote.form.TextWidget._parse(self, request)
if self.value is not None:
try:
@ -586,7 +586,7 @@ class TextWidget(quixote.form.TextWidget):
if maxlength:
if len(self.value) > maxlength:
self.error = _('too many characters (limit is %d)') % maxlength
if self.validation_function:
if use_validation_function and self.validation_function:
try:
self.validation_function(self.value)
except ValueError as e:
@ -1554,7 +1554,7 @@ $("#%s").autocompleteArray([
class WysiwygTextWidget(TextWidget):
def _parse(self, request):
TextWidget._parse(self, request)
TextWidget._parse(self, request, use_validation_function=False)
if self.value:
if _sanitizeHTML:
self.value = _sanitizeHTML(self.value, get_request().charset, 'text/html')
@ -1568,6 +1568,11 @@ class WysiwygTextWidget(TextWidget):
def unquote_django(matchobj):
return force_str(parser.unescape(force_text(matchobj.group(0), charset)))
self.value = re.sub('{[{%](.*?)[%}]}', unquote_django, self.value)
if self.validation_function:
try:
self.validation_function(self.value)
except ValueError as e:
self.error = str(e)
def add_media(self):
get_response().add_javascript(['qommon.wysiwyg.js'])