0001-testdef-add-support-for-computed-fields-73330.patch
tests/test_testdef.py | ||
---|---|---|
437 | 437 |
with pytest.raises(TestError) as excinfo: |
438 | 438 |
testdef.run(formdef) |
439 | 439 |
assert str(excinfo.value) == 'Invalid value "hop.pdf" for field "File": forbidden file type.' |
440 | ||
441 | ||
442 |
def test_computed_field_support(pub): |
|
443 |
formdef = FormDef() |
|
444 |
formdef.name = 'test title' |
|
445 |
formdef.fields = [ |
|
446 |
fields.PageField( |
|
447 |
id='0', |
|
448 |
label='1st page', |
|
449 |
type='page', |
|
450 |
post_conditions=[ |
|
451 |
{ |
|
452 |
'condition': { |
|
453 |
'type': 'django', |
|
454 |
'value': 'form_var_foo == "xxx" and form_var_bar == "hop"', |
|
455 |
}, |
|
456 |
'error_message': '', |
|
457 |
} |
|
458 |
], |
|
459 |
), |
|
460 |
fields.ComputedField( |
|
461 |
id='1', |
|
462 |
label='Computed (frozen)', |
|
463 |
varname='foo', |
|
464 |
value_template='{% firstof form_var_text "xxx" %}', |
|
465 |
freeze_on_initial_value=True, |
|
466 |
), |
|
467 |
fields.ComputedField( |
|
468 |
id='2', label='Computed (live)', varname='bar', value_template='{% firstof form_var_text "xxx" %}' |
|
469 |
), |
|
470 |
fields.StringField(id='3', label='Text', varname='text'), |
|
471 |
] |
|
472 |
formdef.store() |
|
473 | ||
474 |
formdata = formdef.data_class()() |
|
475 |
formdata.just_created() |
|
476 |
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple() |
|
477 |
formdata.data['1'] = 'zzz' |
|
478 |
formdata.data['3'] = 'hop' |
|
479 | ||
480 |
testdef = TestDef.create_from_formdata(formdef, formdata) |
|
481 |
testdef.run(formdef) |
|
482 | ||
483 |
formdef.fields[1].value_template = '{% for %}' |
|
484 |
testdef = TestDef.create_from_formdata(formdef, formdata) |
|
485 |
with pytest.raises(TestError) as excinfo: |
|
486 |
testdef.run(formdef) |
|
487 |
assert ( |
|
488 |
str(excinfo.value) |
|
489 |
== 'Page 1 post condition was not met (form_var_foo == "xxx" and form_var_bar == "hop").' |
|
490 |
) |
|
491 | ||
492 | ||
493 |
def test_computed_field_support_complex_data(pub): |
|
494 |
formdef = FormDef() |
|
495 |
formdef.name = 'test title' |
|
496 |
formdef.fields = [ |
|
497 |
fields.PageField( |
|
498 |
id='0', |
|
499 |
label='1st page', |
|
500 |
type='page', |
|
501 |
post_conditions=[ |
|
502 |
{'condition': {'type': 'django', 'value': '"z" in form_var_foo'}, 'error_message': ''} |
|
503 |
], |
|
504 |
), |
|
505 |
fields.ComputedField( |
|
506 |
id='1', |
|
507 |
label='Computed', |
|
508 |
varname='foo', |
|
509 |
value_template='{{form_objects|first|get:"form_var_items_raw"}}', |
|
510 |
), |
|
511 |
fields.ItemsField(id='2', label='Items', varname='items', required=False), |
|
512 |
] |
|
513 |
formdef.store() |
|
514 | ||
515 |
submitted_formdata = formdef.data_class()() |
|
516 |
submitted_formdata.just_created() |
|
517 |
submitted_formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple() |
|
518 |
submitted_formdata.data['2'] = ['a', 'b'] |
|
519 |
submitted_formdata.store() |
|
520 | ||
521 |
formdata = formdef.data_class()() |
|
522 |
formdata.just_created() |
|
523 |
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple() |
|
524 | ||
525 |
testdef = TestDef.create_from_formdata(formdef, formdata) |
|
526 |
with pytest.raises(TestError) as excinfo: |
|
527 |
testdef.run(formdef) |
|
528 |
assert str(excinfo.value) == 'Page 1 post condition was not met ("z" in form_var_foo).' |
|
529 | ||
530 |
submitted_formdata.data['2'] = ['a', 'b', 'z'] |
|
531 |
submitted_formdata.store() |
|
532 | ||
533 |
testdef.run(formdef) |
wcs/testdef.py | ||
---|---|---|
24 | 24 |
from wcs.compat import CompatHTTPRequest |
25 | 25 |
from wcs.fields import Field, PageField |
26 | 26 |
from wcs.qommon.form import FileWithPreviewWidget, Form, get_selection_error_text |
27 |
from wcs.qommon.template import TemplateError |
|
28 |
from wcs.workflows import WorkflowStatusItem |
|
27 | 29 | |
28 | 30 |
from .qommon import _, misc |
29 | 31 |
from .qommon.storage import Equal |
... | ... | |
158 | 160 |
self.evaluate_page_conditions(previous_page, formdata, objectdef) |
159 | 161 | |
160 | 162 |
def fill_page_fields(self, fields, page, formdata, objectdef): |
163 |
computed_fields = [] |
|
161 | 164 |
for field in fields: |
162 | 165 |
if field.type in ('subtitle', 'title', 'comment', 'computed'): |
163 | 166 |
continue |
... | ... | |
170 | 173 |
) |
171 | 174 |
continue |
172 | 175 | |
173 |
value = self.data['fields'].get(field.id) |
|
174 |
value = field.from_json_value(value) |
|
175 |
self.run_widget_validation(field, value) |
|
176 |
if field.key == 'computed': |
|
177 |
try: |
|
178 |
value = WorkflowStatusItem.compute(field.value_template, raises=True, allow_complex=True) |
|
179 |
except TemplateError: |
|
180 |
continue |
|
181 | ||
182 |
if not field.freeze_on_initial_value: |
|
183 |
computed_fields.append(field) |
|
184 | ||
185 |
formdata.data[field.id] = value |
|
186 |
else: |
|
187 |
value = self.data['fields'].get(field.id) |
|
188 |
value = field.from_json_value(value) |
|
189 |
self.run_widget_validation(field, value) |
|
176 | 190 |
formdata.data[field.id] = value |
177 | 191 | |
178 | 192 |
get_publisher().substitutions.invalidate_cache() |
179 | 193 | |
194 |
for field in computed_fields: |
|
195 |
try: |
|
196 |
value = WorkflowStatusItem.compute(field.value_template, raises=True, allow_complex=True) |
|
197 |
except TemplateError: |
|
198 |
continue |
|
199 | ||
200 |
formdata.data[field.id] = value |
|
201 |
get_publisher().substitutions.invalidate_cache() |
|
202 | ||
180 | 203 |
def evaluate_page_conditions(self, page, formdata, objectdef): |
181 | 204 |
for post_condition in page.post_conditions or []: |
182 | 205 |
condition = post_condition.get('condition', {}) |
183 |
- |