wcs/tests/test_widgets.py

980 lines
36 KiB
Python

# -*- coding: utf-8 -*-
import datetime
import sys
import shutil
import copy
from quixote import cleanup, get_response
from quixote.http_request import parse_query
import mechanize
import pytest
from wcs import publisher
from wcs.qommon import sessions
from wcs.qommon.form import *
from wcs.qommon.http_request import HTTPRequest
from utilities import create_temporary_pub
def setup_module(module):
cleanup()
global pub, req
pub = create_temporary_pub()
req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
req.language = None
pub._set_request(req)
def teardown_module(module):
shutil.rmtree(pub.APP_DIR)
class MockHtmlForm(object):
def __init__(self, widget):
widget = copy.deepcopy(widget)
form = Form(method='post', use_tokens=False, enctype='application/x-www-form-urlencoded')
form.widgets.append(widget)
self.as_html = str(form.render())
response = mechanize._response.test_html_response(self.as_html, headers=[], url='')
factory = mechanize.Browser()
factory.set_response(response)
self.factory = factory
self.form = list(factory.forms())[0]
def set_form_value(self, name, value):
self.form.set_value(value, name)
def set_form_hidden_value(self, name, value):
self.form.find_control(name).readonly = False
self.form.set_value(value, name)
def get_parsed_query(self):
return parse_query(self.form._request_data()[1], 'utf-8')
def mock_form_submission(req, widget, html_vars={}, click=None, hidden_html_vars={}):
form = MockHtmlForm(widget)
for k, v in html_vars.items():
form.set_form_value(k, v)
for k, v in hidden_html_vars.items():
form.set_form_hidden_value(k, v)
if click is not None:
request = form.form.click(click)
req.form = parse_query(request.data, 'utf-8')
else:
req.form = form.get_parsed_query()
def test_stringwidget_values():
widget = StringWidget('test')
form = MockHtmlForm(widget)
assert 'name="test"' in form.as_html
req.form = {}
assert widget.parse() is None
widget = StringWidget('test', value='foo')
req.form = {}
assert widget.parse() == 'foo'
widget = StringWidget('test', value='foo')
mock_form_submission(req, widget, {'test': ''})
assert widget.parse() is None
widget = StringWidget('test', value='foo')
mock_form_submission(req, widget, {'test': 'bar'})
assert widget.parse() == 'bar'
def test_stringwidget_strip():
widget = StringWidget('test', value='foo')
mock_form_submission(req, widget, {'test': ' bar '})
assert widget.parse() == 'bar'
def test_stringwidget_required():
widget = StringWidget('test', value='foo', required=True)
mock_form_submission(req, widget, {'test': ''})
assert widget.has_error()
widget = StringWidget('test', value='foo', required=True)
mock_form_submission(req, widget, {'test': 'bar'})
assert not widget.has_error()
assert widget.parse() == 'bar'
def test_stringwidget_readonly():
widget = StringWidget('test', value='foo', required=True)
assert 'readonly' not in str(widget.render())
widget = StringWidget('test', value='foo', required=True, readonly=False)
assert 'readonly' not in str(widget.render())
widget = StringWidget('test', value='foo', required=True, readonly=True)
assert 'readonly="readonly"' in str(widget.render())
def test_table_list_rows():
widget = TableListRowsWidget('test', columns=['a', 'b', 'c'])
form = MockHtmlForm(widget)
req.form = {}
for row in range(5):
for col in range(3):
assert 'test$element%d$col%d' % (row, col) in form.as_html
widget = TableListRowsWidget('test', columns=['a', 'b', 'c'])
form = MockHtmlForm(widget)
mock_form_submission(req, widget, {'test$element0$col0': 'bar',
'test$element1$col1': 'foo'})
assert widget.parse() == [[u'bar', None, None], [None, u'foo', None]]
def test_table_list_rows_add_row():
widget = TableListRowsWidget('test', columns=['a', 'b', 'c'])
form = MockHtmlForm(widget)
req.form = {}
mock_form_submission(req, widget, click='test$add_element')
widget = TableListRowsWidget('test', columns=['a', 'b', 'c'])
form = MockHtmlForm(widget)
for row in range(6): # one more row
for col in range(3):
assert 'test$element%d$col%d' % (row, col) in form.as_html
def test_table_list_rows_required():
req.form = {}
widget = TableListRowsWidget('test', columns=['a', 'b', 'c'], required=True)
form = MockHtmlForm(widget)
mock_form_submission(req, widget)
widget = TableListRowsWidget('test', columns=['a', 'b', 'c'], required=True)
assert widget.has_error()
req.form = {}
widget = TableListRowsWidget('test', columns=['a', 'b', 'c'], required=True)
mock_form_submission(req, widget, click='test$add_element')
widget = TableListRowsWidget('test', columns=['a', 'b', 'c'], required=True)
assert not widget.has_error()
def test_table_list_rows_set_many_values():
widget = TableListRowsWidget('test', columns=['a', 'b', 'c'])
form = MockHtmlForm(widget)
req.form = {}
widget = TableListRowsWidget('test', columns=['a', 'b', 'c'])
widget.set_value([(str(x), None, None) for x in range(10)])
form = MockHtmlForm(widget)
for row in range(10):
for col in range(3):
assert 'test$element%d$col%d' % (row, col) in form.as_html
assert not 'test$element%d$col%d' % (10, 0) in form.as_html
mock_form_submission(req, widget, click='test$add_element')
widget = TableListRowsWidget('test', columns=['a', 'b', 'c'])
form = MockHtmlForm(widget)
assert 'test$element%d$col%d' % (10, 0) in form.as_html
def test_table_widget():
req.form = {}
widget = TableWidget('test', columns=['a', 'b', 'c'], rows=['A', 'B'])
widget.set_value([['0'], ['1']])
assert widget.get_widget('c-0-0').value == '0'
assert widget.get_widget('c-0-1').value is None
assert widget.get_widget('c-1-0').value == '1'
assert widget.get_widget('c-1-1').value is None
form = MockHtmlForm(widget)
assert 'value="0"' in form.as_html
assert 'value="1"' in form.as_html
mock_form_submission(req, widget, {'test$c-0-0': 'X', 'test$c-0-1': 'Y'})
assert widget.parse() == [[u'X', u'Y', None], [u'1', None, None]]
def test_passwordentry_widget_success():
widget = PasswordEntryWidget('test')
form = MockHtmlForm(widget)
assert 'name="test$pwd1"' in form.as_html
req.form = {}
assert widget.parse() is None
widget = PasswordEntryWidget('test', value={'cleartext': 'foo'}, formats=['cleartext'])
req.form = {}
assert widget.parse() == {'cleartext': 'foo'}
widget = PasswordEntryWidget('test', formats=['cleartext'])
req.form = {}
mock_form_submission(req, widget, {'test$pwd1': ''})
assert widget.parse() is None
widget = PasswordEntryWidget('test', formats=['cleartext'])
req.form = {}
mock_form_submission(req, widget, {'test$pwd1': 'foo', 'test$pwd2': 'foo'})
assert widget.parse() == {'cleartext': 'foo'}
widget = PasswordEntryWidget('test', formats=['cleartext'], confirmation=False)
req.form = {}
mock_form_submission(req, widget, {'test$pwd1': 'foo'})
assert widget.parse() == {'cleartext': 'foo'}
def test_passwordentry_widget_errors():
# mismatch
widget = PasswordEntryWidget('test', formats=['cleartext'])
req.form = {}
mock_form_submission(req, widget, {'test$pwd1': 'foo', 'test$pwd2': 'bar'})
assert widget.parse() is None
assert widget.has_error() is True
# too short
widget = PasswordEntryWidget('test', formats=['cleartext'], min_length=4)
req.form = {}
mock_form_submission(req, widget, {'test$pwd1': 'foo', 'test$pwd2': 'foo'})
assert widget.parse() is None
assert widget.has_error() is True
# uppercases
widget = PasswordEntryWidget('test', formats=['cleartext'], count_uppercase=1)
req.form = {}
mock_form_submission(req, widget, {'test$pwd1': 'foo', 'test$pwd2': 'foo'})
assert widget.parse() is None
assert widget.has_error() is True
# digits
widget = PasswordEntryWidget('test', formats=['cleartext'], count_digit=1)
req.form = {}
mock_form_submission(req, widget, {'test$pwd1': 'foo', 'test$pwd2': 'foo'})
assert widget.parse() is None
assert widget.has_error() is True
# specials
widget = PasswordEntryWidget('test', formats=['cleartext'], count_special=1)
req.form = {}
mock_form_submission(req, widget, {'test$pwd1': 'foo', 'test$pwd2': 'foo'})
assert widget.parse() is None
assert widget.has_error() is True
def test_textwidget():
widget = TextWidget('test')
form = MockHtmlForm(widget)
assert 'name="test"' in form.as_html
req.form = {}
assert widget.parse() is None
widget = TextWidget('test', value='foo')
req.form = {}
assert widget.parse() == 'foo'
widget = TextWidget('test', value='foo')
mock_form_submission(req, widget, {'test': ''})
assert widget.parse() is None
widget = TextWidget('test', value='foo')
mock_form_submission(req, widget, {'test': 'bar'})
assert widget.parse() == 'bar'
widget = TextWidget('test', value='foo', maxlength=10)
mock_form_submission(req, widget, {'test': 'bar'})
assert not widget.has_error()
assert widget.parse() == 'bar'
widget = TextWidget('test', value='foo', maxlength=10)
mock_form_submission(req, widget, {'test': 'bar'*10})
assert widget.has_error()
assert widget.get_error() == 'too many characters (limit is 10)'
def test_emailwidget():
pub.cfg = {'emails': {'check_domain_with_dns': True}}
get_response().javascript_code_parts = []
widget = EmailWidget('test')
form = MockHtmlForm(widget)
assert 'name="test"' in form.as_html
assert 'WCS_WELL_KNOWN_DOMAINS' in ''.join(get_response().javascript_code_parts)
req.form = {}
assert widget.parse() is None
widget = EmailWidget('test')
mock_form_submission(req, widget, {'test': 'foo@localhost'})
assert not widget.has_error()
assert widget.parse() == 'foo@localhost'
widget = EmailWidget('test')
mock_form_submission(req, widget, {'test': 'foo'})
assert widget.has_error()
widget = EmailWidget('test')
mock_form_submission(req, widget, {'test': 'foo@localhost@test'})
assert widget.has_error()
widget = EmailWidget('test')
mock_form_submission(req, widget, {'test': 'foo@localhost..localdomain'})
assert widget.has_error()
def test_date_widget():
widget = DateWidget('test')
form = MockHtmlForm(widget)
assert 'name="test"' in form.as_html
req.form = {}
assert widget.parse() is None
pub.cfg['language'] = {'language': 'en'}
widget = DateWidget('test')
mock_form_submission(req, widget, {'test': '2014-1-20'})
assert not widget.has_error()
assert widget.parse() == '2014-01-20'
# check two-digit years
widget = DateWidget('test')
mock_form_submission(req, widget, {'test': '14-1-20'})
assert not widget.has_error()
assert widget.parse() == '2014-01-20'
widget = DateWidget('test', maximum_date='1/1/2014') # accept "fr" format
mock_form_submission(req, widget, {'test': '2014-1-20'})
assert widget.has_error()
pub.cfg['language'] = {'language': 'fr'}
widget = DateWidget('test')
mock_form_submission(req, widget, {'test': '20/1/2014'})
assert not widget.has_error()
assert widget.parse() == '20/01/2014'
mock_form_submission(req, widget, {'test': '2014-1-20'})
assert not widget.has_error()
assert widget.parse() == '20/01/2014'
widget = DateWidget('test', minimum_date='1/1/2014')
mock_form_submission(req, widget, {'test': '20/1/2014'})
assert not widget.has_error()
widget = DateWidget('test', minimum_date='1/1/2014')
mock_form_submission(req, widget, {'test': '20/1/2013'})
assert widget.has_error()
widget = DateWidget('test', maximum_date='1/1/2014')
mock_form_submission(req, widget, {'test': '20/1/2013'})
assert not widget.has_error()
widget = DateWidget('test', maximum_date='1/1/2014')
mock_form_submission(req, widget, {'test': '20/1/2014'})
assert widget.has_error()
widget = DateWidget('test', maximum_date='2014-1-1') # accept "C" format
mock_form_submission(req, widget, {'test': '20/1/2014'})
assert widget.has_error()
yesterday = (datetime.date.today() - datetime.timedelta(days=1)).strftime(widget.get_format_string())
tomorrow = (datetime.date.today() + datetime.timedelta(days=1)).strftime(widget.get_format_string())
widget = DateWidget('test', minimum_is_future=True)
mock_form_submission(req, widget, {'test': tomorrow})
assert not widget.has_error()
widget = DateWidget('test', minimum_is_future=True)
mock_form_submission(req, widget, {'test': yesterday})
assert widget.has_error()
widget = DateWidget('test', date_in_the_past=True)
mock_form_submission(req, widget, {'test': tomorrow})
assert widget.has_error()
widget = DateWidget('test', date_in_the_past=True)
mock_form_submission(req, widget, {'test': yesterday})
assert not widget.has_error()
def test_wysiwygwidget():
widget = WysiwygTextWidget('test')
form = MockHtmlForm(widget)
assert 'name="test"' in form.as_html
req.form = {}
assert widget.parse() is None
widget = WysiwygTextWidget('test')
mock_form_submission(req, widget, {'test': 'bla bla bla'})
assert not widget.has_error()
assert widget.parse() == 'bla bla bla'
import wcs.qommon.form
sanitize_html = wcs.qommon.form._sanitizeHTML
if sanitize_html:
widget = WysiwygTextWidget('test')
mock_form_submission(req, widget, {'test': '<p>bla bla bla</p>'})
assert not widget.has_error()
assert widget.parse() == '<p>bla bla bla</p>'
widget = WysiwygTextWidget('test')
mock_form_submission(req, widget, {'test': '<a href="#">a</a>'})
assert not widget.has_error()
assert widget.parse() == '<a href="#">a</a>'
widget = WysiwygTextWidget('test')
mock_form_submission(req, widget, {'test': '<a href="javascript:alert()">a</a>'})
assert not widget.has_error()
assert widget.parse() == '<a href="">a</a>' # javascript: got filtered
# check django syntax is kept intact
widget = WysiwygTextWidget('test')
mock_form_submission(req, widget, {'test': '<a href="{% if 1 > 2 %}héllo{% endif %}">{% if 2 > 1 %}{{plop|date:"Y"}}{% endif %}</a>'})
assert not widget.has_error()
assert widget.parse() == '<a href="{% if 1 > 2 %}héllo{% endif %}">{% if 2 > 1 %}{{plop|date:"Y"}}{% endif %}</a>'
# make sure it is kept intact even after ckeditor escaped characters
widget = WysiwygTextWidget('test')
mock_form_submission(req, widget, {'test': '<a href="{% if 1 &gt; 2 %}héllo{% endif %}">{% if 2 &gt; 1 %}{{plop|date:&quot;Y&quot;}}{% endif %}</a>'})
assert not widget.has_error()
assert widget.parse() == '<a href="{% if 1 > 2 %}héllo{% endif %}">{% if 2 > 1 %}{{plop|date:"Y"}}{% endif %}</a>'
# check we don't escape HTML if feedparser _sanitizeHTML is missing
wcs.qommon.form._sanitizeHTML = None
widget = WysiwygTextWidget('test')
mock_form_submission(req, widget, {'test': '<p>bla bla bla</p>'})
assert not widget.has_error()
assert widget.parse() == '<p>bla bla bla</p>'
wcs.qommon.form._sanitizeHTML = sanitize_html
def test_select_widget():
widget = SingleSelectHintWidget('test',
options=[
('apple', 'Apple', 'apple'),
('pear', 'Pear', 'pear'),
('peach', 'Peach', 'peach')])
assert widget.has_valid_options()
widget = SingleSelectHintWidget('test',
options=[
('apple', 'Apple', 'apple'),
('pear', 'Pear', 'pear'),
('peach', 'Peach', 'peach')],
options_with_attributes=[
('apple', 'Apple', 'apple', {}),
('pear', 'Pear', 'pear', {'disabled': True}),
('peach', 'Peach', 'peach', {})])
assert widget.has_valid_options()
mock_form_submission(req, widget, {'test': ['apple']})
assert widget.parse() == 'apple'
with pytest.raises(AttributeError):
# mechanize will
# raise AttributeError(
# "insufficient non-disabled items with name %s" % name)
# as the item is disabled
mock_form_submission(req, widget, {'test': ['pear']})
widget = SingleSelectHintWidget('test',
options=[
('apple', 'Apple', 'apple'),
('pear', 'Pear', 'pear'),
('peach', 'Peach', 'peach')],
options_with_attributes=[
('apple', 'Apple', 'apple', {'disabled': True}),
('pear', 'Pear', 'pear', {'disabled': True}),
('peach', 'Peach', 'peach', {'disabled': True})])
assert not widget.has_valid_options()
# test readonly only includes the selected value
req.form = {}
widget = SingleSelectHintWidget('test',
options=[
('apple', 'Apple', 'apple'),
('pear', 'Pear', 'pear'),
('peach', 'Peach', 'peach')])
widget.readonly = 'readonly'
widget.attrs['readonly'] = 'readonly'
assert 'apple' in str(widget.render()) and 'pear' in str(widget.render())
widget.set_value('pear')
assert 'apple' not in str(widget.render()) and 'pear' in str(widget.render())
assert 'readonly="readonly"' not in str(widget.render())
def test_select_or_other_widget():
widget = SingleSelectWidgetWithOther('test',
options=[('apple', 'Apple'), ('pear', 'Pear'), ('peach', 'Peach')])
form = MockHtmlForm(widget)
assert '__other' in form.as_html
assert 'Other:' in form.as_html
assert widget.parse() is None
widget = SingleSelectWidgetWithOther('test',
options=[('apple', 'Apple'), ('pear', 'Pear'), ('peach', 'Peach')],
other_label='Alternative:')
form = MockHtmlForm(widget)
assert '__other' in form.as_html
assert 'Alternative:' in form.as_html
widget = SingleSelectWidgetWithOther('test',
options=[('apple', 'Apple'), ('pear', 'Pear'), ('peach', 'Peach')])
mock_form_submission(req, widget, {'test$choice': ['apple']})
assert widget.parse() == 'apple'
widget = SingleSelectWidgetWithOther('test',
options=[('apple', 'Apple'), ('pear', 'Pear'), ('peach', 'Peach')])
mock_form_submission(req, widget, {'test$choice': ['__other'], 'test$other': 'Apricot'})
assert widget.parse() == 'Apricot'
def test_checkboxes_widget():
widget = CheckboxesWidget('test',
options=[('apple', 'Apple', 'apple'), ('pear', 'Pear', 'pear'), ('peach', 'Peach', 'peach')])
mock_form_submission(req, widget, {'test$elementpeach': ['yes'], 'test$elementpear': ['yes']})
assert widget.parse() == ['pear', 'peach']
def test_composite_widget():
widget = CompositeWidget('compotest')
widget.add(StringWidget, name='str1')
widget.add(StringWidget, name='str2', required=True)
req.form = {'compotest$str1': 'foo1', 'compotest$str2': 'foo2'}
form = MockHtmlForm(widget)
assert not widget.has_error()
assert len(widget.widgets) == 2
assert widget.widgets[0].parse() == 'foo1'
assert widget.widgets[1].parse() == 'foo2'
widget = CompositeWidget('compotest')
widget.add(StringWidget, name='str1')
widget.add(StringWidget, name='str2', required=True)
req.form = {'compotest$str1': 'alone'}
form = MockHtmlForm(widget)
assert widget.has_error()
assert not widget.widgets[0].has_error()
assert widget.widgets[0].parse() == 'alone'
assert widget.widgets[1].has_error()
assert 'required' in widget.widgets[1].get_error()
req.session = sessions.Session(id=1) # needed by FileWithPreviewWidget
widget = CompositeWidget('compotest')
widget.add(StringWidget, name='str1')
widget.add(FileWithPreviewWidget, name='')
assert 'class="FileWithPreviewWidget widget file-upload-widget"' in str(
widget.render_content_as_tr()) # extra_css_class is present
def test_computed_expression_widget():
widget = ComputedExpressionWidget('test')
form = MockHtmlForm(widget)
mock_form_submission(req, widget, {'test$value_text': 'hello world', 'test$type': ['text']})
assert widget.parse() == 'hello world'
assert not widget.has_error()
widget = ComputedExpressionWidget('test')
form = MockHtmlForm(widget)
mock_form_submission(req, widget, {'test$value_text': '', 'test$type': ['text']})
assert widget.parse() == None
assert not widget.has_error()
# python value left empty
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_python': '', 'test$type': ['python']})
assert not widget.has_error()
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$type': ['python']})
assert not widget.has_error()
# but field marqued as required
widget = ComputedExpressionWidget('test', required=True)
mock_form_submission(req, widget, {'test$value_python': '', 'test$type': ['python']})
assert widget.has_error()
# invalid values
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_python': 'hello world', 'test$type': ['python']})
assert widget.has_error()
assert widget.get_error().startswith('syntax error')
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_python': '=3', 'test$type': ['python']})
assert widget.has_error()
assert widget.get_error().startswith('syntax error')
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_python': '{{form_var_foo}}', 'test$type': ['python']})
assert widget.has_error()
assert 'Python expression cannot contain {{' in widget.get_error()
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_template': '{{ form_var_xxx }}', 'test$type': ['template']})
assert not widget.has_error()
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_template': '{% if True %}', 'test$type': ['template']})
assert widget.has_error()
assert widget.get_error().startswith('syntax error in Django template')
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_template': '[form_var_xxx]', 'test$type': ['template']})
assert not widget.has_error()
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_template': '[end]', 'test$type': ['template']})
assert widget.has_error()
assert widget.get_error().startswith('syntax error in ezt template')
def test_wcsextrastringwidget():
widget = WcsExtraStringWidget('test', value='foo', required=True)
mock_form_submission(req, widget, {'test': ''})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=True)
mock_form_submission(req, widget, {'test': 'bar'})
assert not widget.has_error()
assert widget.parse() == 'bar'
def test_wcsextrastringwidget_regex_validation():
# check regex validation
class FakeField: pass
fakefield = FakeField()
fakefield.validation = {'type': 'regex', 'value': r'\d+'}
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '123'})
assert not widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '123 ab'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': 'cdab 12'})
assert widget.has_error()
fakefield.validation = {'type': 'regex', 'value': r'\d+(\.\d{1,2})?'}
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '12'})
assert not widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '12.34'})
assert not widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '12,34'})
assert widget.has_error()
def test_wcsextrastringwidget_builtin_validation():
class FakeField: pass
fakefield = FakeField()
fakefield.validation = {'type': 'digits'}
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '12'})
assert not widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': 'az'})
assert widget.has_error()
fakefield.validation = {'type': 'zipcode-fr'}
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '12345'})
assert not widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '1234'})
assert widget.has_error()
def test_wcsextrastringwidget_phone():
class FakeField:
pass
fakefield = FakeField()
fakefield.validation = {'type': 'phone'}
# check validation
for valid_case in ('0123456789', '+321234566', '02/123.45.67', '+33(0)2 34 56 78 90'):
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': valid_case})
assert not widget.has_error()
for invalid_case in ('az', '123 az', 'aZ 1234'):
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': invalid_case})
assert widget.has_error()
# and check it gets a special HTML input type
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
assert 'type="tel"' in str(widget.render())
def test_wcsextrastringwidget_phone_fr():
class FakeField:
pass
fakefield = FakeField()
# check validation
fakefield.validation = {'type': 'phone-fr'}
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '0123456789'})
assert not widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '01 23 45 67 89'})
assert not widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': 'az'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '0123'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '01234567890123'})
assert widget.has_error()
# and check it gets a special HTML input type
assert 'type="tel"' in str(widget.render())
def test_wcsextrastringwidget_siren_validation():
class FakeField: pass
fakefield = FakeField()
fakefield.validation = {'type': 'siren-fr'}
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '443170139'})
assert not widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '443170130'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '44317013900036'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': 'XXX170130'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '443170¹39'})
assert widget.has_error()
def test_wcsextrastringwidget_siret_validation():
class FakeField: pass
fakefield = FakeField()
fakefield.validation = {'type': 'siret-fr'}
# regular case
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '44317013900036'})
assert not widget.has_error()
# special case la poste
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '35600000000048'})
assert not widget.has_error()
# failing cases
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '44317013900037'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': 'ABC17013900037'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '443170139'})
assert widget.has_error()
def test_wcsextrastringwidget_nir_validation():
class FakeField: pass
fakefield = FakeField()
fakefield.validation = {'type': 'nir-fr'}
# regular cases
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
# https://fr.wikipedia.org/wiki/Num%C3%A9ro_de_s%C3%A9curit%C3%A9_sociale_en_France#/media/Fichier:CarteVitale2.jpg
mock_form_submission(req, widget, {'test': '269054958815780'})
assert not widget.has_error()
# corsica
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '269052A58815717'})
assert not widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '269052B58815744'})
assert not widget.has_error()
# failing cases
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '42'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '269054958815700'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': 'hello 789012345'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '069054958815780'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '269004958815780'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '269054900015780'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '269054958800080'})
assert widget.has_error()
def test_wcsextrastringwidget_iban_validation():
class FakeField: pass
fakefield = FakeField()
fakefield.validation = {'type': 'iban'}
# regular cases
for iban in ['BE71 0961 2345 6769', # Belgium
'FR76 3000 6000 0112 3456 7890 189', # France
'FR27 2004 1000 0101 2345 6Z02 068', # France (having letter)
'DE91 1000 0000 0123 4567 89', # Germany
'GR96 0810 0010 0000 0123 4567 890', # Greece
'RO09 BCYP 0000 0012 3456 7890', # Romania
'SA44 2000 0001 2345 6789 1234', # Saudi Arabia
'ES79 2100 0813 6101 2345 6789', # Spain
'CH56 0483 5012 3456 7800 9', # Switzerland
'GB98 MIDL 0700 9312 3456 78', # United Kingdom
]:
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': iban.replace(' ', '')})
assert not widget.has_error()
# failing cases
for iban in ['42',
'FR76 2004 1000 0101 2345 6Z02 068',
'FR76 2004 1000 0101 2345 6%02 068',
'FR76 hello 234 6789 1234 6789 123',
'FRxx 2004 1000 0101 2345 6Z02 068',
'FR76 3000 6000 011² 3456 7890 189', # ²
'XX12',
'XX12 0000 00',
'FR76',
'FR76 0000 0000 0000 0000 0000 000',
'FR76 1234 4567',
'Fr76 3000 6000 0112 3456 7890 189',
]:
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': iban.replace(' ', '')})
assert widget.has_error()
def test_wcsextrastringwidget_django_validation():
class FakeField: pass
fakefield = FakeField()
fakefield.validation = {'type': 'django', 'value': 'value|decimal and value|decimal < 20'}
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '12'})
assert not widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '35'})
assert widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': 'az'})
assert widget.has_error()
def test_widgetdict_widget():
widget = WidgetDict('test', value={'a': None, 'b': None, 'c': None})
mock_form_submission(req, widget, {'test$element0key': 'a', 'test$element0value': 'value-a',
'test$element1key': 'c', 'test$element1value': 'value-c',
'test$element2key': 'b', 'test$element2value': 'value-b'})
assert widget.parse() == {'a': 'value-a', 'b': 'value-b', 'c': 'value-c'}
# on rendering, elements are ordered by their key name
html_frags = str(widget.render_content()).split()
assert (html_frags.index('name="test$element0key"') < # a
html_frags.index('name="test$element2key"') < # b
html_frags.index('name="test$element1key"')) # c
def test_map_widget():
widget = MapWidget('test', title='Map')
form = MockHtmlForm(widget)
assert 'name="test$latlng"' in form.as_html
req.form = {}
assert widget.parse() is None
widget = MapWidget('test', title='Map')
mock_form_submission(req, widget, hidden_html_vars={'test$latlng': '1.23;2.34'})
assert not widget.has_error()
assert widget.parse() == '1.23;2.34'
assert '<label' in str(widget.render())
assert not '<label ' in str(widget.render_widget_content())
pub.load_site_options()
pub.site_options.set('options', 'map-bounds-top-left', '1.23;2.34')
pub.site_options.set('options', 'map-bounds-bottom-right', '2.34;3.45')
widget = MapWidget('test', title='Map')
assert 'data-max-bounds-lat1=' in str(widget.render())
assert 'data-max-bounds-lat2=' in str(widget.render())
assert 'data-max-bounds-lng1=' in str(widget.render())
assert 'data-max-bounds-lng2=' in str(widget.render())