0001-workflows-validate-email-body-and-subject-are-correc.patch
tests/test_admin_pages.py | ||
---|---|---|
1362 | 1362 |
assert workflow.possible_status[0].items[0].rules == [ |
1363 | 1363 |
{'value': 'FOOBAR', 'role_id': '1'}, {'value': 'BARFOO', 'role_id': '1'}] |
1364 | 1364 | |
1365 |
def test_workflows_edit_email_action(pub): |
|
1366 |
create_superuser(pub) |
|
1367 |
role = create_role() |
|
1368 |
Workflow.wipe() |
|
1369 |
workflow = Workflow(name='foo') |
|
1370 |
workflow.add_status(name='baz') |
|
1371 |
workflow.store() |
|
1372 | ||
1373 |
app = login(get_app(pub)) |
|
1374 |
resp = app.get('/backoffice/workflows/1/') |
|
1375 |
resp = resp.click('baz') |
|
1376 | ||
1377 |
resp.forms[0]['type'] = 'Send mail' |
|
1378 |
resp = resp.forms[0].submit() |
|
1379 |
resp = resp.follow() |
|
1380 | ||
1381 |
resp = resp.click('Send mail') |
|
1382 |
item_url = resp.request.environ['REQUEST_URI'] |
|
1383 | ||
1384 |
ok_strings = [ |
|
1385 |
'Hello world', # ordinary string |
|
1386 |
'Hello [world]', # unknown reference |
|
1387 |
'Hello [if-any world][world][end]', # unknown reference, in condition |
|
1388 |
'Hello world ][', # random brackets |
|
1389 |
] |
|
1390 | ||
1391 |
for field in ('body', 'subject'): |
|
1392 |
for ok_string in ok_strings: |
|
1393 |
resp = app.get(item_url) |
|
1394 |
resp.form[field] = ok_string |
|
1395 |
resp = resp.form.submit('submit') |
|
1396 |
assert resp.location |
|
1397 | ||
1398 |
resp = app.get(item_url) |
|
1399 |
resp.form[field] = 'Hello [if-any world][world][else].' |
|
1400 |
resp = resp.form.submit('submit') |
|
1401 |
assert 'error in template' in resp.body and 'unclosed block' in resp.body |
|
1402 | ||
1403 |
resp = app.get(item_url) |
|
1404 |
resp.form[field] = 'Hello [if-any world][world][else].[end] [end]' |
|
1405 |
resp = resp.form.submit('submit') |
|
1406 |
assert 'error in template' in resp.body and 'unmatched [end]' in resp.body |
|
1407 | ||
1408 | ||
1365 | 1409 |
def test_workflows_variables(pub): |
1366 | 1410 |
create_superuser(pub) |
1367 | 1411 |
create_role() |
wcs/qommon/form.py | ||
---|---|---|
439 | 439 |
r += htmltext('</tr>\n') |
440 | 440 |
return r.getvalue() |
441 | 441 | |
442 | ||
443 |
class StringWidget(quixote.form.StringWidget): |
|
444 |
def __init__(self, name, *args, **kwargs): |
|
445 |
self.validation_function = kwargs.pop('validation_function', None) |
|
446 |
super(StringWidget, self).__init__(name, *args, **kwargs) |
|
447 | ||
448 |
def _parse(self, request): |
|
449 |
quixote.form.StringWidget._parse(self, request) |
|
450 |
if self.value and self.validation_function: |
|
451 |
try: |
|
452 |
self.validation_function(self.value) |
|
453 |
except ValueError as e: |
|
454 |
self.error = str(e) |
|
455 | ||
456 | ||
442 | 457 |
class TextWidget(quixote.form.TextWidget): |
458 |
def __init__(self, name, *args, **kwargs): |
|
459 |
self.validation_function = kwargs.pop('validation_function', None) |
|
460 |
super(TextWidget, self).__init__(name, *args, **kwargs) |
|
461 | ||
443 | 462 |
def _parse(self, request): |
444 | 463 |
quixote.form.TextWidget._parse(self, request) |
445 | 464 |
if self.value is not None: |
... | ... | |
449 | 468 |
maxlength = 0 |
450 | 469 |
if maxlength and len(self.value) > maxlength: |
451 | 470 |
self.error = _('too many characters (limit is %d)') % maxlength |
471 |
if self.validation_function: |
|
472 |
try: |
|
473 |
self.validation_function(self.value) |
|
474 |
except ValueError as e: |
|
475 |
self.error = str(e) |
|
452 | 476 | |
453 | 477 |
class CheckboxWidget(quixote.form.CheckboxWidget): |
454 | 478 |
''' |
wcs/workflows.py | ||
---|---|---|
1593 | 1593 |
self.get_list_of_roles(include_logged_in_users=False)}) |
1594 | 1594 |
if 'subject' in parameters: |
1595 | 1595 |
form.add(StringWidget, '%ssubject' % prefix, title=_('Subject'), |
1596 |
validation_function=validate_ezt, |
|
1596 | 1597 |
value=self.subject, size=40) |
1597 | 1598 |
if 'body' in parameters: |
1598 | 1599 |
form.add(TextWidget, '%sbody' % prefix, title=_('Body'), |
1599 | 1600 |
value=self.body, cols=80, rows=10, |
1601 |
validation_function=validate_ezt, |
|
1600 | 1602 |
hint=_('Available variables: url, url_status, details, name, number, comment, field_NAME')) |
1601 | 1603 | |
1602 | 1604 | |
... | ... | |
1718 | 1720 | |
1719 | 1721 |
return fd.getvalue() |
1720 | 1722 | |
1723 | ||
1724 |
def validate_ezt(template): |
|
1725 |
processor = ezt.Template(compress_whitespace=False) |
|
1726 |
try: |
|
1727 |
processor.parse(template or '') |
|
1728 |
except ezt.EZTException as e: |
|
1729 |
parts = [] |
|
1730 |
parts.append({ |
|
1731 |
ezt.ArgCountSyntaxError: _('wrong number of arguments'), |
|
1732 |
ezt.UnknownReference: _('unknown reference'), |
|
1733 |
ezt.NeedSequenceError: _('sequence required'), |
|
1734 |
ezt.UnclosedBlocksError: _('unclosed block'), |
|
1735 |
ezt.UnmatchedEndError: _('unmatched [end]'), |
|
1736 |
ezt.BaseUnavailableError: _('unavailable base location'), |
|
1737 |
ezt.BadFormatConstantError: _('bad format constant'), |
|
1738 |
ezt.UnknownFormatConstantError: _('unknown format constant'), |
|
1739 |
}.get(e.__class__)) |
|
1740 |
if e.line: |
|
1741 |
parts.append(_('at line %d and column %d') % (e.line+1, e.column+1)) |
|
1742 |
raise ValueError(_('error in template (%s)') % ' '.join(parts)) |
|
1743 | ||
1721 | 1744 |
class SendSMSWorkflowStatusItem(WorkflowStatusItem): |
1722 | 1745 |
description = N_('Send SMS') |
1723 | 1746 |
key = 'sendsms' |
1724 |
- |